somfy_sdn 1.0.8 → 1.0.9

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