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 +4 -4
- data/lib/sdn/message.rb +1 -0
- data/lib/sdn/mqtt_bridge.rb +38 -24
- data/lib/sdn/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b76beaca35ebf0ae0847fc75bf0fcd12c45e395768cca0c711557b167488e3e
|
4
|
+
data.tar.gz: 64dfc392ef651d1afc6e6a94c8c586e1e95e575c0ff9ba12c74f472cbfe88874
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87a1138187217fb8bf7fe62e00f69e20b742d2527d4f0059b9a2d4ba42012c887947608fdbfad4123400a0968d99d9c257cb361025ecef668786d34b708a0512
|
7
|
+
data.tar.gz: e6ddbe689d8d60d252c24a1291893b05040a638ba3b86ac3a7bc1c28479a9ccdf0485e5914035818c50e1005b076d148263916ae1e7a66e05efdb075786d1d95
|
data/lib/sdn/message.rb
CHANGED
@@ -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
|
data/lib/sdn/mqtt_bridge.rb
CHANGED
@@ -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
|
-
@
|
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
|
-
@
|
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
|
-
|
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
|
-
|
287
|
-
|
288
|
-
message
|
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
|
-
#
|
298
|
-
@cond.wait(@mutex) unless
|
303
|
+
# wait until there is a message
|
304
|
+
@cond.wait(@mutex) unless message_and_retries
|
299
305
|
end
|
300
|
-
next unless
|
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
|
-
@
|
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| @
|
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
|
-
@
|
408
|
-
@
|
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
|
-
@
|
607
|
-
@
|
608
|
-
@
|
609
|
-
@
|
610
|
-
@
|
611
|
-
(1..16).each { |ip| @
|
612
|
-
(0...16).each { |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
|
data/lib/sdn/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2020-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mqtt
|