Skip to content

Commit

Permalink
feat(inner_range/integriti): add review functions
Browse files Browse the repository at this point in the history
  • Loading branch information
stakach committed Dec 11, 2024
1 parent 25b5b2f commit 80b7bc9
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 6 deletions.
108 changes: 102 additions & 6 deletions drivers/inner_range/integriti.cr
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class InnerRange::Integriti < PlaceOS::Driver
guest_card_start: 0,
guest_card_end: (UInt16::MAX - 1),

timezone: "Australia/Sydney",
timezone: "Australia/Sydney",
long_poll_seconds: 10,
})

def on_update
Expand All @@ -52,6 +53,7 @@ class InnerRange::Integriti < PlaceOS::Driver
guest_card_end = setting?(UInt16, :guest_card_end) || (UInt16::MAX - 1_u16)
@guest_card_range = Range.new(guest_card_start, guest_card_end)
@guest_access_group = setting?(String, :guest_access_group) || ""
@long_poll_seconds = setting?(Int32, :long_poll_seconds) || 10

transport.before_request do |request|
logger.debug { "requesting: #{request.method} #{request.path}?#{request.query}\n#{request.body}" }
Expand All @@ -68,6 +70,7 @@ class InnerRange::Integriti < PlaceOS::Driver
@timezone = Time::Location.load(time_zone) if time_zone
end

getter long_poll_seconds : Int32 = 10
getter default_unlock_time : Int32 = 10
getter default_site_id : Int32 = 1
getter default_partition_id : Int32 = 0
Expand All @@ -94,7 +97,8 @@ class InnerRange::Integriti < PlaceOS::Driver
end
end

PROPS = {} of String => String
TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%9N"
PROPS = {} of String => String

abstract struct IntegritiObject
include JSON::Serializable
Expand Down Expand Up @@ -142,6 +146,8 @@ class InnerRange::Integriti < PlaceOS::Driver
var_{{ variable_var }} = %content.downcase == "true"
{% elsif resolved_type == Float64 %}
var_{{ variable_var }} = %content.to_f?
{% elsif resolved_type == Time %}
var_{{ variable_var }} = Time.parse(%content, TIME_FORMAT, Time::Location::UTC)
{% elsif resolved_type.superclass == IntegritiObject %}
var_{{ variable_var }} = extract_{{variable.type.stringify.underscore.id}}(child)
{% else %}
Expand Down Expand Up @@ -182,6 +188,8 @@ class InnerRange::Integriti < PlaceOS::Driver
var_{{ variable_var }} = %content.downcase == "true"
{% elsif resolved_type == Float64 %}
var_{{ variable_var }} = %content.to_f?
{% elsif resolved_type == Time %}
var_{{ variable_var }} = Time.parse(%content, TIME_FORMAT, Time::Location::UTC)
{% elsif resolved_type.superclass == IntegritiObject %}
var_{{ variable_var }} = extract_{{variable.type.stringify.underscore.id}}(child)
{% else %}
Expand Down Expand Up @@ -211,6 +219,8 @@ class InnerRange::Integriti < PlaceOS::Driver
var_{{ variable_var }} = %content.downcase == "true"
{% elsif resolved_type == Float64 %}
var_{{ variable_var }} = %content.to_f?
{% elsif resolved_type == Time %}
var_{{ variable_var }} = Time.parse(%content, TIME_FORMAT, Time::Location::UTC)
{% elsif resolved_type.superclass == IntegritiObject %}
var_{{ variable_var }} = extract_{{variable.type.stringify.underscore.id}}(child)
{% else %}
Expand Down Expand Up @@ -294,14 +304,17 @@ class InnerRange::Integriti < PlaceOS::Driver
end
end

protected def paginate_request(category : String, type : String, filter : Filter = Filter.new, summary_only : Bool = false, &)
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, &)
query_params = "#{query}&"
query_params = "" if query_params.size == 1
filter.compact!
page_count = 0_i64

next_page = if filter.empty?
"/v2/#{category}/#{type}?PageSize=1000&#{prop_param(type, summary_only)}"
"/v2/#{category}/#{type}?PageSize=1000&#{query_params}#{prop_param(type, summary_only)}"
else
body = build_filter(filter)
"/v2/#{category}/GetFilteredEntities/#{type}?PageSize=1000&#{prop_param(type, summary_only)}"
"/v2/#{category}/GetFilteredEntities/#{type}?PageSize=1000&#{query_params}#{prop_param(type, summary_only)}"
end

next_uri = URI.parse(next_page)
Expand Down Expand Up @@ -337,7 +350,8 @@ class InnerRange::Integriti < PlaceOS::Driver
end
end

break if next_page.empty? || rows_returned < page_size
page_count += 1_i64
break if next_page.empty? || rows_returned < page_size || (page_limit && page_count >= page_limit)
end
end

Expand Down Expand Up @@ -952,6 +966,88 @@ class InnerRange::Integriti < PlaceOS::Driver
extract_integriti_door(document)
end

# =========
# Review IO
# =========

define_xml_type(Review, {
"ID" => id : String,
"Text" => text : String,
"UTCTimeGenerated" => time_generated : Time,
"Type" => event_type : String,
"Transition" => transition : String,
}, "Review") do
getter time_gen_ms : String { time_generated.to_s(TIME_FORMAT) }
end

@[PlaceOS::Driver::Security(Level::Support)]
def review_predefined_access(query_id : String | Int64, long_poll : Bool = false, after : String | Int64 | Time? = nil, page_limit : Int64? = nil) : Array(Review)
after_param = case after
in Int64
Time.unix(after)
in String
Time.parse(after, TIME_FORMAT, Time::Location::UTC)
in Time
after
in Nil
long_poll ? Time.utc : 10.minutes.ago
end

params = URI::Params.build do |form|
form.add "UTCTimeGenerated", after_param.to_s(TIME_FORMAT)
form.add "SortProperty", "UTCTimeInserted"
form.add "SortOrder", "Descending"

if long_poll
form.add "LongPoll", "true"
form.add "LongPollTime", @long_poll_seconds.to_s
end
end

review = [] of Review
paginate_request("Review", "PredefinedFilter/#{query_id}", page_limit: page_limit, query: params) do |row|
entry = extract_review(row)
entry.time_gen_ms
review << entry
entry
end
review
end

@[PlaceOS::Driver::Security(Level::Support)]
def review_access(filter : Filter, long_poll : Bool = false, after : String | Int64 | Time? = nil, page_limit : Int64? = nil) : Array(Review)
after_param = case after
in Int64
Time.unix(after)
in String
Time.parse(after, TIME_FORMAT, Time::Location::UTC)
in Time
after
in Nil
long_poll ? Time.utc : 10.minutes.ago
end

params = URI::Params.build do |form|
form.add "UTCTimeGenerated", after_param.to_s(TIME_FORMAT)
form.add "SortProperty", "UTCTimeInserted"
form.add "SortOrder", "Descending"

if long_poll
form.add "LongPoll", "true"
form.add "LongPollTime", @long_poll_seconds.to_s
end
end

review = [] of Review
paginate_request("Review", "Review", filter, page_limit: page_limit, query: params) do |row|
entry = extract_review(row)
entry.time_gen_ms
review << entry
entry
end
review
end

# =======================
# Door Security Interface
# =======================
Expand Down
52 changes: 52 additions & 0 deletions drivers/inner_range/integriti_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -346,4 +346,56 @@ DriverSpecs.mock_driver "InnerRange::Integriti" do
"message" => "1 item/s removed from UserPermission for User with ID U56",
"modified" => 1,
})

# ==============
# Review History
# ==============

result = exec(:review_access, {} of Nil => Nil)

expect_http_request do |request, response|
response.status_code = 200
response << <<-XML
<PagedQueryResult>
<TotalRecords>1</TotalRecords>
<Page>1</Page>
<PageSize>25</PageSize>
<RowVersion>-1</RowVersion>
<NextPageUrl>http://20.213.104.2:80/restapi/v2/Review/Review?Page=1&amp;PageSize=25&amp;SortProperty=UTCTimeGenerated&amp;SortOrder=Descending&amp;FullObject=true&amp;LongPoll=true&amp;UTCTimeGenerated=12/11/2024 5:52:54 AM&amp;</NextPageUrl>
<Rows>
<Review ID="0b36c0d0-ab54-49d0-9681-2db34e0b6f4b">
<ID>0b36c0d0-ab54-49d0-9681-2db34e0b6f4b</ID>
<Text>test - Stopped</Text>
<Actor_ID>1</Actor_ID>
<Controller_ID>0</Controller_ID>
<SourceName>Application Server@outlook-test</SourceName>
<Record>0</Record>
<LocalTimeGenerated>2024-12-11T18:52:54.6086141</LocalTimeGenerated>
<UTCTimeGenerated>2024-12-11T05:52:54.6086141</UTCTimeGenerated>
<UTCTimeInserted>2024-12-11T05:52:54.8427098</UTCTimeInserted>
<Classification>0</Classification>
<Level>InstallerDetailed</Level>
<Priority>None</Priority>
<Type>CommunicationHandler</Type>
<Entity_1_ID>0</Entity_1_ID>
<Entity_2_ID>0</Entity_2_ID>
<Entity_3_ID>0</Entity_3_ID>
<Entity_4_ID>0</Entity_4_ID>
<Entity_5_ID>0</Entity_5_ID>
<Transition>CommunicationHandlerStopped</Transition>
<AnalogValue>0</AnalogValue>
</Review>
</Rows>
</PagedQueryResult>
XML
end

result.get.should eq([{
"id" => "0b36c0d0-ab54-49d0-9681-2db34e0b6f4b",
"text" => "test - Stopped",
"time_generated" => "2024-12-11T05:52:54Z",
"event_type" => "CommunicationHandler",
"transition" => "CommunicationHandlerStopped",
"time_gen_ms" => "2024-12-11T05:52:54.608614100",
}])
end

0 comments on commit 80b7bc9

Please sign in to comment.