homie-mqtt 1.2.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd6f3bb8678e0d56ddc578993ba46f8bafb3361e4d5f7b0d5fbede478e640edc
4
- data.tar.gz: 4961a257ee03d29d623c009dad99f54ac44ee6701fa1364d2b83d6ce44a3898d
3
+ metadata.gz: adb5e19afec9a2e2d3525ea4879992306f2cd56632139bbc4d691ccc1e2b6bbb
4
+ data.tar.gz: ff164da43b91048841edef8488e654108d0c566dfe4e0b8150a1cff423b36214
5
5
  SHA512:
6
- metadata.gz: 5aedd7bde7d6cc07a8837802eaeef6f563d4d846b912f737df888a8d2d893bbe2556191f7e2847f2a903527b5c3d7342f62d63562175eac7207dde46867877b1
7
- data.tar.gz: dfaa32de5c1126801ceeb164fe919a35c266fec727096539e6e3e794c19d380852c0a910a090222ba5d3396edf7a5a25522d25396453c6734cf5ff33b88ff36d
6
+ metadata.gz: b4cd79531f71ce7cc077b7f06acd181dd41694494eacab571323fb3930755a10aa57254b1d81dfec3d66ab880b39adc5b21af62ce8c66e84304ca52bf2021fc6
7
+ data.tar.gz: a11b7bf36fdfb34677d9becdb733ddd4c53cf0ed64f51575b44d257e37b04bd7c07599b0ca6c37b0c7da70466d0b3389373b2d9795327947ba93dd2d14761528
@@ -40,27 +40,30 @@ module MQTT
40
40
  "#{root_topic}/#{id}"
41
41
  end
42
42
 
43
- def node(*args, **kwargs)
43
+ def node(id, *args, **kwargs)
44
+ raise ArgumentError, "Node '#{id}' already exists" if @nodes.key?(id)
45
+
44
46
  init do |prior_state|
45
- node = Node.new(self, *args, **kwargs)
46
- raise ArgumentError, "Node '#{node.id}' already exists" if @nodes.key?(node.id)
47
- @nodes[node.id] = node
47
+ node = Node.new(self, id, *args, **kwargs)
48
+
49
+ @nodes[id] = node
48
50
  yield node if block_given?
49
51
  if prior_state == :ready
50
52
  node.publish
51
53
  mqtt.publish("#{topic}/$nodes", @nodes.keys.join(","), retain: true, qos: 1)
52
54
  end
55
+ node
53
56
  end
54
- self
55
57
  end
56
58
 
57
59
  def remove_node(id)
58
- return unless (node = @nodes[id])
60
+ return false unless (node = @nodes[id])
59
61
  init do
60
62
  node.unpublish
61
63
  @nodes.delete(id)
62
64
  mqtt.publish("#{topic}/$nodes", @nodes.keys.join(","), retain: true, qos: 1) if @published
63
65
  end
66
+ true
64
67
  end
65
68
 
66
69
  def [](id)
@@ -120,28 +123,33 @@ module MQTT
120
123
 
121
124
  def init
122
125
  if state == :init
123
- yield(state)
124
- return
126
+ return yield state
125
127
  end
126
128
 
127
129
  prior_state = state
128
130
  mqtt.publish("#{topic}/$state", (state = :init).to_s, retain: true, qos: 1)
129
- yield(prior_state)
131
+ result = nil
132
+ mqtt.batch_publish do
133
+ result = yield prior_state
134
+ end
130
135
  mqtt.publish("#{topic}/$state", (state = :ready).to_s, retain: true, qos: 1)
131
- nil
136
+ result
132
137
  end
133
138
 
134
- private
135
-
136
139
  def clear_topics
140
+ raise ArgumentError, "cannot clear topics once published" if @published
141
+
137
142
  @mqtt.subscribe("#{topic}/#")
138
143
  @mqtt.unsubscribe("#{topic}/#", wait_for_ack: true)
139
144
  while !@mqtt.queue_empty?
140
145
  packet = @mqtt.get
141
146
  @mqtt.publish(packet.topic, retain: true, qos: 0)
142
147
  end
148
+ true
143
149
  end
144
150
 
151
+ private
152
+
145
153
  def topic_regex
146
154
  @topic_regex ||= Regexp.new("^#{Regexp.escape(topic)}/(?<node>#{REGEX})/(?<property>#{REGEX})/set$")
147
155
  end
@@ -23,17 +23,18 @@ module MQTT
23
23
  raise ArgumentError, "Property '#{property.id}' already exists on '#{id}'" if @properties.key?(property.id)
24
24
  @properties[property.id] = property
25
25
  property.publish if prior_state == :ready
26
+ property
26
27
  end
27
- self
28
28
  end
29
29
 
30
30
  def remove_property(id)
31
- return unless (property = @properties[id])
31
+ return false unless (property = @properties[id])
32
32
  init do
33
33
  property.unpublish
34
34
  @properties.delete(id)
35
35
  mqtt.publish("#{topic}/$properties", @properties.keys.join(","), retain: true, qos: 1) if @published
36
36
  end
37
+ true
37
38
  end
38
39
 
39
40
  def [](id)
@@ -48,6 +49,15 @@ module MQTT
48
49
  device.mqtt
49
50
  end
50
51
 
52
+ # takes a hash with property names as keys, and values as values
53
+ def batch_update(hash)
54
+ mqtt.batch_publish do
55
+ hash.each do |(k, v)|
56
+ self[k].value = v
57
+ end
58
+ end
59
+ end
60
+
51
61
  def publish
52
62
  mqtt.batch_publish do
53
63
  unless @published
@@ -6,7 +6,7 @@ module MQTT
6
6
  attr_reader :node, :datatype, :format, :unit, :value
7
7
 
8
8
  def initialize(node, id, name, datatype, value = nil, format: nil, retained: true, unit: nil, &block)
9
- raise ArgumentError, "Invalid Homie datatype" unless %s{string integer float boolean enum color}
9
+ raise ArgumentError, "Invalid Homie datatype" unless %s{string integer float boolean enum color datetime duration}
10
10
  raise ArgumentError, "retained must be boolean" unless [true, false].include?(retained)
11
11
  format = format.join(",") if format.is_a?(Array) && datatype == :enum
12
12
  if %i{integer float}.include?(datatype) && format.is_a?(Range)
@@ -18,6 +18,7 @@ module MQTT
18
18
  raise ArgumentError, "format is required for enums" if datatype == :enum && format.nil?
19
19
  raise ArgumentError, "format is required for colors" if datatype == :color && format.nil?
20
20
  raise ArgumentError, "format must be either rgb or hsv for colors" if datatype == :color && !%w{rgb hsv}.include?(format.to_s)
21
+ raise ArgumentError, "an initial value cannot be provided for a non-retained property" if !value.nil? && !retained
21
22
 
22
23
  super(id, name)
23
24
 
@@ -49,8 +50,8 @@ module MQTT
49
50
 
50
51
  def value=(value)
51
52
  if @value != value
52
- @value = value
53
- mqtt.publish(topic, value.to_s, retain: retained?, qos: 1) if @published
53
+ @value = value if retained?
54
+ publish_value if @published
54
55
  end
55
56
  end
56
57
 
@@ -108,6 +109,18 @@ module MQTT
108
109
  elsif format == 'hsv'
109
110
  return if value.first > 360 || value[1..2].max > 100
110
111
  end
112
+ when :datetime
113
+ begin
114
+ value = Time.parse(value)
115
+ rescue ArgumentError
116
+ return
117
+ end
118
+ when :duration
119
+ begin
120
+ value = ActiveSupport::Duration.parse(value)
121
+ rescue ActiveSupport::Duration::ISO8601Parser::ParsingError
122
+ return
123
+ end
111
124
  end
112
125
 
113
126
  @block.arity == 2 ? @block.call(value, self) : @block.call(value)
@@ -127,7 +140,7 @@ module MQTT
127
140
  mqtt.publish("#{topic}/$settable", "true", retain: true, qos: 1) if settable?
128
141
  mqtt.publish("#{topic}/$retained", "false", retain: true, qos: 1) unless retained?
129
142
  mqtt.publish("#{topic}/$unit", unit, retain: true, qos: 1) if unit
130
- mqtt.publish(topic, value.to_s, retain: retained?, qos: 1) if value
143
+ publish_value unless value.nil?
131
144
  subscribe
132
145
  end
133
146
 
@@ -149,7 +162,16 @@ module MQTT
149
162
  mqtt.publish("#{topic}/$retained", retain: true, qos: 0) unless retained?
150
163
  mqtt.publish("#{topic}/$unit", retain: true, qos: 0) if unit
151
164
  mqtt.unsubscribe("#{topic}/set") if settable?
152
- mqtt.publish(topic, retain: retained?, qos: 0) if value && retained?
165
+ mqtt.publish(topic, retain: retained?, qos: 0) if !value.nil? && retained?
166
+ end
167
+
168
+ private
169
+
170
+ def publish_value
171
+ serialized = value
172
+ serialized = serialized&.iso8601 if %i[datetime duration].include?(datatype)
173
+
174
+ mqtt.publish(topic, serialized.to_s, retain: retained?, qos: 1)
153
175
  end
154
176
  end
155
177
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module MQTT
4
4
  module Homie
5
- VERSION = '1.2.0'
5
+ VERSION = '1.4.0'
6
6
  end
7
7
  end
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.2.0
4
+ version: 1.4.0
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: 2021-02-20 00:00:00.000000000 Z
11
+ date: 2021-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mqtt-ccutrer
@@ -52,7 +52,7 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '13.0'
55
- description:
55
+ description:
56
56
  email: cody@cutrer.com'
57
57
  executables: []
58
58
  extensions: []
@@ -68,7 +68,7 @@ homepage: https://github.com/ccutrer/homie-mqtt
68
68
  licenses:
69
69
  - MIT
70
70
  metadata: {}
71
- post_install_message:
71
+ post_install_message:
72
72
  rdoc_options: []
73
73
  require_paths:
74
74
  - lib
@@ -83,8 +83,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  - !ruby/object:Gem::Version
84
84
  version: '0'
85
85
  requirements: []
86
- rubygems_version: 3.1.4
87
- signing_key:
86
+ rubygems_version: 3.1.2
87
+ signing_key:
88
88
  specification_version: 4
89
89
  summary: Library for publishing devices that conform to the Homie spec.
90
90
  test_files: []