rsmp 0.6.2 → 0.6.3

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: c4431d2545043cf60f1988e1bbb269e5727719fb6dd152c58908c5cd62b153ef
4
- data.tar.gz: 4cb2c6fe95608ae4093876d2630e5a29547fdea1d6f66cdb697855e7a301470a
3
+ metadata.gz: 4072d3e93ef2223bfc9ac2cb1a1e34b3668456e52a622a2b6f059087dd442c2e
4
+ data.tar.gz: 37603275646789fec0db5ec4c85baf731bebe6786693e6ad57eae7be3b3c29ed
5
5
  SHA512:
6
- metadata.gz: 0dcf33801ca97d92861380ed7ee4a4cb59a343eb0744daf448afbe20fa91e2147a8a59359420cd76dd62b1cbe49026b36e284d6534d8cd71538f68ea378e06c3
7
- data.tar.gz: 59e10a8475fa23b0e0d66c257ee5458acb156db1390e88ae464a73b40b63bea3be7372304bd5d331fb0dfaaf19308c731d3aaae158de5d7f16ebe67bb17ddda3
6
+ metadata.gz: 84a5e06ed20c8cb3331cf13ebd9bfc8d2baaf6c81ec14d67e83900d198153d86b89aeb09485f87afa9ef5c2aa7ca4469caa190a745dc9936caedc31bbb14d5a5
7
+ data.tar.gz: 9aa602447f391353632bf59fccd2ca48ab2eea492913cab875614c50279c362f04ebbf89559d1ea6a72878ef22e632a29160379b682356e8411568710a9d8525
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.6.2)
4
+ rsmp (0.6.3)
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)
@@ -8,15 +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
- component: true
15
- ip: false
16
11
  port: true
17
12
  site_id: 9
18
- component_id: 3
19
- text: true
13
+ component: 2
20
14
  direction: false
21
15
  level: false
22
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,17 +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
- component_id: true
37
45
  ip: false
38
46
  site_id: 9
39
- component: 3
47
+ component: 2
40
48
  level: false
41
49
  debug: true
42
- text: true
43
- direction: false
44
50
  json: true
45
51
  acknowledgements: false
46
52
  watchdogs: false
data/lib/rsmp/archive.rb CHANGED
@@ -21,7 +21,7 @@ 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,: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
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.
@@ -52,7 +52,8 @@ module RSMP
52
52
  component = inferred.new node: self, id: component_id
53
53
  @components[ component_id] = component
54
54
  class_name = component.class.name.split('::').last
55
- 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
56
57
  component
57
58
  else
58
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,10 @@ module RSMP
23
24
  'ip'=>false,
24
25
  'port'=>false,
25
26
  'site_id'=>true,
26
- 'component'=>true,
27
27
  'direction'=>false,
28
28
  'level'=>false,
29
29
  'id'=>true,
30
- 'str'=>true,
30
+ 'text'=>true,
31
31
  }
32
32
 
33
33
  default_lengths = {
@@ -38,7 +38,7 @@ module RSMP
38
38
  'port'=>5,
39
39
  'site_id'=>19,
40
40
  'component'=>19,
41
- 'direction'=>4,
41
+ 'direction'=>3,
42
42
  'level'=>7,
43
43
  'id'=>4,
44
44
  }
@@ -190,14 +190,14 @@ module RSMP
190
190
  build_part( parts, item, :port )
191
191
  build_part( parts, item, :site_id )
192
192
  build_part( parts, item, :component )
193
- build_part( parts, item, :direction ) { |part| {in:"-->",out:"<--"}[part] }
193
+ build_part( parts, item, :direction ) { |part| {in:"In",out:"Out"}[part] }
194
194
  build_part( parts, item, :level ) { |part| part.capitalize }
195
195
  build_part( parts, item, :id ) { Logger.shorten_message_id(item[:message].m_id,4) if item[:message] }
196
- build_part( parts, item, :str )
196
+ build_part( parts, item, :text )
197
197
  build_part( parts, item, :json ) { item[:message].json if item[:message] }
198
198
  build_part( parts, item, :exception ) { |e| [e.class,e.backtrace].flatten.join("\n") }
199
199
 
200
- parts.join(' ').chomp(@settings['tabs']).rstrip
200
+ parts.join(' ').chomp(@settings['tabs'].to_s).rstrip
201
201
  end
202
202
  end
203
203
  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
@@ -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