mqtt-homie-homeassistant 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ea47bfb9fc5d373702f2edf0bd746412d12cd884132d87f098fdd29a5b552b51
|
4
|
+
data.tar.gz: a229e5225e2a77daadb9caca7edb547da464211dc0f66aa3840429015970e39a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b4df1f4dff3da9e5becc45c539720383b7f0f9fed40125412a03b668b5048fff2a9206a01f831f140e986c0a5844d4ae016b5586228ae0d4b1a1710dd49097b9
|
7
|
+
data.tar.gz: 73d1824ec2f29d95414368a1fbbc360c0a250ce54e0a0fecfc93c2c4dd1d2086fcca7f71c2c7b3e33e545c331d69d31da237ff1a8ec15b3f0b0d548218175e5b
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MQTT
|
4
|
+
module Homie
|
5
|
+
module HomeAssistant
|
6
|
+
module Device
|
7
|
+
def self.included(klass)
|
8
|
+
super
|
9
|
+
klass.attr_accessor :home_assistant_device, :home_assistant_discovery_prefix
|
10
|
+
end
|
11
|
+
|
12
|
+
# @!visibility private
|
13
|
+
def base_hass_config(config)
|
14
|
+
config[:availability] = [{
|
15
|
+
topic: "#{topic}/$state",
|
16
|
+
payload_available: "ready",
|
17
|
+
payload_not_available: "lost"
|
18
|
+
}]
|
19
|
+
config[:device] ||= {}
|
20
|
+
config[:device][:name] ||= name
|
21
|
+
config[:device][:identifiers] ||= id
|
22
|
+
config[:device][:sw_version] ||= MQTT::Homie::Device::VERSION
|
23
|
+
config[:node_id] = id
|
24
|
+
config[:qos] = 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
Device.include(HomeAssistant::Device)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MQTT
|
4
|
+
module Homie
|
5
|
+
module HomeAssistant
|
6
|
+
module Node
|
7
|
+
def hass_climate(action_property: nil,
|
8
|
+
current_humidity_property: nil,
|
9
|
+
current_temperature_property: nil,
|
10
|
+
fan_mode_property: nil,
|
11
|
+
mode_property: nil,
|
12
|
+
power_property: nil,
|
13
|
+
preset_mode_property: nil,
|
14
|
+
swing_mode_property: nil,
|
15
|
+
target_humidity_property: nil,
|
16
|
+
temperature_property: nil,
|
17
|
+
temperature_high_property: nil,
|
18
|
+
temperature_low_property: nil,
|
19
|
+
**kwargs)
|
20
|
+
if power_property && power_property.datatype != :boolean
|
21
|
+
raise ArgumentError, "Power property must be a boolean"
|
22
|
+
end
|
23
|
+
|
24
|
+
temperature_property = resolve_property(temperature_property)
|
25
|
+
temperature_high_property = resolve_property(temperature_high_property)
|
26
|
+
temperature_low_property = resolve_property(temperature_low_property)
|
27
|
+
temp_properties = [
|
28
|
+
temperature_property,
|
29
|
+
temperature_high_property,
|
30
|
+
temperature_low_property
|
31
|
+
].compact
|
32
|
+
unless (temp_ranges = temp_properties.map(&:range).compact).empty?
|
33
|
+
min = temp_ranges.map(&:begin).min
|
34
|
+
max = temp_ranges.map(&:end).max
|
35
|
+
kwargs[:temp_range] = min..max
|
36
|
+
end
|
37
|
+
kwargs[:temperature_unit] = temp_properties.map(&:unit).compact.first
|
38
|
+
if power_property
|
39
|
+
kwargs[:payload_off] = "false"
|
40
|
+
kwargs[:payload_on] = "true"
|
41
|
+
end
|
42
|
+
|
43
|
+
hass_property(kwargs, action_property, :action, read_only: true)
|
44
|
+
hass_property(kwargs, current_humidity_property, :current_humidity, read_only: true)
|
45
|
+
hass_property(kwargs, current_temperature_property, :current_temperature, read_only: true)
|
46
|
+
hass_enum(kwargs, fan_mode_property, :fan_mode)
|
47
|
+
hass_enum(kwargs, mode_property, :mode, MQTT::HomeAssistant::DEFAULTS[:climate][:modes])
|
48
|
+
hass_property(kwargs, power_property, :power)
|
49
|
+
hass_enum(kwargs, preset_mode_property, :preset_mode)
|
50
|
+
hass_enum(kwargs, swing_mode_property, :swing_mode)
|
51
|
+
hass_property(kwargs, target_humidity_property, :target_humidity)
|
52
|
+
hass_property(kwargs, temperature_property, :temperature)
|
53
|
+
hass_property(kwargs, temperature_high_property, :temperature_high)
|
54
|
+
hass_property(kwargs, temperature_low_property, :temperature_low)
|
55
|
+
publish_hass_component(platform: :climate, **kwargs)
|
56
|
+
end
|
57
|
+
|
58
|
+
def hass_fan(property,
|
59
|
+
oscillation_property: nil,
|
60
|
+
preset_mode_property: nil,
|
61
|
+
**kwargs)
|
62
|
+
hass_property(kwargs, property)
|
63
|
+
hass_property(kwargs, oscillation_property, :oscillation)
|
64
|
+
hass_enum(kwargs, preset_mode_property, :preset_mode)
|
65
|
+
publish_hass_component(platform: :fan, **kwargs)
|
66
|
+
end
|
67
|
+
|
68
|
+
def hass_humidifier(property,
|
69
|
+
target_humidity_property: nil,
|
70
|
+
mode_property: nil,
|
71
|
+
**kwargs)
|
72
|
+
hass_property(kwargs, property)
|
73
|
+
hass_property(kwargs, target_humidity_property, :target_humidity)
|
74
|
+
hass_property(kwargs, mode_property, :mode)
|
75
|
+
publish_hass_component(platform: :humidifier,
|
76
|
+
payload_off: "false",
|
77
|
+
payload_on: "true",
|
78
|
+
**kwargs)
|
79
|
+
end
|
80
|
+
|
81
|
+
def hass_light(property = nil,
|
82
|
+
brightness_property: nil,
|
83
|
+
color_mode_property: nil,
|
84
|
+
color_temp_property: nil,
|
85
|
+
effect_property: nil,
|
86
|
+
hs_property: nil,
|
87
|
+
rgb_property: nil,
|
88
|
+
white_property: nil,
|
89
|
+
xy_property: nil,
|
90
|
+
**kwargs)
|
91
|
+
# automatically infer a brightness-only light and adjust config
|
92
|
+
if brightness_property && property.nil?
|
93
|
+
property = brightness_property
|
94
|
+
kwargs[:on_command_type] = :brightness
|
95
|
+
end
|
96
|
+
case property.datatype
|
97
|
+
when :boolean
|
98
|
+
kwargs[:payload_off] = "false"
|
99
|
+
kwargs[:payload_on] = "true"
|
100
|
+
when :integer
|
101
|
+
kwargs[:payload_off] = "0"
|
102
|
+
when :float
|
103
|
+
kwargs[:payload_off] = "0.0"
|
104
|
+
end
|
105
|
+
kwargs[:brightness_scale] = brightness_property.range.end if brightness_property&.range
|
106
|
+
kwargs[:effect_list] = effect_property.range if effect_property&.datatype == :enum
|
107
|
+
kwargs[:mireds_range] = color_temp_property.range if color_temp_property.unit == "mired"
|
108
|
+
kwargs[:white_scale] = white_property.range.end if white_property&.range
|
109
|
+
|
110
|
+
hass_property(kwargs, property)
|
111
|
+
hass_property(kwargs, brightness_property, :brightness)
|
112
|
+
hass_property(kwargs, color_mode_property, :color_mode)
|
113
|
+
hass_property(kwargs, color_temp_property, :color_temp)
|
114
|
+
hass_property(kwargs, effect_property, :effect)
|
115
|
+
hass_property(kwargs, hs_property, :hs)
|
116
|
+
hass_property(kwargs, rgb_property, :rgb)
|
117
|
+
hass_property(kwargs, white_property, :white)
|
118
|
+
hass_property(kwargs, xy_property, :xy)
|
119
|
+
publish_hass_component(platform: :light, **kwargs)
|
120
|
+
end
|
121
|
+
|
122
|
+
def hass_water_heater(
|
123
|
+
current_temperature_property: nil,
|
124
|
+
mode_property: nil,
|
125
|
+
power_property: nil,
|
126
|
+
temperature_property: nil,
|
127
|
+
**kwargs)
|
128
|
+
temperature_property = resolve_property(temperature_property)
|
129
|
+
current_temperature_property = resolve_property(current_temperature_property)
|
130
|
+
temp_properties = [
|
131
|
+
temperature_property,
|
132
|
+
current_temperature_property
|
133
|
+
].compact
|
134
|
+
kwargs[:range] = temperature_property&.range
|
135
|
+
kwargs[:temperature_unit] = temp_properties.map(&:unit).compact.first
|
136
|
+
if power_property
|
137
|
+
kwargs[:payload_off] = "false"
|
138
|
+
kwargs[:payload_on] = "true"
|
139
|
+
end
|
140
|
+
hass_property(kwargs, current_temperature_property, :current_temperature, read_only: true)
|
141
|
+
hass_enum(kwargs, mode_property, :mode, MQTT::HomeAssistant::DEFAULTS[:water_heater][:modes])
|
142
|
+
hass_property(kwargs, power_property, :power)
|
143
|
+
hass_property(kwargs, temperature_property, :temperature)
|
144
|
+
publish_hass_component(platform: :water_heater, **kwargs)
|
145
|
+
end
|
146
|
+
|
147
|
+
def publish
|
148
|
+
super.tap do
|
149
|
+
@pending_hass_registrations&.each do |(object_id, kwargs)|
|
150
|
+
device.mqtt.publish_hass_component(object_id, **kwargs)
|
151
|
+
end
|
152
|
+
@pending_hass_registrations = nil
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def resolve_property(property)
|
159
|
+
return if property.nil?
|
160
|
+
|
161
|
+
orig_property = property
|
162
|
+
property = self[property] if property.is_a?(String)
|
163
|
+
raise ArgumentError, "Unknown property #{orig_property}" if property.nil?
|
164
|
+
|
165
|
+
property
|
166
|
+
end
|
167
|
+
|
168
|
+
def hass_property(config, property, prefix = nil, read_only: false, templates: {})
|
169
|
+
resolve_property(property)&.hass_property(config, prefix, read_only: read_only, templates: templates)
|
170
|
+
end
|
171
|
+
|
172
|
+
def hass_enum(config, property, prefix = nil, valid_set = nil)
|
173
|
+
return if property.nil?
|
174
|
+
|
175
|
+
property = resolve_property(property)
|
176
|
+
hass_property(config, property, prefix)
|
177
|
+
|
178
|
+
return unless property.datatype == :enum
|
179
|
+
|
180
|
+
values = property.range
|
181
|
+
values &= valid_set if valid_set
|
182
|
+
config[:"#{prefix}s"] = values
|
183
|
+
end
|
184
|
+
|
185
|
+
def publish_hass_component(device: nil, discovery_prefix: nil, object_id: nil, **kwargs)
|
186
|
+
discovery_prefix ||= self.device.home_assistant_discovery_prefix
|
187
|
+
device = self.device.home_assistant_device.merge(device || {}) if self.device.home_assistant_device
|
188
|
+
|
189
|
+
object_id ||= id
|
190
|
+
kwargs[:name] ||= name
|
191
|
+
kwargs[:device] = device
|
192
|
+
kwargs[:discovery_prefix] ||= discovery_prefix
|
193
|
+
kwargs[:unique_id] ||= "#{self.device.id}_#{object_id}"
|
194
|
+
self.device.base_hass_config(kwargs)
|
195
|
+
if published?
|
196
|
+
self.device.mqtt.publish_hass_component(object_id, **kwargs)
|
197
|
+
else
|
198
|
+
pending_hass_registrations << [object_id, kwargs]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def pending_hass_registrations
|
203
|
+
@pending_hass_registrations ||= []
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
Node.prepend(HomeAssistant::Node)
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MQTT
|
4
|
+
module Homie
|
5
|
+
module HomeAssistant
|
6
|
+
module Property
|
7
|
+
def initialize(*args, hass: nil, **kwargs)
|
8
|
+
super(*args, **kwargs)
|
9
|
+
|
10
|
+
return unless hass
|
11
|
+
|
12
|
+
case hass
|
13
|
+
when Symbol
|
14
|
+
public_send("hass_#{hass}")
|
15
|
+
when Hash
|
16
|
+
raise ArgumentError, "hass must only contain one item" unless hass.length == 1
|
17
|
+
|
18
|
+
public_send("hass_#{hass.first.first}", **hass.first.last)
|
19
|
+
else
|
20
|
+
raise ArgumentError, "hass must be a Symbol or a Hash of HASS device type to additional HASS options"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def hass_binary_sensor(**kwargs)
|
25
|
+
raise ArgumentError, "Property must be a boolean" unless datatype == :boolean
|
26
|
+
raise ArgumentError, "Property must not be settable" if settable?
|
27
|
+
|
28
|
+
hass_property(kwargs)
|
29
|
+
publish_hass_component(platform: :binary_sensor,
|
30
|
+
payload_off: "false",
|
31
|
+
payload_on: "true",
|
32
|
+
**kwargs)
|
33
|
+
end
|
34
|
+
|
35
|
+
def hass_fan(**kwargs)
|
36
|
+
raise ArgumentError, "Property must be a boolean" unless datatype == :boolean
|
37
|
+
raise ArgumentError, "Property must be settable" unless settable?
|
38
|
+
|
39
|
+
hass_property(kwargs)
|
40
|
+
publish_hass_component(platform: :fan,
|
41
|
+
payload_off: "false",
|
42
|
+
payload_on: "true",
|
43
|
+
**kwargs)
|
44
|
+
end
|
45
|
+
|
46
|
+
def hass_light(**kwargs)
|
47
|
+
case datatype
|
48
|
+
when :boolean
|
49
|
+
kwargs[:payload_off] = "false"
|
50
|
+
kwargs[:payload_on] = "true"
|
51
|
+
when :integer
|
52
|
+
kwargs[:payload_off] = "0"
|
53
|
+
when :float
|
54
|
+
kwargs[:payload_off] = "0.0"
|
55
|
+
end
|
56
|
+
|
57
|
+
hass_property(kwargs)
|
58
|
+
publish_hass_component(platform: :light, **kwargs)
|
59
|
+
end
|
60
|
+
|
61
|
+
def hass_number(**kwargs)
|
62
|
+
raise ArgumentError, "Property must be an integer or a float" unless %i[integer float].include?(datatype)
|
63
|
+
|
64
|
+
hass_property(kwargs)
|
65
|
+
kwargs[:range] = range if range
|
66
|
+
kwargs[:unit_of_measurement] = unit if unit
|
67
|
+
|
68
|
+
publish_hass_component(platform: :number, **kwargs)
|
69
|
+
end
|
70
|
+
|
71
|
+
def hass_scene(**kwargs)
|
72
|
+
unless datatype == :enum && range.length == 1
|
73
|
+
raise ArgumentError, "Property must be an enum with a single value"
|
74
|
+
end
|
75
|
+
raise ArgumentError, "Property must be settable" unless settable?
|
76
|
+
|
77
|
+
publish_hass_component(platform: :scene,
|
78
|
+
command_topic: "#{topic}/set",
|
79
|
+
payload_on: range.first,
|
80
|
+
**kwargs)
|
81
|
+
end
|
82
|
+
|
83
|
+
def hass_select(**kwargs)
|
84
|
+
raise ArgumentError, "Property must be an enum" unless datatype == :enum
|
85
|
+
raise ArgumentError, "Property must be settable" unless settable?
|
86
|
+
|
87
|
+
hass_property(kwargs)
|
88
|
+
publish_hass_component(platform: :select, options: range, **kwargs)
|
89
|
+
end
|
90
|
+
|
91
|
+
def hass_sensor(**kwargs)
|
92
|
+
if datatype == :enum
|
93
|
+
kwargs[:device_class] = :enum
|
94
|
+
kwargs[:options] = range
|
95
|
+
end
|
96
|
+
|
97
|
+
publish_hass_component(platform: :sensor,
|
98
|
+
state_topic: topic,
|
99
|
+
**kwargs)
|
100
|
+
end
|
101
|
+
|
102
|
+
def hass_switch(**kwargs)
|
103
|
+
raise ArgumentError, "Property must be a boolean" unless datatype == :boolean
|
104
|
+
|
105
|
+
hass_property(kwargs)
|
106
|
+
publish_hass_component(platform: :switch,
|
107
|
+
payload_off: "false",
|
108
|
+
payload_on: "true",
|
109
|
+
**kwargs)
|
110
|
+
end
|
111
|
+
|
112
|
+
def publish
|
113
|
+
super.tap do
|
114
|
+
@pending_hass_registrations&.each do |(object_id, kwargs)|
|
115
|
+
device.mqtt.publish_hass_component(object_id, **kwargs)
|
116
|
+
end
|
117
|
+
@pending_hass_registrations = nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @!visibility private
|
122
|
+
def hass_property(config, prefix = nil, read_only: false, templates: {})
|
123
|
+
prefix = "#{prefix}_" if prefix
|
124
|
+
state_prefix = "state_" unless read_only
|
125
|
+
config[:"#{prefix}#{state_prefix}topic"] = topic if retained?
|
126
|
+
if !read_only && settable?
|
127
|
+
config[:"#{prefix}command_topic"] = "#{topic}/set"
|
128
|
+
config[:"#{prefix}command_template"] = "{{ value | round(0) }}" if datatype == :integer
|
129
|
+
end
|
130
|
+
config.merge!(templates.slice(:"#{prefix}template", :"#{prefix}command_template"))
|
131
|
+
end
|
132
|
+
|
133
|
+
# @!visibility private
|
134
|
+
def hass_enum(config, prefix = nil, valid_set = nil)
|
135
|
+
prefix = "#{prefix}_" if prefix
|
136
|
+
|
137
|
+
return unless datatype == :enum
|
138
|
+
|
139
|
+
modes = range
|
140
|
+
modes &= valid_set if valid_set
|
141
|
+
config[:"#{prefix}modes"] = modes
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def publish_hass_component(device: nil, discovery_prefix: nil, object_id: nil, **kwargs)
|
147
|
+
discovery_prefix ||= self.device.home_assistant_discovery_prefix
|
148
|
+
device = self.device.home_assistant_device.merge(device || {}) if self.device.home_assistant_device
|
149
|
+
|
150
|
+
object_id ||= "#{node.id}_#{id}"
|
151
|
+
kwargs[:name] ||= "#{node.name} #{name}"
|
152
|
+
kwargs[:device] = device
|
153
|
+
kwargs[:discovery_prefix] ||= discovery_prefix
|
154
|
+
kwargs[:unique_id] ||= "#{self.device.id}_#{object_id}"
|
155
|
+
self.device.base_hass_config(kwargs)
|
156
|
+
if published?
|
157
|
+
self.device.mqtt.publish_hass_component(object_id, **kwargs)
|
158
|
+
else
|
159
|
+
pending_hass_registrations << [object_id, kwargs]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def pending_hass_registrations
|
164
|
+
@pending_hass_registrations ||= []
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
Property.prepend(HomeAssistant::Property)
|
169
|
+
end
|
170
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mqtt-homie-homeassistant
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cody Cutrer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-01-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: homie-mqtt
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mqtt-homeassistant
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
description:
|
56
|
+
email: cody@cutrer.com'
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- lib/mqtt-homie-homeassistant.rb
|
62
|
+
- lib/mqtt/homie/home_assistant/device.rb
|
63
|
+
- lib/mqtt/homie/home_assistant/node.rb
|
64
|
+
- lib/mqtt/homie/home_assistant/property.rb
|
65
|
+
- lib/mqtt/homie/home_assistant/version.rb
|
66
|
+
homepage: https://github.com/ccutrer/ruby-mqtt-homie-homeassistant
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata:
|
70
|
+
rubygems_mfa_required: 'true'
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '2.5'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubygems_version: 3.5.11
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Library for publishing device auto-discovery configuration for Homie devices
|
90
|
+
to Home Assistant as well.
|
91
|
+
test_files: []
|