rsmp 0.5.6 → 0.6.3

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.
@@ -0,0 +1,136 @@
1
+ module RSMP
2
+ module TLC
3
+ # Simulates a Traffic Light Controller Site
4
+ class TrafficControllerSite < Site
5
+ attr_accessor :main, :signal_plans
6
+
7
+ def initialize options={}
8
+ @sxl = 'traffic_light_controller'
9
+ @security_codes = options[:site_settings]['security_codes']
10
+ @interval = options[:site_settings].dig('intervals','timer') || 1
11
+ build_plans options[:site_settings].dig('signal_plans')
12
+ super options
13
+ unless @main
14
+ raise ConfigurationError.new "TLC must have a main component"
15
+ end
16
+ end
17
+
18
+ def build_plans signal_plans
19
+ @signal_plans = {}
20
+ return unless signal_plans
21
+ signal_plans.each_pair do |id,settings|
22
+ @signal_plans[id.to_i] = SignalPlan.new(nr: id.to_i, states:settings['states'],dynamic_bands:settings['dynamic_bands'])
23
+ end
24
+ end
25
+
26
+ def get_plan group_id, plan_nr
27
+ 'NN1BB1'
28
+ end
29
+
30
+ def build_component id:, type:, settings:{}
31
+ component = case type
32
+ when 'main'
33
+ @main = TrafficController.new node: self, id: id,
34
+ cycle_time: settings['cycle_time'],
35
+ signal_plans: @signal_plans
36
+ when 'signal_group'
37
+ group = SignalGroup.new node: self, id: id
38
+ @main.add_signal_group group
39
+ group
40
+ when 'detector_logic'
41
+ logic = DetectorLogic.new node: self, id: id
42
+ @main.add_detector_logic logic
43
+ logic
44
+ end
45
+ end
46
+
47
+ def start_action
48
+ super
49
+ start_timer
50
+ end
51
+
52
+ def start_timer
53
+ task_name = "tlc timer"
54
+ log "Starting #{task_name} with interval #{@interval} seconds", level: :debug
55
+
56
+ @timer = @task.async do |task|
57
+ task.annotate task_name
58
+ next_time = Time.now.to_f
59
+ loop do
60
+ begin
61
+ timer(@clock.now)
62
+ rescue EOFError => e
63
+ log "Connection closed: #{e}", level: :warning
64
+ rescue IOError => e
65
+ log "IOError", level: :warning
66
+ rescue Errno::ECONNRESET
67
+ log "Connection reset by peer", level: :warning
68
+ rescue Errno::EPIPE => e
69
+ log "Broken pipe", level: :warning
70
+ rescue StandardError => e
71
+ notify_error e, level: :internal
72
+ ensure
73
+ # adjust sleep duration to avoid drift. so wake up always happens on the
74
+ # same fractional second.
75
+ # note that Time.now is not monotonic. If the clock is changed,
76
+ # either manaully or via NTP, the sleep interval might jump.
77
+ # an alternative is to use ::Process.clock_gettime(::Process::CLOCK_MONOTONIC),
78
+ # to get the current time. this ensures a constant interval, but
79
+ # if the clock is changed, the wake up would then happen on a different
80
+ # fractional second
81
+ next_time += @interval
82
+ duration = next_time - Time.now.to_f
83
+ task.sleep duration
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ def timer now
90
+ return unless @main
91
+ @main.timer now
92
+ end
93
+
94
+ def verify_security_code level, code
95
+ raise ArgumentError.new("Level must be 1-2, got #{level}") unless (1..2).include?(level)
96
+ if @security_codes[level] != code
97
+ raise MessageRejected.new("Wrong security code for level #{level}")
98
+ end
99
+ end
100
+
101
+ def change_security_code level, old_code, new_code
102
+ verify_security_code level, old_code
103
+ @security_codes[level] = new_code
104
+ end
105
+
106
+ def self.to_rmsp_bool bool
107
+ if bool
108
+ 'True'
109
+ else
110
+ 'False'
111
+ end
112
+ end
113
+
114
+ def self.from_rsmp_bool str
115
+ str == 'True'
116
+ end
117
+
118
+ def self.make_status value, q='recent'
119
+ case value
120
+ when true, false
121
+ return to_rmsp_bool(value), q
122
+ else
123
+ return value, q
124
+ end
125
+ end
126
+
127
+ def do_deferred item
128
+ case item
129
+ when :restart
130
+ log "Restarting TLC", level: :info
131
+ restart
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.5.6"
2
+ VERSION = "0.6.3"
3
3
  end
data/lib/rsmp.rb CHANGED
@@ -33,7 +33,11 @@ require 'rsmp/error'
33
33
  require 'rsmp/message'
34
34
  require 'rsmp/logger'
35
35
  require 'rsmp/archive'
36
- require 'rsmp/tlc'
36
+ require 'rsmp/tlc/traffic_controller_site'
37
+ require 'rsmp/tlc/traffic_controller'
38
+ require 'rsmp/tlc/detector_logic'
39
+ require 'rsmp/tlc/signal_group'
40
+ require 'rsmp/tlc/signal_plan'
37
41
 
38
42
  require 'rsmp/convert/import/yaml'
39
43
  require 'rsmp/convert/export/json_schema'
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.5.6
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Tin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-09 00:00:00.000000000 Z
11
+ date: 2021-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -230,7 +230,11 @@ files:
230
230
  - lib/rsmp/site_proxy_wait.rb
231
231
  - lib/rsmp/supervisor.rb
232
232
  - lib/rsmp/supervisor_proxy.rb
233
- - lib/rsmp/tlc.rb
233
+ - lib/rsmp/tlc/detector_logic.rb
234
+ - lib/rsmp/tlc/signal_group.rb
235
+ - lib/rsmp/tlc/signal_plan.rb
236
+ - lib/rsmp/tlc/traffic_controller.rb
237
+ - lib/rsmp/tlc/traffic_controller_site.rb
234
238
  - lib/rsmp/version.rb
235
239
  - lib/rsmp/wait.rb
236
240
  - rsmp.gemspec
@@ -258,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
262
  - !ruby/object:Gem::Version
259
263
  version: '0'
260
264
  requirements: []
261
- rubygems_version: 3.2.26
265
+ rubygems_version: 3.2.15
262
266
  signing_key:
263
267
  specification_version: 4
264
268
  summary: RoadSide Message Protocol (RSMP) library.