rsmp 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.6.2"
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.6.2
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-12 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