balboa_worldwide_app 1.3.0 → 2.0.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.
data/bin/bwa_mqtt_bridge DELETED
@@ -1,614 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'mqtt'
4
- require 'sd_notify'
5
- require 'set'
6
- require 'json'
7
-
8
- require 'bwa/logger'
9
- require 'bwa/client'
10
- require 'bwa/discovery'
11
- require 'bwa/version'
12
-
13
- class MQTTBridge
14
- def initialize(mqtt_uri, bwa, device_id: "bwa", base_topic: "homie")
15
- @base_topic = "#{base_topic}/#{device_id}"
16
- @mqtt = MQTT::Client.new(mqtt_uri)
17
- @mqtt.set_will("#{@base_topic}/$state", "lost", true)
18
- @mqtt.connect
19
- @bwa = bwa
20
- @attributes = {}
21
- @things = Set.new
22
-
23
- hass_discovery_topic = "homeassistant/"
24
- @ha_binary_path = hass_discovery_topic + "binary_sensor/"
25
- @ha_sensor_path = hass_discovery_topic + "sensor/"
26
- @ha_switch_path = hass_discovery_topic + "switch/"
27
- @ha_selects_path = hass_discovery_topic + "select/"
28
- @ha_number_path = hass_discovery_topic + "number/"
29
-
30
- @hass_device = {
31
- device: {
32
- identifiers: [device_id],
33
- sw_version: BWA::VERSION,
34
- name: "BWA Link"
35
- }
36
- }
37
-
38
- # bwa availability topics (works for all devices)
39
- @hass_availability = {
40
- availability_topic: "#{@base_topic}/$state",
41
- payload_available: "ready",
42
- payload_not_available: "lost"
43
- }
44
-
45
- publish_basic_attributes
46
- publish_filtercycles
47
-
48
- # Home Assistant MQTT Discovery Section
49
- publish_hass_discovery
50
-
51
- # Tell systemd we've started up OK. Ignored if systemd not in use.
52
- BWA.logger.warn "Balboa MQTT Bridge running (version #{BWA::VERSION})"
53
- SdNotify.ready
54
-
55
- bwa_thread = Thread.new do
56
- loop do
57
- begin
58
- message = @bwa.poll
59
- next if message.is_a?(BWA::Messages::Ready)
60
-
61
- case message
62
- when BWA::Messages::ControlConfiguration
63
- publish("spa/$type", message.model)
64
- when BWA::Messages::ControlConfiguration2
65
- message.pumps.each_with_index do |speed, i|
66
- publish_pump(i + 1, speed) if speed != 0
67
- end
68
- message.lights.each_with_index do |exists, i|
69
- publish_thing(:light, i + 1) if exists
70
- end
71
- message.aux.each_with_index do |exists, i|
72
- publish_thing(:aux, i + 1) if exists
73
- end
74
- publish_mister if message.mister
75
- publish_blower(message.blower) if message.blower != 0
76
- publish_circpump if message.circ_pump
77
- publish("$state", "ready")
78
- when BWA::Messages::FilterCycles
79
- publish_attribute("spa/filter1hour",message.filter1_hour)
80
- publish_attribute("spa/filter1minute",message.filter1_minute)
81
- publish_attribute("spa/filter1durationhours",message.filter1_duration_hours)
82
- publish_attribute("spa/filter1durationminutes",message.filter1_duration_minutes)
83
- publish_attribute("spa/filter2enabled",message.filter2_enabled)
84
- publish_attribute("spa/filter2hour",message.filter2_hour)
85
- publish_attribute("spa/filter2minute",message.filter2_minute)
86
- publish_attribute("spa/filter2durationhours",message.filter2_duration_hours)
87
- publish_attribute("spa/filter2durationminutes",message.filter2_duration_minutes)
88
- when BWA::Messages::Status
89
- @bwa.request_control_info unless @bwa.last_control_configuration
90
- @bwa.request_control_info2 unless @bwa.last_control_configuration2
91
- @bwa.request_filter_configuration unless @bwa.last_filter_configuration
92
-
93
- # make sure time is in sync
94
- now = Time.now
95
- now_minutes = now.hour * 60 + now.min
96
- spa_minutes = message.hour * 60 + message.minute
97
- # check the difference in both directions
98
- diff = [(spa_minutes - now_minutes) % 1440, 1440 - (spa_minutes - now_minutes) % 1440].min
99
-
100
- # allow a skew of 1 minute, since the seconds will always be off
101
- if diff > 1
102
- BWA.logger.info "Spa time #{"%02d:%02d" % [message.hour, message.minute]}, actually #{"%02d:%02d" % [now.hour, now.min]}; correcting difference of #{diff} min"
103
- @bwa.set_time(now.hour, now.min, message.twenty_four_hour_time)
104
- end
105
- publish_attribute("spa/hold", message.hold)
106
- publish_attribute("spa/priming", message.priming)
107
- publish_attribute("spa/heatingmode", message.heating_mode)
108
- publish_attribute("spa/temperaturescale", message.temperature_scale)
109
- publish_attribute("spa/24htime", message.twenty_four_hour_time)
110
- publish_attribute("spa/heating", message.heating)
111
- publish_attribute("spa/temperaturerange", message.temperature_range)
112
- publish_attribute("spa/currenttemperature", message.current_temperature)
113
- publish_attribute("spa/currenttemperature/$unit", "º#{message.temperature_scale.to_s[0].upcase}")
114
- publish_attribute("spa/settemperature", message.set_temperature)
115
- publish_attribute("spa/settemperature/$unit", "º#{message.temperature_scale.to_s[0].upcase}")
116
- if message.temperature_scale == :celsius
117
- publish_attribute("spa/currenttemperature/$format", "0:42")
118
- publish_attribute("spa/settemperature/$format", message.temperature_range == :high ? "26:40" : "10:26")
119
- publish_hass_discovery_settemp(:celsius)
120
- else
121
- publish_attribute("spa/currenttemperature/$format", "32:108")
122
- publish_attribute("spa/settemperature/$format", message.temperature_range == :high ? "80:106" : "50:99")
123
- publish_hass_discovery_settemp(:fahrenheit)
124
- end
125
- publish_attribute("spa/filter1", message.filter[0])
126
- publish_attribute("spa/filter2", message.filter[1])
127
-
128
- publish_attribute("spa/circpump", message.circ_pump) if @bwa.last_control_configuration2&.circ_pump
129
- publish_attribute("spa/blower", message.blower) if @bwa.last_control_configuration2&.blower.to_i != 0
130
- publish_attribute("spa/mister", message.mister) if @bwa.last_control_configuration2&.mister
131
- (0..5).each do |i|
132
- publish_attribute("spa/pump#{i + 1}", message.pumps[i]) if @bwa.last_control_configuration2&.pumps&.[](i).to_i != 0
133
- end
134
- (0..1).each do |i|
135
- publish_attribute("spa/light#{i + 1}", message.lights[i]) if @bwa.last_control_configuration2&.lights&.[](i)
136
- end
137
- (0..1).each do |i|
138
- publish_attribute("spa/aux#{i + 1}", message.lights[i]) if @bwa.last_control_configuration2&.aux&.[](i)
139
- end
140
-
141
- # Tell systemd we are still alive and kicking. Ignored if systemd not in use.
142
- SdNotify.watchdog
143
-
144
- end
145
- end
146
- end
147
- end
148
-
149
- @mqtt.get do |topic, value|
150
- BWA.logger.warn "from mqtt: #{value.inspect} at #{topic}"
151
- case topic[@base_topic.length + 1..-1]
152
- when "spa/hold/set"
153
- next @bwa.toggle_hold if value == 'toggle'
154
- next unless %w{true false}.include?(value)
155
- @bwa.set_hold(value == 'true')
156
- when "spa/heatingmode/set"
157
- next @bwa.toggle_heating_mode if value == 'toggle'
158
- next unless %w{ready rest}.include?(value)
159
- @bwa.set_heating_mode(value.to_sym)
160
- when "spa/temperaturescale/set"
161
- next unless %w{fahrenheit celsius}.include?(value)
162
- @bwa.set_temperature_scale(value.to_sym)
163
- when "spa/24htime/set"
164
- next unless %w{true false}.include?(value)
165
- now = Time.now
166
- @bwa.set_time(now.hour, now.min, value == 'true')
167
- when "spa/temperaturerange/set"
168
- next @bwa.toggle_temperature_range if value == 'toggle'
169
- next unless %w{low high}.include?(value)
170
- @bwa.set_temperature_range(value.to_sym)
171
- when %r{^spa/pump([1-6])/set$}
172
- next @bwa.toggle_pump($1.to_i) if value == 'toggle'
173
- @bwa.set_pump($1.to_i, value.to_i)
174
- when %r{^spa/(light|aux)([12])/set$}
175
- next @bwa.send(:"toggle_#{$1}", $2.to_i) if value == 'toggle'
176
- next unless %w{true false}.include?(value)
177
- @bwa.send(:"set_#{$1}", $2.to_i, value == 'true')
178
- when "spa/mister/set"
179
- next @bwa.toggle_mister if value == 'toggle'
180
- next unless %w{true false}.include?(value)
181
- @bwa.set_mister(value == 'true')
182
- when "spa/blower/set"
183
- next @bwa.toggle_blower if value == 'toggle'
184
- @bwa.set_blower(value.to_i)
185
- when "spa/settemperature/set"
186
- @bwa.set_temperature(value.to_f)
187
- when %r{^spa/(filter[12](hour|minute|durationhours|durationminutes|enabled))/set$}
188
- @bwa.set_filtercycles($1, value)
189
- end
190
- end
191
- end
192
-
193
- def publish(topic, value)
194
- BWA.logger.debug " to mqtt: #{topic}: #{value}"
195
- @mqtt.publish("#{@base_topic}/#{topic}", value, true)
196
- end
197
-
198
- def publish_attribute(attr, value)
199
- if !@attributes.key?(attr) || @attributes[attr] != value
200
- publish(attr, value.to_s)
201
- @attributes[attr] = value
202
- end
203
- end
204
-
205
- def subscribe(topic)
206
- @mqtt.subscribe("#{@base_topic}/#{topic}")
207
- end
208
-
209
- def publish_hass_discovery()
210
- #Priming
211
- priming_config = {
212
- name: "Hot Tub Priming",
213
- state_topic: "#{@base_topic}/spa/priming",
214
- device_class: "running",
215
- unique_id: "spa_priming",
216
- icon: "mdi:fast-forward"
217
- }
218
- @mqtt.publish(@ha_binary_path + "priming/config", priming_config
219
- .merge(@hass_device)
220
- .merge(@hass_availability)
221
- .to_json, true)
222
-
223
- #Circulation Pump
224
- circ_config = {
225
- name: "Hot Tub Circulation Pump",
226
- state_topic: "#{@base_topic}/spa/circpump",
227
- device_class: "running",
228
- unique_id: "spa_circpump",
229
- icon: "mdi:sync"
230
- }
231
- @mqtt.publish(@ha_binary_path + "circpump/config", circ_config
232
- .merge(@hass_device)
233
- .merge(@hass_availability)
234
- .to_json, true)
235
-
236
- # Filter 1 Cycle Running
237
- filter1_config = {
238
- name: "Hot Tub Filter 1 Cycle Running",
239
- state_topic: "#{@base_topic}/spa/filter1",
240
- device_class: "running",
241
- unique_id: "spa_filtercycle1",
242
- icon: "mdi:air-filter"
243
- }
244
- @mqtt.publish(@ha_binary_path + "filter1/config", filter1_config
245
- .merge(@hass_device)
246
- .merge(@hass_availability)
247
- .to_json, true)
248
-
249
- # Filter 2 Cycle Running
250
- filter2_config = {
251
- name: "Hot Tub Filter 2 Cycle Running",
252
- state_topic: "#{@base_topic}/spa/filter2",
253
- device_class: "running",
254
- unique_id: "spa_filtercycle2",
255
- icon: "mdi:air-filter"
256
- }
257
- @mqtt.publish(@ha_binary_path + "filter2/config", filter2_config
258
- .merge(@hass_device)
259
- .merge(@hass_availability)
260
- .to_json, true)
261
-
262
- # Heater Running
263
- heater_config = {
264
- name: "Hot Tub Heater",
265
- state_topic: "#{@base_topic}/spa/heating",
266
- device_class: "running",
267
- unique_id: "spa_heating",
268
- icon: "mdi:hot-tub"
269
- }
270
- @mqtt.publish(@ha_binary_path + "heating/config", heater_config
271
- .merge(@hass_device)
272
- .merge(@hass_availability)
273
- .to_json, true)
274
-
275
- # Heating Mode
276
- heatingmode_config = {
277
- name: "Hot Tub Heating Mode",
278
- state_topic: "#{@base_topic}/spa/heatingmode",
279
- command_topic: "#{@base_topic}/spa/heatingmode/set",
280
- unique_id: "spa_heating_mode",
281
- options: ["ready","rest","ready_in_rest"],
282
- icon: "mdi:cog-play"
283
- }
284
- @mqtt.publish(@ha_selects_path + "heatingmode/config", heatingmode_config
285
- .merge(@hass_device)
286
- .merge(@hass_availability)
287
- .to_json, true)
288
-
289
- # Temperature Range
290
- temperaturerange_config = {
291
- name: "Hot Tub Temperature Range",
292
- state_topic: "#{@base_topic}/spa/temperaturerange",
293
- command_topic: "#{@base_topic}/spa/temperaturerange/set",
294
- unique_id: "spa_temperaturerange_range",
295
- options: ["high","low"],
296
- icon: "mdi:thermometer-lines"
297
- }
298
- @mqtt.publish(@ha_selects_path + "temperaturerange/config", temperaturerange_config
299
- .merge(@hass_device)
300
- .merge(@hass_availability)
301
- .to_json, true)
302
-
303
- # Temperature Scale
304
- temperaturescale_config = {
305
- name: "Hot Tub Temperature Scale",
306
- state_topic: "#{@base_topic}/spa/temperaturescale",
307
- unique_id: "spa_temperaturescale"
308
- }
309
- @mqtt.publish(@ha_sensor_path + "temperaturescale/config", temperaturescale_config
310
- .merge(@hass_device)
311
- .merge(@hass_availability)
312
- .to_json, true)
313
-
314
- # Current Temperature
315
- currenttemperature_config = {
316
- name: "Hot Tub Current Temperature",
317
- state_topic: "#{@base_topic}/spa/currenttemperature",
318
- unique_id: "spa_currenttemperature",
319
- device_class: "temperature"
320
- }
321
- @mqtt.publish(@ha_sensor_path + "currenttemperature/config", currenttemperature_config
322
- .merge(@hass_device)
323
- .merge(@hass_availability)
324
- .to_json, true)
325
-
326
- # Set Temperature - Assuming fahrenheit first
327
- settemperature_config = {
328
- name: "Hot Tub Set Temperature",
329
- unique_id: "spa_settemperature",
330
- state_topic: "#{@base_topic}/spa/settemperature",
331
- command_topic: "#{@base_topic}/spa/settemperature/set",
332
- min: 50,
333
- max: 106,
334
- unit_of_measurement: "°F",
335
- icon: "mdi:thermometer"
336
- }
337
- @mqtt.publish(@ha_number_path + "settemperature/config", settemperature_config
338
- .merge(@hass_device)
339
- .merge(@hass_availability)
340
- .to_json, true)
341
- end
342
-
343
- def publish_hass_discovery_settemp(scale)
344
- return if scale == @last_scale
345
- @last_scale = scale
346
-
347
- # Update temp ranges when scale changes
348
- settemperature_config = {
349
- name: "Hot Tub Set Temperature",
350
- unique_id: "spa_settemperature",
351
- state_topic: "#{@base_topic}/spa/settemperature",
352
- command_topic: "#{@base_topic}/spa/settemperature/set",
353
- min: 50,
354
- max: 106,
355
- unit_of_measurement: "°F",
356
- icon: "mdi:thermometer"
357
- }
358
-
359
- if scale == :celsius
360
- settemperature_config[:min] = 10
361
- settemperature_config[:max] = 40
362
- settemperature_config[:unit_of_measurement] = "°C"
363
- else
364
- settemperature_config[:min] = 50
365
- settemperature_config[:max] = 106
366
- settemperature_config[:unit_of_measurement] = "°F"
367
- end
368
-
369
- @mqtt.publish(@ha_number_path + "settemperature/config", settemperature_config
370
- .merge(@hass_device)
371
- .merge(@hass_availability)
372
- .to_json, true)
373
- end
374
-
375
- def publish_hass_discovery_pumps(i, speeds)
376
- pump_config = {
377
- name: "Hot Tub Pump #{i}",
378
- unique_id: "spa_pump#{i}",
379
- state_topic: "#{@base_topic}/spa/pump#{i}",
380
- command_topic: "#{@base_topic}/spa/pump#{i}/set",
381
- payload_on: "toggle",
382
- payload_off: "toggle",
383
- state_on: "2",
384
- state_off: "0",
385
- icon: "mdi:chart-bubble"
386
- }
387
- @mqtt.publish(@ha_switch_path + "pump#{i}/config", pump_config
388
- .merge(@hass_device)
389
- .merge(@hass_availability)
390
- .to_json, true)
391
- end
392
-
393
- def publish_hass_discovery_things(type, i)
394
- #Things - Lights and such
395
- thing_config = {
396
- name: "Hot Tub #{type} #{i}",
397
- unique_id: "spa_#{type}#{i}",
398
- state_topic: "#{@base_topic}/spa/#{type}#{i}",
399
- command_topic: "#{@base_topic}/spa/#{type}#{i}/set",
400
- payload_on: "true",
401
- payload_off: "false",
402
- state_on: "true",
403
- state_off: "false"
404
- }
405
- case type
406
- when :light
407
- thing_config[:icon] = "mdi:car-parking-lights"
408
- when :mister
409
- thing_config[:icon] = "mdi:sprinkler-fire"
410
- when :blower
411
- thing_config[:icon] = "mdi:chart-bubble"
412
- end
413
- @mqtt.publish(@ha_switch_path+ "#{type}#{i}/config", thing_config
414
- .merge(@hass_device)
415
- .merge(@hass_availability)
416
- .to_json, true)
417
- end
418
-
419
- def publish_basic_attributes
420
- publish("$homie", "4.0.0")
421
- publish("$name", "BWA Spa")
422
- publish("$state", "init")
423
- publish("$nodes", "spa")
424
-
425
- publish("spa/$name", "BWA Spa")
426
- publish("spa/$type", "spa")
427
- publish_nodes
428
-
429
- publish("spa/hold/$name", "In Hold mode")
430
- publish("spa/hold/$datatype", "boolean")
431
- publish("spa/hold/$settable", "true")
432
- subscribe("spa/hold/set")
433
-
434
- publish("spa/priming/$name", "Is the pump priming")
435
- publish("spa/priming/$datatype", "boolean")
436
-
437
- publish("spa/heatingmode/$name", "Current heating mode")
438
- publish("spa/heatingmode/$datatype", "enum")
439
- publish("spa/heatingmode/$format", "ready,rest,ready_in_rest")
440
- publish("spa/heatingmode/$settable", "true")
441
- subscribe("spa/heatingmode/set")
442
-
443
- publish("spa/temperaturescale/$name", "Temperature scale")
444
- publish("spa/temperaturescale/$datatype", "enum")
445
- publish("spa/temperaturescale/$format", "fahrenheit,celsius")
446
- publish("spa/temperaturescale/$settable", "true")
447
- subscribe("spa/temperaturescale/set")
448
-
449
- publish("spa/24htime/$name", "Clock is 24 hour time")
450
- publish("spa/24htime/$datatype", "boolean")
451
- publish("spa/24htime/$settable", "true")
452
- subscribe("spa/24htime/set")
453
-
454
- publish("spa/heating/$name", "Heater is currently running")
455
- publish("spa/heating/$datatype", "boolean")
456
-
457
- publish("spa/temperaturerange/$name", "Current temperature range")
458
- publish("spa/temperaturerange/$datatype", "enum")
459
- publish("spa/temperaturerange/$format", "high,low")
460
- publish("spa/temperaturerange/$settable", "true")
461
- subscribe("spa/temperaturerange/set")
462
-
463
- publish("spa/currenttemperature/$name", "Current temperature")
464
- publish("spa/currenttemperature/$datatype", "float")
465
-
466
- publish("spa/settemperature/$name", "Set Temperature")
467
- publish("spa/settemperature/$datatype", "float")
468
- publish("spa/settemperature/$settable", "true")
469
- subscribe("spa/settemperature/set")
470
-
471
- publish("spa/filter1/$name", "Filter cycle 1 is currently running")
472
- publish("spa/filter1/$datatype", "boolean")
473
-
474
- publish("spa/filter2/$name", "Filter cycle 2 is currently running")
475
- publish("spa/filter2/$datatype", "boolean")
476
- end
477
-
478
- def publish_pump(i, speeds)
479
- publish("spa/pump#{i}/$name", "Pump #{i} speed")
480
- publish("spa/pump#{i}/$datatype", "integer")
481
- publish("spa/pump#{i}/$format", "0:#{speeds}")
482
- publish("spa/pump#{i}/$settable", "true")
483
- subscribe("spa/pump#{i}/set")
484
-
485
- @things << "pump#{i}"
486
- publish_hass_discovery_pumps(i, speeds)
487
- publish_nodes
488
- end
489
-
490
- def publish_thing(type, i)
491
- publish("spa/#{type}#{i}/$name", "#{type} #{i}")
492
- publish("spa/#{type}#{i}/$datatype", "boolean")
493
- publish("spa/#{type}#{i}/$settable", "true")
494
- subscribe("spa/#{type}#{i}/set")
495
-
496
- @things << "#{type}#{i}"
497
- publish_hass_discovery_things(type, i)
498
- publish_nodes
499
- end
500
-
501
- def publish_mister
502
- publish("spa/mister/$name", type)
503
- publish("spa/mister/$datatype", "boolean")
504
- publish("spa/mister/$settable", "true")
505
- subscribe("spa/mister/set")
506
-
507
- @things << "mister"
508
- publish_nodes
509
- end
510
-
511
- def publish_blower(speeds)
512
- publish("spa/blower/$name", "Blower speed")
513
- publish("spa/blower/$datatype", "integer")
514
- publish("spa/blower/$format", "0:#{speeds}")
515
- publish("spa/blower/$settable", "true")
516
- subscribe("spa/blower/set")
517
-
518
- @things << "blower"
519
- publish_nodes
520
- end
521
-
522
- def publish_circpump
523
- publish("spa/circpump/$name", "Circ pump is currently running")
524
- publish("spa/circpump/$datatype", "boolean")
525
- @things << "circpump"
526
-
527
- publish_nodes
528
- end
529
-
530
- def publish_filtercycles
531
- publish("spa/filter1hour/$name", "Filter Cycle 1 Start Hour")
532
- publish("spa/filter1hour/$datatype", "integer")
533
- publish("spa/filter1hour/$format", "0:24")
534
- publish("spa/filter1hour/$settable", "true")
535
-
536
- publish("spa/filter1minute/$name", "Filter Cycle 1 Start Minutes")
537
- publish("spa/filter1minute/$datatype", "integer")
538
- publish("spa/filter1minute/$format", "0:59")
539
- publish("spa/filter1minute/$settable", "true")
540
-
541
- publish("spa/filter1durationhours/$name", "Filter Cycle 1 Duration Hours")
542
- publish("spa/filter1durationhours/$datatype", "integer")
543
- publish("spa/filter1durationhours/$format", "0:24")
544
- publish("spa/filter1durationhours/$settable", "true")
545
-
546
- publish("spa/filter1durationminutes/$name", "Filter Cycle 1 Duration Minutes")
547
- publish("spa/filter1durationminutes/$datatype", "integer")
548
- publish("spa/filter1durationminutes/$format", "0:59")
549
- publish("spa/filter1durationminutes/$settable", "true")
550
-
551
- publish("spa/filter2enabled/$name", "Filter Cycle 2 Enabled")
552
- publish("spa/filter2enabled/$datatype", "boolean")
553
- publish("spa/filter2enabled/$settable", "true")
554
-
555
- publish("spa/filter2hour/$name", "Filter Cycle 2 Start Hour")
556
- publish("spa/filter2hour/$datatype", "integer")
557
- publish("spa/filter2hour/$format", "0:24")
558
- publish("spa/filter2hour/$settable", "true")
559
-
560
- publish("spa/filter2minute/$name", "Filter Cycle 2 Start Minutes")
561
- publish("spa/filter2minute/$datatype", "integer")
562
- publish("spa/filter2minute/$format", "0:59")
563
- publish("spa/filter2minute/$settable", "true")
564
-
565
- publish("spa/filter2durationhours/$name", "Filter Cycle 2 Duration Hours")
566
- publish("spa/filter2durationhours/$datatype", "integer")
567
- publish("spa/filter2durationhours/$format", "0:24")
568
- publish("spa/filter2durationhours/$settable", "true")
569
-
570
- publish("spa/filter2durationminutes/$name", "Filter Cycle 2 Duration Minutes")
571
- publish("spa/filter2durationminutes/$datatype", "integer")
572
- publish("spa/filter2durationminutes/$format", "0:59")
573
- publish("spa/filter2durationminutes/$settable", "true")
574
-
575
- subscribe("spa/filter1hour/set")
576
- subscribe("spa/filter1minute/set")
577
- subscribe("spa/filter1durationhours/set")
578
- subscribe("spa/filter1durationminutes/set")
579
- subscribe("spa/filter2enabled/set")
580
- subscribe("spa/filter2hour/set")
581
- subscribe("spa/filter2minute/set")
582
- subscribe("spa/filter2durationhours/set")
583
- subscribe("spa/filter2durationminutes/set")
584
-
585
- @things.merge(["filter1hour,filter1minute,filter1durationhours,filter1durationminutes,filter2enabled,filter2hour,filter2minute,filter2durationhours,filter2durationminutes"])
586
-
587
- publish_nodes
588
- end
589
-
590
- def publish_nodes
591
- publish("spa/$properties", (["hold,priming,heatingmode,temperaturescale,24htime,heating,temperaturerange,currenttemperature,settemperature,filter1,filter2"] + @things.to_a).join(','))
592
- end
593
- end
594
-
595
- mqtt_uri = ARGV.shift
596
-
597
- if ARGV.empty?
598
- spas = BWA::Discovery.discover
599
- if spas.empty?
600
- BWA.logger.fatal "Could not find spa!"
601
- $stderr.puts "Could not find spa!"
602
- exit 1
603
- end
604
- spa_ip = "tcp://#{spas.first.first}/"
605
- else
606
- spa_ip = ARGV[0]
607
- end
608
-
609
- spa = BWA::Client.new(spa_ip)
610
-
611
- spa.request_configuration
612
- spa.request_filter_configuration
613
-
614
- MQTTBridge.new(mqtt_uri, spa)