homie-mqtt 1.4.4 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe33f7f3d3d6588a385857dfad083584df0de5af3e66e540732dc3307b7d8a0f
4
- data.tar.gz: ba032b7b5760ac2a71915ebbbc4e3671cceff13bcf3b75bba3181b86a0b3c015
3
+ metadata.gz: d70ea4b44d22d3f2b5348e3e30b4ec4d624b0e3679f9f8da28813563a9296616
4
+ data.tar.gz: 1a7d48f60cc074d9f38a1190fd60e2a6df53f815ca733610ce32aef58c494a1e
5
5
  SHA512:
6
- metadata.gz: f7dabb99327ba052edef139511680ab1a9c5c90e21ce0c3229585e238846f5a2f6abd42365bb2f73cf43767b55e41ad091d45d1c5003fd86d91599d52e73347f
7
- data.tar.gz: a302d00a71bcde1495604da147e2d0e200a0dc686a074cd285e95d1861bc334007cd94a45d79d206c19c80dc5bd93dcec504c07488ae362cc94d592986663a8f
6
+ metadata.gz: '0119a668ccb19e5568d52c8dad148f882a9a17b8913c6f523e5b84c32f738c87437e0d765d780e771bc0b477cbf4bc9287e3004f258185ee1e6b9595de3c1641'
7
+ data.tar.gz: 4be69c2086e1ad51e67972858a6f3d37a84b73ca247c2e37ae6a436934b87130499e04f9fd9e813f626f1a6e667c60e424c5360b45f18bc0b386717ea5738f69
data/lib/homie-mqtt.rb CHANGED
@@ -1,16 +1,3 @@
1
1
  # frozen_string_literal: true
2
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'
3
+ require "mqtt/homie"
@@ -9,18 +9,19 @@ module MQTT
9
9
 
10
10
  def initialize(id, name)
11
11
  raise ArgumentError, "Invalid Homie ID '#{id}'" unless id.is_a?(String) && id =~ Regexp.new("^#{REGEX}$")
12
+
12
13
  @id = id
13
14
  @name = name
14
15
  end
15
16
 
16
17
  def name=(value)
17
- if name != value
18
- name = value
19
- if @published
20
- device.init do
21
- mqtt.publish("#{topic}/$name", name, retain: true, qos: 1)
22
- end
23
- end
18
+ return if name == value
19
+
20
+ name = value
21
+ return unless @published
22
+
23
+ device.init do
24
+ mqtt.publish("#{topic}/$name", name, retain: true, qos: 1)
24
25
  end
25
26
  end
26
27
  end
@@ -1,17 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'mqtt'
3
+ require "mqtt"
4
+ require "ruby2_keywords"
4
5
 
5
6
  module MQTT
6
7
  module Homie
7
8
  class Device < Base
9
+ # the Homie spec version
10
+ VERSION = "4.0.0"
11
+
8
12
  attr_reader :root_topic, :state, :mqtt
9
- attr_accessor :logger
10
- attr_accessor :out_of_band_topic_proc
13
+ attr_accessor :logger, :out_of_band_topic_proc
11
14
 
12
15
  def initialize(id, name, root_topic: nil, mqtt: nil, clear_topics: true, &block)
13
16
  super(id, name)
14
- @root_topic = @root_topic || "homie"
17
+ @root_topic = root_topic || "homie"
15
18
  @state = :init
16
19
  @nodes = {}
17
20
  @published = false
@@ -22,9 +25,7 @@ module MQTT
22
25
 
23
26
  @mqtt.on_reconnect do
24
27
  each do |node|
25
- node.each do |property|
26
- property.subscribe
27
- end
28
+ node.each(&:subscribe)
28
29
  end
29
30
  mqtt.publish("#{topic}/$state", :init, retain: true, qos: 1)
30
31
  mqtt.publish("#{topic}/$state", state, retain: true, qos: 1) unless state == :init
@@ -34,6 +35,10 @@ module MQTT
34
35
  self.clear_topics if clear_topics
35
36
  end
36
37
 
38
+ def inspect
39
+ "#<MQTT::Homie::Device #{topic} name=#{name.inspect}, $state=#{state.inspect}>"
40
+ end
41
+
37
42
  def device
38
43
  self
39
44
  end
@@ -42,11 +47,11 @@ module MQTT
42
47
  "#{root_topic}/#{id}"
43
48
  end
44
49
 
45
- def node(id, *args, **kwargs)
50
+ ruby2_keywords def node(id, *args)
46
51
  raise ArgumentError, "Node '#{id}' already exists" if @nodes.key?(id)
47
52
 
48
53
  init do |prior_state|
49
- node = Node.new(self, id, *args, **kwargs)
54
+ node = Node.new(self, id, *args)
50
55
 
51
56
  @nodes[id] = node
52
57
  yield node if block_given?
@@ -60,10 +65,11 @@ module MQTT
60
65
 
61
66
  def remove_node(id)
62
67
  return false unless (node = @nodes[id])
68
+
63
69
  init do
64
70
  node.unpublish
65
71
  @nodes.delete(id)
66
- mqtt.publish("#{topic}/$nodes", @nodes.keys.join(","), retain: true, qos: 1) if @published
72
+ mqtt.publish("#{topic}/$nodes", @nodes.keys.join(","), retain: true, qos: 1) if published?
67
73
  end
68
74
  true
69
75
  end
@@ -76,11 +82,19 @@ module MQTT
76
82
  @nodes.each_value(&block)
77
83
  end
78
84
 
85
+ def count
86
+ @nodes.count
87
+ end
88
+
89
+ def published?
90
+ @published
91
+ end
92
+
79
93
  def publish
80
- return if @published
94
+ return if published?
81
95
 
82
96
  mqtt.batch_publish do
83
- mqtt.publish("#{topic}/$homie", "4.0.0", retain: true, qos: 1)
97
+ mqtt.publish("#{topic}/$homie", VERSION, retain: true, qos: 1)
84
98
  mqtt.publish("#{topic}/$name", name, retain: true, qos: 1)
85
99
  mqtt.publish("#{topic}/$state", @state.to_s, retain: true, qos: 1)
86
100
 
@@ -105,6 +119,9 @@ module MQTT
105
119
 
106
120
  mqtt.publish("#{topic}/$nodes", @nodes.keys.join(","), retain: true, qos: 1)
107
121
  @nodes.each_value(&:publish)
122
+
123
+ yield if block_given?
124
+
108
125
  mqtt.publish("#{topic}/$state", (@state = :ready).to_s, retain: true, qos: 1)
109
126
  end
110
127
 
@@ -125,26 +142,24 @@ module MQTT
125
142
  end
126
143
 
127
144
  def init
128
- if state == :init
129
- return yield state
130
- end
145
+ return yield state if state == :init
131
146
 
132
147
  prior_state = state
133
- mqtt.publish("#{topic}/$state", (state = :init).to_s, retain: true, qos: 1)
148
+ mqtt.publish("#{topic}/$state", (@state = :init).to_s, retain: true, qos: 1)
134
149
  result = nil
135
150
  mqtt.batch_publish do
136
151
  result = yield prior_state
137
152
  end
138
- mqtt.publish("#{topic}/$state", (state = :ready).to_s, retain: true, qos: 1)
153
+ mqtt.publish("#{topic}/$state", (@state = :ready).to_s, retain: true, qos: 1)
139
154
  result
140
155
  end
141
156
 
142
157
  def clear_topics
143
- raise ArgumentError, "cannot clear topics once published" if @published
158
+ raise ArgumentError, "cannot clear topics once published" if published?
144
159
 
145
160
  @mqtt.subscribe("#{topic}/#")
146
161
  @mqtt.unsubscribe("#{topic}/#", wait_for_ack: true)
147
- while !@mqtt.queue_empty?
162
+ until @mqtt.queue_empty?
148
163
  packet = @mqtt.get
149
164
  @mqtt.publish(packet.topic, retain: true, qos: 0)
150
165
  end
@@ -13,14 +13,25 @@ module MQTT
13
13
  @published = false
14
14
  end
15
15
 
16
+ def inspect
17
+ "#<MQTT::Homie::Node #{topic} name=#{full_name.inspect}, type=#{type.inspect}>"
18
+ end
19
+
20
+ def full_name
21
+ return name if device.count == 1
22
+
23
+ "#{device.name} #{name}"
24
+ end
25
+
16
26
  def topic
17
27
  "#{device.topic}/#{id}"
18
28
  end
19
29
 
20
- def property(*args, **kwargs, &block)
30
+ ruby2_keywords def property(*args, &block)
21
31
  device.init do |prior_state|
22
- property = Property.new(self, *args, **kwargs, &block)
32
+ property = Property.new(self, *args, &block)
23
33
  raise ArgumentError, "Property '#{property.id}' already exists on '#{id}'" if @properties.key?(property.id)
34
+
24
35
  @properties[property.id] = property
25
36
  property.publish if prior_state == :ready
26
37
  property
@@ -29,10 +40,11 @@ module MQTT
29
40
 
30
41
  def remove_property(id)
31
42
  return false unless (property = @properties[id])
43
+
32
44
  init do
33
45
  property.unpublish
34
46
  @properties.delete(id)
35
- mqtt.publish("#{topic}/$properties", @properties.keys.join(","), retain: true, qos: 1) if @published
47
+ mqtt.publish("#{topic}/$properties", @properties.keys.join(","), retain: true, qos: 1) if published?
36
48
  end
37
49
  true
38
50
  end
@@ -58,9 +70,13 @@ module MQTT
58
70
  end
59
71
  end
60
72
 
73
+ def published?
74
+ @published
75
+ end
76
+
61
77
  def publish
62
78
  mqtt.batch_publish do
63
- unless @published
79
+ unless published?
64
80
  mqtt.publish("#{topic}/$name", name, retain: true, qos: 1)
65
81
  mqtt.publish("#{topic}/$type", @type.to_s, retain: true, qos: 1)
66
82
  @published = true
@@ -72,7 +88,8 @@ module MQTT
72
88
  end
73
89
 
74
90
  def unpublish
75
- return unless @published
91
+ return unless published?
92
+
76
93
  @published = false
77
94
 
78
95
  mqtt.publish("#{topic}/$name", retain: true, qos: 0)
@@ -1,37 +1,67 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "time"
4
+
3
5
  module MQTT
4
6
  module Homie
5
7
  class Property < Base
6
8
  attr_reader :node, :datatype, :format, :unit, :value
7
9
 
8
- def initialize(node, id, name, datatype, value = nil, format: nil, retained: true, unit: nil, &block)
9
- raise ArgumentError, "Invalid Homie datatype" unless %i[string integer float boolean enum color datetime duration].include?(datatype)
10
+ def initialize(node,
11
+ id,
12
+ name,
13
+ datatype,
14
+ value = nil,
15
+ format: nil,
16
+ retained: true,
17
+ unit: nil,
18
+ non_standard_value_check: nil,
19
+ &block)
20
+ raise ArgumentError, "Invalid Homie datatype" unless %i[string
21
+ integer
22
+ float
23
+ boolean
24
+ enum
25
+ color
26
+ datetime
27
+ duration].include?(datatype)
10
28
  raise ArgumentError, "retained must be boolean" unless [true, false].include?(retained)
11
- format = format.join(",") if format.is_a?(Array) && datatype == :enum
12
- if %i{integer float}.include?(datatype) && format.is_a?(Range)
13
- raise ArgumentError "only inclusive ranges are supported" if format.exclude_end?
14
- format = "#{format.begin}:#{format.end}"
15
- end
16
- raise ArgumentError, "format must be nil or a string" unless format.nil? || format.is_a?(String)
17
29
  raise ArgumentError, "unit must be nil or a string" unless unit.nil? || unit.is_a?(String)
18
- raise ArgumentError, "format is required for enums" if datatype == :enum && format.nil?
19
- raise ArgumentError, "format is required for colors" if datatype == :color && format.nil?
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
30
+ if !value.nil? && !retained
31
+ raise ArgumentError, "an initial value cannot be provided for a non-retained property"
32
+ end
22
33
 
23
34
  super(id, name)
24
35
 
25
36
  @node = node
26
37
  @datatype = datatype
27
- @format = format
38
+ self.format = format
28
39
  @retained = retained
29
40
  @unit = unit
30
41
  @value = value
31
42
  @published = false
43
+ @non_standard_value_check = non_standard_value_check
32
44
  @block = block
33
45
  end
34
46
 
47
+ def inspect
48
+ result = +"#<MQTT::Homie::Property #{topic} name=#{full_name.inspect}, datatype=#{datatype.inspect}"
49
+ result << ", format=#{format.inspect}" if format
50
+ result << ", unit=#{unit.inspect}" if unit
51
+ result << ", settable=true" if settable?
52
+ result << if retained?
53
+ ", value=#{value.inspect}"
54
+ else
55
+ ", retained=false"
56
+ end
57
+ result << ">"
58
+ result.freeze
59
+ end
60
+
61
+ def full_name
62
+ "#{node.full_name} #{name}"
63
+ end
64
+
35
65
  def device
36
66
  node.device
37
67
  end
@@ -49,89 +79,112 @@ module MQTT
49
79
  end
50
80
 
51
81
  def value=(value)
52
- if @value != value
53
- @value = value if retained?
54
- publish_value if @published
55
- end
82
+ return if @value == value
83
+
84
+ @value = value if retained?
85
+ publish_value if published?
56
86
  end
57
87
 
58
88
  def unit=(unit)
59
- if unit != @unit
60
- @unit = unit
61
- if @published
62
- device.init do
63
- mqtt.publish("#{topic}/$unit", unit.to_s, retain: true, qos: 1)
64
- end
65
- end
89
+ return if unit == @unit
90
+
91
+ @unit = unit
92
+ return unless published?
93
+
94
+ device.init do
95
+ mqtt.publish("#{topic}/$unit", unit.to_s, retain: true, qos: 1)
66
96
  end
67
97
  end
68
98
 
69
99
  def format=(format)
70
- if format != @format
71
- @format = format
72
- if @published
73
- device.init do
74
- mqtt.publish("#{topic}/$format", format.to_s, retain: true, qos: 1)
75
- end
76
- end
100
+ return if format == @format
101
+
102
+ format = format.join(",") if format.is_a?(Array) && datatype == :enum
103
+ if %i[integer float].include?(datatype) && format.is_a?(Range)
104
+ raise ArgumentError, "only inclusive ranges are supported" if format.last.is_a?(Float) && format.exclude_end?
105
+
106
+ last = format.end
107
+ last -= 1 if format.exclude_end?
108
+
109
+ format = "#{format.begin}:#{last}"
110
+ end
111
+ raise ArgumentError, "format must be nil or a string" unless format.nil? || format.is_a?(String)
112
+ raise ArgumentError, "format is required for enums" if datatype == :enum && format.nil?
113
+ raise ArgumentError, "format is required for colors" if datatype == :color && format.nil?
114
+ if datatype == :color && !%w[rgb hsv].include?(format.to_s)
115
+ raise ArgumentError, "format must be either rgb or hsv for colors"
116
+ end
117
+
118
+ @format = format
119
+ return unless published?
120
+
121
+ device.init do
122
+ mqtt.publish("#{topic}/$format", format.to_s, retain: true, qos: 1)
77
123
  end
78
124
  end
79
125
 
80
126
  def range
127
+ return nil unless format
128
+
81
129
  case datatype
82
- when :enum; format.split(',')
83
- when :integer; Range.new(*format.split(':').map(&:to_i))
84
- when :float; Range.new(*format.split(':').map(&:to_f))
130
+ when :enum then format.split(",")
131
+ when :integer then Range.new(*format.split(":").map(&:to_i))
132
+ when :float then Range.new(*format.split(":").map(&:to_f))
85
133
  else; raise MethodNotImplemented
86
134
  end
87
135
  end
88
136
 
89
137
  def set(value)
138
+ casted_value = case datatype
139
+ when :boolean
140
+ %w[true false].include?(value) ? value == "true" : nil
141
+ when :integer
142
+ /^-?\d+$/.match?(value) && value.to_i
143
+ when :float
144
+ /^-?(?:\d+|\d+\.|\.\d+|\d+\.\d+)(?:[eE]-?\d+)?$/.match?(value) && value.to_f
145
+ when :enum
146
+ value
147
+ when :color
148
+ /^\d{1,3},\d{1,3},\d{1,3}$/.match?(value) && value = value.split(",").map(&:to_i)
149
+ when :datetime
150
+ begin
151
+ value = Time.parse(value)
152
+ rescue ArgumentError
153
+ nil
154
+ end
155
+ when :duration
156
+ begin
157
+ value = ActiveSupport::Duration.parse(value)
158
+ rescue ActiveSupport::Duration::ISO8601Parser::ParsingError
159
+ nil
160
+ end
161
+ end
90
162
  case datatype
91
- when :boolean
92
- return unless %w{true false}.include?(value)
93
- value = value == 'true'
94
- when :integer
95
- return unless value =~ /^-?\d+$/
96
- value = value.to_i
97
- return unless range.include?(value) if format
98
- when :float
99
- return unless value =~ /^-?(?:\d+|\d+\.|\.\d+|\d+\.\d+)(?:[eE]-?\d+)?$/
100
- value = value.to_f
101
- return unless range.include?(value) if format
163
+ when :integer, :float
164
+ casted_value = nil if format && !range.cover?(casted_value)
102
165
  when :enum
103
- return unless range.include?(value)
166
+ casted_value = nil if format && !range.include?(casted_value)
104
167
  when :color
105
- return unless value =~ /^\d{1,3},\d{1,3},\d{1,3}$/
106
- value = value.split(',').map(&:to_i)
107
- if format == 'rgb'
108
- return if value.max > 255
109
- elsif format == 'hsv'
110
- return if value.first > 360 || value[1..2].max > 100
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
168
+ casted_value = nil if (format == "rgb" && value.max > 255) ||
169
+ (format == "hsb" && (value.first > 360 || value[1..2].max > 100))
124
170
  end
125
171
 
126
- @block.arity == 2 ? @block.call(value, self) : @block.call(value)
172
+ casted_value = @non_standard_value_check&.call(value) if casted_value.nil?
173
+ return if casted_value.nil?
174
+
175
+ @block.arity == 2 ? @block.call(casted_value, self) : @block.call(casted_value)
127
176
  end
128
177
 
129
178
  def mqtt
130
179
  node.mqtt
131
180
  end
132
181
 
182
+ def published?
183
+ @published
184
+ end
185
+
133
186
  def publish
134
- return if @published
187
+ return if published?
135
188
 
136
189
  mqtt.batch_publish do
137
190
  mqtt.publish("#{topic}/$name", name, retain: true, qos: 1)
@@ -152,7 +205,8 @@ module MQTT
152
205
  end
153
206
 
154
207
  def unpublish
155
- return unless @published
208
+ return unless published?
209
+
156
210
  @published = false
157
211
 
158
212
  mqtt.publish("#{topic}/$name", retain: true, qos: 0)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module MQTT
4
4
  module Homie
5
- VERSION = '1.4.4'
5
+ VERSION = "1.6.1"
6
6
  end
7
7
  end
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.4
4
+ version: 1.6.1
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-08-26 00:00:00.000000000 Z
11
+ date: 2022-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mqtt-ccutrer
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.1
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,23 @@ dependencies:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
29
  version: '1.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: ruby2_keywords
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.0.5
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.0.5
27
47
  - !ruby/object:Gem::Dependency
28
48
  name: byebug
29
49
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +72,48 @@ dependencies:
52
72
  - - "~>"
53
73
  - !ruby/object:Gem::Version
54
74
  version: '13.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rubocop
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.23'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.23'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop-performance
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.12'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.12'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop-rake
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.6'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.6'
55
117
  description:
56
118
  email: cody@cutrer.com'
57
119
  executables: []
@@ -59,6 +121,7 @@ extensions: []
59
121
  extra_rdoc_files: []
60
122
  files:
61
123
  - lib/homie-mqtt.rb
124
+ - lib/mqtt/homie.rb
62
125
  - lib/mqtt/homie/base.rb
63
126
  - lib/mqtt/homie/device.rb
64
127
  - lib/mqtt/homie/node.rb
@@ -67,7 +130,8 @@ files:
67
130
  homepage: https://github.com/ccutrer/homie-mqtt
68
131
  licenses:
69
132
  - MIT
70
- metadata: {}
133
+ metadata:
134
+ rubygems_mfa_required: 'true'
71
135
  post_install_message:
72
136
  rdoc_options: []
73
137
  require_paths:
@@ -76,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
140
  requirements:
77
141
  - - ">="
78
142
  - !ruby/object:Gem::Version
79
- version: '0'
143
+ version: '2.5'
80
144
  required_rubygems_version: !ruby/object:Gem::Requirement
81
145
  requirements:
82
146
  - - ">="