rsmp 0.5.1 → 0.5.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a60faacf7dbd02175c26ff74a0576bcba1eae29d7ac53973ed4991a8952d94d3
4
- data.tar.gz: dffbf77a1385be65a90e1b6ebd8edd8a109bd27ee54eeee5d9d3651c64f10abc
3
+ metadata.gz: 9551219e8b4223f7d3fc615efe9a6e0c648b930c30e023426a4fafd60e15cdc8
4
+ data.tar.gz: 859c020b24d0065d692cbba2ae1cb8de4a3498a03cd6d888fbdf8dab88e90491
5
5
  SHA512:
6
- metadata.gz: a117f1ddeb790ff61d550359bfa28445b13322b66155c6f213035c7a4f01c27cecb0ea1229c2891125e26e06a54314b9fd8f1002b36bd2c8925daa5f630225e7
7
- data.tar.gz: 6e6f9a2e1da0296d9f635b5e07fb74efecaa84b819a7ac16fea84c144a1d48804a3582e4e39de367c5d7fc0ba23da83e30e6650af907848fbc81b309d123dd90
6
+ metadata.gz: 4d5817111ffefe2cef5bc11a66872ef473203eeacd12fbb59c2c001cdb461b8d53cb7965855449083bf7db7225a2390eac4d5f49227c9d8bafa9285a40332837
7
+ data.tar.gz: 85d4bea87373f4d65efd271877627d2be1eb43fc3c75368e312ab2942a3e8db99e512fd2be0351d1add466a43b87c3f8a5477ccb7d72ee9487dd932c43bbaca6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.5.1)
4
+ rsmp (0.5.2)
5
5
  async (~> 1.29.1)
6
6
  async-io (~> 1.32.1)
7
7
  colorize (~> 0.8.1)
@@ -1,4 +1,9 @@
1
1
  module RSMP
2
+
3
+ # Class that represents an RMSP component.
4
+ # Currently this class is used by both SiteProxy and SupervisorProxy, and can
5
+ # therefore represent either a local or remote (proxy) component.
6
+
2
7
  class Component
3
8
  include Inspect
4
9
 
@@ -19,6 +24,7 @@ module RSMP
19
24
  @grouped = grouped
20
25
  @alarms = {}
21
26
  @statuses = {}
27
+ @subscribes = {}
22
28
  clear_aggregated_status
23
29
  end
24
30
 
@@ -83,5 +89,74 @@ module RSMP
83
89
  @alarms[code] = message
84
90
  end
85
91
  end
92
+
93
+ # Handle an incoming status respone, by storing the values
94
+ def handle_status_response message
95
+ store_status message, check_repeated: false
96
+ end
97
+
98
+ # Handle an incoming status update, by storing the values
99
+ def handle_status_update message
100
+ store_status message, check_repeated: true
101
+ end
102
+
103
+ # Our proxy subscribed to status updates
104
+ # Store update rates, so we can check for repeated alarm if we asked for updates only
105
+ # when there's a change, not on a regular interval.
106
+ # After subscribing, an update status us send regarless of whether values changes,
107
+ # and we store that.
108
+ def handle_status_subscribe status_list
109
+ status_list.each do |item|
110
+ sCI, n, uRt = item['sCI'], item['n'], item['uRt']
111
+
112
+ # record the update rate, so we can check for repeated status values if rate is zero
113
+ @subscribes[sCI] ||= {}
114
+ @subscribes[sCI][n] = {'uRt'=>uRt}
115
+
116
+ # record that we expect an upeate, even though the value might not change
117
+ @statuses[sCI] ||= {}
118
+ @statuses[sCI][n] ||= {}
119
+ @statuses[sCI][n][:initial] = true
120
+ end
121
+ #pp @subscribes
122
+ end
123
+
124
+ # Our proxy unsubscribed to status updates.
125
+ # Update our list of update rates.
126
+ def handle_status_unsubscribe status_list
127
+ status_list.each do |item|
128
+ sCI, n = item['sCI'], item['n']
129
+ if @subscribes[sCI]
130
+ @subscribes[sCI].delete n
131
+ end
132
+ if @subscribes[sCI].empty?
133
+ @subscribes.delete sCI
134
+ end
135
+
136
+ # remove any mark that would allow the next update to be a repeat
137
+ item = @statuses.dig sCI, n
138
+ item.delete(:initial) if item
139
+ end
140
+ end
141
+
142
+ # Store the latest status update values, optionally
143
+ # checking that we're not receiving unchanged values if we're subscribed
144
+ # wit updates only on change
145
+ def store_status message, check_repeated:
146
+ message.attribute('sS').each do |item|
147
+ sCI, n, s, q = item['sCI'], item['n'], item['s'], item['q']
148
+ uRt = @subscribes.dig(sCI,n,'uRt')
149
+ new_values = {'s'=>s,'q'=>q}
150
+ old_values = @statuses.dig(sCI,n)
151
+ if check_repeated && uRt.to_i == 0
152
+ if new_values == old_values
153
+ raise RSMP::RepeatedStatusError.new "no change for #{sCI} '#{n}'"
154
+ end
155
+ end
156
+ @statuses[sCI] ||= {}
157
+ @statuses[sCI][n] = new_values
158
+ end
159
+ end
160
+
86
161
  end
87
162
  end
data/lib/rsmp/error.rb CHANGED
@@ -58,4 +58,7 @@ module RSMP
58
58
 
59
59
  class RepeatedAlarmError < Error
60
60
  end
61
+
62
+ class RepeatedStatusError < Error
63
+ end
61
64
  end
@@ -68,6 +68,10 @@ module RSMP
68
68
  else
69
69
  super message
70
70
  end
71
+ rescue RSMP::RepeatedAlarmError, RSMP::RepeatedStatusError => e
72
+ str = "Rejected #{message.type} message,"
73
+ dont_acknowledge message, str, "#{e}"
74
+ notify_error e.exception("#{str}#{e.message} #{message.json}")
71
75
  end
72
76
 
73
77
  def process_command_response message
@@ -145,10 +149,6 @@ module RSMP
145
149
  asp = message.attribute("aSp")
146
150
  log "Received #{message.type}, #{alarm_code} #{asp} [#{status}]", message: message, level: :log
147
151
  acknowledge message
148
- rescue RSMP::RepeatedAlarmError => e
149
- str = "Rejected #{message.type} message, "
150
- dont_acknowledge message, str, "#{e}"
151
- notify_error e.exception("#{str}#{e.message} #{message.json}")
152
152
  end
153
153
 
154
154
  def version_acknowledged
@@ -187,6 +187,8 @@ module RSMP
187
187
  end
188
188
 
189
189
  def process_status_response message
190
+ component = find_component message.attribute("cId")
191
+ component.handle_status_response message
190
192
  log "Received #{message.type}", message: message, level: :log
191
193
  acknowledge message
192
194
  end
@@ -198,7 +200,7 @@ module RSMP
198
200
  message
199
201
  end
200
202
 
201
- def subscribe_to_status component, status_list, options={}
203
+ def subscribe_to_status component_id, status_list, options={}
202
204
  validate_ready 'subscribe to status'
203
205
  m_id = options[:m_id] || RSMP::Message.make_m_id
204
206
 
@@ -206,10 +208,13 @@ module RSMP
206
208
  # but must to remove from the subscribe message
207
209
  subscribe_list = status_list.map { |item| item.slice('sCI','n','uRt') }
208
210
 
211
+ component = find_component component_id
212
+ component.handle_status_subscribe subscribe_list
213
+
209
214
  message = RSMP::StatusSubscribe.new({
210
215
  "ntsOId" => '',
211
216
  "xNId" => '',
212
- "cId" => component,
217
+ "cId" => component_id,
213
218
  "sS" => subscribe_list,
214
219
  'mId' => m_id
215
220
  })
@@ -218,12 +223,15 @@ module RSMP
218
223
  end
219
224
  end
220
225
 
221
- def unsubscribe_to_status component, status_list, options={}
226
+ def unsubscribe_to_status component_id, status_list, options={}
227
+ component = find_component component_id
228
+ component.handle_status_subscribe status_list
229
+
222
230
  validate_ready 'unsubscribe to status'
223
231
  message = RSMP::StatusUnsubscribe.new({
224
232
  "ntsOId" => '',
225
233
  "xNId" => '',
226
- "cId" => component,
234
+ "cId" => component_id,
227
235
  "sS" => status_list
228
236
  })
229
237
  send_message message, validate: options[:validate]
@@ -231,6 +239,8 @@ module RSMP
231
239
  end
232
240
 
233
241
  def process_status_update message
242
+ component = find_component message.attribute("cId")
243
+ component.handle_status_update message
234
244
  log "Received #{message.type}", message: message, level: :log
235
245
  acknowledge message
236
246
  end
@@ -175,7 +175,6 @@ module RSMP
175
175
  if proxy.connected?
176
176
  raise ConnectionError.new("Site #{id} alredy connected from port #{proxy.port}")
177
177
  else
178
- p proxy.state
179
178
  proxy.revive settings
180
179
  end
181
180
  else
@@ -225,7 +225,6 @@ module RSMP
225
225
  def process_status_subcribe message
226
226
  log "Received #{message.type}", message: message, level: :log
227
227
 
228
-
229
228
  # @status_subscriptions is organized by component/code/name, for example:
230
229
  #
231
230
  # {"AA+BBCCC=DDDEE002"=>{"S001"=>["number"]}}
@@ -234,21 +233,14 @@ module RSMP
234
233
  # for each component, containing all the requested statuses
235
234
 
236
235
  update_list = {}
237
-
238
236
  component = message.attributes["cId"]
239
-
240
237
  @status_subscriptions[component] ||= {}
241
238
  update_list[component] ||= {}
242
-
243
- subs = @status_subscriptions[component]
244
239
  now = Time.now # internal timestamp
245
240
 
246
241
  message.attributes["sS"].each do |arg|
247
242
  sCI = arg["sCI"]
248
243
  subcription = {interval: arg["uRt"].to_i, last_sent_at: now}
249
- subs[sCI] ||= {}
250
- subs[sCI][arg["n"]] = subcription
251
-
252
244
  update_list[component][sCI] ||= []
253
245
  update_list[component][sCI] << arg["n"]
254
246
  end
@@ -287,11 +279,15 @@ module RSMP
287
279
  end
288
280
  end
289
281
 
290
- def store_last_sent_status component, code, name, value
282
+ def store_last_sent_status message
283
+ component_id = message.attribute('cId')
291
284
  @last_status_sent ||= {}
292
- @last_status_sent[component] ||= {}
293
- @last_status_sent[component][code] ||= {}
294
- @last_status_sent[component][code][name] = value
285
+ @last_status_sent[component_id] ||= {}
286
+ message.attribute('sS').each do |item|
287
+ sCI, n, s = item['sCI'], item['n'], item['s']
288
+ @last_status_sent[component_id][sCI] ||= {}
289
+ @last_status_sent[component_id][sCI][n] = s
290
+ end
295
291
  end
296
292
 
297
293
  def status_update_timer now
@@ -312,7 +308,6 @@ module RSMP
312
308
  last_sent = fetch_last_sent_status component, code, name
313
309
  if current != last_sent
314
310
  should_send = true
315
- store_last_sent_status component, code, name, current
316
311
  end
317
312
  else
318
313
  # send at regular intervals
@@ -356,6 +351,7 @@ module RSMP
356
351
  "sS"=>sS
357
352
  })
358
353
  send_message update
354
+ store_last_sent_status update
359
355
  end
360
356
  end
361
357
 
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  end
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.1
4
+ version: 0.5.2
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-05 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -258,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
258
  - !ruby/object:Gem::Version
259
259
  version: '0'
260
260
  requirements: []
261
- rubygems_version: 3.2.15
261
+ rubygems_version: 3.2.26
262
262
  signing_key:
263
263
  specification_version: 4
264
264
  summary: RoadSide Message Protocol (RSMP) library.