somfy_sdn 1.0.8 → 1.0.9

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: 66516a3bb03695b73075a496a791502683ec12052219a5cf040cfe6e9f82b04f
4
- data.tar.gz: bad8e87688534b118e679b4126490f5eab3c6e83ee7288184368e852bf0cc450
3
+ metadata.gz: 7b76beaca35ebf0ae0847fc75bf0fcd12c45e395768cca0c711557b167488e3e
4
+ data.tar.gz: 64dfc392ef651d1afc6e6a94c8c586e1e95e575c0ff9ba12c74f472cbfe88874
5
5
  SHA512:
6
- metadata.gz: db18252c03d784aeb3461dacffc16dae04aeb176f5b98f3b796d395f95980350576075a434794e16347eef7bfb308eccf7e4307abeceb4675254a3505d74b60d
7
- data.tar.gz: e17af388921091abe51a23b6fcef7c3bf0d402ad55446bfc86aa698482a22cca341f7612b73d04e97ad91e060ff13f7573016e4ddb7aca24002c69f1ee9706b9
6
+ metadata.gz: 87a1138187217fb8bf7fe62e00f69e20b742d2527d4f0059b9a2d4ba42012c887947608fdbfad4123400a0968d99d9c257cb361025ecef668786d34b708a0512
7
+ data.tar.gz: e6ddbe689d8d60d252c24a1291893b05040a638ba3b86ac3a7bc1c28479a9ccdf0485e5914035818c50e1005b076d148263916ae1e7a66e05efdb075786d1d95
@@ -55,6 +55,7 @@ module SDN
55
55
  singleton_class.include Helpers
56
56
 
57
57
  attr_reader :reserved, :ack_requested, :src, :dest
58
+ attr_writer :ack_requested
58
59
 
59
60
  def initialize(reserved: nil, ack_requested: false, src: nil, dest: nil)
60
61
  @reserved = reserved || 0x02 # message sent to Sonesse 30
@@ -3,6 +3,8 @@ require 'uri'
3
3
  require 'set'
4
4
 
5
5
  module SDN
6
+ MessageAndRetries = Struct.new(:message, :remaining_retries, :priority)
7
+
6
8
  Group = Struct.new(:bridge, :addr, :positionpercent, :state, :motors) do
7
9
  def initialize(*)
8
10
  members.each { |k| self[k] = :nil }
@@ -106,7 +108,7 @@ module SDN
106
108
  sdn_addr = SDN::Message.parse_address(addr)
107
109
  groups.each_with_index do |g, i|
108
110
  if @groups[i] != g
109
- messages << SDN::Message::SetGroupAddr.new(sdn_addr, i, g)
111
+ messages << SDN::Message::SetGroupAddr.new(sdn_addr, i, g).tap { |m| m.ack_requested = true }
110
112
  messages << SDN::Message::GetGroupAddr.new(sdn_addr, i)
111
113
  end
112
114
  end
@@ -139,8 +141,7 @@ module SDN
139
141
 
140
142
  @mutex = Mutex.new
141
143
  @cond = ConditionVariable.new
142
- @command_queue = []
143
- @request_queue = []
144
+ @queues = [[], [], []]
144
145
  @response_pending = false
145
146
  @broadcast_pending = false
146
147
 
@@ -247,7 +248,7 @@ module SDN
247
248
  signal = @response_pending || !follow_ups.empty?
248
249
  @response_pending = @broadcast_pending
249
250
  follow_ups.each do |follow_up|
250
- @request_queue.push(follow_up) unless @request_queue.include?(follow_up)
251
+ @queues[1].push(MessageAndRetries.new(follow_up, 5, 1)) unless @queues[1].any? { |mr| mr.message == follow_up }
251
252
  end
252
253
  @cond.signal if signal
253
254
  end
@@ -265,7 +266,7 @@ module SDN
265
266
  write_thread = Thread.new do
266
267
  begin
267
268
  loop do
268
- message = nil
269
+ message_and_retries = nil
269
270
  @mutex.synchronize do
270
271
  # got woken up early by another command getting queued; spin
271
272
  if @response_pending
@@ -275,35 +276,47 @@ module SDN
275
276
  puts "timed out waiting on response"
276
277
  @response_pending = nil
277
278
  @broadcast_pending = nil
279
+ if @prior_message&.remaining_retries != 0
280
+ puts "retrying #{@prior_message.remaining_retries} more times ..."
281
+ @queues[@prior_message.priority].push(@prior_message)
282
+ @prior_message = nil
283
+ end
278
284
  else
279
285
  @cond.wait(@mutex, remaining_wait)
280
286
  end
281
287
  end
282
288
  else
289
+ # minimum time between messages
283
290
  sleep 0.1
284
291
  end
285
292
 
286
- message = @command_queue.shift
287
- unless message
288
- message = @request_queue.shift
289
- if message
293
+ @queues.find { |q| message_and_retries = q.shift }
294
+ if message_and_retries
295
+ if message_and_retries.message.ack_requested || message_and_retries.class.name =~ /^SDN::Message::Get/
290
296
  @response_pending = Time.now.to_f + WAIT_TIME
291
- if message.dest == BROADCAST_ADDRESS || SDN::Message::is_group_address?(message.src) && message.is_a?(SDN::Message::GetNodeAddr)
297
+ if message_and_retries.message.dest == BROADCAST_ADDRESS || SDN::Message::is_group_address?(message_and_retries.message.src) && message_and_retries.message.is_a?(SDN::Message::GetNodeAddr)
292
298
  @broadcast_pending = Time.now.to_f + BROADCAST_WAIT
293
299
  end
294
300
  end
295
301
  end
296
302
 
297
- # spin until there is a message
298
- @cond.wait(@mutex) unless message
303
+ # wait until there is a message
304
+ @cond.wait(@mutex) unless message_and_retries
299
305
  end
300
- next unless message
306
+ next unless message_and_retries
301
307
 
308
+ message = message_and_retries.message
302
309
  puts "writing #{message.inspect}"
303
310
  serialized = message.serialize
304
311
  @sdn.write(serialized)
305
312
  @sdn.flush
306
313
  puts "wrote #{serialized.unpack("C*").map { |b| '%02x' % b }.join(' ')}"
314
+ if @response_pending
315
+ message_and_retries.remaining_retries -= 1
316
+ @prior_message = message_and_retries
317
+ else
318
+ @prior_message = nil
319
+ end
307
320
  end
308
321
  rescue => e
309
322
  puts "failure writing: #{e}"
@@ -316,7 +329,7 @@ module SDN
316
329
  if topic == "#{@base_topic}/discovery/discover/set" && value == "true"
317
330
  # trigger discovery
318
331
  @mutex.synchronize do
319
- @request_queue.push(SDN::Message::GetNodeAddr.new)
332
+ @queues[2].push(MessageAndRetries.new(SDN::Message::GetNodeAddr.new, 1, 2))
320
333
  @cond.signal
321
334
  end
322
335
  elsif (match = topic.match(%r{^#{Regexp.escape(@base_topic)}/(?<addr>\h{6})/(?<property>discover|label|down|up|stop|positionpulses|positionpercent|ip|wink|reset|(?<speed_type>upspeed|downspeed|slowspeed)|uplimit|downlimit|direction|ip(?<ip>\d+)(?<ip_type>pulses|percent)|groups)/set$}))
@@ -397,15 +410,16 @@ module SDN
397
410
  next unless motor
398
411
  messages = motor.set_groups(value)
399
412
  @mutex.synchronize do
400
- messages.each { |m| @command_queue.push(m) }
413
+ messages.each { |m| @queues[0].push(MessageAndRetries.new(m, 5, 0)) }
401
414
  @cond.signal
402
415
  end
403
416
  nil
404
417
  end
405
418
  if message
419
+ message.ack_requested = true if motor && message.class.name !~ /^SDN::Message::Get/
406
420
  @mutex.synchronize do
407
- @command_queue.push(message)
408
- @request_queue.push(follow_up) unless @request_queue.include?(follow_up)
421
+ @queues[0].push(MessageAndRetries.new(message, message.ack_requested ? 5 : 1, 0))
422
+ @queues[1].push(MessageAndRetries.new(follow_up, 5, 1)) unless @queues[1].any? { |mr| mr.message == follow_up }
409
423
  @cond.signal
410
424
  end
411
425
  end
@@ -603,13 +617,13 @@ module SDN
603
617
 
604
618
  sdn_addr = SDN::Message.parse_address(addr)
605
619
  @mutex.synchronize do
606
- @request_queue.push(SDN::Message::GetNodeLabel.new(sdn_addr))
607
- @request_queue.push(SDN::Message::GetMotorStatus.new(sdn_addr))
608
- @request_queue.push(SDN::Message::GetMotorLimits.new(sdn_addr))
609
- @request_queue.push(SDN::Message::GetMotorDirection.new(sdn_addr))
610
- @request_queue.push(SDN::Message::GetMotorRollingSpeed.new(sdn_addr))
611
- (1..16).each { |ip| @request_queue.push(SDN::Message::GetMotorIP.new(sdn_addr, ip)) }
612
- (0...16).each { |g| @request_queue.push(SDN::Message::GetGroupAddr.new(sdn_addr, g)) }
620
+ @queues[2].push(MessageAndRetries.new(SDN::Message::GetNodeLabel.new(sdn_addr), 5, 2))
621
+ @queues[2].push(MessageAndRetries.new(SDN::Message::GetMotorStatus.new(sdn_addr), 5, 2))
622
+ @queues[2].push(MessageAndRetries.new(SDN::Message::GetMotorLimits.new(sdn_addr), 5, 2))
623
+ @queues[2].push(MessageAndRetries.new(SDN::Message::GetMotorDirection.new(sdn_addr), 5, 2))
624
+ @queues[2].push(MessageAndRetries.new(SDN::Message::GetMotorRollingSpeed.new(sdn_addr), 5, 2))
625
+ (1..16).each { |ip| @queues[2].push(MessageAndRetries.new(SDN::Message::GetMotorIP.new(sdn_addr, ip), 5, 2)) }
626
+ (0...16).each { |g| @queues[2].push(MessageAndRetries.new(SDN::Message::GetGroupAddr.new(sdn_addr, g), 5, 2)) }
613
627
 
614
628
  @cond.signal
615
629
  end
@@ -1,3 +1,3 @@
1
1
  module SDN
2
- VERSION = '1.0.8'
2
+ VERSION = '1.0.9'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: somfy_sdn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2020-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mqtt