rsmp 0.37.0 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.devcontainer/devcontainer.json +22 -0
- data/.github/workflows/rubocop.yaml +17 -0
- data/.gitignore +5 -6
- data/.rubocop.yml +80 -0
- data/Gemfile +13 -1
- data/Gemfile.lock +34 -1
- data/Rakefile +3 -3
- data/lib/rsmp/cli.rb +147 -124
- data/lib/rsmp/collect/ack_collector.rb +8 -7
- data/lib/rsmp/collect/aggregated_status_collector.rb +4 -4
- data/lib/rsmp/collect/alarm_collector.rb +31 -23
- data/lib/rsmp/collect/alarm_matcher.rb +3 -3
- data/lib/rsmp/collect/collector/logging.rb +17 -0
- data/lib/rsmp/collect/collector/reporting.rb +44 -0
- data/lib/rsmp/collect/collector/status.rb +34 -0
- data/lib/rsmp/collect/collector.rb +69 -150
- data/lib/rsmp/collect/command_matcher.rb +19 -6
- data/lib/rsmp/collect/command_response_collector.rb +7 -7
- data/lib/rsmp/collect/distributor.rb +14 -11
- data/lib/rsmp/collect/filter.rb +31 -15
- data/lib/rsmp/collect/matcher.rb +7 -11
- data/lib/rsmp/collect/queue.rb +4 -4
- data/lib/rsmp/collect/receiver.rb +10 -12
- data/lib/rsmp/collect/state_collector.rb +116 -77
- data/lib/rsmp/collect/status_collector.rb +6 -6
- data/lib/rsmp/collect/status_matcher.rb +17 -7
- data/lib/rsmp/{alarm_state.rb → component/alarm_state.rb} +76 -37
- data/lib/rsmp/{component.rb → component/component.rb} +15 -15
- data/lib/rsmp/component/component_base.rb +89 -0
- data/lib/rsmp/component/component_proxy.rb +75 -0
- data/lib/rsmp/component/components.rb +63 -0
- data/lib/rsmp/convert/export/json_schema.rb +116 -110
- data/lib/rsmp/convert/import/yaml.rb +21 -18
- data/lib/rsmp/{rsmp.rb → helpers/clock.rb} +5 -6
- data/lib/rsmp/{deep_merge.rb → helpers/deep_merge.rb} +2 -1
- data/lib/rsmp/helpers/error.rb +71 -0
- data/lib/rsmp/{inspect.rb → helpers/inspect.rb} +6 -10
- data/lib/rsmp/log/archive.rb +98 -0
- data/lib/rsmp/log/colorization.rb +41 -0
- data/lib/rsmp/log/filtering.rb +54 -0
- data/lib/rsmp/log/logger.rb +206 -0
- data/lib/rsmp/{logging.rb → log/logging.rb} +5 -7
- data/lib/rsmp/message.rb +159 -148
- data/lib/rsmp/{node.rb → node/node.rb} +19 -17
- data/lib/rsmp/{protocol.rb → node/protocol.rb} +5 -3
- data/lib/rsmp/node/site/site.rb +195 -0
- data/lib/rsmp/node/supervisor/modules/configuration.rb +59 -0
- data/lib/rsmp/node/supervisor/modules/connection.rb +140 -0
- data/lib/rsmp/node/supervisor/modules/sites.rb +64 -0
- data/lib/rsmp/node/supervisor/supervisor.rb +72 -0
- data/lib/rsmp/{task.rb → node/task.rb} +12 -14
- data/lib/rsmp/proxy/modules/acknowledgements.rb +144 -0
- data/lib/rsmp/proxy/modules/receive.rb +119 -0
- data/lib/rsmp/proxy/modules/send.rb +76 -0
- data/lib/rsmp/proxy/modules/state.rb +25 -0
- data/lib/rsmp/proxy/modules/tasks.rb +105 -0
- data/lib/rsmp/proxy/modules/versions.rb +69 -0
- data/lib/rsmp/proxy/modules/watchdogs.rb +66 -0
- data/lib/rsmp/proxy/proxy.rb +199 -0
- data/lib/rsmp/proxy/site/modules/aggregated_status.rb +52 -0
- data/lib/rsmp/proxy/site/modules/alarms.rb +27 -0
- data/lib/rsmp/proxy/site/modules/commands.rb +31 -0
- data/lib/rsmp/proxy/site/modules/status.rb +110 -0
- data/lib/rsmp/proxy/site/site_proxy.rb +205 -0
- data/lib/rsmp/proxy/supervisor/modules/aggregated_status.rb +47 -0
- data/lib/rsmp/proxy/supervisor/modules/alarms.rb +73 -0
- data/lib/rsmp/proxy/supervisor/modules/commands.rb +53 -0
- data/lib/rsmp/proxy/supervisor/modules/status.rb +204 -0
- data/lib/rsmp/proxy/supervisor/supervisor_proxy.rb +178 -0
- data/lib/rsmp/tlc/detector_logic.rb +18 -34
- data/lib/rsmp/tlc/input_states.rb +126 -0
- data/lib/rsmp/tlc/modules/detector_logics.rb +50 -0
- data/lib/rsmp/tlc/modules/display.rb +78 -0
- data/lib/rsmp/tlc/modules/helpers.rb +41 -0
- data/lib/rsmp/tlc/modules/inputs.rb +173 -0
- data/lib/rsmp/tlc/modules/modes.rb +253 -0
- data/lib/rsmp/tlc/modules/outputs.rb +30 -0
- data/lib/rsmp/tlc/modules/plans.rb +218 -0
- data/lib/rsmp/tlc/modules/signal_groups.rb +109 -0
- data/lib/rsmp/tlc/modules/startup_sequence.rb +22 -0
- data/lib/rsmp/tlc/modules/system.rb +140 -0
- data/lib/rsmp/tlc/modules/traffic_data.rb +49 -0
- data/lib/rsmp/tlc/signal_group.rb +37 -41
- data/lib/rsmp/tlc/signal_plan.rb +14 -11
- data/lib/rsmp/tlc/signal_priority.rb +39 -35
- data/lib/rsmp/tlc/startup_sequence.rb +59 -0
- data/lib/rsmp/tlc/traffic_controller.rb +38 -1010
- data/lib/rsmp/tlc/traffic_controller_site.rb +58 -57
- data/lib/rsmp/version.rb +1 -1
- data/lib/rsmp.rb +82 -48
- data/rsmp.gemspec +24 -31
- metadata +79 -139
- data/lib/rsmp/archive.rb +0 -76
- data/lib/rsmp/collect/message_matchers.rb +0 -0
- data/lib/rsmp/component_base.rb +0 -87
- data/lib/rsmp/component_proxy.rb +0 -57
- data/lib/rsmp/components.rb +0 -65
- data/lib/rsmp/error.rb +0 -71
- data/lib/rsmp/logger.rb +0 -216
- data/lib/rsmp/proxy.rb +0 -693
- data/lib/rsmp/site.rb +0 -188
- data/lib/rsmp/site_proxy.rb +0 -389
- data/lib/rsmp/supervisor.rb +0 -302
- data/lib/rsmp/supervisor_proxy.rb +0 -510
- data/lib/rsmp/tlc/inputs.rb +0 -134
data/lib/rsmp/site.rb
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
# RSMP site
|
|
2
|
-
# The site initializes the connection to the supervisor.
|
|
3
|
-
# Connections to supervisors are handles via supervisor proxies.
|
|
4
|
-
|
|
5
|
-
module RSMP
|
|
6
|
-
class Site < Node
|
|
7
|
-
include Components
|
|
8
|
-
|
|
9
|
-
attr_reader :core_version, :site_settings, :logger, :proxies
|
|
10
|
-
|
|
11
|
-
def initialize options={}
|
|
12
|
-
super options
|
|
13
|
-
initialize_components
|
|
14
|
-
handle_site_settings options
|
|
15
|
-
@proxies = []
|
|
16
|
-
@sleep_condition = Async::Notification.new
|
|
17
|
-
@proxies_condition = Async::Notification.new
|
|
18
|
-
build_proxies
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def sxl_version
|
|
22
|
-
@site_settings['sxl_version']
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def site_id
|
|
26
|
-
@site_settings['site_id']
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def handle_site_settings options={}
|
|
30
|
-
defaults = {
|
|
31
|
-
'site_id' => 'RN+SI0001',
|
|
32
|
-
'supervisors' => [
|
|
33
|
-
{ 'ip' => '127.0.0.1', 'port' => 12111 }
|
|
34
|
-
],
|
|
35
|
-
'sxl' => 'tlc',
|
|
36
|
-
'sxl_version' => RSMP::Schema.latest_version(:tlc),
|
|
37
|
-
'intervals' => {
|
|
38
|
-
'timer' => 0.1,
|
|
39
|
-
'watchdog' => 1,
|
|
40
|
-
'reconnect' => 0.1
|
|
41
|
-
},
|
|
42
|
-
'timeouts' => {
|
|
43
|
-
'watchdog' => 2,
|
|
44
|
-
'acknowledgement' => 2
|
|
45
|
-
},
|
|
46
|
-
'send_after_connect' => true,
|
|
47
|
-
'components' => {
|
|
48
|
-
'main' => {
|
|
49
|
-
'C1' => {}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
# only one main component can be defined, so replace the default if options define one
|
|
54
|
-
if options.dig(:site_settings,'components','main')
|
|
55
|
-
defaults['components']['main'] = options[:site_settings]['components']['main']
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
@site_settings = defaults.deep_merge options[:site_settings]
|
|
59
|
-
|
|
60
|
-
check_sxl_version
|
|
61
|
-
check_core_versions
|
|
62
|
-
setup_components @site_settings['components']
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def check_sxl_version
|
|
66
|
-
sxl = @site_settings['sxl']
|
|
67
|
-
version = @site_settings['sxl_version'].to_s
|
|
68
|
-
RSMP::Schema::find_schema! sxl, version, lenient: true
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def check_core_versions
|
|
72
|
-
version = @site_settings['core_version']
|
|
73
|
-
return unless version
|
|
74
|
-
unless RSMP::Schema::core_versions.include? version
|
|
75
|
-
error_str = "Unknown core version: #{version}"
|
|
76
|
-
raise RSMP::ConfigurationError.new(error_str)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def site_type_name
|
|
81
|
-
"site"
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def log_site_starting
|
|
85
|
-
log "Starting #{site_type_name} #{@site_settings["site_id"]}", level: :info, timestamp: @clock.now
|
|
86
|
-
sxl = "Using #{@site_settings["sxl"]} sxl #{@site_settings["sxl_version"]}"
|
|
87
|
-
version = @site_settings["core_version"]
|
|
88
|
-
unless version
|
|
89
|
-
core = "accepting all core versions [#{RSMP::Schema.core_versions.join(', ')}]"
|
|
90
|
-
else
|
|
91
|
-
core = "accepting only core version #{version}"
|
|
92
|
-
end
|
|
93
|
-
log "#{sxl}, #{core}", level: :info, timestamp: @clock.now
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def run
|
|
97
|
-
log_site_starting
|
|
98
|
-
@proxies.each { |proxy| proxy.start }
|
|
99
|
-
@proxies.each { |proxy| proxy.wait }
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def build_proxies
|
|
103
|
-
@site_settings["supervisors"].each do |supervisor_settings|
|
|
104
|
-
@proxies << SupervisorProxy.new({
|
|
105
|
-
site: self,
|
|
106
|
-
task: @task,
|
|
107
|
-
settings: @site_settings,
|
|
108
|
-
ip: supervisor_settings['ip'],
|
|
109
|
-
port: supervisor_settings['port'],
|
|
110
|
-
logger: @logger,
|
|
111
|
-
archive: @archive,
|
|
112
|
-
collect: @collect
|
|
113
|
-
})
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def aggregated_status_changed component, options={}
|
|
118
|
-
@proxies.each do |proxy|
|
|
119
|
-
proxy.send_aggregated_status component, options if proxy.ready?
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def alarm_acknowledged alarm_state
|
|
124
|
-
send_alarm AlarmAcknowledged.new( alarm_state.to_hash )
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def alarm_suspended_or_resumed alarm_state
|
|
128
|
-
send_alarm AlarmSuspended.new( alarm_state.to_hash )
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def alarm_activated_or_deactivated alarm_state
|
|
132
|
-
send_alarm AlarmIssue.new( alarm_state.to_hash )
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def send_alarm alarm
|
|
136
|
-
@proxies.each do |proxy|
|
|
137
|
-
proxy.send_message alarm if proxy.ready?
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def connect_to_supervisor task, supervisor_settings
|
|
142
|
-
proxy = build_proxy({
|
|
143
|
-
site: self,
|
|
144
|
-
task: @task,
|
|
145
|
-
settings: @site_settings,
|
|
146
|
-
ip: supervisor_settings['ip'],
|
|
147
|
-
port: supervisor_settings['port'],
|
|
148
|
-
logger: @logger,
|
|
149
|
-
archive: @archive,
|
|
150
|
-
collect: @collect
|
|
151
|
-
})
|
|
152
|
-
@proxies << proxy
|
|
153
|
-
proxy.start
|
|
154
|
-
@proxies_condition.signal
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# stop
|
|
158
|
-
def stop
|
|
159
|
-
log "Stopping site #{@site_settings["site_id"]}", level: :info
|
|
160
|
-
super
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def wait_for_supervisor ip, timeout
|
|
164
|
-
supervisor = find_supervisor ip
|
|
165
|
-
return supervisor if supervisor
|
|
166
|
-
wait_for_condition(@proxy_condition,timeout:timeout) { find_supervisor ip }
|
|
167
|
-
rescue Async::TimeoutError
|
|
168
|
-
raise RSMP::TimeoutError.new "Supervisor '#{ip}' did not connect within #{timeout}s"
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def find_supervisor ip
|
|
172
|
-
@proxies.each do |supervisor|
|
|
173
|
-
return supervisor if ip == :any || supervisor.ip == ip
|
|
174
|
-
end
|
|
175
|
-
nil
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def build_component id:, type:, settings:
|
|
179
|
-
settings ||= {}
|
|
180
|
-
if type == 'main'
|
|
181
|
-
Component.new id:id, node: self, grouped: true,
|
|
182
|
-
ntsOId: settings['ntsOId'], xNId: settings['xNId']
|
|
183
|
-
else
|
|
184
|
-
Component.new id:id, node: self, grouped: false
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
end
|
data/lib/rsmp/site_proxy.rb
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
# Handles a supervisor connection to a remote client
|
|
2
|
-
|
|
3
|
-
module RSMP
|
|
4
|
-
class SiteProxy < Proxy
|
|
5
|
-
include Components
|
|
6
|
-
|
|
7
|
-
attr_reader :supervisor, :site_id
|
|
8
|
-
|
|
9
|
-
def initialize options
|
|
10
|
-
super options.merge(node:options[:supervisor])
|
|
11
|
-
initialize_components
|
|
12
|
-
@supervisor = options[:supervisor]
|
|
13
|
-
@settings = @supervisor.supervisor_settings.clone
|
|
14
|
-
@site_id = options[:site_id]
|
|
15
|
-
@status_subscriptions = {}
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# handle communication
|
|
19
|
-
# when we're created, the socket is already open
|
|
20
|
-
def run
|
|
21
|
-
set_state :connected
|
|
22
|
-
start_reader
|
|
23
|
-
wait_for_reader # run until disconnected
|
|
24
|
-
rescue RSMP::ConnectionError => e
|
|
25
|
-
log e, level: :error
|
|
26
|
-
rescue StandardError => e
|
|
27
|
-
distribute_error e, level: :internal
|
|
28
|
-
ensure
|
|
29
|
-
close
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def revive options
|
|
33
|
-
super options
|
|
34
|
-
@supervisor = options[:supervisor]
|
|
35
|
-
@settings = @supervisor.supervisor_settings.clone
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def inspect
|
|
39
|
-
"#<#{self.class.name}:#{self.object_id}, #{inspector(
|
|
40
|
-
:@acknowledgements,:@settings,:@site_settings,:@components
|
|
41
|
-
)}>"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def node
|
|
45
|
-
supervisor
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def handshake_complete
|
|
49
|
-
super
|
|
50
|
-
sanitized_sxl_version = RSMP::Schema.sanitize_version(@site_sxl_version)
|
|
51
|
-
log "Connection to site #{@site_id} established, using core #{@core_version}, #{@sxl} #{sanitized_sxl_version}", level: :info
|
|
52
|
-
start_watchdog
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def process_message message
|
|
56
|
-
case message
|
|
57
|
-
when CommandRequest
|
|
58
|
-
when StatusRequest
|
|
59
|
-
when StatusSubscribe
|
|
60
|
-
when StatusUnsubscribe
|
|
61
|
-
will_not_handle message
|
|
62
|
-
when AggregatedStatus
|
|
63
|
-
process_aggregated_status message
|
|
64
|
-
when AggregatedStatusRequest
|
|
65
|
-
will_not_handle message
|
|
66
|
-
when AlarmIssue, AlarmSuspended, AlarmResumed, AlarmAcknowledged
|
|
67
|
-
process_alarm message
|
|
68
|
-
when CommandResponse
|
|
69
|
-
process_command_response message
|
|
70
|
-
when StatusResponse
|
|
71
|
-
process_status_response message
|
|
72
|
-
when StatusUpdate
|
|
73
|
-
process_status_update message
|
|
74
|
-
else
|
|
75
|
-
super message
|
|
76
|
-
end
|
|
77
|
-
rescue RSMP::RepeatedAlarmError, RSMP::RepeatedStatusError, RSMP::TimestampError => e
|
|
78
|
-
str = "Rejected #{message.type} message,"
|
|
79
|
-
dont_acknowledge message, str, "#{e}"
|
|
80
|
-
distribute_error e.exception("#{str}#{e.message} #{message.json}")
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def process_command_response message
|
|
84
|
-
log "Received #{message.type}", message: message, level: :log
|
|
85
|
-
acknowledge message
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def version_accepted message
|
|
89
|
-
log "Received Version message for site #{@site_id}", message: message, level: :log
|
|
90
|
-
start_timer
|
|
91
|
-
acknowledge message
|
|
92
|
-
send_version @site_id, core_versions
|
|
93
|
-
@version_determined = true
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def acknowledged_first_ingoing message
|
|
97
|
-
case message.type
|
|
98
|
-
when "Watchdog"
|
|
99
|
-
send_watchdog
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def acknowledged_first_outgoing message
|
|
104
|
-
case message.type
|
|
105
|
-
when "Watchdog"
|
|
106
|
-
handshake_complete
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def validate_ready action
|
|
111
|
-
raise NotReady.new("Can't #{action} because connection is not ready. (Currently #{@state})") unless ready?
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def request_aggregated_status component, options={}
|
|
115
|
-
validate_ready 'request aggregated status'
|
|
116
|
-
m_id = options[:m_id] || RSMP::Message.make_m_id
|
|
117
|
-
message = RSMP::AggregatedStatusRequest.new({
|
|
118
|
-
"cId" => component,
|
|
119
|
-
"mId" => m_id
|
|
120
|
-
})
|
|
121
|
-
set_nts_message_attributes message
|
|
122
|
-
send_and_optionally_collect message, options do |collect_options|
|
|
123
|
-
AggregatedStatusCollector.new(
|
|
124
|
-
self,
|
|
125
|
-
collect_options.merge(task:@task,m_id: m_id, num:1)
|
|
126
|
-
)
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def validate_aggregated_status message, se
|
|
131
|
-
unless se && se.is_a?(Array) && se.size == 8
|
|
132
|
-
reason = "invalid AggregatedStatus, 'se' must be an Array of size 8"
|
|
133
|
-
dont_acknowledge message, "Received", reaons
|
|
134
|
-
raise InvalidMessage
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def process_aggregated_status message
|
|
139
|
-
se = message.attribute("se")
|
|
140
|
-
validate_aggregated_status(message,se)
|
|
141
|
-
c_id = message.attributes["cId"]
|
|
142
|
-
component = find_component c_id
|
|
143
|
-
unless component
|
|
144
|
-
reason = "component #{c_id} not found"
|
|
145
|
-
dont_acknowledge message, "Ignoring #{message.type}:", reason
|
|
146
|
-
return
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
component.set_aggregated_status_bools se
|
|
150
|
-
log "Received #{message.type} status for component #{c_id} [#{component.aggregated_status.join(', ')}]", message: message
|
|
151
|
-
acknowledge message
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def aggregated_status_changed component, options={}
|
|
155
|
-
@supervisor.aggregated_status_changed self, component
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def process_alarm message
|
|
159
|
-
component = find_component message.attribute("cId")
|
|
160
|
-
status = ["ack","aS","sS"].map { |key| message.attribute(key) }.join(',')
|
|
161
|
-
component.handle_alarm message
|
|
162
|
-
alarm_code = message.attribute("aCId")
|
|
163
|
-
asp = message.attribute("aSp")
|
|
164
|
-
log "Received #{message.type}, #{alarm_code} #{asp} [#{status}]", message: message, level: :log
|
|
165
|
-
acknowledge message
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def version_acknowledged
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def process_watchdog message
|
|
172
|
-
super
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def site_ids_changed
|
|
176
|
-
@supervisor.site_ids_changed
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def request_status component, status_list, options={}
|
|
180
|
-
validate_ready 'request status'
|
|
181
|
-
m_id = options[:m_id] || RSMP::Message.make_m_id
|
|
182
|
-
|
|
183
|
-
# additional items can be used when verifying the response,
|
|
184
|
-
# but must be removed from the request
|
|
185
|
-
request_list = status_list.map { |item| item.slice('sCI','n') }
|
|
186
|
-
|
|
187
|
-
message = RSMP::StatusRequest.new({
|
|
188
|
-
"cId" => component,
|
|
189
|
-
"sS" => request_list,
|
|
190
|
-
"mId" => m_id
|
|
191
|
-
})
|
|
192
|
-
set_nts_message_attributes message
|
|
193
|
-
send_and_optionally_collect message, options do |collect_options|
|
|
194
|
-
StatusCollector.new(
|
|
195
|
-
self,
|
|
196
|
-
status_list,
|
|
197
|
-
collect_options.merge(task:@task,m_id: m_id)
|
|
198
|
-
)
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
def process_status_response message
|
|
203
|
-
component = find_component message.attribute("cId")
|
|
204
|
-
component.store_status message
|
|
205
|
-
log "Received #{message.type}", message: message, level: :log
|
|
206
|
-
acknowledge message
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def subscribe_to_status component_id, status_list, options={}
|
|
210
|
-
validate_ready 'subscribe to status'
|
|
211
|
-
m_id = options[:m_id] || RSMP::Message.make_m_id
|
|
212
|
-
|
|
213
|
-
# additional items can be used when verifying the response,
|
|
214
|
-
# but must be removed from the subscribe message
|
|
215
|
-
subscribe_list = status_list.map { |item| item.slice('sCI','n','uRt','sOc') }
|
|
216
|
-
|
|
217
|
-
# update our subcription list
|
|
218
|
-
@status_subscriptions[component_id] ||= {}
|
|
219
|
-
subscribe_list.each do |item|
|
|
220
|
-
sCI = item["sCI"]
|
|
221
|
-
n = item["n"]
|
|
222
|
-
uRt = item["uRt"]
|
|
223
|
-
sOc = item["sOc"]
|
|
224
|
-
@status_subscriptions[component_id][sCI] ||= {}
|
|
225
|
-
@status_subscriptions[component_id][sCI][n] ||= {}
|
|
226
|
-
@status_subscriptions[component_id][sCI][n]['uRt'] = uRt
|
|
227
|
-
@status_subscriptions[component_id][sCI][n]['sOc'] = sOc
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
component = find_component component_id
|
|
231
|
-
|
|
232
|
-
message = RSMP::StatusSubscribe.new({
|
|
233
|
-
"cId" => component_id,
|
|
234
|
-
"sS" => subscribe_list,
|
|
235
|
-
'mId' => m_id
|
|
236
|
-
})
|
|
237
|
-
set_nts_message_attributes message
|
|
238
|
-
|
|
239
|
-
send_and_optionally_collect message, options do |collect_options|
|
|
240
|
-
StatusCollector.new(
|
|
241
|
-
self,
|
|
242
|
-
status_list,
|
|
243
|
-
collect_options.merge(task:@task,m_id: m_id)
|
|
244
|
-
)
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
def unsubscribe_to_status component_id, status_list, options={}
|
|
249
|
-
validate_ready 'unsubscribe to status'
|
|
250
|
-
|
|
251
|
-
# update our subcription list
|
|
252
|
-
status_list.each do |item|
|
|
253
|
-
sCI = item["sCI"]
|
|
254
|
-
n = item["n"]
|
|
255
|
-
if @status_subscriptions.dig(component_id,sCI,n)
|
|
256
|
-
@status_subscriptions[component_id][sCI].delete n
|
|
257
|
-
@status_subscriptions[component_id].delete(sCI) if @status_subscriptions[component_id][sCI].empty?
|
|
258
|
-
@status_subscriptions.delete(component_id) if @status_subscriptions[component_id].empty?
|
|
259
|
-
end
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
message = RSMP::StatusUnsubscribe.new({
|
|
263
|
-
"cId" => component_id,
|
|
264
|
-
"sS" => status_list
|
|
265
|
-
})
|
|
266
|
-
set_nts_message_attributes message
|
|
267
|
-
send_message message, validate: options[:validate]
|
|
268
|
-
message
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def process_status_update message
|
|
272
|
-
component = find_component message.attribute("cId")
|
|
273
|
-
component.check_repeat_values message, @status_subscriptions
|
|
274
|
-
component.store_status message
|
|
275
|
-
log "Received #{message.type}", message: message, level: :log
|
|
276
|
-
acknowledge message
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
def send_alarm_acknowledgement component, alarm_code, options={}
|
|
280
|
-
message = RSMP::AlarmAcknowledged.new({
|
|
281
|
-
"cId" => component,
|
|
282
|
-
"aCId" => alarm_code,
|
|
283
|
-
})
|
|
284
|
-
send_message message, validate: options[:validate]
|
|
285
|
-
message
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def send_command component, command_list, options={}
|
|
289
|
-
validate_ready 'send command'
|
|
290
|
-
m_id = options[:m_id] || RSMP::Message.make_m_id
|
|
291
|
-
message = RSMP::CommandRequest.new({
|
|
292
|
-
"cId" => component,
|
|
293
|
-
"arg" => command_list,
|
|
294
|
-
"mId" => m_id
|
|
295
|
-
})
|
|
296
|
-
set_nts_message_attributes message
|
|
297
|
-
send_and_optionally_collect message, options do |collect_options|
|
|
298
|
-
CommandResponseCollector.new(
|
|
299
|
-
self,
|
|
300
|
-
command_list,
|
|
301
|
-
collect_options.merge(task:@task,m_id: m_id)
|
|
302
|
-
)
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
def set_watchdog_interval interval
|
|
307
|
-
@settings['intervals']['watchdog'] = interval
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
def check_sxl_version message
|
|
311
|
-
# check that we have a schema for specified sxl type and version
|
|
312
|
-
# note that the type comes from the site config, while the version
|
|
313
|
-
# comes from the Version message send by the site
|
|
314
|
-
type = @site_settings['sxl']
|
|
315
|
-
version = message.attribute 'SXL'
|
|
316
|
-
RSMP::Schema::find_schema! type, version, lenient: true
|
|
317
|
-
|
|
318
|
-
# store sxl version requested by site
|
|
319
|
-
# TODO should check agaist site settings
|
|
320
|
-
@site_sxl_version = message.attribute 'SXL'
|
|
321
|
-
rescue RSMP::Schema::UnknownSchemaError => e
|
|
322
|
-
dont_acknowledge message, "Rejected #{message.type} message,", "#{e}"
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
def sxl_version
|
|
326
|
-
# a supervisor does not maintain it's own sxl version
|
|
327
|
-
# instead we use what the site requests
|
|
328
|
-
@site_sxl_version
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
def process_version message
|
|
332
|
-
return extraneous_version message if @version_determined
|
|
333
|
-
check_site_ids message
|
|
334
|
-
check_sxl_version message
|
|
335
|
-
version_accepted message
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
def check_site_ids message
|
|
339
|
-
# RSMP support multiple site ids. we don't support this yet. instead we use the first id only
|
|
340
|
-
site_id = message.attribute("siteId").map { |item| item["sId"] }.first
|
|
341
|
-
@supervisor.check_site_id site_id
|
|
342
|
-
site_ids_changed
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
def find_site_settings site_id
|
|
346
|
-
if @settings['sites'] && @settings['sites'][@site_id]
|
|
347
|
-
log "Using site settings for site id #{@site_id}", level: :debug
|
|
348
|
-
return @settings['sites'][@site_id]
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
settings = @settings['guest']
|
|
352
|
-
if @settings['guest']
|
|
353
|
-
log "Using site settings for guest", level: :debug
|
|
354
|
-
return @settings['guest']
|
|
355
|
-
end
|
|
356
|
-
|
|
357
|
-
nil
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
def setup_site_settings
|
|
361
|
-
@site_settings = find_site_settings @site_id
|
|
362
|
-
if @site_settings
|
|
363
|
-
@sxl = @site_settings['sxl']
|
|
364
|
-
setup_components @site_settings['components']
|
|
365
|
-
else
|
|
366
|
-
dont_acknowledge message, 'Rejected', "No config found for site #{@site_id}"
|
|
367
|
-
end
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
def receive_error e, options={}
|
|
371
|
-
@supervisor.receive_error e, options if @supervisor
|
|
372
|
-
distribute_error e, options
|
|
373
|
-
end
|
|
374
|
-
|
|
375
|
-
def build_component id:, type:, settings:{}
|
|
376
|
-
settings ||= {}
|
|
377
|
-
if type == 'main'
|
|
378
|
-
ComponentProxy.new id:id, node: self, grouped: true,
|
|
379
|
-
ntsOId: settings['ntsOId'], xNId: settings['xNId']
|
|
380
|
-
else
|
|
381
|
-
ComponentProxy.new id:id, node: self, grouped: false
|
|
382
|
-
end
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
def infer_component_type component_id
|
|
386
|
-
ComponentProxy
|
|
387
|
-
end
|
|
388
|
-
end
|
|
389
|
-
end
|