rsmp 0.1.21 → 0.1.32
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/.gitmodules +0 -4
- data/Gemfile.lock +13 -11
- data/config/supervisor.yaml +9 -15
- data/config/tlc.yaml +9 -8
- data/documentation/message_distribution.md +8 -8
- data/lib/rsmp.rb +5 -0
- data/lib/rsmp/archive.rb +7 -4
- data/lib/rsmp/cli.rb +133 -102
- data/lib/rsmp/collector.rb +42 -30
- data/lib/rsmp/component.rb +2 -0
- data/lib/rsmp/components.rb +1 -1
- data/lib/rsmp/convert/export/json_schema.rb +204 -0
- data/lib/rsmp/convert/import/yaml.rb +38 -0
- data/lib/rsmp/deep_merge.rb +11 -0
- data/lib/rsmp/inspect.rb +46 -0
- data/lib/rsmp/listener.rb +4 -14
- data/lib/rsmp/logger.rb +3 -1
- data/lib/rsmp/logging.rb +1 -1
- data/lib/rsmp/message.rb +22 -31
- data/lib/rsmp/node.rb +11 -1
- data/lib/rsmp/notifier.rb +7 -2
- data/lib/rsmp/proxy.rb +95 -39
- data/lib/rsmp/rsmp.rb +34 -23
- data/lib/rsmp/site.rb +30 -32
- data/lib/rsmp/site_proxy.rb +103 -22
- data/lib/rsmp/site_proxy_wait.rb +63 -38
- data/lib/rsmp/supervisor.rb +82 -47
- data/lib/rsmp/supervisor_proxy.rb +21 -13
- data/lib/rsmp/tlc.rb +61 -35
- data/lib/rsmp/version.rb +1 -1
- data/rsmp.gemspec +3 -14
- metadata +13 -113
- data/config/site.yaml +0 -40
data/lib/rsmp/supervisor.rb
CHANGED
@@ -17,47 +17,57 @@ module RSMP
|
|
17
17
|
@supervisor_settings['site_id']
|
18
18
|
end
|
19
19
|
|
20
|
-
def handle_supervisor_settings options
|
21
|
-
|
20
|
+
def handle_supervisor_settings options={}
|
21
|
+
defaults = {
|
22
22
|
'port' => 12111,
|
23
|
-
'
|
24
|
-
'
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
:any => {}
|
23
|
+
'ips' => 'all',
|
24
|
+
'guest' => {
|
25
|
+
'rsmp_versions' => 'all',
|
26
|
+
'sxl' => 'tlc',
|
27
|
+
'intervals' => {
|
28
|
+
'timer' => 1,
|
29
|
+
'watchdog' => 1
|
30
|
+
},
|
31
|
+
'timeouts' => {
|
32
|
+
'watchdog' => 2,
|
33
|
+
'acknowledgement' => 2
|
34
|
+
}
|
36
35
|
}
|
37
36
|
}
|
38
|
-
|
39
|
-
if options[:supervisor_settings]
|
40
|
-
converted = options[:supervisor_settings].map { |k,v| [k.to_s,v] }.to_h #convert symbol keys to string keys
|
41
|
-
converted.compact!
|
42
|
-
@supervisor_settings.merge! converted
|
43
|
-
end
|
44
|
-
|
45
|
-
required = [:port, :rsmp_versions, :watchdog_interval, :watchdog_timeout,
|
46
|
-
:acknowledgement_timeout, :command_response_timeout]
|
47
|
-
check_required_settings @supervisor_settings, required
|
48
37
|
|
38
|
+
# merge options into defaults
|
39
|
+
@supervisor_settings = defaults.deep_merge(options[:supervisor_settings] || {})
|
49
40
|
@rsmp_versions = @supervisor_settings["rsmp_versions"]
|
41
|
+
check_site_sxl_types
|
42
|
+
end
|
43
|
+
|
44
|
+
def check_site_sxl_types
|
45
|
+
sites = @supervisor_settings['sites'].clone || {}
|
46
|
+
sites['guest'] = @supervisor_settings['guest']
|
47
|
+
sites.each do |site_id,settings|
|
48
|
+
unless settings
|
49
|
+
raise RSMP::ConfigurationError.new("Configuration for site '#{site_id}' is empty")
|
50
|
+
end
|
51
|
+
sxl = settings['sxl']
|
52
|
+
sxl = 'tlc' unless sxl # temporary fix until configs are updated
|
53
|
+
unless sxl
|
54
|
+
raise RSMP::ConfigurationError.new("Configuration error for site '#{site_id}': No SXL specified")
|
55
|
+
end
|
56
|
+
RSMP::Schemer.find_schemas! sxl if sxl
|
57
|
+
rescue RSMP::Schemer::UnknownSchemaError => e
|
58
|
+
raise RSMP::ConfigurationError.new("Configuration error for site '#{site_id}': #{e}")
|
59
|
+
end
|
50
60
|
end
|
51
61
|
|
52
62
|
def start_action
|
53
63
|
@endpoint = Async::IO::Endpoint.tcp('0.0.0.0', @supervisor_settings["port"])
|
54
|
-
@endpoint.accept do |socket|
|
64
|
+
@endpoint.accept do |socket| # creates async tasks
|
55
65
|
handle_connection(socket)
|
66
|
+
rescue StandardError => e
|
67
|
+
notify_error e, level: :internal
|
56
68
|
end
|
57
|
-
rescue SystemCallError => e # all ERRNO errors
|
58
|
-
log "Exception: #{e.to_s}", level: :error
|
59
69
|
rescue StandardError => e
|
60
|
-
|
70
|
+
notify_error e, level: :internal
|
61
71
|
end
|
62
72
|
|
63
73
|
def stop
|
@@ -74,16 +84,18 @@ module RSMP
|
|
74
84
|
remote_hostname = socket.remote_address.ip_address
|
75
85
|
remote_ip = socket.remote_address.ip_address
|
76
86
|
|
77
|
-
info = {ip:remote_ip, port:remote_port, hostname:remote_hostname, now:
|
87
|
+
info = {ip:remote_ip, port:remote_port, hostname:remote_hostname, now:Clock.now}
|
78
88
|
if accept? socket, info
|
79
89
|
connect socket, info
|
80
90
|
else
|
81
91
|
reject socket, info
|
82
92
|
end
|
83
|
-
rescue
|
84
|
-
log "
|
93
|
+
rescue ConnectionError => e
|
94
|
+
log "Rejected connection from #{remote_ip}:#{remote_port}, #{e.to_s}", level: :warning
|
95
|
+
notify_error e
|
85
96
|
rescue StandardError => e
|
86
|
-
log "
|
97
|
+
log "Connection: #{e.to_s}", exception: e, level: :error
|
98
|
+
notify_error e, level: :internal
|
87
99
|
ensure
|
88
100
|
close socket, info
|
89
101
|
end
|
@@ -91,7 +103,7 @@ module RSMP
|
|
91
103
|
def starting
|
92
104
|
log "Starting supervisor on port #{@supervisor_settings["port"]}",
|
93
105
|
level: :info,
|
94
|
-
timestamp:
|
106
|
+
timestamp: @clock.now
|
95
107
|
end
|
96
108
|
|
97
109
|
def accept? socket, info
|
@@ -110,18 +122,37 @@ module RSMP
|
|
110
122
|
end
|
111
123
|
end
|
112
124
|
|
125
|
+
def authorize_ip ip
|
126
|
+
return if @supervisor_settings['ips'] == 'all'
|
127
|
+
return if @supervisor_settings['ips'].include? ip
|
128
|
+
raise ConnectionError.new('guest ip not allowed')
|
129
|
+
end
|
130
|
+
|
131
|
+
def check_max_sites
|
132
|
+
max = @supervisor_settings['max_sites']
|
133
|
+
if max
|
134
|
+
if @proxies.size >= max
|
135
|
+
raise ConnectionError.new("maximum of #{max} sites already connected")
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
113
140
|
def connect socket, info
|
114
141
|
log "Site connected from #{format_ip_and_port(info)}",
|
115
142
|
ip: info[:ip],
|
116
143
|
port: info[:port],
|
117
144
|
level: :info,
|
118
|
-
timestamp:
|
145
|
+
timestamp: Clock.now
|
146
|
+
|
147
|
+
authorize_ip info[:ip]
|
148
|
+
check_max_sites
|
119
149
|
|
120
|
-
settings = @supervisor_settings['sites'][info[:ip]] || @supervisor_settings['sites'][:any]
|
121
150
|
proxy = build_proxy({
|
122
151
|
supervisor: self,
|
152
|
+
ip: info[:ip],
|
153
|
+
port: info[:port],
|
123
154
|
task: @task,
|
124
|
-
settings:
|
155
|
+
settings: {'collect'=>@supervisor_settings['collect']},
|
125
156
|
socket: socket,
|
126
157
|
info: info,
|
127
158
|
logger: @logger,
|
@@ -133,7 +164,7 @@ module RSMP
|
|
133
164
|
@proxies.delete proxy
|
134
165
|
site_ids_changed
|
135
166
|
|
136
|
-
stop if @supervisor_settings['
|
167
|
+
stop if @supervisor_settings['one_shot']
|
137
168
|
end
|
138
169
|
|
139
170
|
def site_ids_changed
|
@@ -146,9 +177,9 @@ module RSMP
|
|
146
177
|
|
147
178
|
def close socket, info
|
148
179
|
if info
|
149
|
-
log "Connection to #{format_ip_and_port(info)} closed", ip: info[:ip], level: :info, timestamp:
|
180
|
+
log "Connection to #{format_ip_and_port(info)} closed", ip: info[:ip], level: :info, timestamp: Clock.now
|
150
181
|
else
|
151
|
-
log "Connection closed", level: :info, timestamp:
|
182
|
+
log "Connection closed", level: :info, timestamp: Clock.now
|
152
183
|
end
|
153
184
|
|
154
185
|
socket.close
|
@@ -170,32 +201,36 @@ module RSMP
|
|
170
201
|
return site if site
|
171
202
|
wait_for(@site_id_condition,timeout) { find_site site_id }
|
172
203
|
rescue Async::TimeoutError
|
173
|
-
|
204
|
+
raise RSMP::TimeoutError.new "Site '#{site_id}' did not connect within #{timeout}s"
|
174
205
|
end
|
175
206
|
|
176
207
|
def wait_for_site_disconnect site_id, timeout
|
177
208
|
wait_for(@site_id_condition,timeout) { true unless find_site site_id }
|
178
209
|
rescue Async::TimeoutError
|
179
|
-
|
210
|
+
raise RSMP::TimeoutError.new "Site '#{site_id}' did not disconnect within #{timeout}s"
|
180
211
|
end
|
181
212
|
|
182
213
|
def check_site_id site_id
|
183
214
|
check_site_already_connected site_id
|
184
|
-
return
|
215
|
+
return site_id_to_site_setting site_id
|
185
216
|
end
|
186
217
|
|
187
218
|
def check_site_already_connected site_id
|
188
|
-
raise FatalError.new "Site #{site_id} already connected" if find_site(site_id)
|
219
|
+
raise FatalError.new "Site '#{site_id}' already connected" if find_site(site_id)
|
189
220
|
end
|
190
221
|
|
191
|
-
def
|
222
|
+
def site_id_to_site_setting site_id
|
192
223
|
return {} unless @supervisor_settings['sites']
|
193
224
|
@supervisor_settings['sites'].each_pair do |id,settings|
|
194
|
-
if id ==
|
225
|
+
if id == 'guest' || id == site_id
|
195
226
|
return settings
|
196
227
|
end
|
197
228
|
end
|
198
|
-
raise FatalError.new "site id #{site_id}
|
229
|
+
raise FatalError.new "site id #{site_id} unknown"
|
230
|
+
end
|
231
|
+
|
232
|
+
def ip_to_site_settings ip
|
233
|
+
@supervisor_settings['sites'][ip] || @supervisor_settings['sites']['guest']
|
199
234
|
end
|
200
235
|
|
201
236
|
def aggregated_status_changed site_proxy, component
|
@@ -32,8 +32,8 @@ module RSMP
|
|
32
32
|
send_version @site_settings['site_id'], @site_settings["rsmp_versions"]
|
33
33
|
rescue Errno::ECONNREFUSED
|
34
34
|
log "No connection to supervisor at #{@ip}:#{@port}", level: :error
|
35
|
-
unless @site.site_settings[
|
36
|
-
log "Will try to reconnect again every #{@site.site_settings[
|
35
|
+
unless @site.site_settings['intervals']['reconnect'] == :no
|
36
|
+
log "Will try to reconnect again every #{@site.site_settings['intervals']['reconnect']} seconds..", level: :info
|
37
37
|
@logger.mute @ip, @port
|
38
38
|
end
|
39
39
|
end
|
@@ -49,12 +49,12 @@ module RSMP
|
|
49
49
|
@endpoint = Async::IO::Endpoint.tcp(@ip, @port)
|
50
50
|
@socket = @endpoint.connect
|
51
51
|
@stream = Async::IO::Stream.new(@socket)
|
52
|
-
@protocol = Async::IO::Protocol::Line.new(@stream,
|
52
|
+
@protocol = Async::IO::Protocol::Line.new(@stream,WRAPPING_DELIMITER) # rsmp messages are json terminated with a form-feed
|
53
53
|
end
|
54
54
|
|
55
55
|
def connection_complete
|
56
56
|
super
|
57
|
-
log "Connection to supervisor established", level: :info
|
57
|
+
log "Connection to supervisor established, using core #{@rsmp_version}, #{sxl} #{sxl_version}", level: :info
|
58
58
|
start_watchdog
|
59
59
|
end
|
60
60
|
|
@@ -65,6 +65,8 @@ module RSMP
|
|
65
65
|
when StatusUpdate
|
66
66
|
when AggregatedStatus
|
67
67
|
will_not_handle message
|
68
|
+
when AggregatedStatusRequest
|
69
|
+
process_aggregated_status_request message
|
68
70
|
when CommandRequest
|
69
71
|
process_command_request message
|
70
72
|
when CommandResponse
|
@@ -108,7 +110,7 @@ module RSMP
|
|
108
110
|
end
|
109
111
|
|
110
112
|
def reconnect_delay
|
111
|
-
interval = @site_settings[
|
113
|
+
interval = @site_settings['intervals']['reconnect']
|
112
114
|
log "Waiting #{interval} seconds before trying to reconnect", level: :info
|
113
115
|
@task.sleep interval
|
114
116
|
end
|
@@ -123,7 +125,7 @@ module RSMP
|
|
123
125
|
|
124
126
|
def send_aggregated_status component
|
125
127
|
message = AggregatedStatus.new({
|
126
|
-
"aSTS" =>
|
128
|
+
"aSTS" => clock.to_s,
|
127
129
|
"cId" => component.c_id,
|
128
130
|
"fP" => 'NormalControl',
|
129
131
|
"fS" => nil,
|
@@ -161,6 +163,14 @@ module RSMP
|
|
161
163
|
sorted
|
162
164
|
end
|
163
165
|
|
166
|
+
def process_aggregated_status_request message
|
167
|
+
log "Received #{message.type}", message: message, level: :log
|
168
|
+
component_id = message.attributes["cId"]
|
169
|
+
component = @site.find_component component_id
|
170
|
+
acknowledge message
|
171
|
+
send_aggregated_status component
|
172
|
+
end
|
173
|
+
|
164
174
|
def process_command_request message
|
165
175
|
log "Received #{message.type}", message: message, level: :log
|
166
176
|
component_id = message.attributes["cId"]
|
@@ -177,7 +187,7 @@ module RSMP
|
|
177
187
|
end
|
178
188
|
response = CommandResponse.new({
|
179
189
|
"cId"=>component_id,
|
180
|
-
"cTS"=>
|
190
|
+
"cTS"=>clock.to_s,
|
181
191
|
"rvs"=>rvs
|
182
192
|
})
|
183
193
|
acknowledge message
|
@@ -194,7 +204,7 @@ module RSMP
|
|
194
204
|
end
|
195
205
|
response = StatusResponse.new({
|
196
206
|
"cId"=>component_id,
|
197
|
-
"sTs"=>
|
207
|
+
"sTs"=>clock.to_s,
|
198
208
|
"sS"=>sS,
|
199
209
|
"mId" => options[:m_id]
|
200
210
|
})
|
@@ -221,7 +231,7 @@ module RSMP
|
|
221
231
|
update_list[component] ||= {}
|
222
232
|
|
223
233
|
subs = @status_subscriptions[component]
|
224
|
-
now =
|
234
|
+
now = Time.now # internal timestamp
|
225
235
|
|
226
236
|
message.attributes["sS"].each do |arg|
|
227
237
|
sCI = arg["sCI"]
|
@@ -310,12 +320,10 @@ module RSMP
|
|
310
320
|
end
|
311
321
|
end
|
312
322
|
send_status_updates update_list
|
313
|
-
rescue StandardError => e
|
314
|
-
log ["Status update exception: #{e}",e.backtrace].flatten.join("\n"), level: :error
|
315
323
|
end
|
316
324
|
|
317
325
|
def send_status_updates update_list
|
318
|
-
now =
|
326
|
+
now = clock.to_s
|
319
327
|
update_list.each_pair do |component_id,by_code|
|
320
328
|
component = @site.find_component component_id
|
321
329
|
sS = []
|
@@ -343,7 +351,7 @@ module RSMP
|
|
343
351
|
|
344
352
|
def send_alarm
|
345
353
|
message = Alarm.new({
|
346
|
-
"aSTS"=>
|
354
|
+
"aSTS"=>clock.to_s,
|
347
355
|
"fP"=>nil,
|
348
356
|
"fS"=>nil,
|
349
357
|
"se"=>@site.aggregated_status_bools
|
data/lib/rsmp/tlc.rb
CHANGED
@@ -13,7 +13,6 @@ module RSMP
|
|
13
13
|
@cycle_time = cycle_time
|
14
14
|
@num_traffic_situations = 1
|
15
15
|
@num_inputs = 8
|
16
|
-
|
17
16
|
reset
|
18
17
|
end
|
19
18
|
|
@@ -41,6 +40,11 @@ module RSMP
|
|
41
40
|
@input_results = '0'*@num_inputs
|
42
41
|
end
|
43
42
|
|
43
|
+
def clock
|
44
|
+
node.clock
|
45
|
+
end
|
46
|
+
|
47
|
+
|
44
48
|
def add_signal_group group
|
45
49
|
@signal_groups << group
|
46
50
|
end
|
@@ -48,8 +52,12 @@ module RSMP
|
|
48
52
|
def add_detector_logic logic
|
49
53
|
@detector_logics << logic
|
50
54
|
end
|
55
|
+
|
51
56
|
def timer now
|
52
|
-
|
57
|
+
# TODO
|
58
|
+
# We should use a monotone timer, to avoid jumps
|
59
|
+
# in case the user sets the system time
|
60
|
+
pos = Time.now.to_i % @cycle_time
|
53
61
|
if pos != @pos
|
54
62
|
@pos = pos
|
55
63
|
move pos
|
@@ -80,7 +88,11 @@ module RSMP
|
|
80
88
|
end
|
81
89
|
|
82
90
|
def format_signal_group_status
|
83
|
-
@
|
91
|
+
if @yellow_flash
|
92
|
+
'c' * @signal_groups.size
|
93
|
+
else
|
94
|
+
@signal_groups.map { |group| group.state }.join
|
95
|
+
end
|
84
96
|
end
|
85
97
|
|
86
98
|
def handle_command command_code, arg
|
@@ -202,6 +214,17 @@ module RSMP
|
|
202
214
|
|
203
215
|
def handle_m0104 arg
|
204
216
|
@node.verify_security_code 1, arg['securityCode']
|
217
|
+
time = Time.new(
|
218
|
+
arg['year'],
|
219
|
+
arg['month'],
|
220
|
+
arg['day'],
|
221
|
+
arg['hour'],
|
222
|
+
arg['minute'],
|
223
|
+
arg['second'],
|
224
|
+
'UTC'
|
225
|
+
)
|
226
|
+
@node.clock.set time
|
227
|
+
log "Clock set to #{time}, (adjustment is #{@node.clock.adjustment}s)", level: :info
|
205
228
|
end
|
206
229
|
|
207
230
|
def set_input i, value
|
@@ -518,35 +541,37 @@ module RSMP
|
|
518
541
|
end
|
519
542
|
|
520
543
|
def handle_s0096 status_code, status_name=nil
|
544
|
+
now = clock.now
|
521
545
|
case status_name
|
522
546
|
when 'year'
|
523
|
-
RSMP::Tlc.make_status
|
547
|
+
RSMP::Tlc.make_status now.year.to_s.rjust(4, "0")
|
524
548
|
when 'month'
|
525
|
-
RSMP::Tlc.make_status
|
549
|
+
RSMP::Tlc.make_status now.month.to_s.rjust(2, "0")
|
526
550
|
when 'day'
|
527
|
-
RSMP::Tlc.make_status
|
551
|
+
RSMP::Tlc.make_status now.day.to_s.rjust(2, "0")
|
528
552
|
when 'hour'
|
529
|
-
RSMP::Tlc.make_status
|
553
|
+
RSMP::Tlc.make_status now.hour.to_s.rjust(2, "0")
|
530
554
|
when 'minute'
|
531
|
-
RSMP::Tlc.make_status
|
555
|
+
RSMP::Tlc.make_status now.min.to_s.rjust(2, "0")
|
532
556
|
when 'second'
|
533
|
-
RSMP::Tlc.make_status
|
557
|
+
RSMP::Tlc.make_status now.sec.to_s.rjust(2, "0")
|
534
558
|
end
|
535
559
|
end
|
536
560
|
|
537
561
|
def handle_s0097 status_code, status_name=nil
|
538
562
|
case status_name
|
539
|
-
when '
|
540
|
-
RSMP::Tlc.make_status '1'
|
541
|
-
when 'hash'
|
563
|
+
when 'checksum'
|
542
564
|
RSMP::Tlc.make_status '1'
|
565
|
+
when 'timestamp'
|
566
|
+
now = @node.clock.to_s
|
567
|
+
RSMP::Tlc.make_status now
|
543
568
|
end
|
544
569
|
end
|
545
570
|
|
546
571
|
def handle_s0205 status_code, status_name=nil
|
547
572
|
case status_name
|
548
573
|
when 'start'
|
549
|
-
RSMP::Tlc.make_status
|
574
|
+
RSMP::Tlc.make_status clock.to_s
|
550
575
|
when 'vehicles'
|
551
576
|
RSMP::Tlc.make_status 0
|
552
577
|
end
|
@@ -555,7 +580,7 @@ module RSMP
|
|
555
580
|
def handle_s0206 status_code, status_name=nil
|
556
581
|
case status_name
|
557
582
|
when 'start'
|
558
|
-
RSMP::Tlc.make_status
|
583
|
+
RSMP::Tlc.make_status clock.to_s
|
559
584
|
when 'speed'
|
560
585
|
RSMP::Tlc.make_status 0
|
561
586
|
end
|
@@ -564,7 +589,7 @@ module RSMP
|
|
564
589
|
def handle_s0207 status_code, status_name=nil
|
565
590
|
case status_name
|
566
591
|
when 'start'
|
567
|
-
RSMP::Tlc.make_status
|
592
|
+
RSMP::Tlc.make_status clock.to_s
|
568
593
|
when 'occupancy'
|
569
594
|
RSMP::Tlc.make_status 0
|
570
595
|
end
|
@@ -573,7 +598,7 @@ module RSMP
|
|
573
598
|
def handle_s0208 status_code, status_name=nil
|
574
599
|
case status_name
|
575
600
|
when 'start'
|
576
|
-
RSMP::Tlc.make_status
|
601
|
+
RSMP::Tlc.make_status clock.to_s
|
577
602
|
when 'P'
|
578
603
|
RSMP::Tlc.make_status 0
|
579
604
|
when 'PS'
|
@@ -653,21 +678,22 @@ module RSMP
|
|
653
678
|
end
|
654
679
|
|
655
680
|
def handle_s0025 status_code, status_name=nil
|
681
|
+
now = @node.clock.to_s
|
656
682
|
case status_name
|
657
683
|
when 'minToGEstimate'
|
658
|
-
RSMP::Tlc.make_status
|
684
|
+
RSMP::Tlc.make_status now
|
659
685
|
when 'maxToGEstimate'
|
660
|
-
RSMP::Tlc.make_status
|
686
|
+
RSMP::Tlc.make_status now
|
661
687
|
when 'likelyToGEstimate'
|
662
|
-
RSMP::Tlc.make_status
|
688
|
+
RSMP::Tlc.make_status now
|
663
689
|
when 'ToGConfidence'
|
664
690
|
RSMP::Tlc.make_status 0
|
665
691
|
when 'minToREstimate'
|
666
|
-
RSMP::Tlc.make_status
|
692
|
+
RSMP::Tlc.make_status now
|
667
693
|
when 'maxToREstimate'
|
668
|
-
RSMP::Tlc.make_status
|
694
|
+
RSMP::Tlc.make_status now
|
669
695
|
when 'likelyToREstimate'
|
670
|
-
RSMP::Tlc.make_status
|
696
|
+
RSMP::Tlc.make_status now
|
671
697
|
when 'ToRConfidence'
|
672
698
|
RSMP::Tlc.make_status 0
|
673
699
|
end
|
@@ -695,7 +721,7 @@ module RSMP
|
|
695
721
|
def handle_s0201 status_code, status_name=nil
|
696
722
|
case status_name
|
697
723
|
when 'starttime'
|
698
|
-
RSMP::Tlc.make_status
|
724
|
+
RSMP::Tlc.make_status @node.clock.to_s
|
699
725
|
when 'vehicles'
|
700
726
|
RSMP::Tlc.make_status 0
|
701
727
|
end
|
@@ -704,7 +730,7 @@ module RSMP
|
|
704
730
|
def handle_s0202 status_code, status_name=nil
|
705
731
|
case status_name
|
706
732
|
when 'starttime'
|
707
|
-
RSMP::Tlc.make_status
|
733
|
+
RSMP::Tlc.make_status @node.clock.to_s
|
708
734
|
when 'speed'
|
709
735
|
RSMP::Tlc.make_status 0
|
710
736
|
end
|
@@ -713,7 +739,7 @@ module RSMP
|
|
713
739
|
def handle_s0203 status_code, status_name=nil
|
714
740
|
case status_name
|
715
741
|
when 'starttime'
|
716
|
-
RSMP::Tlc.make_status
|
742
|
+
RSMP::Tlc.make_status @node.clock.to_s
|
717
743
|
when 'occupancy'
|
718
744
|
RSMP::Tlc.make_status 0
|
719
745
|
end
|
@@ -722,7 +748,7 @@ module RSMP
|
|
722
748
|
def handle_s0204 status_code, status_name=nil
|
723
749
|
case status_name
|
724
750
|
when 'starttime'
|
725
|
-
RSMP::Tlc.make_status
|
751
|
+
RSMP::Tlc.make_status @node.clock.to_s
|
726
752
|
when 'P'
|
727
753
|
RSMP::Tlc.make_status 0
|
728
754
|
when 'PS'
|
@@ -767,11 +793,12 @@ module RSMP
|
|
767
793
|
end
|
768
794
|
|
769
795
|
class Tlc < Site
|
796
|
+
attr_accessor :main
|
770
797
|
def initialize options={}
|
771
798
|
super options
|
772
799
|
@sxl = 'traffic_light_controller'
|
773
800
|
@security_codes = options[:site_settings]['security_codes']
|
774
|
-
@interval = options[:site_settings]['
|
801
|
+
@interval = options[:site_settings]['intervals']['timer'] || 1
|
775
802
|
unless @main
|
776
803
|
raise ConfigurationError.new "TLC must have a main component"
|
777
804
|
end
|
@@ -806,22 +833,21 @@ module RSMP
|
|
806
833
|
next_time = Time.now.to_f
|
807
834
|
loop do
|
808
835
|
begin
|
809
|
-
now
|
810
|
-
timer(now)
|
836
|
+
timer(@clock.now)
|
811
837
|
rescue EOFError => e
|
812
|
-
log "
|
838
|
+
log "Connection closed: #{e}", level: :warning
|
813
839
|
rescue IOError => e
|
814
|
-
log "
|
840
|
+
log "IOError", level: :warning
|
815
841
|
rescue Errno::ECONNRESET
|
816
|
-
log "
|
842
|
+
log "Connection reset by peer", level: :warning
|
817
843
|
rescue Errno::EPIPE => e
|
818
|
-
log "
|
844
|
+
log "Broken pipe", level: :warning
|
819
845
|
rescue StandardError => e
|
820
|
-
|
846
|
+
notify_error e, level: :internal
|
821
847
|
ensure
|
822
848
|
# adjust sleep duration to avoid drift. so wake up always happens on the
|
823
849
|
# same fractional second.
|
824
|
-
# note that Time.now is not monotonic. If the clock
|
850
|
+
# note that Time.now is not monotonic. If the clock is changed,
|
825
851
|
# either manaully or via NTP, the sleep interval might jump.
|
826
852
|
# an alternative is to use ::Process.clock_gettime(::Process::CLOCK_MONOTONIC),
|
827
853
|
# to get the current time. this ensures a constant interval, but
|