homie-mqtt 1.5.0 → 1.6.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/lib/homie-mqtt.rb +1 -14
- data/lib/mqtt/homie/device.rb +9 -5
- data/lib/mqtt/homie/node.rb +7 -3
- data/lib/mqtt/homie/property.rb +76 -59
- data/lib/mqtt/homie/version.rb +1 -1
- data/lib/mqtt/homie.rb +16 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac2d4aeded4ffe715b8de38705b648c3aa2c80d378f57435f7e5bd854f8eac22
|
4
|
+
data.tar.gz: d4503b114004ebed3cd4987ecc1466ff0c3e6637d474477fb8f9e43eaf4e91b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02f74510916e8fb1d0ef8d40b3aea41320e9e12973175fb41b004598ab84038f16df3b171bf0c88e22e8fa894096871de17add5ca5aa37194bbda27e1cadecae
|
7
|
+
data.tar.gz: ffe27a55cf9e3e561a9469b17931b989e589a319b3e9e1aa976641640510bcbabe7f71988688922bd7ce77077f79f50ccf85f742a08d34bd73667bfc93eca5fc
|
data/lib/homie-mqtt.rb
CHANGED
@@ -1,16 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
module Homie
|
5
|
-
class << self
|
6
|
-
def escape_id(id)
|
7
|
-
id.downcase.gsub(/[^a-z0-9\-]/, "-").sub(/^[^a-z0-9]+/, "")
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
require "mqtt/homie/base"
|
14
|
-
require "mqtt/homie/device"
|
15
|
-
require "mqtt/homie/node"
|
16
|
-
require "mqtt/homie/property"
|
3
|
+
require "mqtt/homie"
|
data/lib/mqtt/homie/device.rb
CHANGED
@@ -69,7 +69,7 @@ module MQTT
|
|
69
69
|
init do
|
70
70
|
node.unpublish
|
71
71
|
@nodes.delete(id)
|
72
|
-
mqtt.publish("#{topic}/$nodes", @nodes.keys.join(","), retain: true, qos: 1) if
|
72
|
+
mqtt.publish("#{topic}/$nodes", @nodes.keys.join(","), retain: true, qos: 1) if published?
|
73
73
|
end
|
74
74
|
true
|
75
75
|
end
|
@@ -86,8 +86,12 @@ module MQTT
|
|
86
86
|
@nodes.count
|
87
87
|
end
|
88
88
|
|
89
|
+
def published?
|
90
|
+
@published
|
91
|
+
end
|
92
|
+
|
89
93
|
def publish
|
90
|
-
return if
|
94
|
+
return if published?
|
91
95
|
|
92
96
|
mqtt.batch_publish do
|
93
97
|
mqtt.publish("#{topic}/$homie", VERSION, retain: true, qos: 1)
|
@@ -141,17 +145,17 @@ module MQTT
|
|
141
145
|
return yield state if state == :init
|
142
146
|
|
143
147
|
prior_state = state
|
144
|
-
mqtt.publish("#{topic}/$state", (
|
148
|
+
mqtt.publish("#{topic}/$state", (@state = :init).to_s, retain: true, qos: 1)
|
145
149
|
result = nil
|
146
150
|
mqtt.batch_publish do
|
147
151
|
result = yield prior_state
|
148
152
|
end
|
149
|
-
mqtt.publish("#{topic}/$state", (
|
153
|
+
mqtt.publish("#{topic}/$state", (@state = :ready).to_s, retain: true, qos: 1)
|
150
154
|
result
|
151
155
|
end
|
152
156
|
|
153
157
|
def clear_topics
|
154
|
-
raise ArgumentError, "cannot clear topics once published" if
|
158
|
+
raise ArgumentError, "cannot clear topics once published" if published?
|
155
159
|
|
156
160
|
@mqtt.subscribe("#{topic}/#")
|
157
161
|
@mqtt.unsubscribe("#{topic}/#", wait_for_ack: true)
|
data/lib/mqtt/homie/node.rb
CHANGED
@@ -44,7 +44,7 @@ module MQTT
|
|
44
44
|
init do
|
45
45
|
property.unpublish
|
46
46
|
@properties.delete(id)
|
47
|
-
mqtt.publish("#{topic}/$properties", @properties.keys.join(","), retain: true, qos: 1) if
|
47
|
+
mqtt.publish("#{topic}/$properties", @properties.keys.join(","), retain: true, qos: 1) if published?
|
48
48
|
end
|
49
49
|
true
|
50
50
|
end
|
@@ -70,9 +70,13 @@ module MQTT
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
def published?
|
74
|
+
@published
|
75
|
+
end
|
76
|
+
|
73
77
|
def publish
|
74
78
|
mqtt.batch_publish do
|
75
|
-
unless
|
79
|
+
unless published?
|
76
80
|
mqtt.publish("#{topic}/$name", name, retain: true, qos: 1)
|
77
81
|
mqtt.publish("#{topic}/$type", @type.to_s, retain: true, qos: 1)
|
78
82
|
@published = true
|
@@ -84,7 +88,7 @@ module MQTT
|
|
84
88
|
end
|
85
89
|
|
86
90
|
def unpublish
|
87
|
-
return unless
|
91
|
+
return unless published?
|
88
92
|
|
89
93
|
@published = false
|
90
94
|
|
data/lib/mqtt/homie/property.rb
CHANGED
@@ -5,24 +5,26 @@ module MQTT
|
|
5
5
|
class Property < Base
|
6
6
|
attr_reader :node, :datatype, :format, :unit, :value
|
7
7
|
|
8
|
-
def initialize(node,
|
9
|
-
|
8
|
+
def initialize(node,
|
9
|
+
id,
|
10
|
+
name,
|
11
|
+
datatype,
|
12
|
+
value = nil,
|
13
|
+
format: nil,
|
14
|
+
retained: true,
|
15
|
+
unit: nil,
|
16
|
+
non_standard_value_check: nil,
|
17
|
+
&block)
|
18
|
+
raise ArgumentError, "Invalid Homie datatype" unless %i[string
|
19
|
+
integer
|
20
|
+
float
|
21
|
+
boolean
|
22
|
+
enum
|
23
|
+
color
|
24
|
+
datetime
|
10
25
|
duration].include?(datatype)
|
11
26
|
raise ArgumentError, "retained must be boolean" unless [true, false].include?(retained)
|
12
|
-
|
13
|
-
format = format.join(",") if format.is_a?(Array) && datatype == :enum
|
14
|
-
if %i[integer float].include?(datatype) && format.is_a?(Range)
|
15
|
-
raise ArgumentError "only inclusive ranges are supported" if format.exclude_end?
|
16
|
-
|
17
|
-
format = "#{format.begin}:#{format.end}"
|
18
|
-
end
|
19
|
-
raise ArgumentError, "format must be nil or a string" unless format.nil? || format.is_a?(String)
|
20
27
|
raise ArgumentError, "unit must be nil or a string" unless unit.nil? || unit.is_a?(String)
|
21
|
-
raise ArgumentError, "format is required for enums" if datatype == :enum && format.nil?
|
22
|
-
raise ArgumentError, "format is required for colors" if datatype == :color && format.nil?
|
23
|
-
if datatype == :color && !%w[rgb hsv].include?(format.to_s)
|
24
|
-
raise ArgumentError, "format must be either rgb or hsv for colors"
|
25
|
-
end
|
26
28
|
if !value.nil? && !retained
|
27
29
|
raise ArgumentError, "an initial value cannot be provided for a non-retained property"
|
28
30
|
end
|
@@ -31,11 +33,12 @@ module MQTT
|
|
31
33
|
|
32
34
|
@node = node
|
33
35
|
@datatype = datatype
|
34
|
-
|
36
|
+
self.format = format
|
35
37
|
@retained = retained
|
36
38
|
@unit = unit
|
37
39
|
@value = value
|
38
40
|
@published = false
|
41
|
+
@non_standard_value_check = non_standard_value_check
|
39
42
|
@block = block
|
40
43
|
end
|
41
44
|
|
@@ -77,14 +80,14 @@ module MQTT
|
|
77
80
|
return if @value == value
|
78
81
|
|
79
82
|
@value = value if retained?
|
80
|
-
publish_value if
|
83
|
+
publish_value if published?
|
81
84
|
end
|
82
85
|
|
83
86
|
def unit=(unit)
|
84
87
|
return if unit == @unit
|
85
88
|
|
86
89
|
@unit = unit
|
87
|
-
return unless
|
90
|
+
return unless published?
|
88
91
|
|
89
92
|
device.init do
|
90
93
|
mqtt.publish("#{topic}/$unit", unit.to_s, retain: true, qos: 1)
|
@@ -94,8 +97,24 @@ module MQTT
|
|
94
97
|
def format=(format)
|
95
98
|
return if format == @format
|
96
99
|
|
100
|
+
format = format.join(",") if format.is_a?(Array) && datatype == :enum
|
101
|
+
if %i[integer float].include?(datatype) && format.is_a?(Range)
|
102
|
+
raise ArgumentError, "only inclusive ranges are supported" if format.last.is_a?(Float) && format.exclude_end?
|
103
|
+
|
104
|
+
last = format.end
|
105
|
+
last -= 1 if format.exclude_end?
|
106
|
+
|
107
|
+
format = "#{format.begin}:#{last}"
|
108
|
+
end
|
109
|
+
raise ArgumentError, "format must be nil or a string" unless format.nil? || format.is_a?(String)
|
110
|
+
raise ArgumentError, "format is required for enums" if datatype == :enum && format.nil?
|
111
|
+
raise ArgumentError, "format is required for colors" if datatype == :color && format.nil?
|
112
|
+
if datatype == :color && !%w[rgb hsv].include?(format.to_s)
|
113
|
+
raise ArgumentError, "format must be either rgb or hsv for colors"
|
114
|
+
end
|
115
|
+
|
97
116
|
@format = format
|
98
|
-
return unless
|
117
|
+
return unless published?
|
99
118
|
|
100
119
|
device.init do
|
101
120
|
mqtt.publish("#{topic}/$format", format.to_s, retain: true, qos: 1)
|
@@ -114,56 +133,54 @@ module MQTT
|
|
114
133
|
end
|
115
134
|
|
116
135
|
def set(value)
|
136
|
+
casted_value = case datatype
|
137
|
+
when :boolean
|
138
|
+
%w[true false].include?(value) ? value == "true" : nil
|
139
|
+
when :integer
|
140
|
+
/^-?\d+$/.match?(value) && value.to_i
|
141
|
+
when :float
|
142
|
+
/^-?(?:\d+|\d+\.|\.\d+|\d+\.\d+)(?:[eE]-?\d+)?$/.match?(value) && value.to_f
|
143
|
+
when :enum
|
144
|
+
value
|
145
|
+
when :color
|
146
|
+
/^\d{1,3},\d{1,3},\d{1,3}$/.match?(value) && value = value.split(",").map(&:to_i)
|
147
|
+
when :datetime
|
148
|
+
begin
|
149
|
+
value = Time.parse(value)
|
150
|
+
rescue ArgumentError
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
when :duration
|
154
|
+
begin
|
155
|
+
value = ActiveSupport::Duration.parse(value)
|
156
|
+
rescue ActiveSupport::Duration::ISO8601Parser::ParsingError
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
end
|
117
160
|
case datatype
|
118
|
-
when :
|
119
|
-
|
120
|
-
|
121
|
-
value = value == "true"
|
122
|
-
when :integer
|
123
|
-
return unless /^-?\d+$/.match?(value)
|
124
|
-
|
125
|
-
value = value.to_i
|
126
|
-
return if format && !range.include?(value)
|
127
|
-
when :float
|
128
|
-
return unless /^-?(?:\d+|\d+\.|\.\d+|\d+\.\d+)(?:[eE]-?\d+)?$/.match?(value)
|
129
|
-
|
130
|
-
value = value.to_f
|
131
|
-
return if format && !range.include?(value)
|
132
|
-
when :enum
|
133
|
-
return unless range.include?(value)
|
161
|
+
when :integer, :float, :enum
|
162
|
+
casted_value = nil if format && !range.include?(casted_value)
|
134
163
|
when :color
|
135
|
-
|
136
|
-
|
137
|
-
value = value.split(",").map(&:to_i)
|
138
|
-
case format
|
139
|
-
when "rgb"
|
140
|
-
return if value.max > 255
|
141
|
-
when "hsv"
|
142
|
-
return if value.first > 360 || value[1..2].max > 100
|
143
|
-
end
|
144
|
-
when :datetime
|
145
|
-
begin
|
146
|
-
value = Time.parse(value)
|
147
|
-
rescue ArgumentError
|
148
|
-
return
|
149
|
-
end
|
150
|
-
when :duration
|
151
|
-
begin
|
152
|
-
value = ActiveSupport::Duration.parse(value)
|
153
|
-
rescue ActiveSupport::Duration::ISO8601Parser::ParsingError
|
154
|
-
return
|
155
|
-
end
|
164
|
+
casted_value = nil if (format == "rgb" && value.max > 255) ||
|
165
|
+
(format == "hsb" && (value.first > 360 || value[1..2].max > 100))
|
156
166
|
end
|
157
167
|
|
158
|
-
|
168
|
+
casted_value = @non_standard_value_check&.call(value) if casted_value.nil?
|
169
|
+
return if casted_value.nil?
|
170
|
+
|
171
|
+
@block.arity == 2 ? @block.call(casted_value, self) : @block.call(casted_value)
|
159
172
|
end
|
160
173
|
|
161
174
|
def mqtt
|
162
175
|
node.mqtt
|
163
176
|
end
|
164
177
|
|
178
|
+
def published?
|
179
|
+
@published
|
180
|
+
end
|
181
|
+
|
165
182
|
def publish
|
166
|
-
return if
|
183
|
+
return if published?
|
167
184
|
|
168
185
|
mqtt.batch_publish do
|
169
186
|
mqtt.publish("#{topic}/$name", name, retain: true, qos: 1)
|
@@ -184,7 +201,7 @@ module MQTT
|
|
184
201
|
end
|
185
202
|
|
186
203
|
def unpublish
|
187
|
-
return unless
|
204
|
+
return unless published?
|
188
205
|
|
189
206
|
@published = false
|
190
207
|
|
data/lib/mqtt/homie/version.rb
CHANGED
data/lib/mqtt/homie.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MQTT
|
4
|
+
module Homie
|
5
|
+
class << self
|
6
|
+
def escape_id(id)
|
7
|
+
id.downcase.gsub(/[^a-z0-9\-]/, "-").sub(/^[^a-z0-9]+/, "")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require "mqtt/homie/base"
|
14
|
+
require "mqtt/homie/device"
|
15
|
+
require "mqtt/homie/node"
|
16
|
+
require "mqtt/homie/property"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: homie-mqtt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mqtt-ccutrer
|
@@ -121,6 +121,7 @@ extensions: []
|
|
121
121
|
extra_rdoc_files: []
|
122
122
|
files:
|
123
123
|
- lib/homie-mqtt.rb
|
124
|
+
- lib/mqtt/homie.rb
|
124
125
|
- lib/mqtt/homie/base.rb
|
125
126
|
- lib/mqtt/homie/device.rb
|
126
127
|
- lib/mqtt/homie/node.rb
|