rsmp 0.41.0 → 0.42.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.
@@ -3,13 +3,17 @@ module RSMP
3
3
  module Modules
4
4
  # Handles status requests, responses, subscriptions and updates
5
5
  module Status
6
- def request_status(component, status_list, options = {})
6
+ # Build and send a StatusRequest. Returns { sent: message }.
7
+ def request_status(status_list, component: nil, m_id: nil, validate: true)
7
8
  validate_ready 'request status'
8
- m_id = options[:m_id] || RSMP::Message.make_m_id
9
+ component ||= main.c_id
10
+ m_id ||= RSMP::Message.make_m_id
11
+
12
+ list = RSMP::StatusList.new(status_list)
9
13
 
10
14
  # additional items can be used when verifying the response,
11
15
  # but must be removed from the request
12
- request_list = status_list.map { |item| item.slice('sCI', 'n') }
16
+ request_list = list.map { |item| item.slice('sCI', 'n') }
13
17
 
14
18
  message = RSMP::StatusRequest.new({
15
19
  'cId' => component,
@@ -17,13 +21,31 @@ module RSMP
17
21
  'mId' => m_id
18
22
  })
19
23
  apply_nts_message_attributes message
20
- send_and_optionally_collect message, options do |collect_options|
21
- StatusCollector.new(
22
- self,
23
- status_list,
24
- collect_options.merge(task: @task, m_id: m_id)
25
- )
26
- end
24
+ send_message message, validate: validate
25
+ { sent: message }
26
+ end
27
+
28
+ # Build, send a StatusRequest and collect the StatusResponse. Returns the collector.
29
+ # Call .ok! on the result to raise on NotAck or timeout.
30
+ def request_status_and_collect(status_list, within:, component: nil, m_id: nil, validate: true)
31
+ validate_ready 'request status'
32
+ component ||= main.c_id
33
+ m_id ||= RSMP::Message.make_m_id
34
+
35
+ list = RSMP::StatusList.new(status_list)
36
+
37
+ # additional items can be used when verifying the response,
38
+ # but must be removed from the request
39
+ request_list = list.map { |item| item.slice('sCI', 'n') }
40
+
41
+ message = RSMP::StatusRequest.new({
42
+ 'cId' => component,
43
+ 'sS' => request_list,
44
+ 'mId' => m_id
45
+ })
46
+ apply_nts_message_attributes message
47
+ collector = StatusCollector.new(self, list.to_a, timeout: within, m_id: m_id)
48
+ send_message_and_collect(message, collector, validate: validate)[:collector]
27
49
  end
28
50
 
29
51
  def process_status_response(message)
@@ -49,28 +71,49 @@ module RSMP
49
71
  end
50
72
  end
51
73
 
52
- def subscribe_to_status(component_id, status_list, options = {})
74
+ # Build and send a StatusSubscribe. Returns { sent: message }.
75
+ def subscribe_to_status(status_list, component: nil, m_id: nil, validate: true)
53
76
  validate_ready 'subscribe to status'
54
- m_id = options[:m_id] || RSMP::Message.make_m_id
55
- subscribe_list = status_list.map { |item| item.slice('sCI', 'n', 'uRt', 'sOc') }
77
+ component ||= main.c_id
78
+ m_id ||= RSMP::Message.make_m_id
56
79
 
57
- update_subscription(component_id, subscribe_list)
58
- find_component component_id
80
+ list = RSMP::StatusList.new(status_list)
81
+ subscribe_list = list.map { |item| item.slice('sCI', 'n', 'uRt', 'sOc') }
82
+
83
+ update_subscription(component, subscribe_list)
84
+ find_component component
59
85
 
60
86
  message = RSMP::StatusSubscribe.new({
61
- 'cId' => component_id,
87
+ 'cId' => component,
62
88
  'sS' => subscribe_list,
63
89
  'mId' => m_id
64
90
  })
65
91
  apply_nts_message_attributes message
92
+ send_message message, validate: validate
93
+ { sent: message }
94
+ end
66
95
 
67
- send_and_optionally_collect message, options do |collect_options|
68
- StatusCollector.new(
69
- self,
70
- status_list,
71
- collect_options.merge(task: @task, m_id: m_id)
72
- )
73
- end
96
+ # Build, send a StatusSubscribe and collect the first matching status update. Returns the collector.
97
+ # Call .ok! on the result to raise on NotAck or timeout.
98
+ def subscribe_to_status_and_collect(status_list, within:, component: nil, m_id: nil, validate: true)
99
+ validate_ready 'subscribe to status'
100
+ component ||= main.c_id
101
+ m_id ||= RSMP::Message.make_m_id
102
+
103
+ list = RSMP::StatusList.new(status_list)
104
+ subscribe_list = list.map { |item| item.slice('sCI', 'n', 'uRt', 'sOc') }
105
+
106
+ update_subscription(component, subscribe_list)
107
+ find_component component
108
+
109
+ message = RSMP::StatusSubscribe.new({
110
+ 'cId' => component,
111
+ 'sS' => subscribe_list,
112
+ 'mId' => m_id
113
+ })
114
+ apply_nts_message_attributes message
115
+ collector = StatusCollector.new(self, list.to_a, timeout: within, m_id: m_id)
116
+ send_message_and_collect(message, collector, validate: validate)[:collector]
74
117
  end
75
118
 
76
119
  def remove_subscription_item(component_id, code, name)
@@ -81,29 +124,31 @@ module RSMP
81
124
  @status_subscriptions.delete(component_id) if @status_subscriptions[component_id].empty?
82
125
  end
83
126
 
84
- def unsubscribe_to_status(component_id, status_list, options = {})
127
+ def unsubscribe_to_status(status_list, component: nil, validate: nil)
85
128
  validate_ready 'unsubscribe to status'
129
+ component ||= main.c_id
86
130
 
87
131
  status_list.each do |item|
88
- remove_subscription_item(component_id, item['sCI'], item['n'])
132
+ remove_subscription_item(component, item['sCI'], item['n'])
89
133
  end
90
134
 
91
135
  message = RSMP::StatusUnsubscribe.new({
92
- 'cId' => component_id,
136
+ 'cId' => component,
93
137
  'sS' => status_list
94
138
  })
95
139
  apply_nts_message_attributes message
96
- send_message message, validate: options[:validate]
140
+ send_message message, validate: validate
97
141
  message
98
142
  end
99
143
 
100
144
  # unsubscribes to all statuses (with all attributes) defined in the used SXL
101
- def unsubscribe_from_all(component_id)
145
+ def unsubscribe_from_all(component: nil)
146
+ component ||= main.c_id
102
147
  catalogue = RSMP::Schema.status_catalogue(@sxl, sxl_version)
103
148
  status_list = catalogue.flat_map do |status_code_id, names|
104
149
  names.map { |name| { 'sCI' => status_code_id.to_s, 'n' => name.to_s } }
105
150
  end
106
- unsubscribe_to_status component_id, status_list
151
+ unsubscribe_to_status status_list, component: component
107
152
  end
108
153
 
109
154
  def process_status_update(message)
@@ -10,8 +10,8 @@ module RSMP
10
10
  end
11
11
 
12
12
  # Send aggregated status for a component
13
- def send_aggregated_status(component, options = {})
14
- m_id = options[:m_id] || RSMP::Message.make_m_id
13
+ def send_aggregated_status(component, m_id: nil)
14
+ m_id ||= RSMP::Message.make_m_id
15
15
 
16
16
  se = if Proxy.version_meets_requirement?(core_version, '<=3.1.2')
17
17
  component.aggregated_status_bools.map { |bool| bool ? 'true' : 'false' }
@@ -29,9 +29,7 @@ module RSMP
29
29
  })
30
30
 
31
31
  apply_nts_message_attributes message
32
- send_and_optionally_collect message, options do |collect_options|
33
- Collector.new self, collect_options.merge(task: @task, type: 'MessageAck')
34
- end
32
+ send_message message
35
33
  end
36
34
 
37
35
  def process_aggregated_status_request(message)
@@ -3,12 +3,6 @@ module RSMP
3
3
  module Modules
4
4
  # Alarm handling
5
5
  module Alarms
6
- def send_alarm(_component, alarm, options = {})
7
- send_and_optionally_collect alarm, options do |collect_options|
8
- Collector.new self, collect_options.merge(task: @task, type: 'MessageAck')
9
- end
10
- end
11
-
12
6
  def send_active_alarms
13
7
  @site.components.each_pair do |_c_id, component|
14
8
  component.alarms.each_pair do |_alarm_code, alarm_state|
@@ -0,0 +1,44 @@
1
+ module RSMP
2
+ # Represents an RSMP status list and converts between the two common formats:
3
+ #
4
+ # Compact Hash (symbol or string keys):
5
+ # { S0014: [:status, :source] }
6
+ # { 'S0014' => ['status', 'source'] }
7
+ #
8
+ # Raw wire Array (used in RSMP messages):
9
+ # [{ 'sCI' => 'S0014', 'n' => 'status' }, { 'sCI' => 'S0014', 'n' => 'source' }]
10
+ class StatusList
11
+ include Enumerable
12
+
13
+ def initialize(input)
14
+ @list = case input
15
+ when StatusList
16
+ input.to_a
17
+ when Array
18
+ input
19
+ when Hash
20
+ input.flat_map do |code, names|
21
+ names.map { |name| { 'sCI' => code.to_s, 'n' => name.to_s } }
22
+ end
23
+ else
24
+ raise ArgumentError, "StatusList requires an Array, Hash, or StatusList, got #{input.class}"
25
+ end
26
+ end
27
+
28
+ def each(&)
29
+ @list.each(&)
30
+ end
31
+
32
+ def to_a
33
+ @list
34
+ end
35
+
36
+ def to_h
37
+ @list.each_with_object({}) do |item, hash|
38
+ code = item['sCI']
39
+ name = item['n']
40
+ (hash[code] ||= []) << name
41
+ end
42
+ end
43
+ end
44
+ end
@@ -196,8 +196,8 @@ module RSMP
196
196
 
197
197
  # S0006 - Emergency route status (deprecated, use S0035)
198
198
  def handle_s0006(_status_code, status_name = nil, options = {})
199
- if Proxy.version_meets_requirement? options[:sxl_version],
200
- '>=1.2.0'
199
+ if RSMP::Proxy.version_meets_requirement? options[:sxl_version],
200
+ '>=1.2.0'
201
201
  log 'S0006 is depreciated, use S0035 instead.',
202
202
  level: :warning
203
203
  end
@@ -63,22 +63,36 @@ module RSMP
63
63
  end
64
64
 
65
65
  # S0091 - Operator logged in/out OP-panel
66
- def handle_s0091(_status_code, status_name = nil, _options = {})
67
- case status_name
68
- when 'user'
69
- TrafficControllerSite.make_status 0
70
- when 'username'
71
- TrafficControllerSite.make_status ''
66
+ def handle_s0091(_status_code, status_name = nil, options = {})
67
+ if RSMP::Proxy.version_meets_requirement?(options[:sxl_version], '>=1.1')
68
+ case status_name
69
+ when 'user'
70
+ TrafficControllerSite.make_status 0
71
+ end
72
+ else
73
+ case status_name
74
+ when 'user'
75
+ TrafficControllerSite.make_status 'nobody'
76
+ when 'status'
77
+ TrafficControllerSite.make_status 'logout'
78
+ end
72
79
  end
73
80
  end
74
81
 
75
82
  # S0092 - Operator logged in/out web-interface
76
- def handle_s0092(_status_code, status_name = nil, _options = {})
77
- case status_name
78
- when 'user'
79
- TrafficControllerSite.make_status 0
80
- when 'username'
81
- TrafficControllerSite.make_status ''
83
+ def handle_s0092(_status_code, status_name = nil, options = {})
84
+ if RSMP::Proxy.version_meets_requirement?(options[:sxl_version], '>=1.1')
85
+ case status_name
86
+ when 'user'
87
+ TrafficControllerSite.make_status 0
88
+ end
89
+ else
90
+ case status_name
91
+ when 'user'
92
+ TrafficControllerSite.make_status 'nobody'
93
+ when 'status'
94
+ TrafficControllerSite.make_status 'logout'
95
+ end
82
96
  end
83
97
  end
84
98
 
@@ -5,17 +5,20 @@ module RSMP
5
5
  # Covers functional position, emergency routes, I/O modes, signal group orders, and system settings.
6
6
  module Control
7
7
  # M0001 — Set functional position (NormalControl, YellowFlash, Dark).
8
- def set_functional_position(status, timeout_minutes: 0, options: {})
8
+ def set_functional_position(status, within:, timeout_minutes: 0)
9
9
  validate_ready 'set functional position'
10
10
  raise 'TLC main component not found' unless main
11
11
 
12
12
  command_list = functional_position_command_list(status, timeout_minutes)
13
13
  confirm_status = functional_position_confirm_status(status)
14
- send_command_with_confirm main.c_id, command_list, options, "functional position #{status}", confirm_status
14
+ collector = send_command_and_collect(command_list, within: within)
15
+ collector.ok!
16
+ wait_for_status "functional position #{status}", confirm_status, timeout: within unless confirm_status.empty?
17
+ { collector: collector }
15
18
  end
16
19
 
17
20
  # M0005 — Set or clear an emergency route.
18
- def set_emergency_route(route:, active:, options: {})
21
+ def set_emergency_route(route:, active:, within:)
19
22
  validate_ready 'set emergency route'
20
23
  raise 'TLC main component not found' unless main
21
24
 
@@ -39,13 +42,11 @@ module RSMP
39
42
  'v' => route.to_s
40
43
  }]
41
44
 
42
- confirm_status = [{ 'sCI' => 'S0006', 'n' => 'status', 's' => active_str }]
43
- send_command_with_confirm main.c_id, command_list, options,
44
- "emergency route #{route} #{active ? 'active' : 'inactive'}", confirm_status
45
+ send_command_and_collect(command_list, within: within).ok!
45
46
  end
46
47
 
47
48
  # M0007 — Enable or disable fixed-time control.
48
- def set_fixed_time(status, options: {})
49
+ def set_fixed_time(status, within:)
49
50
  validate_ready 'set fixed time'
50
51
  raise 'TLC main component not found' unless main
51
52
 
@@ -65,11 +66,12 @@ module RSMP
65
66
 
66
67
  confirm_status = [{ 'sCI' => 'S0009', 'n' => 'status',
67
68
  's' => /^#{Regexp.escape(status.to_s)}(,#{Regexp.escape(status.to_s)})*$/ }]
68
- send_command_with_confirm main.c_id, command_list, options, "fixed time #{status}", confirm_status
69
+ send_command_and_collect(command_list, within: within).ok!
70
+ wait_for_status "fixed time #{status}", confirm_status, timeout: within
69
71
  end
70
72
 
71
73
  # M0003 — Set traffic situation (activate a specific situation number).
72
- def set_traffic_situation(situation, options: {})
74
+ def set_traffic_situation(situation, within:)
73
75
  validate_ready 'set traffic situation'
74
76
  raise 'TLC main component not found' unless main
75
77
 
@@ -93,11 +95,12 @@ module RSMP
93
95
  }]
94
96
 
95
97
  confirm_status = [{ 'sCI' => 'S0015', 'n' => 'status', 's' => situation.to_s }]
96
- send_command_with_confirm main.c_id, command_list, options, "traffic situation #{situation}", confirm_status
98
+ send_command_and_collect(command_list, within: within).ok!
99
+ wait_for_status "traffic situation #{situation}", confirm_status, timeout: within
97
100
  end
98
101
 
99
102
  # M0003 — Clear the active traffic situation.
100
- def unset_traffic_situation(options: {})
103
+ def unset_traffic_situation(within:)
101
104
  validate_ready 'unset traffic situation'
102
105
  raise 'TLC main component not found' unless main
103
106
 
@@ -121,7 +124,8 @@ module RSMP
121
124
  }]
122
125
 
123
126
  confirm_status = [{ 'sCI' => 'S0015', 'n' => 'status', 's' => '1' }]
124
- send_command_with_confirm main.c_id, command_list, options, 'traffic situation unset', confirm_status
127
+ send_command_and_collect(command_list, within: within).ok!
128
+ wait_for_status 'traffic situation unset', confirm_status, timeout: within
125
129
  end
126
130
 
127
131
  private
@@ -6,7 +6,7 @@ module RSMP
6
6
  module Detectors
7
7
  # M0008 — Force detector logic to a given mode and status.
8
8
  # component_id must refer to the detector logic component, not main.
9
- def force_detector_logic(component_id, status:, mode:, options: {})
9
+ def force_detector_logic(component_id, status:, mode:, within:)
10
10
  validate_ready 'force detector logic'
11
11
 
12
12
  security_code = security_code_for(2)
@@ -27,12 +27,11 @@ module RSMP
27
27
  'n' => 'mode',
28
28
  'v' => mode.to_s
29
29
  }]
30
-
31
- send_command_with_confirm component_id, command_list, options, "force detector logic #{component_id}", nil
30
+ send_command_and_collect(command_list, component: component_id, within: within).ok!
32
31
  end
33
32
 
34
33
  # M0021 — Set the trigger level for traffic counting.
35
- def set_trigger_level(status, options: {})
34
+ def set_trigger_level(status, within:)
36
35
  validate_ready 'set trigger level'
37
36
  raise 'TLC main component not found' unless main
38
37
 
@@ -49,8 +48,7 @@ module RSMP
49
48
  'n' => 'securityCode',
50
49
  'v' => security_code.to_s
51
50
  }]
52
-
53
- send_command_with_confirm main.c_id, command_list, options, "trigger level #{status}", nil
51
+ send_command_and_collect(command_list, within: within).ok!
54
52
  end
55
53
  end
56
54
  end
@@ -5,7 +5,7 @@ module RSMP
5
5
  # Covers detector logic, input/output forcing and setting.
6
6
  module IO
7
7
  # M0006 — Set a single input to a given status.
8
- def set_input(input:, status:, options: {})
8
+ def set_input(input:, status:, within:)
9
9
  validate_ready 'set input'
10
10
  raise 'TLC main component not found' unless main
11
11
 
@@ -27,12 +27,11 @@ module RSMP
27
27
  'n' => 'input',
28
28
  'v' => input.to_s
29
29
  }]
30
-
31
- send_command_with_confirm main.c_id, command_list, options, "input #{input} set to #{status}", nil
30
+ send_command_and_collect(command_list, within: within).ok!
32
31
  end
33
32
 
34
33
  # M0013 — Set all inputs via a bit-pattern string.
35
- def set_inputs(status, options: {})
34
+ def set_inputs(status, within:)
36
35
  validate_ready 'set inputs'
37
36
  raise 'TLC main component not found' unless main
38
37
 
@@ -40,31 +39,31 @@ module RSMP
40
39
 
41
40
  command_list = [{
42
41
  'cCI' => 'M0013',
43
- 'cO' => 'setInputs',
42
+ 'cO' => 'setInput',
44
43
  'n' => 'status',
45
44
  'v' => status.to_s
46
45
  }, {
47
46
  'cCI' => 'M0013',
48
- 'cO' => 'setInputs',
47
+ 'cO' => 'setInput',
49
48
  'n' => 'securityCode',
50
49
  'v' => security_code.to_s
51
50
  }]
52
-
53
- send_command_with_confirm main.c_id, command_list, options, "inputs #{status}", nil
51
+ send_command_and_collect(command_list, within: within).ok!
54
52
  end
55
53
 
56
54
  # M0019 — Force an input to a given value.
57
- def force_input(input:, status:, value:, options: {})
55
+ def force_input(input:, status:, value:, within:)
58
56
  validate_ready 'force input'
59
57
  raise 'TLC main component not found' unless main
60
58
 
61
59
  command_list = force_input_command_list(input, status, value)
62
60
  confirm_status = force_input_confirm_status(input, status, value)
63
- send_command_with_confirm main.c_id, command_list, options, "force input #{input}", confirm_status
61
+ send_command_and_collect(command_list, within: within).ok!
62
+ wait_for_status "force input #{input}", confirm_status, timeout: within
64
63
  end
65
64
 
66
65
  # M0020 — Force an output to a given value.
67
- def force_output(output:, status:, value:, options: {})
66
+ def force_output(output:, status:, value:, within:)
68
67
  validate_ready 'force output'
69
68
  raise 'TLC main component not found' unless main
70
69
 
@@ -91,8 +90,7 @@ module RSMP
91
90
  'n' => 'outputValue',
92
91
  'v' => value.to_s
93
92
  }]
94
-
95
- send_command_with_confirm main.c_id, command_list, options, "force output #{output}", nil
93
+ send_command_and_collect(command_list, within: within).ok!
96
94
  end
97
95
 
98
96
  private
@@ -108,10 +106,14 @@ module RSMP
108
106
  end
109
107
 
110
108
  def force_input_confirm_status(input, status, value)
111
- [
112
- { 'sCI' => 'S0029', 'n' => 'status', 's' => /^.{#{input.to_i - 1}}#{status == 'True' ? '1' : '0'}/ },
113
- { 'sCI' => 'S0003', 'n' => 'inputstatus', 's' => /^.{#{input.to_i - 1}}#{value == 'True' ? '1' : '0'}/ }
109
+ result = [
110
+ { 'sCI' => 'S0029', 'n' => 'status', 's' => /^.{#{input.to_i - 1}}#{status == 'True' ? '1' : '0'}/ }
114
111
  ]
112
+ if status == 'True'
113
+ result << { 'sCI' => 'S0003', 'n' => 'inputstatus',
114
+ 's' => /^.{#{input.to_i - 1}}#{value == 'True' ? '1' : '0'}/ }
115
+ end
116
+ result
115
117
  end
116
118
  end
117
119
  end
@@ -5,7 +5,7 @@ module RSMP
5
5
  # Covers time plans, week/day tables, bands, offsets, and cycle times.
6
6
  module Plans
7
7
  # M0014 — Set dynamic bands for a signal plan.
8
- def set_dynamic_bands(plan:, status:, options: {})
8
+ def set_dynamic_bands(plan:, status:, within:)
9
9
  validate_ready 'set dynamic bands'
10
10
  raise 'TLC main component not found' unless main
11
11
 
@@ -27,12 +27,11 @@ module RSMP
27
27
  'n' => 'plan',
28
28
  'v' => plan.to_s
29
29
  }]
30
-
31
- send_command_with_confirm main.c_id, command_list, options, "dynamic bands plan #{plan}", nil
30
+ send_command_and_collect(command_list, within: within).ok!
32
31
  end
33
32
 
34
33
  # M0023 — Set timeout for dynamic bands.
35
- def set_dynamic_bands_timeout(status, options: {})
34
+ def set_dynamic_bands_timeout(status, within:)
36
35
  validate_ready 'set dynamic bands timeout'
37
36
  raise 'TLC main component not found' unless main
38
37
 
@@ -49,12 +48,11 @@ module RSMP
49
48
  'n' => 'securityCode',
50
49
  'v' => security_code.to_s
51
50
  }]
52
-
53
- send_command_with_confirm main.c_id, command_list, options, "dynamic bands timeout #{status}", nil
51
+ send_command_and_collect(command_list, within: within).ok!
54
52
  end
55
53
 
56
54
  # M0015 — Set offset for a signal plan.
57
- def set_offset(plan:, offset:, options: {})
55
+ def set_offset(plan:, offset:, within:)
58
56
  validate_ready 'set offset'
59
57
  raise 'TLC main component not found' unless main
60
58
 
@@ -76,12 +74,11 @@ module RSMP
76
74
  'n' => 'plan',
77
75
  'v' => plan.to_s
78
76
  }]
79
-
80
- send_command_with_confirm main.c_id, command_list, options, "offset plan #{plan} to #{offset}", nil
77
+ send_command_and_collect(command_list, within: within).ok!
81
78
  end
82
79
 
83
80
  # Set the timeplan (signal plan) on the remote TLC.
84
- def set_timeplan(plan_nr, options: {})
81
+ def set_timeplan(plan_nr, within:)
85
82
  validate_ready 'set timeplan'
86
83
  raise 'TLC main component not found' unless main
87
84
 
@@ -103,13 +100,13 @@ module RSMP
103
100
  'n' => 'timeplan',
104
101
  'v' => plan_nr.to_s
105
102
  }]
106
-
107
103
  confirm_status = [{ 'sCI' => 'S0014', 'n' => 'status', 's' => plan_nr.to_s }]
108
- send_command_with_confirm main.c_id, command_list, options, "timeplan #{plan_nr}", confirm_status
104
+ send_command_and_collect(command_list, within: within).ok!
105
+ wait_for_status("timeplan #{plan_nr}", confirm_status, timeout: within)
109
106
  end
110
107
 
111
108
  # M0016 — Set week table (mapping week days to traffic situations).
112
- def set_week_table(status, options: {})
109
+ def set_week_table(status, within:)
113
110
  validate_ready 'set week table'
114
111
  raise 'TLC main component not found' unless main
115
112
 
@@ -126,12 +123,11 @@ module RSMP
126
123
  'n' => 'securityCode',
127
124
  'v' => security_code.to_s
128
125
  }]
129
-
130
- send_command_with_confirm main.c_id, command_list, options, 'week table', nil
126
+ send_command_and_collect(command_list, within:).ok!
131
127
  end
132
128
 
133
129
  # M0017 — Set day table (mapping time periods to signal plans).
134
- def set_day_table(status, options: {})
130
+ def set_day_table(status, within:)
135
131
  validate_ready 'set day table'
136
132
  raise 'TLC main component not found' unless main
137
133
 
@@ -139,21 +135,20 @@ module RSMP
139
135
 
140
136
  command_list = [{
141
137
  'cCI' => 'M0017',
142
- 'cO' => 'setDayTable',
138
+ 'cO' => 'setTimeTable',
143
139
  'n' => 'status',
144
140
  'v' => status.to_s
145
141
  }, {
146
142
  'cCI' => 'M0017',
147
- 'cO' => 'setDayTable',
143
+ 'cO' => 'setTimeTable',
148
144
  'n' => 'securityCode',
149
145
  'v' => security_code.to_s
150
146
  }]
151
-
152
- send_command_with_confirm main.c_id, command_list, options, 'day table', nil
147
+ send_command_and_collect(command_list, within:).ok!
153
148
  end
154
149
 
155
150
  # M0018 — Set cycle time for a signal plan.
156
- def set_cycle_time(plan:, cycle_time:, options: {})
151
+ def set_cycle_time(plan:, cycle_time:, within:)
157
152
  validate_ready 'set cycle time'
158
153
  raise 'TLC main component not found' unless main
159
154
 
@@ -175,12 +170,11 @@ module RSMP
175
170
  'n' => 'plan',
176
171
  'v' => plan.to_s
177
172
  }]
178
-
179
- send_command_with_confirm main.c_id, command_list, options, "cycle time plan #{plan} to #{cycle_time}", nil
173
+ send_command_and_collect(command_list, within:).ok!
180
174
  end
181
175
 
182
176
  # M0010 — Order signal start for a signal group component.
183
- def order_signal_start(component_id, options: {})
177
+ def order_signal_start(component_id, within:)
184
178
  validate_ready 'order signal start'
185
179
 
186
180
  security_code = security_code_for(2)
@@ -196,12 +190,11 @@ module RSMP
196
190
  'n' => 'securityCode',
197
191
  'v' => security_code.to_s
198
192
  }]
199
-
200
- send_command_with_confirm component_id, command_list, options, "signal start #{component_id}", nil
193
+ send_command_and_collect(command_list, component: component_id, within:).ok!
201
194
  end
202
195
 
203
196
  # M0011 — Order signal stop for a signal group component.
204
- def order_signal_stop(component_id, options: {})
197
+ def order_signal_stop(component_id, within:)
205
198
  validate_ready 'order signal stop'
206
199
 
207
200
  security_code = security_code_for(2)
@@ -217,8 +210,7 @@ module RSMP
217
210
  'n' => 'securityCode',
218
211
  'v' => security_code.to_s
219
212
  }]
220
-
221
- send_command_with_confirm component_id, command_list, options, "signal stop #{component_id}", nil
213
+ send_command_and_collect(command_list, component: component_id, within:).ok!
222
214
  end
223
215
  end
224
216
  end