@@ -39,7 +39,8 @@ class InnerRange::Integriti < PlaceOS::Driver
3939 guest_card_start: 0 ,
4040 guest_card_end: (UInt16 ::MAX - 1 ),
4141
42- timezone: " Australia/Sydney" ,
42+ timezone: " Australia/Sydney" ,
43+ long_poll_seconds: 10 ,
4344 })
4445
4546 def on_update
@@ -52,6 +53,7 @@ class InnerRange::Integriti < PlaceOS::Driver
5253 guest_card_end = setting?(UInt16 , :guest_card_end ) || (UInt16 ::MAX - 1 _u16 )
5354 @guest_card_range = Range .new(guest_card_start, guest_card_end)
5455 @guest_access_group = setting?(String , :guest_access_group ) || " "
56+ @long_poll_seconds = setting?(Int32 , :long_poll_seconds ) || 10
5557
5658 transport.before_request do |request |
5759 logger.debug { " requesting: #{ request.method } #{ request.path } ?#{ request.query } \n #{ request.body } " }
@@ -68,6 +70,7 @@ class InnerRange::Integriti < PlaceOS::Driver
6870 @timezone = Time ::Location .load(time_zone) if time_zone
6971 end
7072
73+ getter long_poll_seconds : Int32 = 10
7174 getter default_unlock_time : Int32 = 10
7275 getter default_site_id : Int32 = 1
7376 getter default_partition_id : Int32 = 0
@@ -94,7 +97,8 @@ class InnerRange::Integriti < PlaceOS::Driver
9497 end
9598 end
9699
97- PROPS = {} of String => String
100+ TIME_FORMAT = " %Y-%m-%dT%H:%M:%S.%9N"
101+ PROPS = {} of String => String
98102
99103 abstract struct IntegritiObject
100104 include JSON ::Serializable
@@ -142,6 +146,8 @@ class InnerRange::Integriti < PlaceOS::Driver
142146 var_{{ variable_var }} = % content.downcase == " true"
143147 {% elsif resolved_type == Float64 % }
144148 var_{{ variable_var }} = % content.to_f?
149+ {% elsif resolved_type == Time % }
150+ var_{{ variable_var }} = Time .parse(% content, TIME_FORMAT , Time ::Location ::UTC )
145151 {% elsif resolved_type.superclass == IntegritiObject % }
146152 var_{{ variable_var }} = extract_{{variable.type.stringify.underscore.id}}(child)
147153 {% else % }
@@ -182,6 +188,8 @@ class InnerRange::Integriti < PlaceOS::Driver
182188 var_{{ variable_var }} = % content.downcase == " true"
183189 {% elsif resolved_type == Float64 % }
184190 var_{{ variable_var }} = % content.to_f?
191+ {% elsif resolved_type == Time % }
192+ var_{{ variable_var }} = Time .parse(% content, TIME_FORMAT , Time ::Location ::UTC )
185193 {% elsif resolved_type.superclass == IntegritiObject % }
186194 var_{{ variable_var }} = extract_{{variable.type.stringify.underscore.id}}(child)
187195 {% else % }
@@ -211,6 +219,8 @@ class InnerRange::Integriti < PlaceOS::Driver
211219 var_{{ variable_var }} = % content.downcase == " true"
212220 {% elsif resolved_type == Float64 % }
213221 var_{{ variable_var }} = % content.to_f?
222+ {% elsif resolved_type == Time % }
223+ var_{{ variable_var }} = Time .parse(% content, TIME_FORMAT , Time ::Location ::UTC )
214224 {% elsif resolved_type.superclass == IntegritiObject % }
215225 var_{{ variable_var }} = extract_{{variable.type.stringify.underscore.id}}(child)
216226 {% else % }
@@ -294,14 +304,17 @@ class InnerRange::Integriti < PlaceOS::Driver
294304 end
295305 end
296306
297- protected def paginate_request (category : String , type : String , filter : Filter = Filter .new, summary_only : Bool = false , & )
307+ protected def paginate_request (category : String , type : String , filter : Filter = Filter .new, summary_only : Bool = false , query : URI ::Params | String ? = nil , page_limit : Int64 ? = nil , & )
308+ query_params = " #{ query } &"
309+ query_params = " " if query_params.size == 1
298310 filter.compact!
311+ page_count = 0 _i64
299312
300313 next_page = if filter.empty?
301- " /v2/#{ category } /#{ type } ?PageSize=1000&#{ prop_param(type , summary_only) } "
314+ " /v2/#{ category } /#{ type } ?PageSize=1000&#{ query_params } #{ prop_param(type , summary_only) } "
302315 else
303316 body = build_filter(filter)
304- " /v2/#{ category } /GetFilteredEntities/#{ type } ?PageSize=1000&#{ prop_param(type , summary_only) } "
317+ " /v2/#{ category } /GetFilteredEntities/#{ type } ?PageSize=1000&#{ query_params } #{ prop_param(type , summary_only) } "
305318 end
306319
307320 next_uri = URI .parse(next_page)
@@ -337,7 +350,8 @@ class InnerRange::Integriti < PlaceOS::Driver
337350 end
338351 end
339352
340- break if next_page.empty? || rows_returned < page_size
353+ page_count += 1 _i64
354+ break if next_page.empty? || rows_returned < page_size || (page_limit && page_count >= page_limit)
341355 end
342356 end
343357
@@ -952,6 +966,88 @@ class InnerRange::Integriti < PlaceOS::Driver
952966 extract_integriti_door(document)
953967 end
954968
969+ # =========
970+ # Review IO
971+ # =========
972+
973+ define_xml_type(Review , {
974+ " ID" => id : String ,
975+ " Text" => text : String ,
976+ " UTCTimeGenerated" => time_generated : Time ,
977+ " Type" => event_type : String ,
978+ " Transition" => transition : String ,
979+ }, " Review" ) do
980+ getter time_gen_ms : String { time_generated.to_s(TIME_FORMAT ) }
981+ end
982+
983+ @[PlaceOS ::Driver ::Security (Level ::Support )]
984+ def review_predefined_access (query_id : String | Int64 , long_poll : Bool = false , after : String | Int64 | Time ? = nil , page_limit : Int64 ? = nil ) : Array (Review )
985+ after_param = case after
986+ in Int64
987+ Time .unix(after)
988+ in String
989+ Time .parse(after, TIME_FORMAT , Time ::Location ::UTC )
990+ in Time
991+ after
992+ in Nil
993+ long_poll ? Time .utc : 10 .minutes.ago
994+ end
995+
996+ params = URI ::Params .build do |form |
997+ form.add " UTCTimeGenerated" , after_param.to_s(TIME_FORMAT )
998+ form.add " SortProperty" , " UTCTimeInserted"
999+ form.add " SortOrder" , " Descending"
1000+
1001+ if long_poll
1002+ form.add " LongPoll" , " true"
1003+ form.add " LongPollTime" , @long_poll_seconds .to_s
1004+ end
1005+ end
1006+
1007+ review = [] of Review
1008+ paginate_request(" Review" , " PredefinedFilter/#{ query_id } " , page_limit: page_limit, query: params) do |row |
1009+ entry = extract_review(row)
1010+ entry.time_gen_ms
1011+ review << entry
1012+ entry
1013+ end
1014+ review
1015+ end
1016+
1017+ @[PlaceOS ::Driver ::Security (Level ::Support )]
1018+ def review_access (filter : Filter , long_poll : Bool = false , after : String | Int64 | Time ? = nil , page_limit : Int64 ? = nil ) : Array (Review )
1019+ after_param = case after
1020+ in Int64
1021+ Time .unix(after)
1022+ in String
1023+ Time .parse(after, TIME_FORMAT , Time ::Location ::UTC )
1024+ in Time
1025+ after
1026+ in Nil
1027+ long_poll ? Time .utc : 10 .minutes.ago
1028+ end
1029+
1030+ params = URI ::Params .build do |form |
1031+ form.add " UTCTimeGenerated" , after_param.to_s(TIME_FORMAT )
1032+ form.add " SortProperty" , " UTCTimeInserted"
1033+ form.add " SortOrder" , " Descending"
1034+
1035+ if long_poll
1036+ form.add " LongPoll" , " true"
1037+ form.add " LongPollTime" , @long_poll_seconds .to_s
1038+ end
1039+ end
1040+
1041+ review = [] of Review
1042+ paginate_request(" Review" , " Review" , filter, page_limit: page_limit, query: params) do |row |
1043+ entry = extract_review(row)
1044+ entry.time_gen_ms
1045+ review << entry
1046+ entry
1047+ end
1048+ review
1049+ end
1050+
9551051 # =======================
9561052 # Door Security Interface
9571053 # =======================
0 commit comments