rsmp 0.5.1 → 0.5.2

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: 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.