Search
K

Import Bookable Rooms

Steps required to import existing rooms into PlaceOS
The PlaceOS room bookings module performs the following roles:
  • A cache of upcoming bookings for staff apps
  • Data for real-time analytics (room booked, in-use, empty, etc)
  • Data for room booking panel displays
  • Data for maps
A typical configuration consists of:
  • A system with a resource email addresses defined
  • A unique instance of the PlaceOS Bookings module for that room (logic module)
  • A shared instance of the PlaceOS Calendar module, for making requests to the calendaring system
The script below runs through the level zones and updates any systems with a resource email address to the standard configuration.

Prerequisites

The client ID and secret from the domains tab in Backoffice. You can use any valid administration account credentials for that domain.
  • Create a calendar module that will be shared between all systems, note the module ID
  • Add the Bookings driver to the system and note the driver ID

Room bookings import script

The only dependency is the PlaceOS crystal client.
name: bookings-import
version: 1.0.0
# PlaceOS API integration
dependencies:
placeos:
github: placeos/crystal-client
branch: master
The script below supports redistribution and customization via the command-line options. You can also update the defaults and run it without any options.
require "option_parser"
require "placeos"
username = "[email protected]"
password = "development"
client_id = "72a17dc552329402d68b6b02191c8f"
client_secret = "f1162a1dbe96a1dc15c33cdbe41bddb98dfd107b28e00d7aff306db60d454c8a6a507c"
place_domain = "https://placeos.place.tech"
calendar_module_id = "mod-FSqCVJUOP48"
bookings_driver_id = "driver-FTIqL3xTyeD"
# Command line options
OptionParser.parse do |parser|
parser.banner = "Usage: #{PROGRAM_NAME} [arguments]"
parser.on("-m MODULE_ID", "--module=MODULE_ID", "the calendar module id to be shared in all bookable spaces") do |mod|
calendar_module_id = mod
end
parser.on("-b DRIVER_ID", "--booking=DRIVER_ID", "the bookings driver that we want in each room") do |driver|
bookings_driver_id = driver
end
parser.on("-u USERNAME", "--user=USERNAME", "username to use for import") do |user|
username = user
end
parser.on("-p PASSWORD", "--pass=PASSWORD", "password to use for import") do |pass|
password = pass
end
parser.on("-d DOMAIN", "--domain=DOMAIN", "the domain of the PlaceOS server") do |dom|
place_domain = dom
end
parser.on("-c CLIENT", "--client=CLIENT", "placeos application client") do |c|
client_id = c
end
parser.on("-s SECRET", "--secret=SECRET", "placeos application secret") do |s|
client_secret = s
end
parser.on("-h", "--help", "Show this help") do
puts parser
exit 0
end
end
# Ignore certificate errors (where self-signed certificate is in use)
class OpenSSL::SSL::Context::Client
def initialize(method : LibSSL::SSLMethod = Context.default_method)
super(method)
self.verify_mode = OpenSSL::SSL::VerifyMode::NONE
<div data-gb-custom-block data-tag="if" data-0='1.0.2' data-1='1.0.2' data-2='1.0.2' data-3='1.0.2' data-4='1.0.2' data-5='1.0.2' data-6='0' data-7='0' data-8='0' data-9='0'>
self.default_verify_param = "ssl_server"
</div>
end
end
# Configure the PlaceOS client
client = PlaceOS::Client.new(place_domain,
email: username,
password: password,
client_id: client_id,
client_secret: client_secret
)
system_count = 0
created = 0
updated = 0
errors = 0
puts "grabbing level zones..."
# Grab all the zones
zones = client.zones.search(limit: 1000, tags: "level")
puts "found #{zones.size} zones"
zones.each do |zone|
puts "checking systems in #{zone.name}..."
# Grab the systems in each zone
systems = client.systems.search(limit: 1000, zone_id: zone.id)
system_count += systems.size
# Make sure all the systems have the calendar module and a bookings driver - if email set
systems.each do |system|
next unless system.email.presence
if !system.modules.includes?(calendar_module_id)
system.modules << calendar_module_id
begin
client.systems.update(
id: system.id,
version: system.version,
modules: system.modules,
)
updated += 1
rescue error
errors += 1
puts error.inspect_with_backtrace
end
end
# check if the any of the modules are a Bookings module
modules = system.modules.dup
modules.delete(calendar_module_id) # we can safely ignore this
module_found = false
modules.each do |mod_id|
if client.modules.fetch(mod_id).driver_id == bookings_driver_id
module_found = true
break
end
end
# Add the module to the system
if !module_found
module_id = client.modules.create(
driver_id: bookings_driver_id,
control_system_id: system.id,
).id
begin
client.modules.start(module_id)
rescue
puts "failed to start #{module_id}"
errors += 1
end
created += 1
end
end
end
puts "\nchecked #{system_count} systems,\nupdated #{updated} systems,\ncreated #{created} modules."
if errors == 0
puts "success"
else
puts "#{errors} errors"
end