somfy_sdn 1.0.12 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/somfy_sdn +60 -0
- data/lib/sdn/cli/mqtt/group.rb +31 -0
- data/lib/sdn/cli/mqtt/motor.rb +103 -0
- data/lib/sdn/cli/mqtt/read.rb +156 -0
- data/lib/sdn/cli/mqtt/subscriptions.rb +156 -0
- data/lib/sdn/cli/mqtt/write.rb +93 -0
- data/lib/sdn/cli/mqtt.rb +397 -0
- data/lib/sdn/cli/provisioner.rb +234 -0
- data/lib/sdn/cli/simulator.rb +197 -0
- data/lib/sdn/client.rb +86 -0
- data/lib/sdn/{messages → message}/control.rb +79 -38
- data/lib/sdn/{messages → message}/get.rb +48 -40
- data/lib/sdn/{messages → message}/helpers.rb +33 -3
- data/lib/sdn/message/ilt2/get.rb +48 -0
- data/lib/sdn/message/ilt2/master_control.rb +35 -0
- data/lib/sdn/message/ilt2/post.rb +127 -0
- data/lib/sdn/message/ilt2/set.rb +192 -0
- data/lib/sdn/{messages → message}/post.rb +127 -61
- data/lib/sdn/{messages → message}/set.rb +99 -84
- data/lib/sdn/message.rb +81 -30
- data/lib/sdn/version.rb +1 -1
- data/lib/sdn.rb +16 -1
- metadata +63 -26
- data/bin/sdn_mqtt_bridge +0 -5
- data/lib/sdn/messages/ilt2/get.rb +0 -9
- data/lib/sdn/messages/ilt2/post.rb +0 -18
- data/lib/sdn/messages/ilt2/set.rb +0 -59
- data/lib/sdn/mqtt_bridge.rb +0 -711
@@ -1,46 +1,67 @@
|
|
1
1
|
module SDN
|
2
2
|
class Message
|
3
|
-
class
|
4
|
-
MSG =
|
5
|
-
PARAMS_LENGTH =
|
6
|
-
|
7
|
-
TARGET = { down: 0x00, up: 0x01 }
|
3
|
+
class SetFactoryDefault < Message
|
4
|
+
MSG = 0x1f
|
5
|
+
PARAMS_LENGTH = 1
|
6
|
+
RESET = { all_settings: 0x00, group_addresses: 0x01, limits: 0x11, rotation: 0x12, rolling_speed: 0x13, ips: 0x15, locks: 0x17 }
|
8
7
|
|
9
|
-
attr_reader :
|
8
|
+
attr_reader :reset
|
10
9
|
|
11
|
-
def initialize(dest = nil,
|
12
|
-
kwargs[:dest]
|
10
|
+
def initialize(dest = nil, reset = :all_settings, **kwargs)
|
11
|
+
kwargs[:dest] ||= dest
|
13
12
|
super(**kwargs)
|
14
|
-
self.
|
15
|
-
self.target = target
|
16
|
-
self.value = value
|
13
|
+
self.reset = reset
|
17
14
|
end
|
18
15
|
|
19
16
|
def parse(params)
|
20
17
|
super
|
21
|
-
self.
|
22
|
-
self.target = TARGET.invert[to_number(params[1])]
|
23
|
-
self.value = to_number(params[2..3])
|
18
|
+
self.reset = RESET.invert[to_number(params)]
|
24
19
|
end
|
25
20
|
|
26
|
-
def
|
27
|
-
raise ArgumentError, "
|
28
|
-
@
|
21
|
+
def reset=(value)
|
22
|
+
raise ArgumentError, "reset must be one of :all_settings, :group_addresses, :limits, :rotation, :rolling_speed, :ips, :locks" unless RESET.keys.include?(value)
|
23
|
+
@reset = value
|
29
24
|
end
|
30
25
|
|
31
|
-
def
|
32
|
-
|
33
|
-
@target = value
|
26
|
+
def params
|
27
|
+
transform_param(RESET[reset])
|
34
28
|
end
|
29
|
+
end
|
35
30
|
|
36
|
-
|
37
|
-
|
31
|
+
class SetGroupAddr < Message
|
32
|
+
MSG = 0x51
|
33
|
+
PARAMS_LENGTH = 4
|
34
|
+
|
35
|
+
attr_reader :group_index, :group_address
|
36
|
+
|
37
|
+
def initialize(dest = nil, group_index = 1, group_address = nil, **kwargs)
|
38
|
+
kwargs[:dest] ||= dest
|
39
|
+
super(**kwargs)
|
40
|
+
self.group_index = group_index
|
41
|
+
self.group_address = group_address
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse(params)
|
45
|
+
super
|
46
|
+
self.group_index = to_number(params[0]) + 1
|
47
|
+
self.group_address = transform_param(params[1..3])
|
48
|
+
end
|
49
|
+
|
50
|
+
def group_index=(value)
|
51
|
+
raise ArgumentError, "group_index is out of range" unless (1..16).include?(value)
|
52
|
+
@group_index = value
|
53
|
+
end
|
54
|
+
|
55
|
+
def group_address=(value)
|
56
|
+
@group_address = value
|
38
57
|
end
|
39
58
|
|
40
59
|
def params
|
41
|
-
|
42
|
-
|
43
|
-
|
60
|
+
transform_param(group_index - 1) + transform_param(group_address || [0, 0, 0])
|
61
|
+
end
|
62
|
+
|
63
|
+
def class_inspect
|
64
|
+
", group_index=#{group_index.inspect}, group_address=#{group_address ? print_address(group_address) : 'nil'}"
|
44
65
|
end
|
45
66
|
end
|
46
67
|
|
@@ -72,31 +93,6 @@ module SDN
|
|
72
93
|
end
|
73
94
|
end
|
74
95
|
|
75
|
-
class SetMotorRollingSpeed < Message
|
76
|
-
MSG = 0x13
|
77
|
-
PARAMS_LENGTH = 3
|
78
|
-
|
79
|
-
attr_accessor :up_speed, :down_speed, :slow_speed
|
80
|
-
def initialize(dest = nil, up_speed: nil, down_speed: nil, slow_speed: nil, **kwargs)
|
81
|
-
kwargs[:dest] ||= dest
|
82
|
-
super(**kwargs)
|
83
|
-
self.up_speed = up_speed
|
84
|
-
self.down_speed = down_speed
|
85
|
-
self.slow_speed = slow_speed
|
86
|
-
end
|
87
|
-
|
88
|
-
def parse(params)
|
89
|
-
super
|
90
|
-
self.up_speed = to_number(params[0])
|
91
|
-
self.down_speed = to_number(params[1])
|
92
|
-
self.slow_speed = to_number(params[2])
|
93
|
-
end
|
94
|
-
|
95
|
-
def params
|
96
|
-
transform_param(up_speed || 0xff) + transform_param(down_speed || 0xff) + transform_param(slow_speed || 0xff)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
96
|
class SetMotorIP < Message
|
101
97
|
MSG = 0x15
|
102
98
|
PARAMS_LENGTH = 4
|
@@ -141,74 +137,93 @@ module SDN
|
|
141
137
|
end
|
142
138
|
end
|
143
139
|
|
144
|
-
class
|
145
|
-
MSG =
|
146
|
-
PARAMS_LENGTH =
|
147
|
-
|
140
|
+
class SetMotorLimits < Message
|
141
|
+
MSG = 0x11
|
142
|
+
PARAMS_LENGTH = 4
|
143
|
+
TYPE = { delete: 0x00, current_position: 0x01, specified_position: 0x02, jog_ms: 0x04, jog_pulses: 0x05 }
|
144
|
+
TARGET = { down: 0x00, up: 0x01 }
|
148
145
|
|
149
|
-
attr_reader :
|
146
|
+
attr_reader :type, :target, :value
|
150
147
|
|
151
|
-
def initialize(dest = nil,
|
148
|
+
def initialize(dest = nil, type = :delete, target = :up, value = nil, **kwargs)
|
152
149
|
kwargs[:dest] ||= dest
|
153
150
|
super(**kwargs)
|
154
|
-
self.
|
151
|
+
self.type = type
|
152
|
+
self.target = target
|
153
|
+
self.value = value
|
155
154
|
end
|
156
155
|
|
157
156
|
def parse(params)
|
158
157
|
super
|
159
|
-
self.
|
158
|
+
self.type = TYPE.invert[to_number(params[0])]
|
159
|
+
self.target = TARGET.invert[to_number(params[1])]
|
160
|
+
self.value = to_number(params[2..3])
|
160
161
|
end
|
161
162
|
|
162
|
-
def
|
163
|
-
raise ArgumentError, "
|
164
|
-
@
|
163
|
+
def type=(value)
|
164
|
+
raise ArgumentError, "type must be one of :delete, :current_position, :specified_position, :jog_ms, :jog_pulses" unless TYPE.keys.include?(value)
|
165
|
+
@type = value
|
166
|
+
end
|
167
|
+
|
168
|
+
def target=(value)
|
169
|
+
raise ArgumentError, "target must be one of :up, :down" unless TARGET.keys.include?(value)
|
170
|
+
@target = value
|
171
|
+
end
|
172
|
+
|
173
|
+
def value=(value)
|
174
|
+
@value = value&. & 0xffff
|
165
175
|
end
|
166
176
|
|
167
177
|
def params
|
168
|
-
|
178
|
+
param = value || 0
|
179
|
+
param /= 10 if target == :jog_ms
|
180
|
+
transform_param(TYPE[type]) + transform_param(TARGET[target]) + from_number(param, 2)
|
169
181
|
end
|
170
182
|
end
|
171
183
|
|
172
|
-
class
|
173
|
-
MSG =
|
174
|
-
PARAMS_LENGTH =
|
175
|
-
|
176
|
-
attr_reader :group_index, :group_address
|
184
|
+
class SetMotorRollingSpeed < Message
|
185
|
+
MSG = 0x13
|
186
|
+
PARAMS_LENGTH = 3
|
177
187
|
|
178
|
-
|
188
|
+
attr_accessor :up_speed, :down_speed, :slow_speed
|
189
|
+
def initialize(dest = nil, up_speed: nil, down_speed: nil, slow_speed: nil, **kwargs)
|
179
190
|
kwargs[:dest] ||= dest
|
180
191
|
super(**kwargs)
|
181
|
-
self.
|
182
|
-
self.
|
192
|
+
self.up_speed = up_speed
|
193
|
+
self.down_speed = down_speed
|
194
|
+
self.slow_speed = slow_speed
|
183
195
|
end
|
184
196
|
|
185
197
|
def parse(params)
|
186
198
|
super
|
187
|
-
self.
|
188
|
-
self.
|
199
|
+
self.up_speed = to_number(params[0])
|
200
|
+
self.down_speed = to_number(params[1])
|
201
|
+
self.slow_speed = to_number(params[2])
|
189
202
|
end
|
190
203
|
|
191
|
-
def
|
192
|
-
|
193
|
-
@group_index = value
|
204
|
+
def params
|
205
|
+
transform_param(up_speed || 0xff) + transform_param(down_speed || 0xff) + transform_param(slow_speed || 0xff)
|
194
206
|
end
|
207
|
+
end
|
195
208
|
|
196
|
-
|
197
|
-
|
198
|
-
end
|
209
|
+
class SetNetworkLock < Message
|
210
|
+
MSG = 0x16
|
199
211
|
|
200
|
-
|
201
|
-
|
212
|
+
attr_accessor :locked, :priority
|
213
|
+
|
214
|
+
def parse(params)
|
215
|
+
self.locked = to_number(params[0]) == 1 ? true : false
|
216
|
+
self.priority = to_number(params[1])
|
202
217
|
end
|
203
218
|
|
204
|
-
def
|
205
|
-
|
219
|
+
def params
|
220
|
+
transform_param(locked ? 1 : 0) + transform_param(priority)
|
206
221
|
end
|
207
222
|
end
|
208
223
|
|
209
224
|
class SetNodeLabel < Message
|
210
225
|
MSG = 0x55
|
211
|
-
|
226
|
+
MAX_LENGTH = 16
|
212
227
|
|
213
228
|
attr_accessor :label
|
214
229
|
|
@@ -223,7 +238,7 @@ module SDN
|
|
223
238
|
end
|
224
239
|
|
225
240
|
def params
|
226
|
-
from_string(label,
|
241
|
+
from_string(label, self.class::MAX_LENGTH)
|
227
242
|
end
|
228
243
|
end
|
229
244
|
end
|
data/lib/sdn/message.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
|
-
require 'sdn/
|
1
|
+
require 'sdn/message/helpers'
|
2
2
|
|
3
3
|
module SDN
|
4
4
|
class MalformedMessage < RuntimeError; end
|
5
5
|
|
6
6
|
class Message
|
7
7
|
class << self
|
8
|
-
def
|
8
|
+
def inherited(klass)
|
9
|
+
return Message.inherited(klass) unless self == Message
|
10
|
+
@message_map = nil
|
11
|
+
(@subclasses ||= []) << klass
|
12
|
+
end
|
13
|
+
|
14
|
+
def expected_response?(message)
|
9
15
|
if name =~ /::Get([A-Za-z]+)/
|
10
|
-
|
16
|
+
message.class.name == name.sub("::Get", "::Post")
|
11
17
|
else
|
12
|
-
Ack
|
18
|
+
message.is_a?(Ack) || message.is_a?(Nack)
|
13
19
|
end
|
14
20
|
end
|
15
21
|
|
@@ -19,20 +25,22 @@ module SDN
|
|
19
25
|
# we loop here scanning for a valid message
|
20
26
|
loop do
|
21
27
|
offset += 1
|
28
|
+
# give these weird messages a chance
|
29
|
+
result = ILT2::MasterControl.parse(data)
|
30
|
+
return result if result
|
31
|
+
|
22
32
|
return [nil, 0] if data.length - offset < 11
|
23
33
|
msg = to_number(data[offset])
|
24
34
|
length = to_number(data[offset + 1])
|
25
35
|
ack_requested = length & 0x80 == 0x80
|
26
36
|
length &= 0x7f
|
27
37
|
# impossible message
|
28
|
-
next if length < 11 || length >
|
38
|
+
next if length < 11 || length > 43
|
29
39
|
# don't have enough data for what this message wants;
|
30
40
|
# it could be garbage on the line so keep scanning
|
31
41
|
next if length > data.length - offset
|
32
42
|
|
33
|
-
message_class =
|
34
|
-
message_class = const_get(message_class, false) if message_class
|
35
|
-
message_class ||= UnknownMessage
|
43
|
+
message_class = message_map[msg] || UnknownMessage
|
36
44
|
|
37
45
|
calculated_sum = checksum(data.slice(offset, length - 2))
|
38
46
|
read_sum = data.slice(offset + length - 2, 2)
|
@@ -41,34 +49,41 @@ module SDN
|
|
41
49
|
break
|
42
50
|
end
|
43
51
|
|
44
|
-
|
45
|
-
puts "read #{data.slice(offset, length).map { |b| '%02x' % b }.join(' ')}"
|
46
|
-
|
47
|
-
reserved = to_number(data[offset + 2])
|
52
|
+
node_type = node_type_from_number(to_number(data[offset + 2]))
|
48
53
|
src = transform_param(data.slice(offset + 3, 3))
|
49
54
|
dest = transform_param(data.slice(offset + 6, 3))
|
50
55
|
begin
|
51
|
-
result = message_class.new(
|
56
|
+
result = message_class.new(node_type: node_type, ack_requested: ack_requested, src: src, dest: dest)
|
52
57
|
result.parse(data.slice(offset + 9, length - 11))
|
53
58
|
result.msg = msg if message_class == UnknownMessage
|
54
59
|
rescue ArgumentError => e
|
55
|
-
|
60
|
+
SDN.logger.warn "discarding illegal message of type #{message_class.name}: #{e}"
|
56
61
|
result = nil
|
57
62
|
end
|
58
63
|
[result, offset + length]
|
59
64
|
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def message_map
|
69
|
+
@message_map ||=
|
70
|
+
@subclasses.inject({}) do |memo, klass|
|
71
|
+
next memo unless klass.constants(false).include?(:MSG)
|
72
|
+
memo[klass.const_get(:MSG, false)] = klass
|
73
|
+
memo
|
74
|
+
end
|
75
|
+
end
|
60
76
|
end
|
61
77
|
|
62
78
|
include Helpers
|
63
79
|
singleton_class.include Helpers
|
64
80
|
|
65
|
-
|
66
|
-
attr_writer :ack_requested
|
81
|
+
attr_accessor :node_type, :ack_requested, :src, :dest
|
67
82
|
|
68
|
-
def initialize(
|
69
|
-
@
|
83
|
+
def initialize(node_type: nil, ack_requested: false, src: nil, dest: nil)
|
84
|
+
@node_type = node_type || 0
|
70
85
|
@ack_requested = ack_requested
|
71
|
-
if src.nil? && is_group_address?(dest)
|
86
|
+
if src.nil? && !dest.nil? && is_group_address?(dest)
|
72
87
|
src = dest
|
73
88
|
dest = nil
|
74
89
|
end
|
@@ -81,7 +96,7 @@ module SDN
|
|
81
96
|
end
|
82
97
|
|
83
98
|
def serialize
|
84
|
-
result = transform_param(
|
99
|
+
result = transform_param(node_type_to_number(node_type)) + transform_param(src) + transform_param(dest) + params
|
85
100
|
length = result.length + 4
|
86
101
|
length |= 0x80 if ack_requested
|
87
102
|
result = transform_param(self.class.const_get(:MSG)) + transform_param(length) + result
|
@@ -94,11 +109,11 @@ module SDN
|
|
94
109
|
end
|
95
110
|
|
96
111
|
def inspect
|
97
|
-
"#<%s @
|
112
|
+
"#<%s @node_type=%s, @ack_requested=%s, @src=%s, @dest=%s%s>" % [self.class.name, node_type_to_string(node_type), ack_requested, print_address(src), print_address(dest), class_inspect]
|
98
113
|
end
|
99
114
|
|
100
115
|
def class_inspect
|
101
|
-
ivars = instance_variables - [:@
|
116
|
+
ivars = instance_variables - [:@node_type, :@ack_requested, :@src, :@dest, :@params]
|
102
117
|
return if ivars.empty?
|
103
118
|
ivars.map { |iv| ", #{iv}=#{instance_variable_get(iv).inspect}" }.join
|
104
119
|
end
|
@@ -121,19 +136,36 @@ module SDN
|
|
121
136
|
class Nack < Message
|
122
137
|
MSG = 0x6f
|
123
138
|
PARAMS_LENGTH = 1
|
124
|
-
VALUES = { data_error: 0x01,
|
139
|
+
VALUES = { data_error: 0x01,
|
140
|
+
unknown_message: 0x10,
|
141
|
+
node_is_locked: 0x20,
|
142
|
+
wrong_position: 0x21,
|
143
|
+
limits_not_set: 0x22,
|
144
|
+
ip_not_set: 0x23,
|
145
|
+
out_of_range: 0x24,
|
146
|
+
busy: 0xff }
|
147
|
+
# 17 limits not set?
|
148
|
+
# 37 not implemented? (get motor rolling speed)
|
149
|
+
# 39 at limit? blocked?
|
150
|
+
|
125
151
|
|
126
152
|
# presumed
|
127
153
|
attr_accessor :error_code
|
128
154
|
|
155
|
+
def initialize(dest = nil, error_code = nil, **kwargs)
|
156
|
+
kwargs[:dest] ||= dest
|
157
|
+
super(**kwargs)
|
158
|
+
self.error_code = error_code
|
159
|
+
end
|
160
|
+
|
129
161
|
def parse(params)
|
130
162
|
super
|
131
163
|
error_code = to_number(params[0])
|
132
|
-
self.error_code = VALUES[error_code] || error_code
|
164
|
+
self.error_code = VALUES.invert[error_code] || error_code
|
133
165
|
end
|
134
166
|
end
|
135
167
|
|
136
|
-
class Ack <
|
168
|
+
class Ack < SimpleRequest
|
137
169
|
MSG = 0x7f
|
138
170
|
PARAMS_LENGTH = 0
|
139
171
|
end
|
@@ -142,10 +174,25 @@ module SDN
|
|
142
174
|
class UnknownMessage < Message
|
143
175
|
attr_accessor :msg, :params
|
144
176
|
|
177
|
+
def initialize(params = [], **kwargs)
|
178
|
+
super(**kwargs)
|
179
|
+
self.params = params
|
180
|
+
end
|
181
|
+
|
145
182
|
alias parse params=
|
146
183
|
|
184
|
+
def serialize
|
185
|
+
# prevent serializing something we don't know
|
186
|
+
raise NotImplementedError unless params
|
187
|
+
super
|
188
|
+
end
|
189
|
+
|
147
190
|
def class_inspect
|
148
|
-
result =
|
191
|
+
result = if self.class == UnknownMessage
|
192
|
+
result = ", @msg=%02xh" % msg
|
193
|
+
else
|
194
|
+
super || ""
|
195
|
+
end
|
149
196
|
return result if params.empty?
|
150
197
|
|
151
198
|
result << ", @params=#{params.map { |b| "%02x" % b }.join(' ')}"
|
@@ -154,7 +201,11 @@ module SDN
|
|
154
201
|
end
|
155
202
|
end
|
156
203
|
|
157
|
-
require 'sdn/
|
158
|
-
require 'sdn/
|
159
|
-
require 'sdn/
|
160
|
-
require 'sdn/
|
204
|
+
require 'sdn/message/control'
|
205
|
+
require 'sdn/message/get'
|
206
|
+
require 'sdn/message/post'
|
207
|
+
require 'sdn/message/set'
|
208
|
+
require 'sdn/message/ilt2/get'
|
209
|
+
require 'sdn/message/ilt2/master_control'
|
210
|
+
require 'sdn/message/ilt2/post'
|
211
|
+
require 'sdn/message/ilt2/set'
|
data/lib/sdn/version.rb
CHANGED
data/lib/sdn.rb
CHANGED
@@ -1,6 +1,21 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
require 'sdn/client'
|
1
4
|
require 'sdn/message'
|
2
|
-
require 'sdn/mqtt_bridge'
|
3
5
|
|
4
6
|
module SDN
|
5
7
|
BROADCAST_ADDRESS = [0xff, 0xff, 0xff]
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def logger
|
11
|
+
@logger ||= begin
|
12
|
+
Logger.new(STDOUT, :info).tap do |logger|
|
13
|
+
logger.datetime_format = '%Y-%m-%d %H:%M:%S.%L'
|
14
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
15
|
+
"#{datetime.strftime(logger.datetime_format)} [#{Process.pid}/#{Thread.current.object_id}] #{severity}: #{msg}\n"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
6
21
|
end
|
metadata
CHANGED
@@ -1,57 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: somfy_sdn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 2.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: mqtt
|
14
|
+
name: mqtt-ccutrer
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ccutrer-serialport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: curses
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.4'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: net-telnet-rfc2217
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
61
|
+
version: '1.0'
|
34
62
|
type: :runtime
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
68
|
+
version: '1.0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
70
|
+
name: thor
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.
|
75
|
+
version: '1.1'
|
48
76
|
type: :runtime
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.
|
82
|
+
version: '1.1'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: byebug
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,32 +108,41 @@ dependencies:
|
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '13.0'
|
83
|
-
description:
|
111
|
+
description:
|
84
112
|
email: cody@cutrer.com'
|
85
113
|
executables:
|
86
|
-
-
|
114
|
+
- somfy_sdn
|
87
115
|
extensions: []
|
88
116
|
extra_rdoc_files: []
|
89
117
|
files:
|
90
|
-
- bin/
|
118
|
+
- bin/somfy_sdn
|
91
119
|
- lib/sdn.rb
|
120
|
+
- lib/sdn/cli/mqtt.rb
|
121
|
+
- lib/sdn/cli/mqtt/group.rb
|
122
|
+
- lib/sdn/cli/mqtt/motor.rb
|
123
|
+
- lib/sdn/cli/mqtt/read.rb
|
124
|
+
- lib/sdn/cli/mqtt/subscriptions.rb
|
125
|
+
- lib/sdn/cli/mqtt/write.rb
|
126
|
+
- lib/sdn/cli/provisioner.rb
|
127
|
+
- lib/sdn/cli/simulator.rb
|
128
|
+
- lib/sdn/client.rb
|
92
129
|
- lib/sdn/message.rb
|
93
|
-
- lib/sdn/
|
94
|
-
- lib/sdn/
|
95
|
-
- lib/sdn/
|
96
|
-
- lib/sdn/
|
97
|
-
- lib/sdn/
|
98
|
-
- lib/sdn/
|
99
|
-
- lib/sdn/
|
100
|
-
- lib/sdn/
|
101
|
-
- lib/sdn/
|
130
|
+
- lib/sdn/message/control.rb
|
131
|
+
- lib/sdn/message/get.rb
|
132
|
+
- lib/sdn/message/helpers.rb
|
133
|
+
- lib/sdn/message/ilt2/get.rb
|
134
|
+
- lib/sdn/message/ilt2/master_control.rb
|
135
|
+
- lib/sdn/message/ilt2/post.rb
|
136
|
+
- lib/sdn/message/ilt2/set.rb
|
137
|
+
- lib/sdn/message/post.rb
|
138
|
+
- lib/sdn/message/set.rb
|
102
139
|
- lib/sdn/version.rb
|
103
140
|
- lib/somfy_sdn.rb
|
104
141
|
homepage: https://github.com/ccutrer/somfy_sdn
|
105
142
|
licenses:
|
106
143
|
- MIT
|
107
144
|
metadata: {}
|
108
|
-
post_install_message:
|
145
|
+
post_install_message:
|
109
146
|
rdoc_options: []
|
110
147
|
require_paths:
|
111
148
|
- lib
|
@@ -120,8 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
157
|
- !ruby/object:Gem::Version
|
121
158
|
version: '0'
|
122
159
|
requirements: []
|
123
|
-
rubygems_version: 3.1.
|
124
|
-
signing_key:
|
160
|
+
rubygems_version: 3.1.2
|
161
|
+
signing_key:
|
125
162
|
specification_version: 4
|
126
163
|
summary: Library for communication with Somfy SDN RS-485 motorized shades
|
127
164
|
test_files: []
|
data/bin/sdn_mqtt_bridge
DELETED