rsmp 0.15.0 → 0.15.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53db2e5d294329ddcaed57088f8b1ef6a3b3bae1327d7a41727b5b242df5e9d7
4
- data.tar.gz: fa5926fe27b1f24be2998d7860ba8ceaddb1d51a23bedc3554d31e48b0293ec6
3
+ metadata.gz: 54f63cca69dba59878ba09d7463f4767f8489ce53b29139d6acb57c4fc2e5d1e
4
+ data.tar.gz: f28e12b4230f0c7cb545b9519fbdef68df0179f5e668989689ba83d13f5ce9b6
5
5
  SHA512:
6
- metadata.gz: 2f3448a60f9bd4edda200b165a612217f57086b0342b04f11d6a03087c77500093fd61c21c85946d4cf91b1b228404634d6d884fc0ffc7de7f62f8b552fa373e
7
- data.tar.gz: 87ce720b9a3e2c7b9ed7db64c07a18ac84058b38007172fabe1c8847513c93fd1002ac9c8e6f3ba6635d24c9bf36c9f3b36324d6edc0b135887bcc3039d3dc61
6
+ metadata.gz: 415b6caa24f354c51ad61ddc46b06325e7d9dde714186217db142e3cf73e18a3aedecc4a400ab432f5edf14a236163005b7618a4ca2ab63f8d9610440b843d78
7
+ data.tar.gz: 398baeed8be6a5918546c2954590c4dead4919b613bbf71ea03ec2dae2d2cdf3155c92598c0151869c36e48b635b6a232e0b6ec093a283493e3398962dcbb688
data/Gemfile.lock CHANGED
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.15.0)
4
+ rsmp (0.15.1)
5
5
  async (~> 1.30.3)
6
6
  async-io (~> 1.33.0)
7
7
  colorize (~> 0.8.1)
8
- rsmp_schema (~> 0.2.3)
8
+ rsmp_schema (~> 0.2.5)
9
9
  thor (~> 1.2.1)
10
10
 
11
11
  GEM
@@ -80,7 +80,7 @@ GEM
80
80
  nio4r (2.5.8)
81
81
  rake (13.0.6)
82
82
  regexp_parser (2.5.0)
83
- rsmp_schema (0.2.3)
83
+ rsmp_schema (0.2.5)
84
84
  json_schemer (~> 0.2.21)
85
85
  thor (~> 1.2.1)
86
86
  rspec (3.10.0)
@@ -0,0 +1,16 @@
1
+ module RSMP
2
+ # Class for waiting for a message acknowledgement
3
+ class AckCollector < Collector
4
+ def initialize proxy, options={}
5
+ raise ArgumentError.new("m_id must be provided") unless options[:m_id]
6
+ required = { type: 'MessageAck', num: 1, title: 'message acknowledgement' }
7
+ super proxy, options.merge(required)
8
+ end
9
+
10
+ # Check if we the MessageAck related to initiating request, identified by @m_id.
11
+ def type_match? message
12
+ return false if super(message) == false
13
+ return message.attribute('oMId') == @options[:m_id]
14
+ end
15
+ end
16
+ end
@@ -17,8 +17,8 @@ module RSMP
17
17
  check_main_component settings
18
18
  settings.each_pair do |type,components_by_type|
19
19
  if components_by_type
20
- components_by_type.each_pair do |id,settings|
21
- @components[id] = build_component(id:id, type:type, settings:settings)
20
+ components_by_type.each_pair do |id,component_settings|
21
+ @components[id] = build_component(id:id, type:type, settings:component_settings)
22
22
  @main = @components[id] if type=='main'
23
23
  end
24
24
  end
data/lib/rsmp/proxy.rb CHANGED
@@ -560,8 +560,11 @@ module RSMP
560
560
  message.original = original
561
561
  log_acknowledgement_for_original message, original
562
562
 
563
- if original.type == "Version"
563
+ case original.type
564
+ when "Version"
564
565
  version_acknowledged
566
+ when "StatusSubscribe"
567
+ status_subscribe_acknowledged original
565
568
  end
566
569
 
567
570
  check_outgoing_acknowledged original
@@ -653,5 +656,14 @@ module RSMP
653
656
  Gem::Requirement.new(requirement).satisfied_by?(Gem::Version.new(version))
654
657
  end
655
658
 
659
+ def status_subscribe_acknowledged original
660
+ component = find_component original.attribute('cId')
661
+ return unless component
662
+ short = Message.shorten_m_id original.m_id
663
+ subscribe_list = original.attributes['sS']
664
+ log "StatusSubscribe #{short} acknowledged, allowing repeated status values for #{subscribe_list}", level: :info
665
+ component.allow_repeat_updates subscribe_list
666
+ end
667
+
656
668
  end
657
669
  end
data/lib/rsmp/site.rb CHANGED
@@ -145,7 +145,8 @@ module RSMP
145
145
  nil
146
146
  end
147
147
 
148
- def build_component id:, type:, settings:{}
148
+ def build_component id:, type:, settings:
149
+ settings ||= {}
149
150
  if type == 'main'
150
151
  Component.new id:id, node: self, grouped: true,
151
152
  ntsOId: settings['ntsOId'], xNId: settings['xNId']
@@ -228,7 +228,6 @@ module RSMP
228
228
  end
229
229
 
230
230
  component = find_component component_id
231
- component.allow_repeat_updates subscribe_list
232
231
 
233
232
  message = RSMP::StatusSubscribe.new({
234
233
  "cId" => component_id,
@@ -236,6 +235,7 @@ module RSMP
236
235
  'mId' => m_id
237
236
  })
238
237
  set_nts_message_attributes message
238
+
239
239
  send_and_optionally_collect message, options do |collect_options|
240
240
  StatusCollector.new(
241
241
  self,
@@ -270,13 +270,18 @@ module RSMP
270
270
  send_message response
271
271
  end
272
272
 
273
+ def rsmpify_value v
274
+ return v if v.is_a? Array
275
+ v.to_s
276
+ end
277
+
273
278
  def process_status_request message, options={}
274
279
  component_id = message.attributes["cId"]
275
280
  component = @site.find_component component_id
276
281
  log "Received #{message.type}", message: message, level: :log
277
282
  sS = message.attributes["sS"].map do |arg|
278
283
  value, quality = component.get_status arg['sCI'], arg['n'], {sxl_version: sxl_version}
279
- { "s" => value.to_s, "q" => quality.to_s }.merge arg
284
+ { "s" => rsmpify_value(value), "q" => quality.to_s }.merge arg
280
285
  end
281
286
  response = StatusResponse.new({
282
287
  "cId"=>component_id,
@@ -375,7 +380,7 @@ module RSMP
375
380
  # send as soon as the data changes
376
381
  if component_object
377
382
  current, age = *(component_object.get_status code, name)
378
- current = current.to_s
383
+ current = rsmpify_value(current)
379
384
  end
380
385
  last_sent = fetch_last_sent_status component, code, name
381
386
  if current != last_sent
@@ -413,7 +418,7 @@ module RSMP
413
418
  end
414
419
  sS << { "sCI" => code,
415
420
  "n" => status_name,
416
- "s" => value.to_s,
421
+ "s" => rsmpify_value(value),
417
422
  "q" => quality }
418
423
  end
419
424
  end
@@ -0,0 +1,28 @@
1
+ class RSMP::TLC::SignalPriority
2
+ attr_reader :state, :node, :id, :level, :eta, :vehicleType, :age, :updated
3
+
4
+ def initialize node:, id:, level:, eta:, vehicleType:
5
+ @node = node
6
+ @id = id
7
+ @level = level
8
+ @eta = eta
9
+ @vehicleType = vehicleType
10
+ set_state 'received'
11
+ end
12
+
13
+ def set_state state
14
+ @state = state
15
+ @updated = node.clock.now
16
+ node.signal_priority_changed self, @state
17
+ end
18
+
19
+ def timer
20
+ @age = @node.clock.now - @updated
21
+ case @state
22
+ when 'received'
23
+ set_state 'activated' if @age >= 0.5
24
+ when 'activated'
25
+ set_state 'completed' if @age >= 0.5
26
+ end
27
+ end
28
+ end
@@ -60,6 +60,7 @@ module RSMP
60
60
  @startup_sequence_pos = 0
61
61
  @time_int = nil
62
62
  @inputs.reset
63
+ @signal_priorities = []
63
64
  end
64
65
 
65
66
  def dark?
@@ -105,8 +106,30 @@ module RSMP
105
106
  move_startup_sequence if @startup_sequence_active
106
107
 
107
108
  @signal_groups.each { |group| group.timer }
109
+ @signal_priorities.each {|priority| priority.timer }
108
110
 
109
111
  output_states
112
+ prune_priorities
113
+ end
114
+
115
+ def signal_priority_changed priority, state
116
+ #puts "priority #{priority.id} -> #{state}"
117
+ end
118
+
119
+ def prune_priorities
120
+ # TODO spec states that update must be send one time when it reaches the state 'completed',
121
+ # and then be removed. so we need to know when it has been sent
122
+ @signal_priorities.delete_if {|priority| priority.state=='completed' && priority.age >= 1.5 }
123
+ end
124
+
125
+ def get_priority_list
126
+ @signal_priorities.map do |priority|
127
+ {
128
+ "r" => priority.id,
129
+ "t" => RSMP::Clock.to_s(priority.updated),
130
+ "s" => priority.state
131
+ }
132
+ end
110
133
  end
111
134
 
112
135
  def move_cycle_counter
@@ -398,6 +421,43 @@ module RSMP
398
421
  @node.verify_security_code 2, arg['securityCode']
399
422
  end
400
423
 
424
+ def handle_m0022 arg, options={}
425
+ id = arg['requestId']
426
+ type = arg['type']
427
+ priority = @signal_priorities.find { |priority| priority.id == id }
428
+ case type
429
+ when 'new'
430
+ if priority
431
+ raise MessageRejected.new("Priority Request #{id} already exists")
432
+ else
433
+ #ref = arg.slice('signalGroupId','inputId','connectionId','approachId','laneInId','laneOutId')
434
+ if arg['signalGroupId']
435
+ signal_group = node.find_component arg['signalGroupId']
436
+ end
437
+
438
+ level = arg['level']
439
+ eta = arg['eta']
440
+ vehicleType = arg['vehicleType']
441
+ @signal_priorities << SignalPriority.new(node:self, id:id, level:level, eta:eta, vehicleType:vehicleType)
442
+ log "Priority request for signal group #{signal_group.c_id} received with id #{id}", level: :info
443
+ end
444
+ when 'update'
445
+ if priority
446
+ log "Priority Request #{id} updated", level: :info
447
+ else
448
+ raise MessageRejected.new("Cannot update priority request #{id}, not found")
449
+ end
450
+ when 'cancel'
451
+ if priority
452
+ @signal_priorities.delete priority
453
+ else
454
+ raise MessageRejected.new("Cannot cancel priority request #{id}, not found")
455
+ end
456
+ else
457
+ raise MessageRejected.new("Unknown type #{type}")
458
+ end
459
+ end
460
+
401
461
  def handle_m0103 arg, options={}
402
462
  level = {'Level1'=>1,'Level2'=>2}[arg['status']]
403
463
  @node.change_security_code level, arg['oldSecurityCode'], arg['newSecurityCode']
@@ -465,7 +525,7 @@ module RSMP
465
525
  'S0008', 'S0009', 'S0010', 'S0011', 'S0012', 'S0013', 'S0014',
466
526
  'S0015', 'S0016', 'S0017', 'S0018', 'S0019', 'S0020', 'S0021',
467
527
  'S0022', 'S0023', 'S0024', 'S0026', 'S0027', 'S0028',
468
- 'S0029', 'S0030', 'S0031',
528
+ 'S0029', 'S0030', 'S0031', 'S0032', 'S0033',
469
529
  'S0091', 'S0092', 'S0095', 'S0096', 'S0097',
470
530
  'S0205', 'S0206', 'S0207', 'S0208'
471
531
  return send("handle_#{code.downcase}", code, name, options)
@@ -717,6 +777,24 @@ module RSMP
717
777
  end
718
778
  end
719
779
 
780
+ def handle_s0032 status_code, status_name=nil, options={}
781
+ case status_name
782
+ when 'intersection'
783
+ TrafficControllerSite.make_status @intersection
784
+ when 'status'
785
+ TrafficControllerSite.make_status 'local'
786
+ when 'source'
787
+ TrafficControllerSite.make_status 'startup'
788
+ end
789
+ end
790
+
791
+ def handle_s0033 status_code, status_name=nil, options={}
792
+ case status_name
793
+ when 'status'
794
+ TrafficControllerSite.make_status get_priority_list
795
+ end
796
+ end
797
+
720
798
  def handle_s0091 status_code, status_name=nil, options={}
721
799
  if Proxy.version_requirement_met? '>=1.1',options[:sxl_version]
722
800
  case status_name
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.15.0"
2
+ VERSION = "0.15.1"
3
3
  end
data/lib/rsmp.rb CHANGED
@@ -30,6 +30,7 @@ require 'rsmp/collect/status_collector'
30
30
  require 'rsmp/collect/command_response_collector'
31
31
  require 'rsmp/collect/aggregated_status_collector'
32
32
  require 'rsmp/collect/alarm_collector'
33
+ require 'rsmp/collect/ack_collector'
33
34
  require 'rsmp/alarm_state'
34
35
  require 'rsmp/component_base'
35
36
  require 'rsmp/component'
@@ -48,6 +49,7 @@ require 'rsmp/tlc/detector_logic'
48
49
  require 'rsmp/tlc/signal_group'
49
50
  require 'rsmp/tlc/signal_plan'
50
51
  require 'rsmp/tlc/inputs'
52
+ require 'rsmp/tlc/signal_priority'
51
53
 
52
54
  require 'rsmp/convert/import/yaml'
53
55
  require 'rsmp/convert/export/json_schema'
data/rsmp.gemspec CHANGED
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency "async-io", "~> 1.33.0"
35
35
  spec.add_dependency "colorize", "~> 0.8.1"
36
36
  spec.add_dependency "thor", "~> 1.2.1"
37
- spec.add_dependency "rsmp_schema", "~> 0.2.3"
37
+ spec.add_dependency "rsmp_schema", "~> 0.2.5"
38
38
 
39
39
  spec.add_development_dependency "bundler", "~> 2.3.7"
40
40
  spec.add_development_dependency "rake", "~> 13.0.6"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Tin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-25 00:00:00.000000000 Z
11
+ date: 2022-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.2.3
75
+ version: 0.2.5
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.2.3
82
+ version: 0.2.5
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -211,6 +211,7 @@ files:
211
211
  - lib/rsmp/alarm_state.rb
212
212
  - lib/rsmp/archive.rb
213
213
  - lib/rsmp/cli.rb
214
+ - lib/rsmp/collect/ack_collector.rb
214
215
  - lib/rsmp/collect/aggregated_status_collector.rb
215
216
  - lib/rsmp/collect/alarm_collector.rb
216
217
  - lib/rsmp/collect/alarm_query.rb
@@ -249,6 +250,7 @@ files:
249
250
  - lib/rsmp/tlc/inputs.rb
250
251
  - lib/rsmp/tlc/signal_group.rb
251
252
  - lib/rsmp/tlc/signal_plan.rb
253
+ - lib/rsmp/tlc/signal_priority.rb
252
254
  - lib/rsmp/tlc/traffic_controller.rb
253
255
  - lib/rsmp/tlc/traffic_controller_site.rb
254
256
  - lib/rsmp/version.rb