lifx-lan 0.1.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 +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/.yardopts +3 -0
- data/CHANGES.md +45 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +23 -0
- data/README.md +15 -0
- data/Rakefile +20 -0
- data/bin/lifx-snoop +50 -0
- data/examples/auto-off/auto-off.rb +34 -0
- data/examples/blink/blink.rb +19 -0
- data/examples/identify/identify.rb +69 -0
- data/examples/travis-build-light/build-light.rb +57 -0
- data/lib/bindata_ext/bool.rb +30 -0
- data/lib/bindata_ext/record.rb +11 -0
- data/lib/lifx-lan.rb +27 -0
- data/lib/lifx/lan/client.rb +149 -0
- data/lib/lifx/lan/color.rb +199 -0
- data/lib/lifx/lan/config.rb +17 -0
- data/lib/lifx/lan/firmware.rb +60 -0
- data/lib/lifx/lan/gateway_connection.rb +185 -0
- data/lib/lifx/lan/light.rb +440 -0
- data/lib/lifx/lan/light_collection.rb +111 -0
- data/lib/lifx/lan/light_target.rb +185 -0
- data/lib/lifx/lan/logging.rb +14 -0
- data/lib/lifx/lan/message.rb +168 -0
- data/lib/lifx/lan/network_context.rb +188 -0
- data/lib/lifx/lan/observable.rb +66 -0
- data/lib/lifx/lan/protocol/address.rb +25 -0
- data/lib/lifx/lan/protocol/device.rb +387 -0
- data/lib/lifx/lan/protocol/header.rb +24 -0
- data/lib/lifx/lan/protocol/light.rb +142 -0
- data/lib/lifx/lan/protocol/message.rb +19 -0
- data/lib/lifx/lan/protocol/metadata.rb +23 -0
- data/lib/lifx/lan/protocol/payload.rb +12 -0
- data/lib/lifx/lan/protocol/sensor.rb +31 -0
- data/lib/lifx/lan/protocol/type.rb +204 -0
- data/lib/lifx/lan/protocol/wan.rb +51 -0
- data/lib/lifx/lan/protocol/wifi.rb +102 -0
- data/lib/lifx/lan/protocol_path.rb +85 -0
- data/lib/lifx/lan/required_keyword_arguments.rb +12 -0
- data/lib/lifx/lan/routing_manager.rb +114 -0
- data/lib/lifx/lan/routing_table.rb +48 -0
- data/lib/lifx/lan/seen.rb +25 -0
- data/lib/lifx/lan/site.rb +97 -0
- data/lib/lifx/lan/tag_manager.rb +111 -0
- data/lib/lifx/lan/tag_table.rb +49 -0
- data/lib/lifx/lan/target.rb +24 -0
- data/lib/lifx/lan/thread.rb +13 -0
- data/lib/lifx/lan/timers.rb +29 -0
- data/lib/lifx/lan/transport.rb +46 -0
- data/lib/lifx/lan/transport/tcp.rb +91 -0
- data/lib/lifx/lan/transport/udp.rb +87 -0
- data/lib/lifx/lan/transport_manager.rb +43 -0
- data/lib/lifx/lan/transport_manager/lan.rb +169 -0
- data/lib/lifx/lan/utilities.rb +36 -0
- data/lib/lifx/lan/version.rb +5 -0
- data/lifx-lan.gemspec +26 -0
- data/spec/color_spec.rb +43 -0
- data/spec/gateway_connection_spec.rb +30 -0
- data/spec/integration/client_spec.rb +42 -0
- data/spec/integration/light_spec.rb +56 -0
- data/spec/integration/tags_spec.rb +42 -0
- data/spec/light_collection_spec.rb +37 -0
- data/spec/message_spec.rb +183 -0
- data/spec/protocol_path_spec.rb +109 -0
- data/spec/routing_manager_spec.rb +25 -0
- data/spec/routing_table_spec.rb +23 -0
- data/spec/spec_helper.rb +56 -0
- data/spec/transport/udp_spec.rb +44 -0
- data/spec/transport_spec.rb +14 -0
- metadata +187 -0
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'lifx/lan/timers'
|
2
|
+
require 'lifx/lan/transport_manager'
|
3
|
+
require 'lifx/lan/routing_manager'
|
4
|
+
require 'lifx/lan/tag_manager'
|
5
|
+
require 'lifx/lan/light'
|
6
|
+
require 'lifx/lan/protocol_path'
|
7
|
+
require 'lifx/lan/timers'
|
8
|
+
|
9
|
+
require 'weakref'
|
10
|
+
|
11
|
+
module LIFX
|
12
|
+
module LAN
|
13
|
+
class NetworkContext
|
14
|
+
include Logging
|
15
|
+
include Utilities
|
16
|
+
include RequiredKeywordArguments
|
17
|
+
include Timers
|
18
|
+
extend Forwardable
|
19
|
+
|
20
|
+
# NetworkContext stores lights and ties together TransportManager, TagManager and RoutingManager
|
21
|
+
attr_reader :transport_manager, :tag_manager, :routing_manager
|
22
|
+
|
23
|
+
def initialize(transport_manager: required!('transport_manager'))
|
24
|
+
@devices = {}
|
25
|
+
|
26
|
+
@transport_manager = transport_manager
|
27
|
+
@transport_manager.context = WeakRef.new(self)
|
28
|
+
@transport_manager.add_observer(self, :message_received) do |message: nil, ip: nil, transport: nil|
|
29
|
+
handle_message(message, ip, transport)
|
30
|
+
end
|
31
|
+
|
32
|
+
reset!
|
33
|
+
|
34
|
+
@threads = []
|
35
|
+
@threads << initialize_timer_thread
|
36
|
+
end
|
37
|
+
|
38
|
+
def discover
|
39
|
+
@transport_manager.discover
|
40
|
+
end
|
41
|
+
|
42
|
+
def refresh(force: true)
|
43
|
+
@routing_manager.refresh(force: force)
|
44
|
+
end
|
45
|
+
|
46
|
+
def reset!
|
47
|
+
@routing_manager = RoutingManager.new(context: self)
|
48
|
+
@tag_manager = TagManager.new(context: self, tag_table: @routing_manager.tag_table)
|
49
|
+
end
|
50
|
+
|
51
|
+
def stop_discovery
|
52
|
+
@transport_manager.stop_discovery
|
53
|
+
end
|
54
|
+
|
55
|
+
def stop
|
56
|
+
@transport_manager.stop
|
57
|
+
stop_timers
|
58
|
+
@threads.each do |thread|
|
59
|
+
thread.abort
|
60
|
+
thread.join
|
61
|
+
end
|
62
|
+
@threads = nil
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sends a message to their destination(s)
|
66
|
+
# @param target: [Target] Target of the message
|
67
|
+
# @param payload: [Protocol::Payload] Message payload
|
68
|
+
# @param acknowledge: [Boolean] If recipients must acknowledge with a response
|
69
|
+
# @param at_time: [Integer] Unix epoch in milliseconds to run the payload. Only applicable to certain payload types.
|
70
|
+
def send_message(target: required!(:target), payload: required!(:payload), acknowledge: false, at_time: nil)
|
71
|
+
paths = @routing_manager.resolve_target(target)
|
72
|
+
|
73
|
+
messages = paths.map do |path|
|
74
|
+
Message.new(path: path, payload: payload, acknowledge: acknowledge, at_time: at_time)
|
75
|
+
end
|
76
|
+
|
77
|
+
if within_sync?
|
78
|
+
Thread.current[:sync_messages].push(*messages)
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
messages.each do |message|
|
83
|
+
@transport_manager.write(message)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def within_sync?
|
88
|
+
!!Thread.current[:sync_enabled]
|
89
|
+
end
|
90
|
+
protected :within_sync?
|
91
|
+
|
92
|
+
# Synchronize asynchronous set_color, set_waveform and set_power messages to multiple devices.
|
93
|
+
# You cannot use synchronous methods in the block
|
94
|
+
# @note This is alpha
|
95
|
+
# @param delay: [Float] The delay to add to sync commands when dealing with latency.
|
96
|
+
# @yield Block to synchronize commands in
|
97
|
+
# @return [Float] Delay before messages are executed
|
98
|
+
NSEC_PER_SEC = 1_000_000_000
|
99
|
+
AT_TIME_DELTA = 0.002
|
100
|
+
def sync(delay: 0, &block)
|
101
|
+
if within_sync?
|
102
|
+
raise "You cannot nest sync"
|
103
|
+
end
|
104
|
+
messages = Thread.start do
|
105
|
+
Thread.current[:sync_enabled] = true
|
106
|
+
Thread.current[:sync_messages] = messages = []
|
107
|
+
block.call
|
108
|
+
Thread.current[:sync_enabled] = false
|
109
|
+
messages
|
110
|
+
end.join.value
|
111
|
+
|
112
|
+
time = nil
|
113
|
+
failed_lights = []
|
114
|
+
try_until -> { time }, timeout: 5, action_interval: 1 do
|
115
|
+
light = (lights.alive - failed_lights).sample
|
116
|
+
begin
|
117
|
+
time = light && light.send_message!(Protocol::Device::GetTime.new, wait_for: Protocol::Device::StateTime, wait_timeout: 1, retry_interval: 0.5) do |payload|
|
118
|
+
Time.at(payload.time.to_f / NSEC_PER_SEC)
|
119
|
+
end
|
120
|
+
rescue => ex
|
121
|
+
logger.debug("!!! Add light failed")
|
122
|
+
failed_lights << light
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
delay += (messages.count + 1) * (1.0 / @transport_manager.message_rate)
|
127
|
+
at_time = ((time.to_f + delay) * NSEC_PER_SEC).to_i
|
128
|
+
messages.each_with_index do |m, i|
|
129
|
+
m.at_time = at_time + (i * AT_TIME_DELTA * NSEC_PER_SEC).to_i
|
130
|
+
@transport_manager.write(m)
|
131
|
+
end
|
132
|
+
flush
|
133
|
+
delay
|
134
|
+
end
|
135
|
+
|
136
|
+
def flush(**options)
|
137
|
+
@transport_manager.flush(**options)
|
138
|
+
end
|
139
|
+
|
140
|
+
def register_device(device)
|
141
|
+
return if device.site_id == NULL_SITE_ID
|
142
|
+
device_id = device.id
|
143
|
+
@devices[device_id] = device # What happens when there's already one registered?
|
144
|
+
end
|
145
|
+
|
146
|
+
def lights
|
147
|
+
LightCollection.new(context: self)
|
148
|
+
end
|
149
|
+
|
150
|
+
def all_lights
|
151
|
+
@devices.values
|
152
|
+
end
|
153
|
+
|
154
|
+
# Tags
|
155
|
+
|
156
|
+
def_delegators :@tag_manager, :tags,
|
157
|
+
:unused_tags,
|
158
|
+
:purge_unused_tags!,
|
159
|
+
:add_tag_to_device,
|
160
|
+
:remove_tag_from_device
|
161
|
+
|
162
|
+
def tags_for_device(device)
|
163
|
+
@routing_manager.tags_for_device_id(device.id)
|
164
|
+
end
|
165
|
+
|
166
|
+
def to_s
|
167
|
+
%Q{#<LIFX::LAN::NetworkContext transport_manager=#{transport_manager}>}
|
168
|
+
end
|
169
|
+
alias_method :inspect, :to_s
|
170
|
+
|
171
|
+
protected
|
172
|
+
|
173
|
+
def handle_message(message, ip, transport)
|
174
|
+
logger.debug("<- #{self} #{transport}: #{message}")
|
175
|
+
|
176
|
+
@routing_manager.update_from_message(message)
|
177
|
+
if !message.tagged?
|
178
|
+
if @devices[message.device_id].nil? && message.payload.is_a?(Protocol::Light::State)
|
179
|
+
device = Light.new(context: self, id: message.device_id, site_id: message.site_id)
|
180
|
+
end
|
181
|
+
device = @devices[message.device_id]
|
182
|
+
return if !device # Virgin bulb
|
183
|
+
device.handle_message(message, ip, transport)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module LIFX
|
2
|
+
module LAN
|
3
|
+
# @private
|
4
|
+
module Observable
|
5
|
+
class ObserverCallbackMismatch < ArgumentError; end
|
6
|
+
class ObserverCallbackNotFound < ArgumentError; end
|
7
|
+
|
8
|
+
def add_observer(obj, type, &callback)
|
9
|
+
if !callback_type_exists?(type)
|
10
|
+
raise ObserverCallbackNotFound.new("Callback #{type} not found in #{observer_callback_definition.keys}")
|
11
|
+
end
|
12
|
+
if !callback_has_required_keys?(type, callback)
|
13
|
+
raise ObserverCallbackMismatch.new
|
14
|
+
end
|
15
|
+
observers[type][obj] = callback
|
16
|
+
end
|
17
|
+
|
18
|
+
def remove_observer(obj, type)
|
19
|
+
observers[type].delete(obj)
|
20
|
+
end
|
21
|
+
|
22
|
+
def remove_observers
|
23
|
+
observers.clear
|
24
|
+
end
|
25
|
+
|
26
|
+
def notify_observers(type, **args)
|
27
|
+
if !callback_type_exists?(type)
|
28
|
+
raise ObserverCallbackNotFound.new("Callback #{type} not found in #{observer_callback_definition.keys}")
|
29
|
+
end
|
30
|
+
observers[type].each do |_, callback|
|
31
|
+
callback.call(**args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def callback_type_exists?(type)
|
36
|
+
!!observer_callback_definition[type]
|
37
|
+
end
|
38
|
+
|
39
|
+
def callback_has_required_keys?(type, callback)
|
40
|
+
(required_keys_for_callback(type) - required_keys_in_proc(callback)).empty?
|
41
|
+
end
|
42
|
+
|
43
|
+
def observer_callback_definition
|
44
|
+
{}
|
45
|
+
end
|
46
|
+
|
47
|
+
def required_keys_for_callback(type)
|
48
|
+
@_required_keys_for_callback ||= {}
|
49
|
+
@_required_keys_for_callback[type] ||= begin
|
50
|
+
return [] if !observer_callback_definition[type]
|
51
|
+
required_keys_in_proc(observer_callback_definition[type])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def required_keys_in_proc(proc)
|
56
|
+
proc.parameters.select do |type, _|
|
57
|
+
type == :keyreq
|
58
|
+
end.map(&:last)
|
59
|
+
end
|
60
|
+
|
61
|
+
def observers
|
62
|
+
@_observers ||= Hash.new { |h, k| h[k] = {} }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module LIFX
|
2
|
+
module LAN
|
3
|
+
module Protocol
|
4
|
+
module AddressFields
|
5
|
+
def AddressFields.included(mod)
|
6
|
+
mod.instance_eval do
|
7
|
+
hide :_reserved2
|
8
|
+
string :raw_target, length: 8
|
9
|
+
string :raw_site, length: 6 # Deprecated, should be zeros or "LIFXV2"
|
10
|
+
bit6le :_reserved2
|
11
|
+
bool_bit1 :acknowledge # Acknowledgement required
|
12
|
+
bool_bit1 :res_required # Response required
|
13
|
+
uint8 :sequence # Wrap around message sequence number
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Address < BinData::Record
|
19
|
+
endian :little
|
20
|
+
|
21
|
+
include AddressFields
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,387 @@
|
|
1
|
+
module LIFX
|
2
|
+
module LAN
|
3
|
+
module Protocol
|
4
|
+
# @api private
|
5
|
+
module Device
|
6
|
+
|
7
|
+
# Describes the services exposed by the device
|
8
|
+
module Service
|
9
|
+
UDP = 1 # Datagram transport on specified port
|
10
|
+
TCP = 2 # Reliable transport on specified port
|
11
|
+
ONBOARDING = 3 # Onboarding service on specified port
|
12
|
+
OTA = 4 # Active over-the-air update service on specified port. This is only exposed when the device is in active OTA mode with degraded service
|
13
|
+
end
|
14
|
+
|
15
|
+
# class SetSite < Payload
|
16
|
+
# endian :little
|
17
|
+
|
18
|
+
# string :site, length: 6
|
19
|
+
# end
|
20
|
+
|
21
|
+
|
22
|
+
# class GetPanGateway < Payload
|
23
|
+
# endian :little
|
24
|
+
|
25
|
+
# end
|
26
|
+
|
27
|
+
# class StatePanGateway < Payload
|
28
|
+
# endian :little
|
29
|
+
|
30
|
+
# uint8 :service
|
31
|
+
# uint32 :port
|
32
|
+
# end
|
33
|
+
|
34
|
+
# Discover devices and services exposed
|
35
|
+
class GetService < Payload
|
36
|
+
endian :little
|
37
|
+
end
|
38
|
+
|
39
|
+
# Response to GetService. Specifies service and port. Service temporarily unavailable if port is 0
|
40
|
+
class StateService < Payload
|
41
|
+
endian :little
|
42
|
+
|
43
|
+
uint8 :service # maps to Service enumerated type above
|
44
|
+
uint32 :port
|
45
|
+
end
|
46
|
+
|
47
|
+
# Gets device current time
|
48
|
+
class GetTime < Payload
|
49
|
+
endian :little
|
50
|
+
end
|
51
|
+
|
52
|
+
# Set the device time
|
53
|
+
class SetTime < Payload
|
54
|
+
endian :little
|
55
|
+
|
56
|
+
uint64 :time # Nanoseconds since epoch.
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the time at device when message was sent
|
60
|
+
class StateTime < Payload
|
61
|
+
endian :little
|
62
|
+
|
63
|
+
uint64 :time # Nanoseconds since epoch.
|
64
|
+
end
|
65
|
+
|
66
|
+
# class GetResetSwitch < Payload
|
67
|
+
# endian :little
|
68
|
+
|
69
|
+
# end
|
70
|
+
|
71
|
+
# class StateResetSwitch < Payload
|
72
|
+
# endian :little
|
73
|
+
|
74
|
+
# uint8 :position
|
75
|
+
# end
|
76
|
+
|
77
|
+
# class GetMeshInfo < Payload
|
78
|
+
# endian :little
|
79
|
+
|
80
|
+
# end
|
81
|
+
|
82
|
+
# class StateMeshInfo < Payload
|
83
|
+
# endian :little
|
84
|
+
|
85
|
+
# float :signal # Milliwatts.
|
86
|
+
# uint32 :tx # Bytes.
|
87
|
+
# uint32 :rx # Bytes.
|
88
|
+
# int16 :mcu_temperature # Deci-celsius. 25.45 celsius is 2545
|
89
|
+
# end
|
90
|
+
|
91
|
+
# class GetMeshFirmware < Payload
|
92
|
+
# endian :little
|
93
|
+
|
94
|
+
# end
|
95
|
+
|
96
|
+
# class StateMeshFirmware < Payload
|
97
|
+
# endian :little
|
98
|
+
|
99
|
+
# uint64 :build # Firmware build nanoseconds since epoch.
|
100
|
+
# uint64 :install # Firmware install nanoseconds since epoch.
|
101
|
+
# uint32 :version # Firmware human readable version.
|
102
|
+
# end
|
103
|
+
|
104
|
+
# Get Host MCU information
|
105
|
+
class GetHostInfo < Payload
|
106
|
+
endian :little
|
107
|
+
end
|
108
|
+
|
109
|
+
# Host MCU information
|
110
|
+
class StateHostInfo < Payload
|
111
|
+
endian :little
|
112
|
+
|
113
|
+
float :signal # radio receive signal strength in Milliwatts (mw)
|
114
|
+
uint32 :tx # bytes transmitted since power on
|
115
|
+
uint32 :rx # bytes received since power on
|
116
|
+
int16 :mcu_temperature # internal temperature (deci-celsius). 25.45 celsius is 2545
|
117
|
+
end
|
118
|
+
|
119
|
+
# Gets Host MCU firmware
|
120
|
+
class GetHostFirmware < Payload
|
121
|
+
endian :little
|
122
|
+
end
|
123
|
+
|
124
|
+
class StateHostFirmware < Payload
|
125
|
+
endian :little
|
126
|
+
|
127
|
+
uint64 :build # build time in nanonseconds since epoch
|
128
|
+
uint64 :install # install time, depricated
|
129
|
+
uint32 :version # firmware version
|
130
|
+
end
|
131
|
+
|
132
|
+
# Get Wifi subsystem information
|
133
|
+
class GetWifiInfo < Payload
|
134
|
+
endian :little
|
135
|
+
end
|
136
|
+
|
137
|
+
# Wifi subsystem information
|
138
|
+
class StateWifiInfo < Payload
|
139
|
+
endian :little
|
140
|
+
|
141
|
+
float :signal # radio receive signal strength in Milliwatts (mw)
|
142
|
+
uint32 :tx # bytes transmitted since power on
|
143
|
+
uint32 :rx # bytes received since power on
|
144
|
+
int16 :mcu_temperature # internal temperature (deci-celsius). 25.45 celsius is 2545
|
145
|
+
end
|
146
|
+
|
147
|
+
# Get Wifi subsystem firmware
|
148
|
+
class GetWifiFirmware < Payload
|
149
|
+
endian :little
|
150
|
+
end
|
151
|
+
|
152
|
+
class StateWifiFirmware < Payload
|
153
|
+
endian :little
|
154
|
+
|
155
|
+
uint64 :build # build time in nanonseconds since epoch
|
156
|
+
uint64 :install # install time, depricated
|
157
|
+
uint32 :version # firmware version
|
158
|
+
end
|
159
|
+
|
160
|
+
# Get device power level
|
161
|
+
class GetPower < Payload
|
162
|
+
endian :little
|
163
|
+
end
|
164
|
+
|
165
|
+
# Set device power level
|
166
|
+
class SetPower < Payload
|
167
|
+
endian :little
|
168
|
+
|
169
|
+
uint16 :level # Zero implies standby and non-zero sets a corresponding power draw level on device. Currently only 0 and 65535 are supported
|
170
|
+
end
|
171
|
+
|
172
|
+
# Device power level
|
173
|
+
class StatePower < Payload
|
174
|
+
endian :little
|
175
|
+
|
176
|
+
uint16 :level # 0 Standby. > 0 On.
|
177
|
+
end
|
178
|
+
|
179
|
+
# Introspect the device label. Returns StateLabel
|
180
|
+
class GetLabel < Payload
|
181
|
+
endian :little
|
182
|
+
end
|
183
|
+
|
184
|
+
# Set the device label text
|
185
|
+
class SetLabel < Payload
|
186
|
+
endian :little
|
187
|
+
|
188
|
+
string :label, length: 32, trim_padding: true
|
189
|
+
end
|
190
|
+
|
191
|
+
# Device label
|
192
|
+
class StateLabel < Payload
|
193
|
+
endian :little
|
194
|
+
|
195
|
+
string :label, length: 32, trim_padding: true
|
196
|
+
end
|
197
|
+
|
198
|
+
# Get the device tags. Returns StateTags
|
199
|
+
class GetTags < Payload
|
200
|
+
endian :little
|
201
|
+
end
|
202
|
+
|
203
|
+
# Set the device tags
|
204
|
+
class SetTags < Payload
|
205
|
+
endian :little
|
206
|
+
|
207
|
+
uint64 :tags # Bitfield, allows 64 tags. A device can be tagged with one or more of them
|
208
|
+
end
|
209
|
+
|
210
|
+
# Device tags
|
211
|
+
class StateTags < Payload
|
212
|
+
endian :little
|
213
|
+
|
214
|
+
uint64 :tags
|
215
|
+
end
|
216
|
+
|
217
|
+
# Get the text labels describing the tags. Returns StateTagLabels
|
218
|
+
class GetTagLabels < Payload
|
219
|
+
endian :little
|
220
|
+
|
221
|
+
uint64 :tags # Retrieve the labels for tags selected in the bitfield
|
222
|
+
end
|
223
|
+
|
224
|
+
# Sets the text label for the corresponding tags. Note you can label or reset multiple labels at the same time
|
225
|
+
class SetTagLabels < Payload
|
226
|
+
endian :little
|
227
|
+
|
228
|
+
uint64 :tags # Set labels for tags selected in the bitfield
|
229
|
+
string :label, length: 32, trim_padding: true
|
230
|
+
end
|
231
|
+
|
232
|
+
# The tag label for tags in the bitfield
|
233
|
+
class StateTagLabels < Payload
|
234
|
+
endian :little
|
235
|
+
|
236
|
+
uint64 :tags
|
237
|
+
string :label, length: 32, trim_padding: true
|
238
|
+
end
|
239
|
+
|
240
|
+
# Get the hardware version. Returns StateVersion
|
241
|
+
class GetVersion < Payload
|
242
|
+
endian :little
|
243
|
+
end
|
244
|
+
|
245
|
+
# The hardware version of the device
|
246
|
+
class StateVersion < Payload
|
247
|
+
endian :little
|
248
|
+
|
249
|
+
uint32 :vendor # Vendor ID
|
250
|
+
uint32 :product # Product ID
|
251
|
+
uint32 :version # Hardware version
|
252
|
+
end
|
253
|
+
|
254
|
+
# Get runtime information. Returns StateInfo
|
255
|
+
class GetInfo < Payload
|
256
|
+
endian :little
|
257
|
+
end
|
258
|
+
|
259
|
+
# Runtime information of device
|
260
|
+
class StateInfo < Payload
|
261
|
+
endian :little
|
262
|
+
|
263
|
+
uint64 :time # wallclock time on device, nanoseconds since epoch
|
264
|
+
uint64 :uptime # device uptime, nanoseconds since boot
|
265
|
+
uint64 :downtime # last measured downtime, accurate to 5s, nanoseconds off last power cycle
|
266
|
+
end
|
267
|
+
|
268
|
+
# class GetMcuRailVoltage < Payload
|
269
|
+
# endian :little
|
270
|
+
# end
|
271
|
+
|
272
|
+
# class StateMcuRailVoltage < Payload
|
273
|
+
# endian :little
|
274
|
+
|
275
|
+
# uint32 :voltage
|
276
|
+
# end
|
277
|
+
|
278
|
+
# class Reboot < Payload
|
279
|
+
# endian :little
|
280
|
+
# end
|
281
|
+
|
282
|
+
# Soft reboot the device in 1000ms from time received
|
283
|
+
class SetReboot < Payload
|
284
|
+
endian :little
|
285
|
+
end
|
286
|
+
|
287
|
+
# Sent back if reboot is pending on SetReboot
|
288
|
+
class StateReboot < Payload
|
289
|
+
endian :little
|
290
|
+
end
|
291
|
+
|
292
|
+
# Sent back from device on receipt of a message with ack_required set to 1
|
293
|
+
class Acknowledgement < Payload
|
294
|
+
endian :little
|
295
|
+
end
|
296
|
+
|
297
|
+
# Clear all settings from the device
|
298
|
+
class SetFactoryReset < Payload
|
299
|
+
endian :little
|
300
|
+
end
|
301
|
+
|
302
|
+
# Signifies pending reset
|
303
|
+
class StateFactoryReset < Payload
|
304
|
+
endian :little
|
305
|
+
end
|
306
|
+
|
307
|
+
# Get the device location
|
308
|
+
class GetLocation < Payload
|
309
|
+
endian :little
|
310
|
+
end
|
311
|
+
|
312
|
+
# Set the device location
|
313
|
+
class SetLocation < Payload
|
314
|
+
endian :little
|
315
|
+
|
316
|
+
string :location, length: 16 # guid byte array
|
317
|
+
string :label, length: 32, trim_padding: true # text label for location
|
318
|
+
end
|
319
|
+
|
320
|
+
# Device location
|
321
|
+
class StateLocation < Payload
|
322
|
+
endian :little
|
323
|
+
|
324
|
+
string :location, length: 16 # guid byte array
|
325
|
+
string :label, length: 32, trim_padding: true # text label for location
|
326
|
+
end
|
327
|
+
|
328
|
+
# Get the device group. A device can belong to a single logical group
|
329
|
+
class GetGroup < Payload
|
330
|
+
endian :little
|
331
|
+
end
|
332
|
+
|
333
|
+
# Set the device group
|
334
|
+
class SetGroup < Payload
|
335
|
+
endian :little
|
336
|
+
|
337
|
+
string :group, length: 16 # guid byte array
|
338
|
+
string :label, length: 32, trim_padding: true # text label for group
|
339
|
+
end
|
340
|
+
|
341
|
+
# Set the device group
|
342
|
+
class StateGroup < Payload
|
343
|
+
endian :little
|
344
|
+
|
345
|
+
string :group, length: 16 # guid byte array
|
346
|
+
string :label, length: 32, trim_padding: true # text label for group
|
347
|
+
end
|
348
|
+
|
349
|
+
# Introspect the device owner. Returns StateOwner
|
350
|
+
class GetOwner < Payload
|
351
|
+
endian :little
|
352
|
+
end
|
353
|
+
|
354
|
+
# Set the device owner
|
355
|
+
class SetOwner < Payload
|
356
|
+
endian :little
|
357
|
+
|
358
|
+
string :owner, length: 16 # guid byte array
|
359
|
+
string :label, length: 32, trim_padding: true # text label of owner details
|
360
|
+
end
|
361
|
+
|
362
|
+
# Return the device owner information
|
363
|
+
class StateOwner < Payload
|
364
|
+
endian :little
|
365
|
+
|
366
|
+
string :owner, length: 16 # guid byte array
|
367
|
+
string :label, length: 32, trim_padding: true # text label of owner details
|
368
|
+
end
|
369
|
+
|
370
|
+
# Request an arbitrary payload be echoed back
|
371
|
+
class EchoRequest < Payload
|
372
|
+
endian :little
|
373
|
+
|
374
|
+
string :payload, length: 64 # byte array
|
375
|
+
end
|
376
|
+
|
377
|
+
# Echo response with payload sent in request
|
378
|
+
class EchoResponse < Payload
|
379
|
+
endian :little
|
380
|
+
|
381
|
+
string :payload, length: 64 # byte array
|
382
|
+
end
|
383
|
+
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|