mqtt-homeassistant 0.0.1
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 +7 -0
- data/lib/mqtt/home_assistant/version.rb +7 -0
- data/lib/mqtt/home_assistant.rb +535 -0
- data/lib/mqtt-homeassistant.rb +3 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 63f377ed2f680df05fcdd443d7827be88ad49630b6a2e046a1291f3ccbe1fe41
|
4
|
+
data.tar.gz: 9f48fd3a21b57073ae31bc488c5f8fda3369a2e3d2ef37d41426e1865d1d307a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e378a1edd2a12093be108cb9b1685393422274fcc65b578dee2e73c0a429a06dc35f17889f113998ac03a3f4a936fb01028a07f201061dc5420b3557b204b0f2
|
7
|
+
data.tar.gz: 82f86cf62752b56a357844149c2b51952a9fa448783a29e2396053a77648d73acae97921db149a7745a423b97edbd606bd53185f8431b865026383d7cb7d2227
|
@@ -0,0 +1,535 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module MQTT
|
6
|
+
module HomeAssistant
|
7
|
+
class << self
|
8
|
+
ENTITY_CATEGORIES = %i[config diagnostic system].freeze
|
9
|
+
DEVICE_CLASSES = {
|
10
|
+
binary_sensor: %i[
|
11
|
+
battery
|
12
|
+
battery_charging
|
13
|
+
cold
|
14
|
+
connectivity
|
15
|
+
door
|
16
|
+
garage_door
|
17
|
+
gas
|
18
|
+
heat
|
19
|
+
light
|
20
|
+
lock
|
21
|
+
moisture
|
22
|
+
motion
|
23
|
+
moving
|
24
|
+
occupancy
|
25
|
+
opening
|
26
|
+
plug
|
27
|
+
power
|
28
|
+
presence
|
29
|
+
problem
|
30
|
+
running
|
31
|
+
safety
|
32
|
+
smoke
|
33
|
+
sound
|
34
|
+
tamper
|
35
|
+
update
|
36
|
+
vibration
|
37
|
+
window
|
38
|
+
].freeze,
|
39
|
+
humidifier: %i[
|
40
|
+
humidifier
|
41
|
+
dehumidifier
|
42
|
+
].freeze,
|
43
|
+
sensor: %i[
|
44
|
+
aqi
|
45
|
+
battery
|
46
|
+
carbon_dioxide
|
47
|
+
carbon_monoxide
|
48
|
+
current
|
49
|
+
date
|
50
|
+
energy
|
51
|
+
gas
|
52
|
+
humidity
|
53
|
+
illuminance
|
54
|
+
monetary
|
55
|
+
nitrogen_dioxide
|
56
|
+
nitrogen_monoxide
|
57
|
+
nitrous_oxide
|
58
|
+
ozone
|
59
|
+
pm1
|
60
|
+
pm10
|
61
|
+
pm25
|
62
|
+
power_factor
|
63
|
+
power
|
64
|
+
pressure
|
65
|
+
signal_strength
|
66
|
+
sulphur_dioxide
|
67
|
+
temperature
|
68
|
+
timestamp
|
69
|
+
volatile_organic_compounds
|
70
|
+
voltage
|
71
|
+
].freeze
|
72
|
+
}.freeze
|
73
|
+
STATE_CLASSES = %i[measurement total total_increasing].freeze
|
74
|
+
ON_COMMAND_TYPES = %i[last first brightness].freeze
|
75
|
+
|
76
|
+
# @param property [MQTT::Homie::Property] A Homie property object of datatype :boolean
|
77
|
+
def publish_binary_sensor(
|
78
|
+
property,
|
79
|
+
device_class: nil,
|
80
|
+
expire_after: nil,
|
81
|
+
force_update: false,
|
82
|
+
off_delay: nil,
|
83
|
+
|
84
|
+
device: nil,
|
85
|
+
discovery_prefix: nil,
|
86
|
+
entity_category: nil,
|
87
|
+
icon: nil
|
88
|
+
)
|
89
|
+
raise ArgumentError, "Homie property must be a boolean" unless property.datatype == :boolean
|
90
|
+
if device_class && !DEVICE_CLASSES[:binary_sensor].include?(device_class)
|
91
|
+
raise ArgumentError, "Unrecognized device_class #{device_class.inspect}"
|
92
|
+
end
|
93
|
+
|
94
|
+
config = base_config(property.device,
|
95
|
+
property.full_name,
|
96
|
+
device_class: device_class,
|
97
|
+
device: device,
|
98
|
+
entity_category: entity_category,
|
99
|
+
icon: icon)
|
100
|
+
.merge({
|
101
|
+
payload_off: "false",
|
102
|
+
payload_on: "true",
|
103
|
+
unique_id: "#{property.device.id}_#{property.node.id}_#{property.id}",
|
104
|
+
state_topic: property.topic
|
105
|
+
})
|
106
|
+
config[:expire_after] = expire_after if expire_after
|
107
|
+
config[:force_update] = true if force_update
|
108
|
+
config[:off_delay] = off_delay if off_delay
|
109
|
+
|
110
|
+
publish(property.mqtt, "binary_sensor", config, discovery_prefix: discovery_prefix)
|
111
|
+
end
|
112
|
+
|
113
|
+
def publish_climate(
|
114
|
+
action_property: nil,
|
115
|
+
aux_property: nil,
|
116
|
+
away_mode_property: nil,
|
117
|
+
current_temperature_property: nil,
|
118
|
+
fan_mode_property: nil,
|
119
|
+
mode_property: nil,
|
120
|
+
hold_property: nil,
|
121
|
+
power_property: nil,
|
122
|
+
swing_mode_property: nil,
|
123
|
+
temperature_property: nil,
|
124
|
+
temperature_high_property: nil,
|
125
|
+
temperature_low_property: nil,
|
126
|
+
name: nil,
|
127
|
+
id: nil,
|
128
|
+
precision: nil,
|
129
|
+
temp_step: nil,
|
130
|
+
|
131
|
+
device: nil,
|
132
|
+
discovery_prefix: nil,
|
133
|
+
entity_category: nil,
|
134
|
+
icon: nil,
|
135
|
+
templates: {}
|
136
|
+
)
|
137
|
+
properties = {
|
138
|
+
action: action_property,
|
139
|
+
aux: aux_property,
|
140
|
+
away_mode: away_mode_property,
|
141
|
+
current_temperature: current_temperature_property,
|
142
|
+
fan_mode: fan_mode_property,
|
143
|
+
mode: mode_property,
|
144
|
+
hold: hold_property,
|
145
|
+
power: power_property,
|
146
|
+
swing_mode: swing_mode_property,
|
147
|
+
temperature: temperature_property,
|
148
|
+
temperature_high: temperature_high_property,
|
149
|
+
temperature_low: temperature_low_property
|
150
|
+
}.compact
|
151
|
+
raise ArgumentError, "At least one property must be specified" if properties.empty?
|
152
|
+
raise ArgumentError, "Power property must be a boolean" if power_property && power_property.datatype != :boolean
|
153
|
+
|
154
|
+
node = properties.first.last.node
|
155
|
+
|
156
|
+
config = base_config(node.device,
|
157
|
+
name || node.full_name,
|
158
|
+
device: device,
|
159
|
+
entity_category: entity_category,
|
160
|
+
icon: icon)
|
161
|
+
config[:unique_id] = "#{node.device.id}_#{id || node.id}"
|
162
|
+
properties.each do |prefix, property|
|
163
|
+
add_property(config, property, prefix, templates)
|
164
|
+
end
|
165
|
+
temp_properties = [
|
166
|
+
temperature_property,
|
167
|
+
temperature_high_property,
|
168
|
+
temperature_low_property
|
169
|
+
].compact
|
170
|
+
unless (temp_ranges = temp_properties.map(&:range).compact).empty?
|
171
|
+
config[:min_temp] = temp_ranges.map(&:begin).min
|
172
|
+
config[:max_temp] = temp_ranges.map(&:end).max
|
173
|
+
end
|
174
|
+
temperature_unit = temp_properties.map(&:unit).compact.first
|
175
|
+
config[:temperature_unit] = temperature_unit[-1] if temperature_unit
|
176
|
+
{
|
177
|
+
nil => mode_property,
|
178
|
+
:fan => fan_mode_property,
|
179
|
+
:hold => hold_property,
|
180
|
+
:swing => swing_mode_property
|
181
|
+
}.compact.each do |prefix, property|
|
182
|
+
valid_set = %w[auto off cool heat dry fan_only] if prefix.nil?
|
183
|
+
add_enum(config, property, prefix, valid_set)
|
184
|
+
end
|
185
|
+
config[:precision] = precision if precision
|
186
|
+
config[:temp_step] = temp_step if temp_step
|
187
|
+
if power_property
|
188
|
+
config[:payload_on] = "true"
|
189
|
+
config[:payload_off] = "false"
|
190
|
+
end
|
191
|
+
|
192
|
+
publish(node.mqtt, "climate", config, discovery_prefix: discovery_prefix)
|
193
|
+
end
|
194
|
+
|
195
|
+
def publish_fan(
|
196
|
+
property,
|
197
|
+
oscillation_property: nil,
|
198
|
+
percentage_property: nil,
|
199
|
+
preset_mode_property: nil,
|
200
|
+
|
201
|
+
device: nil,
|
202
|
+
discovery_prefix: nil,
|
203
|
+
entity_category: nil,
|
204
|
+
icon: nil
|
205
|
+
)
|
206
|
+
config = base_config(property.device,
|
207
|
+
name || property.node.full_name,
|
208
|
+
device: device,
|
209
|
+
device_class: device_class,
|
210
|
+
entity_category: entity_category,
|
211
|
+
icon: icon,
|
212
|
+
templates: {})
|
213
|
+
add_property(config, oscillation_property, :oscillation_property, templates)
|
214
|
+
add_property(config, percentage_property, :percentage, templates)
|
215
|
+
if percentage_property&.range
|
216
|
+
config[:speed_range_min] = percentage_property.range.begin
|
217
|
+
config[:speed_range_max] = percentage_property.range.end
|
218
|
+
end
|
219
|
+
add_property(config, preset_mode_property, :preset, templates)
|
220
|
+
add_enum(config, preset_mode_property, :preset)
|
221
|
+
|
222
|
+
publish(node.mqtt, "fan", config, discovery_prefix: discovery_prefix)
|
223
|
+
end
|
224
|
+
|
225
|
+
def publish_humidifier(
|
226
|
+
property,
|
227
|
+
device_class:,
|
228
|
+
target_property:,
|
229
|
+
mode_property: nil,
|
230
|
+
name: nil,
|
231
|
+
id: nil,
|
232
|
+
|
233
|
+
device: nil,
|
234
|
+
discovery_prefix: nil,
|
235
|
+
entity_category: nil,
|
236
|
+
icon: nil
|
237
|
+
)
|
238
|
+
raise ArgumentError, "Homie property must be a boolean" unless property.datatype == :boolean
|
239
|
+
|
240
|
+
unless DEVICE_CLASSES[:humidifier].include?(device_class)
|
241
|
+
raise ArgumentError, "Unrecognized device_class #{device_class.inspect}"
|
242
|
+
end
|
243
|
+
|
244
|
+
config = base_config(property.device,
|
245
|
+
name || property.node.full_name,
|
246
|
+
device: device,
|
247
|
+
device_class: device_class,
|
248
|
+
entity_category: entity_category,
|
249
|
+
icon: icon)
|
250
|
+
.merge({
|
251
|
+
command_topic: "#{property.topic}/set",
|
252
|
+
target_humidity_command_topic: "#{target_property.topic}/set",
|
253
|
+
payload_off: "false",
|
254
|
+
payload_on: "true",
|
255
|
+
unique_id: "#{property.device.id}_#{id || property.node.id}"
|
256
|
+
})
|
257
|
+
add_property(config, property)
|
258
|
+
add_property(config, target_property, :target_humidity)
|
259
|
+
if (range = target_property.range)
|
260
|
+
config[:min_humidity] = range.begin
|
261
|
+
config[:max_humidity] = range.end
|
262
|
+
end
|
263
|
+
add_property(config, mode_property, :mode)
|
264
|
+
add_enum(config, mode_property)
|
265
|
+
|
266
|
+
publish(property.mqtt, "humidifier", config, discovery_prefix: discovery_prefix)
|
267
|
+
end
|
268
|
+
|
269
|
+
# `default` schema only for now
|
270
|
+
def publish_light(
|
271
|
+
property = nil,
|
272
|
+
brightness_property: nil,
|
273
|
+
color_mode_property: nil,
|
274
|
+
color_temp_property: nil,
|
275
|
+
effect_property: nil,
|
276
|
+
hs_property: nil,
|
277
|
+
rgb_property: nil,
|
278
|
+
white_property: nil,
|
279
|
+
xy_property: nil,
|
280
|
+
on_command_type: nil,
|
281
|
+
|
282
|
+
device: nil,
|
283
|
+
discovery_prefix: nil,
|
284
|
+
entity_category: nil,
|
285
|
+
icon: nil,
|
286
|
+
templates: {}
|
287
|
+
)
|
288
|
+
if on_command_type && !ON_COMMAND_TYPES.include?(on_command_type)
|
289
|
+
raise ArgumentError, "Invalid on_command_type #{on_command_type.inspect}"
|
290
|
+
end
|
291
|
+
|
292
|
+
# automatically infer a brightness-only light and adjust config
|
293
|
+
if brightness_property && property.nil?
|
294
|
+
property = brightness_property
|
295
|
+
on_command_type = :brightness
|
296
|
+
end
|
297
|
+
|
298
|
+
config = base_config(property.device,
|
299
|
+
property.full_name,
|
300
|
+
device: device,
|
301
|
+
entity_category: entity_category,
|
302
|
+
icon: icon)
|
303
|
+
add_property(config, property)
|
304
|
+
case property.datatype
|
305
|
+
when :boolean
|
306
|
+
config[:payload_off] = "false"
|
307
|
+
config[:payload_on] = "true"
|
308
|
+
when :integer
|
309
|
+
config[:payload_off] = "0"
|
310
|
+
when :float
|
311
|
+
config[:payload_off] = "0.0"
|
312
|
+
end
|
313
|
+
add_property(config, brightness_property, :brightness, templates)
|
314
|
+
config[:brightness_scale] = brightness_property.range.end if brightness_property&.range
|
315
|
+
add_property(config, color_mode_property, :color_mode, templates)
|
316
|
+
add_property(config, color_temp_property, :color_temp, templates)
|
317
|
+
if color_temp_property&.range && color_temp_property.unit == "mired"
|
318
|
+
config[:min_mireds] = color_temp_property.range.begin
|
319
|
+
config[:max_mireds] = color_temp_property.range.end
|
320
|
+
end
|
321
|
+
add_property(config, effect_property, :effect, templates)
|
322
|
+
config[:effect_list] = effect_property.range if effect_property&.datatype == :enum
|
323
|
+
add_property(config, hs_property, :hs, templates)
|
324
|
+
add_property(config, rgb_property, :rgb, templates)
|
325
|
+
add_property(config, white_property, :white, templates)
|
326
|
+
config[:white_scale] = white_property.range.end if white_property&.range
|
327
|
+
add_property(config, xy_property, :xy, templates)
|
328
|
+
config[:on_command_type] = on_command_type if on_command_type
|
329
|
+
|
330
|
+
publish(property.mqtt, "light", config, discovery_prefix: discovery_prefix)
|
331
|
+
end
|
332
|
+
|
333
|
+
def publish_number(
|
334
|
+
property,
|
335
|
+
step: nil,
|
336
|
+
|
337
|
+
device: nil,
|
338
|
+
discovery_prefix: nil,
|
339
|
+
entity_category: nil,
|
340
|
+
icon: nil
|
341
|
+
)
|
342
|
+
raise ArgumentError, "Homie property must be an integer or a float" unless %i[integer
|
343
|
+
float].include?(property.datatype)
|
344
|
+
|
345
|
+
config = base_config(property.device,
|
346
|
+
property.full_name,
|
347
|
+
device: device,
|
348
|
+
entity_category: entity_category,
|
349
|
+
icon: icon)
|
350
|
+
config[:unique_id] = "#{property.device.id}_#{property.node.id}_#{property.id}"
|
351
|
+
add_property(config, property)
|
352
|
+
config[:unit_of_measurement] = property.unit if property.unit
|
353
|
+
if property.range
|
354
|
+
config[:min] = property.range.begin
|
355
|
+
config[:max] = property.range.end
|
356
|
+
end
|
357
|
+
config[:step] = step if step
|
358
|
+
|
359
|
+
publish(property.mqtt, "number", config, discovery_prefix: discovery_prefix)
|
360
|
+
end
|
361
|
+
|
362
|
+
def publish_scene(
|
363
|
+
property,
|
364
|
+
|
365
|
+
device: nil,
|
366
|
+
discovery_prefix: nil,
|
367
|
+
entity_category: nil,
|
368
|
+
icon: nil
|
369
|
+
)
|
370
|
+
unless property.datatype == :enum && property.range.length == 1
|
371
|
+
raise ArgumentError, "Homie property must be an enum with a single value"
|
372
|
+
end
|
373
|
+
|
374
|
+
config = base_config(property.device,
|
375
|
+
property.full_name,
|
376
|
+
device: device,
|
377
|
+
entity_category: entity_category,
|
378
|
+
icon: icon)
|
379
|
+
config[:unique_id] = "#{property.device.id}_#{property.node.id}_#{property.id}"
|
380
|
+
add_property(config, property)
|
381
|
+
config[:payload_on] = property.range.first
|
382
|
+
|
383
|
+
publish(property.mqtt, "scene", config, discovery_prefix: discovery_prefix)
|
384
|
+
end
|
385
|
+
|
386
|
+
def publish_select(
|
387
|
+
property,
|
388
|
+
|
389
|
+
device: nil,
|
390
|
+
discovery_prefix: nil,
|
391
|
+
entity_category: nil,
|
392
|
+
icon: nil
|
393
|
+
)
|
394
|
+
raise ArgumentError, "Homie property must be an enum" unless property.datatype == :enum
|
395
|
+
raise ArgumentError, "Homie property must be settable" unless property.settable?
|
396
|
+
|
397
|
+
config = base_config(property.device,
|
398
|
+
property.full_name,
|
399
|
+
device: device,
|
400
|
+
entity_category: entity_category,
|
401
|
+
icon: icon)
|
402
|
+
config[:unique_id] = "#{property.device.id}_#{property.node.id}_#{property.id}"
|
403
|
+
add_property(config, property)
|
404
|
+
config[:options] = property.range
|
405
|
+
|
406
|
+
publish(property.mqtt, "select", config, discovery_prefix: discovery_prefix)
|
407
|
+
end
|
408
|
+
|
409
|
+
# @param property [MQTT::Homie::Property] A Homie property object
|
410
|
+
def publish_sensor(
|
411
|
+
property,
|
412
|
+
device_class: nil,
|
413
|
+
expire_after: nil,
|
414
|
+
force_update: false,
|
415
|
+
state_class: nil,
|
416
|
+
|
417
|
+
device: nil,
|
418
|
+
discovery_prefix: nil,
|
419
|
+
entity_category: nil,
|
420
|
+
icon: nil
|
421
|
+
)
|
422
|
+
if device_class && !DEVICE_CLASSES[:sensor].include?(device_class)
|
423
|
+
raise ArgumentError, "Unrecognized device_class #{device_class.inspect}"
|
424
|
+
end
|
425
|
+
if state_class && !STATE_CLASSES.include?(state_class)
|
426
|
+
raise ArgumentError, "Unrecognized state_class #{state_class.inspect}"
|
427
|
+
end
|
428
|
+
|
429
|
+
config = base_config(property.device,
|
430
|
+
property.full_name,
|
431
|
+
device: device,
|
432
|
+
device_class: device_class,
|
433
|
+
entity_category: entity_category,
|
434
|
+
icon: icon)
|
435
|
+
.merge({
|
436
|
+
unique_id: "#{property.device.id}_#{property.node.id}_#{property.id}",
|
437
|
+
state_topic: property.topic
|
438
|
+
})
|
439
|
+
config[:state_class] = state_class if state_class
|
440
|
+
config[:expire_after] = expire_after if expire_after
|
441
|
+
config[:force_update] = true if force_update
|
442
|
+
config[:unit_of_measurement] = property.unit if property.unit
|
443
|
+
|
444
|
+
publish(property.mqtt, "sensor", config, discovery_prefix: discovery_prefix)
|
445
|
+
end
|
446
|
+
|
447
|
+
# @param property [MQTT::Homie::Property] A Homie property object of datatype :boolean
|
448
|
+
def publish_switch(property,
|
449
|
+
device_class: nil,
|
450
|
+
|
451
|
+
device: nil,
|
452
|
+
discovery_prefix: nil,
|
453
|
+
entity_category: nil,
|
454
|
+
icon: nil)
|
455
|
+
raise ArgumentError, "Homie property must be a boolean" unless property.datatype == :boolean
|
456
|
+
|
457
|
+
config = base_config(property.device,
|
458
|
+
property.full_name,
|
459
|
+
device: device,
|
460
|
+
device_class: device_class,
|
461
|
+
entity_category: entity_category,
|
462
|
+
icon: icon)
|
463
|
+
.merge({
|
464
|
+
unique_id: "#{property.device.id}_#{property.node.id}_#{property.id}",
|
465
|
+
payload_off: "false",
|
466
|
+
payload_on: "true"
|
467
|
+
})
|
468
|
+
add_property(config, property)
|
469
|
+
|
470
|
+
publish(property.mqtt, "switch", config, discovery_prefix: discovery_prefix)
|
471
|
+
end
|
472
|
+
|
473
|
+
private
|
474
|
+
|
475
|
+
def add_property(config, property, prefix = nil, templates = {})
|
476
|
+
return unless property
|
477
|
+
|
478
|
+
prefix = "#{prefix}_" if prefix
|
479
|
+
config[:"#{prefix}state_topic"] = property.topic if property.retained?
|
480
|
+
if property.settable?
|
481
|
+
config[:"#{prefix}command_topic"] = "#{property.topic}/set"
|
482
|
+
config[:"#{prefix}command_template"] = "{{ value | round(0) }}" if property.datatype == :integer
|
483
|
+
end
|
484
|
+
config.merge!(templates.slice(:"#{prefix}_template", :"#{prefix}_command_template"))
|
485
|
+
end
|
486
|
+
|
487
|
+
def add_enum(config, property, prefix = nil, valid_set = nil)
|
488
|
+
prefix = "#{prefix}_" if prefix
|
489
|
+
|
490
|
+
return unless property&.datatype == :enum
|
491
|
+
|
492
|
+
modes = property.range
|
493
|
+
modes &= valid_set if valid_set
|
494
|
+
config[:"#{prefix}modes"] = modes
|
495
|
+
end
|
496
|
+
|
497
|
+
def base_config(homie_device,
|
498
|
+
name,
|
499
|
+
device:,
|
500
|
+
entity_category:,
|
501
|
+
icon:,
|
502
|
+
device_class: nil)
|
503
|
+
if entity_category && !ENTITY_CATEGORIES.include?(entity_category)
|
504
|
+
raise ArgumentError, "Unrecognized entity_category #{entity_category.inspect}"
|
505
|
+
end
|
506
|
+
|
507
|
+
config = {
|
508
|
+
name: name,
|
509
|
+
availability_topic: "#{homie_device.topic}/$state",
|
510
|
+
payload_available: "ready",
|
511
|
+
payload_not_available: "lost",
|
512
|
+
qos: 1
|
513
|
+
}
|
514
|
+
config[:device_class] = device_class if device_class
|
515
|
+
config[:entity_category] = entity_category if entity_category
|
516
|
+
config[:icon] = icon if icon
|
517
|
+
|
518
|
+
device = device&.dup || {}
|
519
|
+
device[:name] ||= homie_device.name
|
520
|
+
device[:sw_version] ||= MQTT::Homie::Device::VERSION
|
521
|
+
device[:identifiers] ||= homie_device.id unless device[:connections]
|
522
|
+
config[:device] = device
|
523
|
+
|
524
|
+
config
|
525
|
+
end
|
526
|
+
|
527
|
+
def publish(mqtt, component, config, discovery_prefix:)
|
528
|
+
mqtt.publish("#{discovery_prefix || "homeassistant"}/#{component}/#{config[:unique_id]}/config",
|
529
|
+
config.to_json,
|
530
|
+
retain: true,
|
531
|
+
qos: 1)
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mqtt-homeassistant
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cody Cutrer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-12-08 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.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '11.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '11.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '13.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '13.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.23'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.23'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-performance
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.12'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.6'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.6'
|
111
|
+
description:
|
112
|
+
email: cody@cutrer.com'
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- lib/mqtt-homeassistant.rb
|
118
|
+
- lib/mqtt/home_assistant.rb
|
119
|
+
- lib/mqtt/home_assistant/version.rb
|
120
|
+
homepage: https://github.com/ccutrer/ruby-mqtt-homeassistant
|
121
|
+
licenses:
|
122
|
+
- MIT
|
123
|
+
metadata:
|
124
|
+
rubygems_mfa_required: 'true'
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '2.5'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubygems_version: 3.1.2
|
141
|
+
signing_key:
|
142
|
+
specification_version: 4
|
143
|
+
summary: Library for publishing device auto-discovery configuration for Home Assistant
|
144
|
+
via MQTT.
|
145
|
+
test_files: []
|