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 incoming alarm.
- #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
-
#send_alarm(code:, status:) ⇒ Object
set alarm.
- #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
handle incoming alarm
81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/rsmp/component.rb', line 81 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
118 119 120 |
# File 'lib/rsmp/component.rb', line 118 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.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/rsmp/component.rb', line 132 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.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/rsmp/component.rb', line 149 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
123 124 125 |
# File 'lib/rsmp/component.rb', line 123 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 |
#send_alarm(code:, status:) ⇒ Object
set alarm
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rsmp/component.rb', line 97 def send_alarm code:, status: # TODO # we need to manage the state of alarms internally (an ALarm class probably), # and handle request from the supervisor to suspend and resume alarms etc. # when this state changes, we then send an alarm message alarm = Alarm.new( 'cId' => c_id, 'aTs' => @node.clock.to_s, 'aCId' => code, 'aSp' => 'Issue', 'ack' => 'Acknowledged', 'sS' => 'notSuspended', 'aS' => status, 'cat' => 'D', 'pri' => '2', 'rvs' => [] ) @node.alarm_changed self, alarm 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
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/rsmp/component.rb', line 168 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 |