somfy_sdn 2.1.5 → 2.2.0
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/exe/somfy_sdn +69 -0
- data/lib/sdn/cli/mqtt/group.rb +12 -10
- data/lib/sdn/cli/mqtt/motor.rb +19 -14
- data/lib/sdn/cli/mqtt/p_queue.rb +18 -0
- data/lib/sdn/cli/mqtt/read.rb +125 -126
- data/lib/sdn/cli/mqtt/subscriptions.rb +186 -140
- data/lib/sdn/cli/mqtt/write.rb +39 -34
- data/lib/sdn/cli/mqtt.rb +84 -53
- data/lib/sdn/cli/provisioner.rb +56 -33
- data/lib/sdn/cli/simulator.rb +99 -65
- data/lib/sdn/client.rb +38 -24
- data/lib/sdn/message/control.rb +60 -30
- data/lib/sdn/message/get.rb +6 -2
- data/lib/sdn/message/helpers.rb +23 -22
- data/lib/sdn/message/ilt2/get.rb +6 -3
- data/lib/sdn/message/ilt2/master_control.rb +10 -7
- data/lib/sdn/message/ilt2/post.rb +7 -5
- data/lib/sdn/message/ilt2/set.rb +28 -19
- data/lib/sdn/message/post.rb +3 -5
- data/lib/sdn/message/set.rb +48 -22
- data/lib/sdn/message.rb +50 -34
- data/lib/sdn/version.rb +3 -1
- data/lib/sdn.rb +18 -12
- data/lib/somfy_sdn.rb +3 -1
- metadata +43 -13
- data/bin/somfy_sdn +0 -60
data/lib/sdn/cli/simulator.rb
CHANGED
@@ -1,8 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SDN
|
2
4
|
module CLI
|
3
5
|
class Simulator
|
4
6
|
class MockMotor
|
5
|
-
attr_accessor :address,
|
7
|
+
attr_accessor :address,
|
8
|
+
:node_type,
|
9
|
+
:label,
|
10
|
+
:ips,
|
11
|
+
:position_pulses,
|
12
|
+
:up_limit,
|
13
|
+
:down_limit,
|
14
|
+
:groups,
|
15
|
+
:network_lock_priority,
|
16
|
+
:lock_priority,
|
17
|
+
:ir_channels
|
18
|
+
|
19
|
+
ALLOWED_MOVE_TYPES = %i[up_limit
|
20
|
+
down_limit
|
21
|
+
ip
|
22
|
+
position_pulses
|
23
|
+
position_percent].freeze
|
6
24
|
|
7
25
|
def initialize(client)
|
8
26
|
@client = client
|
@@ -20,56 +38,67 @@ module SDN
|
|
20
38
|
@client.receive do |message|
|
21
39
|
SDN.logger.info "Received #{message.inspect}"
|
22
40
|
next unless message.is_a?(Message::ILT2::MasterControl) ||
|
23
|
-
|
24
|
-
|
25
|
-
|
41
|
+
message.dest == address ||
|
42
|
+
message.dest == BROADCAST_ADDRESS
|
43
|
+
|
26
44
|
case message
|
27
45
|
when Message::GetGroupAddr
|
28
|
-
next nack(message) unless (1..16).
|
46
|
+
next nack(message) unless (1..16).cover?(message.group_index)
|
47
|
+
|
29
48
|
respond(message.src, Message::PostGroupAddr.new(message.group_index, groups[message.group_index - 1]))
|
30
49
|
when Message::GetMotorIP
|
31
|
-
next nack(message) unless (1..16).
|
32
|
-
|
50
|
+
next nack(message) unless (1..16).cover?(message.ip)
|
51
|
+
|
52
|
+
respond(message.src,
|
53
|
+
Message::PostMotorIP.new(message.ip, ips[message.ip - 1], to_percent(ips[message.ip - 1])))
|
33
54
|
when Message::GetMotorLimits
|
34
55
|
respond(message.src, Message::PostMotorLimits.new(up_limit, down_limit))
|
35
56
|
when Message::GetMotorPosition
|
36
57
|
respond(message.src, Message::PostMotorPosition.new(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
when Message::GetNodeAddr
|
42
|
-
when Message::GetNodeLabel
|
43
|
-
when Message::ILT2::GetIRConfig
|
44
|
-
when Message::ILT2::GetLockStatus
|
45
|
-
|
46
|
-
when Message::ILT2::
|
47
|
-
|
48
|
-
when Message::ILT2::
|
49
|
-
|
58
|
+
position_pulses,
|
59
|
+
to_percent(position_pulses),
|
60
|
+
ips.index(position_pulses)&.+(1)
|
61
|
+
))
|
62
|
+
when Message::GetNodeAddr then respond(message.src, Message::PostNodeAddr.new)
|
63
|
+
when Message::GetNodeLabel then respond(message.src, Message::PostNodeLabel.new(label))
|
64
|
+
when Message::ILT2::GetIRConfig then respond(message.src, Message::ILT2::PostIRConfig.new(ir_channels))
|
65
|
+
when Message::ILT2::GetLockStatus then respond(message.src,
|
66
|
+
Message::ILT2::PostLockStatus.new(lock_priority))
|
67
|
+
when Message::ILT2::GetMotorIP
|
68
|
+
respond(message.src, Message::ILT2::PostMotorIP.new(message.ip, ips[message.ip - 1]))
|
69
|
+
when Message::ILT2::GetMotorPosition
|
70
|
+
respond(message.src, Message::ILT2::PostMotorPosition.new(position_pulses, to_percent(position_pulses)))
|
71
|
+
when Message::ILT2::GetMotorSettings
|
72
|
+
respond(message.src, Message::ILT2::PostMotorSettings.new(down_limit))
|
73
|
+
when Message::ILT2::SetIRConfig then self.ir_channels = message.channels
|
74
|
+
when Message::ILT2::SetLockStatus then self.lock_priority = message.priority
|
50
75
|
when Message::ILT2::SetMotorIP
|
51
|
-
next nack(message) unless (1..16).
|
76
|
+
next nack(message) unless (1..16).cover?(message.ip)
|
77
|
+
|
52
78
|
ips[message.ip - 1] = message.value
|
53
79
|
ack(message)
|
54
80
|
when Message::ILT2::SetMotorPosition
|
55
81
|
next nack(message) unless down_limit
|
56
82
|
|
57
83
|
self.position_pulses = case message.target_type
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
84
|
+
when :up_limit then 0
|
85
|
+
when :down_limit then down_limit
|
86
|
+
when :ip
|
87
|
+
next nack(message) unless (1..16).cover?(message.target)
|
88
|
+
next nack(message) unless ips[message.target]
|
89
|
+
|
90
|
+
ips[message.target]
|
91
|
+
when :position_pulses
|
92
|
+
next nack(message) if message.target - 1 > down_limit
|
93
|
+
|
94
|
+
message.target - 1
|
95
|
+
when :jog_up_pulses then [0, position_pulses - message.target].max
|
96
|
+
when :jog_down_pulses then [down_limit, position_pulses + message.target].min
|
97
|
+
when :position_percent
|
98
|
+
next nack(message) if message.target > 100
|
99
|
+
|
100
|
+
to_pulses(message.target.to_f)
|
101
|
+
end
|
73
102
|
ack(message)
|
74
103
|
when Message::ILT2::SetMotorSettings
|
75
104
|
if message.down_limit != 0
|
@@ -78,29 +107,33 @@ module SDN
|
|
78
107
|
end
|
79
108
|
when Message::MoveTo
|
80
109
|
next nack(message) unless down_limit
|
81
|
-
next nack(message) unless
|
82
|
-
|
110
|
+
next nack(message) unless ALLOWED_MOVE_TYPES.include?(message.target_type)
|
111
|
+
|
83
112
|
self.position_pulses = case message.target_type
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
113
|
+
when :up_limit then 0
|
114
|
+
when :down_limit then down_limit
|
115
|
+
when :ip
|
116
|
+
next nack(message) unless (1..16).cover?(message.target)
|
117
|
+
next nack(message) unless ips[message.target - 1]
|
118
|
+
|
119
|
+
ips[message.target - 1]
|
120
|
+
when :position_pulses
|
121
|
+
next nack(message) if message.target > down_limit
|
122
|
+
|
123
|
+
message.target
|
124
|
+
when :position_percent
|
125
|
+
next nack(message) if message.target > 100
|
126
|
+
|
127
|
+
to_pulses(message.target)
|
128
|
+
end
|
97
129
|
ack(message)
|
98
130
|
when Message::SetGroupAddr
|
99
|
-
next nack(message) unless (1..16).
|
100
|
-
|
131
|
+
next nack(message) unless (1..16).cover?(message.group_index)
|
132
|
+
|
133
|
+
groups[message.group_index - 1] = (message.group_address == [0, 0, 0]) ? nil : message.group_address
|
101
134
|
ack(message)
|
102
135
|
when Message::SetMotorIP
|
103
|
-
next nack(message) unless (1..16).
|
136
|
+
next nack(message) unless (1..16).cover?(message.ip) || message.type == :distribute
|
104
137
|
|
105
138
|
case message.type
|
106
139
|
when :delete
|
@@ -122,7 +155,8 @@ module SDN
|
|
122
155
|
end
|
123
156
|
when :distribute
|
124
157
|
next nack(message) unless down_limit
|
125
|
-
next nack(message) unless (1..15).
|
158
|
+
next nack(message) unless (1..15).cover?(message.value)
|
159
|
+
|
126
160
|
span = down_limit / (message.value + 1)
|
127
161
|
current = 0
|
128
162
|
(0...message.value).each do |ip|
|
@@ -134,8 +168,8 @@ module SDN
|
|
134
168
|
ack(message)
|
135
169
|
end
|
136
170
|
when Message::SetMotorLimits
|
137
|
-
next nack(message) unless
|
138
|
-
next nack(message) unless
|
171
|
+
next nack(message) unless Message::SetMotorLimits::TARGET.key?(message.target)
|
172
|
+
next nack(message) unless message.type == :jog_pulses
|
139
173
|
|
140
174
|
self.up_limit ||= 0
|
141
175
|
self.down_limit ||= 0
|
@@ -150,27 +184,30 @@ module SDN
|
|
150
184
|
self.position_pulses += message.value if message.target == :down
|
151
185
|
end
|
152
186
|
ack(message)
|
153
|
-
when Message::SetNodeLabel
|
187
|
+
when Message::SetNodeLabel then self.label = message.label
|
188
|
+
ack(message)
|
154
189
|
end
|
155
190
|
end
|
156
191
|
end
|
157
192
|
end
|
158
193
|
|
159
194
|
def to_percent(pulses)
|
160
|
-
pulses && down_limit ? 100.0 * pulses / down_limit : nil
|
195
|
+
(pulses && down_limit) ? 100.0 * pulses / down_limit : nil
|
161
196
|
end
|
162
197
|
|
163
198
|
def to_pulses(percent)
|
164
|
-
percent && down_limit ? down_limit * percent / 100 : nil
|
199
|
+
(percent && down_limit) ? down_limit * percent / 100 : nil
|
165
200
|
end
|
166
201
|
|
167
202
|
def ack(message)
|
168
203
|
return unless message.ack_requested
|
204
|
+
|
169
205
|
respond(Message::Ack.new(message.dest))
|
170
206
|
end
|
171
207
|
|
172
|
-
def nack(message,
|
208
|
+
def nack(message, _error_code = nil)
|
173
209
|
return unless message.ack_requested
|
210
|
+
|
174
211
|
respond(Message::Nack.new(message.dest))
|
175
212
|
end
|
176
213
|
|
@@ -178,14 +215,11 @@ module SDN
|
|
178
215
|
message.src = address
|
179
216
|
message.node_type = node_type
|
180
217
|
message.dest = dest
|
181
|
-
SDN.logger.info "Sending #{message.inspect}"
|
182
218
|
@client.send(message)
|
183
219
|
end
|
184
220
|
end
|
185
221
|
|
186
|
-
def initialize(
|
187
|
-
sdn = Client.new(port)
|
188
|
-
|
222
|
+
def initialize(sdn, address = nil)
|
189
223
|
motor = MockMotor.new(sdn)
|
190
224
|
motor.address = Message.parse_address(address) if address
|
191
225
|
motor.node_type = :lt50
|
data/lib/sdn/client.rb
CHANGED
@@ -1,33 +1,42 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "io/wait"
|
2
4
|
|
3
5
|
module SDN
|
4
6
|
class Client
|
7
|
+
attr_writer :trace
|
8
|
+
|
5
9
|
def initialize(port)
|
6
10
|
uri = URI.parse(port)
|
7
11
|
@io = if uri.scheme == "tcp"
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@buffer = ""
|
12
|
+
require "socket"
|
13
|
+
TCPSocket.new(uri.host, uri.port)
|
14
|
+
elsif uri.scheme == "telnet" || uri.scheme == "rfc2217"
|
15
|
+
require "net/telnet/rfc2217"
|
16
|
+
Net::Telnet::RFC2217.new(host: uri.host,
|
17
|
+
port: uri.port || 23,
|
18
|
+
baud: 4800,
|
19
|
+
data_bits: 8,
|
20
|
+
parity: :odd,
|
21
|
+
stop_bits: 1)
|
22
|
+
elsif port == "/dev/ptmx"
|
23
|
+
require "pty"
|
24
|
+
io, slave = PTY.open
|
25
|
+
puts "Slave PTY available at #{slave.path}"
|
26
|
+
io
|
27
|
+
else
|
28
|
+
require "ccutrer-serialport"
|
29
|
+
CCutrer::SerialPort.new(port, baud: 4800, data_bits: 8, parity: :odd, stop_bits: 1)
|
30
|
+
end
|
31
|
+
@buffer = +""
|
32
|
+
end
|
33
|
+
|
34
|
+
def trace?
|
35
|
+
@trace
|
28
36
|
end
|
29
37
|
|
30
38
|
def send(message)
|
39
|
+
SDN.logger.debug("Sending #{message.inspect}")
|
31
40
|
@io.write(message.serialize)
|
32
41
|
end
|
33
42
|
|
@@ -42,6 +51,7 @@ module SDN
|
|
42
51
|
messages = transact(message)
|
43
52
|
next if messages.empty?
|
44
53
|
next unless message.class.expected_response?(messages.first)
|
54
|
+
|
45
55
|
return messages.first
|
46
56
|
end
|
47
57
|
end
|
@@ -63,7 +73,7 @@ module SDN
|
|
63
73
|
eofs = 0
|
64
74
|
begin
|
65
75
|
block = @io.read_nonblock(64 * 1024)
|
66
|
-
SDN.logger.debug
|
76
|
+
SDN.logger.debug("Read #{block.unpack1("H*").gsub(/\h{2}/, "\\0 ")}") if trace?
|
67
77
|
@buffer.concat(block)
|
68
78
|
next
|
69
79
|
rescue IO::WaitReadable, EOFError => e
|
@@ -77,8 +87,10 @@ module SDN
|
|
77
87
|
wait = @buffer.empty? ? timeout : WAIT_TIME
|
78
88
|
if @io.wait_readable(wait).nil?
|
79
89
|
# timed out; just discard everything
|
80
|
-
|
81
|
-
|
90
|
+
unless @buffer.empty?
|
91
|
+
SDN.logger.debug "Discarding #{@buffer.unpack1("H*").gsub(/\h{2}/, "\\0 ")} due to timeout"
|
92
|
+
end
|
93
|
+
@buffer = +""
|
82
94
|
return messages if timeout
|
83
95
|
end
|
84
96
|
|
@@ -86,6 +98,8 @@ module SDN
|
|
86
98
|
end
|
87
99
|
next
|
88
100
|
end
|
101
|
+
|
102
|
+
SDN.logger.debug("Received message #{message.inspect}")
|
89
103
|
if block_given?
|
90
104
|
yield message
|
91
105
|
else
|
data/lib/sdn/message/control.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SDN
|
2
4
|
class Message
|
3
5
|
class Lock < Message
|
4
6
|
MSG = 0x06
|
5
7
|
PARAMS_LENGTH = 5
|
6
|
-
TARGET_TYPE = { current: 0, up_limit: 1, down_limit: 2, ip: 4, unlock: 5, position_percent: 7 }
|
8
|
+
TARGET_TYPE = { current: 0, up_limit: 1, down_limit: 2, ip: 4, unlock: 5, position_percent: 7 }.freeze
|
7
9
|
|
8
10
|
attr_reader :target_type, :target, :priority
|
9
11
|
|
@@ -16,12 +18,16 @@ module SDN
|
|
16
18
|
end
|
17
19
|
|
18
20
|
def target_type=(value)
|
19
|
-
|
21
|
+
unless TARGET_TYPE.key?(value)
|
22
|
+
raise ArgumentError,
|
23
|
+
"target_type must be one of :current, :up_limit, :down_limit, :ip, :unlock, or :position_percent"
|
24
|
+
end
|
25
|
+
|
20
26
|
@target_type = value
|
21
27
|
end
|
22
28
|
|
23
29
|
def target=(value)
|
24
|
-
@target = value
|
30
|
+
@target = value&.& 0xffff
|
25
31
|
end
|
26
32
|
|
27
33
|
def priority=(value)
|
@@ -37,7 +43,8 @@ module SDN
|
|
37
43
|
end
|
38
44
|
|
39
45
|
def params
|
40
|
-
transform_param(TARGET_TYPE[target_type]) + from_number(target,
|
46
|
+
transform_param(TARGET_TYPE[target_type]) + from_number(target,
|
47
|
+
2) + transform_param(priority) + transform_param(0)
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
@@ -56,29 +63,38 @@ module SDN
|
|
56
63
|
self.direction = direction
|
57
64
|
self.duration = duration
|
58
65
|
self.speed = speed
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse(params)
|
69
|
+
super
|
70
|
+
self.direction = DIRECTION.invert[to_number(params[0])]
|
71
|
+
duration = to_number(params[1])
|
72
|
+
duration = nil if duration.zero?
|
73
|
+
self.duration = duration
|
74
|
+
self.speed = SPEED.invert[to_number(params[3])]
|
75
|
+
end
|
76
|
+
|
77
|
+
def direction=(value)
|
78
|
+
unless DIRECTION.key?(value)
|
79
|
+
raise ArgumentError,
|
80
|
+
"direction must be one of :down, :up, or :cancel (#{value})"
|
81
|
+
end
|
82
|
+
|
72
83
|
@direction = value
|
73
|
-
|
84
|
+
end
|
85
|
+
|
86
|
+
def duration=(value)
|
87
|
+
if value && (value < 0x0a || value > 0xff)
|
88
|
+
raise ArgumentError,
|
89
|
+
"duration must be in range 0x0a to 0xff (#{value})"
|
90
|
+
end
|
74
91
|
|
75
|
-
def duration=(value)
|
76
|
-
raise ArgumentError, "duration must be in range 0x0a to 0xff (#{value})" if value && (value < 0x0a || value > 0xff)
|
77
92
|
@duration = value
|
78
|
-
|
93
|
+
end
|
94
|
+
|
95
|
+
def speed=(value)
|
96
|
+
raise ArgumentError, "speed must be one of :up, :down, or :slow (#{value})" unless SPEED.key?(value)
|
79
97
|
|
80
|
-
def speed=(value)
|
81
|
-
raise ArgumentError, "speed must be one of :up, :down, or :slow (#{value})" unless SPEED.keys.include?(value)
|
82
98
|
@speed = speed
|
83
99
|
end
|
84
100
|
|
@@ -93,7 +109,12 @@ module SDN
|
|
93
109
|
class MoveOf < Message
|
94
110
|
MSG = 0x04
|
95
111
|
PARAMS_LENGTH = 4
|
96
|
-
TARGET_TYPE = { next_ip: 0x00,
|
112
|
+
TARGET_TYPE = { next_ip: 0x00,
|
113
|
+
previous_ip: 0x01,
|
114
|
+
jog_down_pulses: 0x02,
|
115
|
+
jog_up_pulses: 0x03,
|
116
|
+
jog_down_ms: 0x04,
|
117
|
+
jog_up_ms: 0x05 }.freeze
|
97
118
|
|
98
119
|
attr_reader :target_type, :target
|
99
120
|
|
@@ -108,12 +129,16 @@ module SDN
|
|
108
129
|
super
|
109
130
|
self.target_type = TARGET_TYPE.invert[to_number(params[0])]
|
110
131
|
target = to_number(params[1..2], nillable: true)
|
111
|
-
target *= 10 if %I
|
132
|
+
target *= 10 if %I[jog_down_ms jog_up_ms].include?(target_type)
|
112
133
|
self.target = target
|
113
134
|
end
|
114
135
|
|
115
136
|
def target_type=(value)
|
116
|
-
|
137
|
+
unless value.nil? || TARGET_TYPE.key?(value)
|
138
|
+
raise ArgumentError, "target_type must be one of :next_ip, :previous_ip, " \
|
139
|
+
":jog_down_pulses, :jog_up_pulses, :jog_down_ms, :jog_up_ms"
|
140
|
+
end
|
141
|
+
|
117
142
|
@target_type = value
|
118
143
|
end
|
119
144
|
|
@@ -124,7 +149,7 @@ module SDN
|
|
124
149
|
|
125
150
|
def params
|
126
151
|
param = target || 0xffff
|
127
|
-
param /= 10 if %I
|
152
|
+
param /= 10 if %I[jog_down_ms jog_up_ms].include?(target_type)
|
128
153
|
transform_param(TARGET_TYPE[target_type]) + from_number(param, 2) + transform_param(0)
|
129
154
|
end
|
130
155
|
end
|
@@ -138,7 +163,7 @@ module SDN
|
|
138
163
|
|
139
164
|
attr_reader :target_type, :target, :speed
|
140
165
|
|
141
|
-
def initialize(dest= nil, target_type = :down_limit, target = nil, speed = :up, **kwargs)
|
166
|
+
def initialize(dest = nil, target_type = :down_limit, target = nil, speed = :up, **kwargs)
|
142
167
|
kwargs[:dest] ||= dest
|
143
168
|
super(**kwargs)
|
144
169
|
self.target_type = target_type
|
@@ -154,7 +179,11 @@ module SDN
|
|
154
179
|
end
|
155
180
|
|
156
181
|
def target_type=(value)
|
157
|
-
|
182
|
+
unless TARGET_TYPE.key?(value)
|
183
|
+
raise ArgumentError,
|
184
|
+
"target_type must be one of :down_limit, :up_limit, :ip, :position_pulses, or :position_percent"
|
185
|
+
end
|
186
|
+
|
158
187
|
@target_type = value
|
159
188
|
end
|
160
189
|
|
@@ -164,7 +193,8 @@ module SDN
|
|
164
193
|
end
|
165
194
|
|
166
195
|
def speed=(value)
|
167
|
-
raise ArgumentError, "speed must be one of :up, :down, or :slow" unless SPEED.
|
196
|
+
raise ArgumentError, "speed must be one of :up, :down, or :slow" unless SPEED.key?(value)
|
197
|
+
|
168
198
|
@speed = value
|
169
199
|
end
|
170
200
|
|
data/lib/sdn/message/get.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SDN
|
2
4
|
class Message
|
3
5
|
class GetGroupAddr < Message
|
@@ -18,7 +20,8 @@ module SDN
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def group_index=(value)
|
21
|
-
raise ArgumentError, "group_index is out of range" unless (1..16).
|
23
|
+
raise ArgumentError, "group_index is out of range" unless (1..16).cover?(value)
|
24
|
+
|
22
25
|
@group_index = value
|
23
26
|
end
|
24
27
|
|
@@ -49,7 +52,8 @@ module SDN
|
|
49
52
|
end
|
50
53
|
|
51
54
|
def ip=(value)
|
52
|
-
raise ArgumentError, "invalid IP #{value} (should be 1-16)" unless (1..16).
|
55
|
+
raise ArgumentError, "invalid IP #{value} (should be 1-16)" unless (1..16).cover?(value)
|
56
|
+
|
53
57
|
@ip = value
|
54
58
|
end
|
55
59
|
|
data/lib/sdn/message/helpers.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SDN
|
2
4
|
class Message
|
3
5
|
module Helpers
|
@@ -6,39 +8,39 @@ module SDN
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def print_address(addr_bytes)
|
9
|
-
"%02X.%02X.%02X"
|
11
|
+
format("%02X.%02X.%02X", *addr_bytes)
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
14
|
+
def group_address?(addr_bytes)
|
13
15
|
addr_bytes[0..1] == [1, 1]
|
14
16
|
end
|
15
17
|
|
16
18
|
def node_type_from_number(number)
|
17
19
|
case number
|
18
|
-
when 1
|
19
|
-
when 2
|
20
|
-
when 6
|
21
|
-
when 7
|
22
|
-
when 8
|
23
|
-
when 0x70
|
20
|
+
when 1 then :st50ilt2
|
21
|
+
when 2 then :st30
|
22
|
+
when 6 then :glydea
|
23
|
+
when 7 then :st50ac
|
24
|
+
when 8 then :st50dc
|
25
|
+
when 0x70 then :lt50
|
24
26
|
else; number
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
30
|
def node_type_to_number(type)
|
29
31
|
case type
|
30
|
-
when :st50ilt2
|
31
|
-
when :st30
|
32
|
-
when :glydea
|
33
|
-
when :st50ac
|
34
|
-
when :st50dc
|
35
|
-
when :lt50
|
32
|
+
when :st50ilt2 then 1
|
33
|
+
when :st30 then 2
|
34
|
+
when :glydea then 6
|
35
|
+
when :st50ac then 7
|
36
|
+
when :st50dc then 8
|
37
|
+
when :lt50 then 0x70
|
36
38
|
else; type
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
40
42
|
def node_type_to_string(type)
|
41
|
-
type.is_a?(Integer) ? "%02xh"
|
43
|
+
type.is_a?(Integer) ? format("%02xh", type) : type.inspect
|
42
44
|
end
|
43
45
|
|
44
46
|
def transform_param(param)
|
@@ -52,28 +54,27 @@ module SDN
|
|
52
54
|
end
|
53
55
|
|
54
56
|
def from_number(number, bytes = 1)
|
55
|
-
number ||= 1
|
57
|
+
number ||= (1**(bytes * 8)) - 1
|
56
58
|
number = number.to_i
|
57
|
-
bytes.times.
|
58
|
-
res << (0xff - number & 0xff)
|
59
|
+
bytes.times.each_with_object([]) do |_, res|
|
60
|
+
res << ((0xff - number) & 0xff)
|
59
61
|
number >>= 8
|
60
|
-
res
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
64
65
|
def to_string(param)
|
65
66
|
chars = param.map { |b| 0xff - b }
|
66
|
-
chars.pack("C*").sub(/\0+$/,
|
67
|
+
chars.pack("C*").sub(/\0+$/, "").strip
|
67
68
|
end
|
68
69
|
|
69
70
|
def from_string(string, bytes)
|
70
71
|
chars = string.bytes
|
71
|
-
chars = chars[0...bytes].fill(
|
72
|
+
chars = chars[0...bytes].fill(" ".ord, chars.length, bytes - chars.length)
|
72
73
|
chars.map { |b| 0xff - b }
|
73
74
|
end
|
74
75
|
|
75
76
|
def checksum(bytes)
|
76
|
-
result = bytes.
|
77
|
+
result = bytes.sum
|
77
78
|
[result >> 8, result & 0xff]
|
78
79
|
end
|
79
80
|
end
|
data/lib/sdn/message/ilt2/get.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SDN
|
2
4
|
class Message
|
3
5
|
module ILT2
|
@@ -22,15 +24,16 @@ module SDN
|
|
22
24
|
end
|
23
25
|
|
24
26
|
def ip=(value)
|
25
|
-
raise ArgumentError, "invalid IP #{value} (should be 1-16)" unless (1..16).
|
27
|
+
raise ArgumentError, "invalid IP #{value} (should be 1-16)" unless (1..16).cover?(value)
|
28
|
+
|
26
29
|
@ip = value
|
27
30
|
end
|
28
|
-
|
31
|
+
|
29
32
|
def parse(params)
|
30
33
|
super
|
31
34
|
self.ip = to_number(params[0]) + 1
|
32
35
|
end
|
33
|
-
|
36
|
+
|
34
37
|
def params
|
35
38
|
transform_param(@ip - 1)
|
36
39
|
end
|