lifx-lan 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|