rsmp 0.6.0 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4e37b5be3866a109446020e5c6eafcd6f42d459e4c4a49e740804dd8523a9f3
4
- data.tar.gz: 60487c581cbf0e89d00e66398a80ba7c9fdf080d4f69d7fd9e1db5166f0190fd
3
+ metadata.gz: 33b8c859b9c8450af6a45d52a9d42d982c5becdaf1d4424f398b417bc1c387d8
4
+ data.tar.gz: 7f194bb392a69555f7ba30364466dfed9eeb1b04996505fa13af13d9045bb071
5
5
  SHA512:
6
- metadata.gz: 51d7732d473f79779250ea80bbb62cf0bf47cce700a69954bf162241c8ee271a27308600f6dc10c1016c644b109f27e3a9a0f5c91728cc69f096f550c3c896c9
7
- data.tar.gz: fe7d9db2ced99c524673114d8f0f128821e127400474ac28e91054a83a1777e5340ab79bb48339c799ac78039482e5e06d19ea9f31ea6ff49d0dc5605556caed
6
+ metadata.gz: 2d9da45e5f1a96756cd50f58ea3ce16dc0de51138daa45aa114f432e0531595883c5cf3dba86ad63dd0a33aed7ba02d706f058378c257129a8b877eb45e2246b
7
+ data.tar.gz: 59965992a0e7bcdd6e401fac5baa2e8839c392713812da579865020d6cf5d9cf73d51b250f9be72cab3264fd5a9edd287e85619e2ebab0259fb303da9cfe25ff
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.6.0)
4
+ rsmp (0.6.4)
5
5
  async (~> 1.29.1)
6
6
  async-io (~> 1.32.1)
7
7
  colorize (~> 0.8.1)
@@ -96,7 +96,7 @@ GEM
96
96
  thread_safe
97
97
  rake (13.0.3)
98
98
  regexp_parser (2.1.1)
99
- rsmp_schemer (0.3.1)
99
+ rsmp_schemer (0.3.2)
100
100
  json_schemer (~> 0.2.18)
101
101
  rspec (3.10.0)
102
102
  rspec-core (~> 3.10.0)
data/README.md CHANGED
@@ -125,7 +125,7 @@ This will output messages form both the site and the supervisor, ordered chronol
125
125
  ```console
126
126
  RN+SU0001 Starting supervisor RN+SU0001 on port 12111
127
127
  RN+SI0001 Starting site RN+SI0001
128
- RN+SI0001 Connecting to superviser at 127.0.0.1:12111
128
+ RN+SI0001 Connecting to supervisor at 127.0.0.1:12111
129
129
  RN+SI0001 <-- f8c7 Sent Version
130
130
  RN+SU0001 Site connected from 127.0.0.1:53500
131
131
  RN+SU0001 RN+SI0001 --> f8c7 Received Version message for sites [RN+SI0001] using RSMP 3.1.4
@@ -156,7 +156,7 @@ The ```site``` command will start an RSMP site, which will try to connect to one
156
156
  ```console
157
157
  % rsmp site
158
158
  2019-11-11 12:22:00 UTC Starting site RN+SI0001
159
- 2019-11-11 12:22:00 UTC Connecting to superviser at 127.0.0.1:12111
159
+ 2019-11-11 12:22:00 UTC Connecting to supervisor at 127.0.0.1:12111
160
160
  2019-11-11 12:22:00 UTC <-- 792f Sent Version
161
161
  2019-11-11 12:22:00 UTC RN+SU0001 --> e70e Received Version message, using RSMP 3.1.4
162
162
  2019-11-11 12:22:00 UTC RN+SU0001 Connection to supervisor established
@@ -8,16 +8,9 @@ guest:
8
8
  watchdog: 0.2
9
9
  acknowledgement: 0.2
10
10
  log:
11
- active: true
12
- color: true
13
- timestamp: true
14
- id: true
15
- component: true
16
- ip: false
17
11
  port: true
18
12
  site_id: 9
19
- component_id: 3
20
- text: true
13
+ component: 2
21
14
  direction: false
22
15
  level: false
23
16
  debug: true
data/config/tlc.yaml CHANGED
@@ -10,15 +10,27 @@ components:
10
10
  cycle_time: 6
11
11
  signal_group:
12
12
  A1:
13
- plan: '11NBBB'
14
13
  A2:
15
- plan: '1NBBBB'
16
14
  B1:
17
- plan: 'BBB11N'
18
15
  B2:
19
- plan: 'BBB1NB'
20
16
  detector_logic:
21
17
  DL1:
18
+ signal_plans:
19
+ 1:
20
+ dynamic_bands:
21
+ 1: 0
22
+ 2: 5
23
+ states:
24
+ A1: '11NBBB'
25
+ A2: '1NBBBB'
26
+ B1: 'BBB11N'
27
+ B2: 'BBB1NB'
28
+ 2:
29
+ states:
30
+ A1: '111NBB'
31
+ A2: '11NBBB'
32
+ B1: 'BBB11N'
33
+ B2: 'BBB1NB'
22
34
  intervals:
23
35
  timer: 0.1
24
36
  watchdog: 0.1
@@ -30,18 +42,11 @@ security_codes:
30
42
  1: '1111'
31
43
  2: '2222'
32
44
  log:
33
- active: true
34
- color: true
35
- timestamp: true
36
- id: true
37
- component_id: true
38
45
  ip: false
39
46
  site_id: 9
40
- component_id: 3
47
+ component: 2
41
48
  level: false
42
49
  debug: true
43
- text: true
44
- direction: false
45
50
  json: true
46
51
  acknowledgements: false
47
52
  watchdogs: false
data/lib/rsmp/archive.rb CHANGED
@@ -21,11 +21,11 @@ module RSMP
21
21
  def self.prepare_item item
22
22
  raise ArgumentError unless item.is_a? Hash
23
23
 
24
- cleaned = item.select { |k,v| [:author,:level,:ip,:port,:site_id,:component_id,:str,:message,:exception].include? k }
24
+ cleaned = item.select { |k,v| [:author,:level,:ip,:port,:site_id,:component,:text,:message,:exception].include? k }
25
25
  cleaned[:timestamp] = Clock.now
26
26
  if item[:message]
27
27
  cleaned[:direction] = item[:message].direction
28
- cleaned[:component_id] = item[:message].attributes['cId']
28
+ cleaned[:component] = item[:message].attributes['cId']
29
29
  end
30
30
 
31
31
  cleaned
data/lib/rsmp/cli.rb CHANGED
@@ -51,7 +51,7 @@ module RSMP
51
51
  if options[:type]
52
52
  case options[:type]
53
53
  when 'tlc'
54
- site_class = RSMP::Tlc
54
+ site_class = RSMP::TLC::TrafficControllerSite
55
55
  else
56
56
  site_class = RSMP::Site
57
57
  end
@@ -65,7 +65,8 @@ module RSMP
65
65
  end
66
66
 
67
67
  def log str, options
68
- @node.log str, options
68
+ default = { component: c_id}
69
+ @node.log str, default.merge(options)
69
70
  end
70
71
 
71
72
  def handle_command command_code, arg
@@ -118,7 +119,6 @@ module RSMP
118
119
  @statuses[sCI][n] ||= {}
119
120
  @statuses[sCI][n][:initial] = true
120
121
  end
121
- #pp @subscribes
122
122
  end
123
123
 
124
124
  # Our proxy unsubscribed to status updates.
@@ -15,8 +15,10 @@ module RSMP
15
15
  return unless settings
16
16
  check_main_component settings
17
17
  settings.each_pair do |type,components_by_type|
18
- components_by_type.each_pair do |id,settings|
19
- @components[id] = build_component(id:id, type:type, settings:settings)
18
+ if components_by_type
19
+ components_by_type.each_pair do |id,settings|
20
+ @components[id] = build_component(id:id, type:type, settings:settings)
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -50,7 +52,8 @@ module RSMP
50
52
  component = inferred.new node: self, id: component_id
51
53
  @components[ component_id] = component
52
54
  class_name = component.class.name.split('::').last
53
- log "Inferred #{class_name} component #{component_id}", level: :info
55
+ class_name << " compoent" unless class_name == 'Component'
56
+ log "Inferred #{class_name} #{component_id}", level: :debug
54
57
  component
55
58
  else
56
59
  raise UnknownComponent.new("Component #{component_id} not found") unless component
data/lib/rsmp/logger.rb CHANGED
@@ -5,7 +5,7 @@ module RSMP
5
5
 
6
6
  def initialize settings={}
7
7
  defaults = {
8
- 'active'=>false,
8
+ 'active'=>true,
9
9
  'path'=>nil,
10
10
  'stream'=>nil,
11
11
  'color'=>true,
@@ -13,6 +13,7 @@ module RSMP
13
13
  'statistics'=>false,
14
14
  'hide_ip_and_port' => false,
15
15
  'acknowledgements' => false,
16
+ 'watchdogs' => false,
16
17
  'json'=>false,
17
18
  'tabs'=>'-',
18
19
 
@@ -23,11 +24,11 @@ module RSMP
23
24
  'ip'=>false,
24
25
  'port'=>false,
25
26
  'site_id'=>true,
26
- 'component_id'=>true,
27
+ 'component'=>true,
27
28
  'direction'=>false,
28
29
  'level'=>false,
29
- 'id'=>false,
30
- 'str'=>true,
30
+ 'id'=>true,
31
+ 'text'=>true,
31
32
  }
32
33
 
33
34
  default_lengths = {
@@ -37,8 +38,8 @@ module RSMP
37
38
  'ip'=>22,
38
39
  'port'=>5,
39
40
  'site_id'=>19,
40
- 'component_id'=>19,
41
- 'direction'=>4,
41
+ 'component'=>19,
42
+ 'direction'=>3,
42
43
  'level'=>7,
43
44
  'id'=>4,
44
45
  }
@@ -189,15 +190,15 @@ module RSMP
189
190
  build_part( parts, item, :ip )
190
191
  build_part( parts, item, :port )
191
192
  build_part( parts, item, :site_id )
192
- build_part( parts, item, :component_id )
193
- build_part( parts, item, :direction ) { |part| {in:"-->",out:"<--"}[part] }
193
+ build_part( parts, item, :component )
194
+ build_part( parts, item, :direction ) { |part| {in:"In",out:"Out"}[part] }
194
195
  build_part( parts, item, :level ) { |part| part.capitalize }
195
196
  build_part( parts, item, :id ) { Logger.shorten_message_id(item[:message].m_id,4) if item[:message] }
196
- build_part( parts, item, :str )
197
+ build_part( parts, item, :text )
197
198
  build_part( parts, item, :json ) { item[:message].json if item[:message] }
198
199
  build_part( parts, item, :exception ) { |e| [e.class,e.backtrace].flatten.join("\n") }
199
200
 
200
- parts.join(' ').chomp(@settings['tabs']).rstrip
201
+ parts.join(' ').chomp(@settings['tabs'].to_s).rstrip
201
202
  end
202
203
  end
203
204
  end
data/lib/rsmp/logging.rb CHANGED
@@ -15,7 +15,7 @@ module RSMP
15
15
  end
16
16
 
17
17
  def log str, options={}
18
- default = { str:str, level: :log, author: author, ip: @ip, port: @port }
18
+ default = { text:str, level: :log, author: author, ip: @ip, port: @port }
19
19
  prepared = RSMP::Archive.prepare_item default.merge(options)
20
20
  @archive.add prepared
21
21
  @logger.log prepared
data/lib/rsmp/proxy.rb CHANGED
@@ -348,20 +348,23 @@ module RSMP
348
348
  # cannot send NotAcknowledged for a malformed message since we can't read it, just ignore it
349
349
  nil
350
350
  rescue SchemaError, RSMP::Schemer::Error => e
351
- str = "Received invalid #{message.type}, schema errors: #{e.message}"
351
+ reason = "schema errors: #{e.message}"
352
+ str = "Received invalid #{message.type}, #{reason}"
352
353
  log str, message: message, level: :warning
353
354
  notify_error e.exception(str), message: message
354
- dont_acknowledge message, str
355
+ dont_acknowledge message, str, reason
355
356
  message
356
357
  rescue InvalidMessage => e
357
- str = "Received", "invalid #{message.type}, #{e.message}"
358
+ reason = "#{e.message}"
359
+ str = "Received invalid #{message.type},"
358
360
  notify_error e.exception("#{str} #{message.json}"), message: message
359
- dont_acknowledge message, str
361
+ dont_acknowledge message, str, reason
360
362
  message
361
363
  rescue FatalError => e
364
+ reason = e.message
362
365
  str = "Rejected #{message.type},"
363
366
  notify_error e.exception(str), message: message
364
- dont_acknowledge message, str, "#{e.message}"
367
+ dont_acknowledge message, str, reason
365
368
  stop
366
369
  message
367
370
  ensure
@@ -7,6 +7,7 @@ module RSMP
7
7
  attr_reader :rsmp_versions, :site_id, :supervisor_settings, :proxies, :logger
8
8
 
9
9
  def initialize options={}
10
+
10
11
  handle_supervisor_settings( options[:supervisor_settings] || {} )
11
12
  super options
12
13
  @proxies = []
@@ -23,15 +23,22 @@ module RSMP
23
23
  end
24
24
 
25
25
  def start
26
- log "Connecting to superviser at #{@ip}:#{@port}", level: :info
26
+ log "Connecting to supervisor at #{@ip}:#{@port}", level: :info
27
27
  super
28
28
  connect
29
29
  @logger.unmute @ip, @port
30
- log "Connected to superviser at #{@ip}:#{@port}", level: :info
30
+ log "Connected to supervisor at #{@ip}:#{@port}", level: :info
31
31
  start_reader
32
32
  send_version @site_settings['site_id'], @site_settings["rsmp_versions"]
33
- rescue Errno::ECONNREFUSED
34
- log "No connection to supervisor at #{@ip}:#{@port}", level: :error
33
+ rescue SystemCallError => e
34
+ log "Could not connect to supervisor at #{@ip}:#{@port}: Errno #{e.errno} #{e}", level: :error
35
+ retry_notice
36
+ rescue StandardError => e
37
+ log "Error while connecting to supervisor at #{@ip}:#{@port}: #{e}", level: :error
38
+ retry_notice
39
+ end
40
+
41
+ def retry_notice
35
42
  unless @site.site_settings['intervals']['reconnect'] == :no
36
43
  log "Will try to reconnect again every #{@site.site_settings['intervals']['reconnect']} seconds..", level: :info
37
44
  @logger.mute @ip, @port
@@ -0,0 +1,101 @@
1
+ module RSMP
2
+ module TLC
3
+ class DetectorLogic < Component
4
+ attr_reader :forced, :value
5
+
6
+ def initialize node:, id:
7
+ super node: node, id: id, grouped: false
8
+ @forced = 0
9
+ @value = 0
10
+ end
11
+
12
+ def get_status code, name=nil
13
+ case code
14
+ when 'S0201', 'S0202', 'S0203', 'S0204'
15
+ return send("handle_#{code.downcase}", code, name)
16
+ else
17
+ raise InvalidMessage.new "unknown status code #{code}"
18
+ end
19
+ end
20
+
21
+ def handle_s0201 status_code, status_name=nil
22
+ case status_name
23
+ when 'starttime'
24
+ TrafficControllerSite.make_status @node.clock.to_s
25
+ when 'vehicles'
26
+ TrafficControllerSite.make_status 0
27
+ end
28
+ end
29
+
30
+ def handle_s0202 status_code, status_name=nil
31
+ case status_name
32
+ when 'starttime'
33
+ TrafficControllerSite.make_status @node.clock.to_s
34
+ when 'speed'
35
+ TrafficControllerSite.make_status 0
36
+ end
37
+ end
38
+
39
+ def handle_s0203 status_code, status_name=nil
40
+ case status_name
41
+ when 'starttime'
42
+ TrafficControllerSite.make_status @node.clock.to_s
43
+ when 'occupancy'
44
+ TrafficControllerSite.make_status 0
45
+ end
46
+ end
47
+
48
+ def handle_s0204 status_code, status_name=nil
49
+ case status_name
50
+ when 'starttime'
51
+ TrafficControllerSite.make_status @node.clock.to_s
52
+ when 'P'
53
+ TrafficControllerSite.make_status 0
54
+ when 'PS'
55
+ TrafficControllerSite.make_status 0
56
+ when 'L'
57
+ TrafficControllerSite.make_status 0
58
+ when 'LS'
59
+ TrafficControllerSite.make_status 0
60
+ when 'B'
61
+ TrafficControllerSite.make_status 0
62
+ when 'SP'
63
+ TrafficControllerSite.make_status 0
64
+ when 'MC'
65
+ TrafficControllerSite.make_status 0
66
+ when 'C'
67
+ TrafficControllerSite.make_status 0
68
+ when 'F'
69
+ TrafficControllerSite.make_status 0
70
+ end
71
+ end
72
+
73
+ def handle_command command_code, arg
74
+ case command_code
75
+ when 'M0008'
76
+ handle_m0008 arg
77
+ else
78
+ raise UnknownCommand.new "Unknown command #{command_code}"
79
+ end
80
+ end
81
+
82
+ def handle_m0008 arg
83
+ @node.verify_security_code 2, arg['securityCode']
84
+ status = arg['status']=='True'
85
+ mode = arg['mode']=='True'
86
+ force_detector_logic status, mode
87
+ arg
88
+ end
89
+
90
+ def force_detector_logic forced, value
91
+ @forced = forced
92
+ @value = value
93
+ if @forced
94
+ log "Forcing to #{value}", level: :info
95
+ else
96
+ log "Releasing", level: :info
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,85 @@
1
+ module RSMP
2
+ module TLC
3
+ class SignalGroup < Component
4
+ attr_reader :plan, :state
5
+
6
+ # plan is a string, with each character representing a signal phase at a particular second in the cycle
7
+ def initialize node:, id:
8
+ super node: node, id: id, grouped: false
9
+ move 0
10
+ end
11
+
12
+ def get_state pos
13
+ default = 'a' # phase a means disabled/dark
14
+ plan = node.main.current_plan
15
+ return default unless plan
16
+ return default unless plan.states
17
+ states = plan.states[c_id]
18
+ return default unless states
19
+ state =states[pos]
20
+ return default unless state =~ /[a-hA-G0-9N-P]/ # valid signal group states
21
+ state
22
+ end
23
+
24
+ def move pos
25
+ @state = get_state pos
26
+ end
27
+
28
+ def handle_command command_code, arg
29
+ case command_code
30
+ when 'M0010', 'M0011'
31
+ return send("handle_#{command_code.downcase}", arg)
32
+ else
33
+ raise UnknownCommand.new "Unknown command #{command_code}"
34
+ end
35
+ end
36
+
37
+ # Start of signal group. Orders a signal group to green
38
+ def handle_m0010 arg
39
+ @node.verify_security_code 2, arg['securityCode']
40
+ if TrafficControllerSite.from_rsmp_bool arg['status']
41
+ log "Start signal group #{c_id}, go to green", level: :info
42
+ end
43
+ end
44
+
45
+ # Stop of signal group. Orders a signal group to red
46
+ def handle_m0011 arg
47
+ @node.verify_security_code 2, arg['securityCode']
48
+ if TrafficControllerSite.from_rsmp_bool arg['status']
49
+ log "Stop signal group #{c_id}, go to red", level: :info
50
+ end
51
+ end
52
+
53
+ def get_status code, name=nil
54
+ case code
55
+ when 'S0025'
56
+ return send("handle_#{code.downcase}", code, name)
57
+ else
58
+ raise InvalidMessage.new "unknown status code #{code}"
59
+ end
60
+ end
61
+
62
+ def handle_s0025 status_code, status_name=nil
63
+ now = @node.clock.to_s
64
+ case status_name
65
+ when 'minToGEstimate'
66
+ TrafficControllerSite.make_status now
67
+ when 'maxToGEstimate'
68
+ TrafficControllerSite.make_status now
69
+ when 'likelyToGEstimate'
70
+ TrafficControllerSite.make_status now
71
+ when 'ToGConfidence'
72
+ TrafficControllerSite.make_status 0
73
+ when 'minToREstimate'
74
+ TrafficControllerSite.make_status now
75
+ when 'maxToREstimate'
76
+ TrafficControllerSite.make_status now
77
+ when 'likelyToREstimate'
78
+ TrafficControllerSite.make_status now
79
+ when 'ToRConfidence'
80
+ TrafficControllerSite.make_status 0
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ module RSMP
2
+ module TLC
3
+ # A Traffic Light Controller Signal Plan.
4
+ # A signal plan is a description of how all signal groups should change
5
+ # state over time.
6
+ class SignalPlan
7
+ attr_reader :nr, :states, :dynamic_bands
8
+ def initialize nr:, states:, dynamic_bands:
9
+ @nr = nr
10
+ @states = states
11
+ @dynamic_bands = dynamic_bands || {}
12
+ end
13
+
14
+ def dynamic_bands_string
15
+ str = @dynamic_bands.map { |band,value| "#{nr}-#{band}-#{value}" }.join(',')
16
+ return nil if str == ''
17
+ str
18
+ end
19
+
20
+ def set_band band, value
21
+ @dynamic_bands[ band.to_i ] = value.to_i
22
+ end
23
+
24
+ def get_band band
25
+ @dynamic_bands[ band.to_i ]
26
+ end
27
+ end
28
+ end
29
+ end