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