Class: RSMP::Component
- Inherits:
-
Object
- Object
- RSMP::Component
- Includes:
- Inspect
- Defined in:
- lib/rsmp/component.rb
Overview
Class that represents an RMSP component. Currently this class is used by both SiteProxy and SupervisorProxy, and can therefore represent either a local or remote (proxy) component.
Direct Known Subclasses
TLC::DetectorLogic, TLC::SignalGroup, TLC::TrafficController
Constant Summary collapse
- AGGREGATED_STATUS_KEYS =
[ :local_control, :communication_distruption, :high_priority_alarm, :medium_priority_alarm, :low_priority_alarm, :normal, :rest, :not_connected ]
Instance Attribute Summary collapse
-
#aggregated_status ⇒ Object
readonly
Returns the value of attribute aggregated_status.
-
#aggregated_status_bools ⇒ Object
readonly
Returns the value of attribute aggregated_status_bools.
-
#alarms ⇒ Object
readonly
Returns the value of attribute alarms.
-
#c_id ⇒ Object
readonly
Returns the value of attribute c_id.
-
#grouped ⇒ Object
readonly
Returns the value of attribute grouped.
-
#node ⇒ Object
readonly
Returns the value of attribute node.
-
#statuses ⇒ Object
readonly
Returns the value of attribute statuses.
Instance Method Summary collapse
- #aggregated_status_changed(options = {}) ⇒ Object
- #clear_aggregated_status ⇒ Object
- #get_status(status_code, status_name = nil) ⇒ Object
- #handle_alarm(message) ⇒ Object
- #handle_command(command_code, arg) ⇒ Object
-
#handle_status_response(message) ⇒ Object
Handle an incoming status respone, by storing the values.
-
#handle_status_subscribe(status_list) ⇒ Object
Our proxy subscribed to status updates Store update rates, so we can check for repeated alarm if we asked for updates only when there's a change, not on a regular interval.
-
#handle_status_unsubscribe(status_list) ⇒ Object
Our proxy unsubscribed to status updates.
-
#handle_status_update(message) ⇒ Object
Handle an incoming status update, by storing the values.
-
#initialize(node:, id:, grouped: false) ⇒ Component
constructor
A new instance of Component.
- #log(str, options) ⇒ Object
- #set_aggregated_status(status, options = {}) ⇒ Object
- #set_aggregated_status_bools(status) ⇒ Object
-
#store_status(message, check_repeated:) ⇒ Object
Store the latest status update values, optionally checking that we're not receiving unchanged values if we're subscribed wit updates only on change.
Methods included from Inspect
Constructor Details
#initialize(node:, id:, grouped: false) ⇒ Component
Returns a new instance of Component.
21 22 23 24 25 26 27 28 29 |
# File 'lib/rsmp/component.rb', line 21 def initialize node:, id:, grouped: false @c_id = id @node = node @grouped = grouped @alarms = {} @statuses = {} @subscribes = {} clear_aggregated_status end |
Instance Attribute Details
#aggregated_status ⇒ Object (readonly)
Returns the value of attribute aggregated_status.
10 11 12 |
# File 'lib/rsmp/component.rb', line 10 def aggregated_status @aggregated_status end |
#aggregated_status_bools ⇒ Object (readonly)
Returns the value of attribute aggregated_status_bools.
10 11 12 |
# File 'lib/rsmp/component.rb', line 10 def aggregated_status_bools @aggregated_status_bools end |
#alarms ⇒ Object (readonly)
Returns the value of attribute alarms.
10 11 12 |
# File 'lib/rsmp/component.rb', line 10 def alarms @alarms end |
#c_id ⇒ Object (readonly)
Returns the value of attribute c_id.
10 11 12 |
# File 'lib/rsmp/component.rb', line 10 def c_id @c_id end |
#grouped ⇒ Object (readonly)
Returns the value of attribute grouped.
10 11 12 |
# File 'lib/rsmp/component.rb', line 10 def grouped @grouped end |
#node ⇒ Object (readonly)
Returns the value of attribute node.
10 11 12 |
# File 'lib/rsmp/component.rb', line 10 def node @node end |
#statuses ⇒ Object (readonly)
Returns the value of attribute statuses.
10 11 12 |
# File 'lib/rsmp/component.rb', line 10 def statuses @statuses end |
Instance Method Details
#aggregated_status_changed(options = {}) ⇒ Object
63 64 65 |
# File 'lib/rsmp/component.rb', line 63 def aggregated_status_changed ={} @node.aggregated_status_changed self, end |
#clear_aggregated_status ⇒ Object
31 32 33 34 35 |
# File 'lib/rsmp/component.rb', line 31 def clear_aggregated_status @aggregated_status = [] @aggregated_status_bools = Array.new(8,false) @aggregated_status_bools[5] = true end |
#get_status(status_code, status_name = nil) ⇒ Object
76 77 78 |
# File 'lib/rsmp/component.rb', line 76 def get_status status_code, status_name=nil raise UnknownStatus.new "Status #{status_code}/#{status_name} not implemented by #{self.class}" end |
#handle_alarm(message) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/rsmp/component.rb', line 80 def handle_alarm code = .attribute('aCId') previous = @alarms[code] if previous unless .differ?(previous) raise RepeatedAlarmError.new("no changes from previous alarm #{previous.m_id_short}") end if Time.parse(.attribute('aTs')) < Time.parse(previous.attribute('aTs')) raise TimestampError.new("timestamp is earlier than previous alarm #{previous.m_id_short}") end end ensure @alarms[code] = end |
#handle_command(command_code, arg) ⇒ Object
72 73 74 |
# File 'lib/rsmp/component.rb', line 72 def handle_command command_code, arg raise UnknownCommand.new "Command #{command_code} not implemented by #{self.class}" end |
#handle_status_response(message) ⇒ Object
Handle an incoming status respone, by storing the values
96 97 98 |
# File 'lib/rsmp/component.rb', line 96 def handle_status_response store_status , check_repeated: false end |
#handle_status_subscribe(status_list) ⇒ Object
Our proxy subscribed to status updates Store update rates, so we can check for repeated alarm if we asked for updates only when there's a change, not on a regular interval. After subscribing, an update status us send regarless of whether values changes, and we store that.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/rsmp/component.rb', line 110 def handle_status_subscribe status_list status_list.each do |item| sCI, n, uRt = item['sCI'], item['n'], item['uRt'] # record the update rate, so we can check for repeated status values if rate is zero @subscribes[sCI] ||= {} @subscribes[sCI][n] = {'uRt'=>uRt} # record that we expect an upeate, even though the value might not change @statuses[sCI] ||= {} @statuses[sCI][n] ||= {} @statuses[sCI][n][:initial] = true end end |
#handle_status_unsubscribe(status_list) ⇒ Object
Our proxy unsubscribed to status updates. Update our list of update rates.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/rsmp/component.rb', line 127 def handle_status_unsubscribe status_list status_list.each do |item| sCI, n = item['sCI'], item['n'] if @subscribes[sCI] @subscribes[sCI].delete n end if @subscribes[sCI].empty? @subscribes.delete sCI end # remove any mark that would allow the next update to be a repeat item = @statuses.dig sCI, n item.delete(:initial) if item end end |
#handle_status_update(message) ⇒ Object
Handle an incoming status update, by storing the values
101 102 103 |
# File 'lib/rsmp/component.rb', line 101 def handle_status_update store_status , check_repeated: true end |
#log(str, options) ⇒ Object
67 68 69 70 |
# File 'lib/rsmp/component.rb', line 67 def log str, default = { component: c_id} @node.log str, default.merge() end |
#set_aggregated_status(status, options = {}) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/rsmp/component.rb', line 37 def set_aggregated_status status, ={} status = [status] if status.is_a? Symbol raise InvalidArgument unless status.is_a? Array input = status & AGGREGATED_STATUS_KEYS if input != @aggregated_status AGGREGATED_STATUS_KEYS.each_with_index do |key,index| @aggregated_status_bools[index] = status.include?(key) end aggregated_status_changed end end |
#set_aggregated_status_bools(status) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rsmp/component.rb', line 49 def set_aggregated_status_bools status raise InvalidArgument unless status.is_a? Array raise InvalidArgument unless status.size == 8 if status != @aggregated_status_bools @aggregated_status = [] AGGREGATED_STATUS_KEYS.each_with_index do |key,index| on = status[index] == true @aggregated_status_bools[index] = on @aggregated_status << key if on end aggregated_status_changed end end |
#store_status(message, check_repeated:) ⇒ Object
Store the latest status update values, optionally checking that we're not receiving unchanged values if we're subscribed wit updates only on change
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/rsmp/component.rb', line 146 def store_status , check_repeated: .attribute('sS').each do |item| sCI, n, s, q = item['sCI'], item['n'], item['s'], item['q'] uRt = @subscribes.dig(sCI,n,'uRt') new_values = {'s'=>s,'q'=>q} old_values = @statuses.dig(sCI,n) if check_repeated && uRt.to_i == 0 if new_values == old_values raise RSMP::RepeatedStatusError.new "no change for #{sCI} '#{n}'" end end @statuses[sCI] ||= {} @statuses[sCI][n] = new_values end end |