@@ -17,7 +17,8 @@ class Gallagher::ZoneSchedule < PlaceOS::Driver
1717 " free" => " default" ,
1818 },
1919
20- strict_presence: false ,
20+ # max time in minutes that presence can prevent a lock
21+ presence_timeout: 30 ,
2122 })
2223
2324 getter system_id : String = " "
@@ -28,7 +29,6 @@ class Gallagher::ZoneSchedule < PlaceOS::Driver
2829 getter state_mappings : Hash (String , String ) = {} of String => String
2930
3031 @update_mutex = Mutex .new
31- @strict_presence : Bool = false
3232
3333 def on_load
3434 on_update
@@ -38,7 +38,7 @@ class Gallagher::ZoneSchedule < PlaceOS::Driver
3838 @system_id = setting?(String , :gallagher_system ).presence || config.control_system.not_nil!.id
3939 @state_mappings = setting(Hash (String , String ), :state_mappings )
4040 @zone_id = setting?(String | Int64 , :zone_id ) || setting(String | Int64 , :door_zone_id )
41- @strict_presence = setting?(Bool , :strict_presence ) || false
41+ @presence_timeout = ( setting?(Int32 , :presence_timeout ) || 30 ).minutes
4242 end
4343
4444 bind Bookings_1 , :status , :status_changed
@@ -47,6 +47,9 @@ class Gallagher::ZoneSchedule < PlaceOS::Driver
4747 getter last_status : String ? = nil
4848 getter last_presence : Bool ? = nil
4949
50+ @presence_relevant : Bool = false
51+ @presence_timeout : Time ::Span = 30 .minutes
52+
5053 private def status_changed (_subscription , new_value )
5154 logger.debug { " new room status: #{ new_value } " }
5255 new_status = (String ?).from_json(new_value) rescue new_value.to_s
@@ -80,11 +83,19 @@ class Gallagher::ZoneSchedule < PlaceOS::Driver
8083 return
8184 end
8285
86+ schedule.clear
87+
8388 # This is checking if want to lock the room (not free)
84- # and if someone is possibly present
85- # then change zone state to unlock unless we are unsure about presence and the strict flag is set
86- if apply_zone_state != " free" && presence != false
87- apply_zone_state = " free" unless @strict_presence && presence.nil?
89+ # and if someone is present and presence matters
90+ # then change zone state to unlock
91+ if apply_zone_state == " free"
92+ @presence_relevant = true
93+ elsif presence && @presence_relevant
94+ apply_zone_state = " free"
95+ @presence_relevant = false
96+ schedule.in(@presence_timeout ) do
97+ @update_mutex .synchronize { apply_new_state(@last_status , @last_presence ) }
98+ end
8899 end
89100
90101 self [:zone_state ] = apply_zone_state rescue nil
0 commit comments