waterfurnace_aurora 0.6.4 → 0.7.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: aa7915f9b848e8cea608787f628b077e7fc2d5904044581758099db9a3b26742
4
- data.tar.gz: ecf97a652368c8ed73d6bffdea6d1961e1cbb85c0587e50ba5211735368fb7b3
3
+ metadata.gz: 874cdb2301677f41dcae609df8e59651bb875a2f537bb6afa6f66cd2a3a38f1f
4
+ data.tar.gz: 1bda4a259f0989eb7bdff05feac18a9f75a1679edffe1ffe220e5ca3f0bbad32
5
5
  SHA512:
6
- metadata.gz: a8b861192fcb395fbec9643840b9b91aaa3d42193d55efda03812d10114a3f4e076afc2eb79a6294bc89a0e340bd5c14f3f2e2fca25e6d1eefa32c9bff359a20
7
- data.tar.gz: a35c95acd756183eb2bd2af220e65a182a2206b054453fb49c0e550d512831328d74f72df8e46aec118824efd581fd26e04374b67dbc7898b07f9a964d1123d8
6
+ metadata.gz: a7bb6b496cf370651f22292b225a72113ad390ebbfcfada985d6d7b3bd5d50b84f9d61b89053e2cd80159abd083adfbc14a90dcb183326048f002b941763e348
7
+ data.tar.gz: 31d6afb25c7df8ccef66da014605bc8a04618cd5b99377ce54462814000b134eb4486554d94bd9b25ef098e3dad07f38617533d0cdcfb4ad0b015070f7667b02
data/exe/aurora_mock CHANGED
@@ -38,7 +38,7 @@ r = slave1.holding_registers = slave2.holding_registers = slave255.holding_regis
38
38
  registers = YAML.safe_load(File.read(ARGV[2]))
39
39
  registers.each { |(k, v)| r[k] = v }
40
40
 
41
- server1.request_callback = lambda { |uid, func, req|
41
+ server1.request_callback = lambda do |uid, func, req|
42
42
  if func == 68
43
43
  puts "===== no idea to #{uid}: #{req.inspect}"
44
44
  elsif func == 67
@@ -54,9 +54,9 @@ server1.request_callback = lambda { |uid, func, req|
54
54
  else
55
55
  puts "**** new func #{func}"
56
56
  end
57
- }
57
+ end
58
58
 
59
- server1.response_callback = lambda { |uid, func, res, req|
59
+ server1.response_callback = lambda do |uid, func, res, req|
60
60
  if func == 3 && res.is_a?(Array) && req
61
61
  unless req[:quant] == res.length
62
62
  puts "wrong number of results"
@@ -88,7 +88,7 @@ server1.response_callback = lambda { |uid, func, res, req|
88
88
  else
89
89
  puts "**** new func #{func}"
90
90
  end
91
- }
91
+ end
92
92
 
93
93
  server2.start
94
94
  server1.send(:serve, server1.instance_variable_get(:@sp))
data/exe/aurora_monitor CHANGED
@@ -79,7 +79,7 @@ diff_and_print = lambda do |registers|
79
79
  last_registers = new_registers
80
80
  end
81
81
 
82
- server.request_callback = lambda { |uid, func, req|
82
+ server.request_callback = lambda do |uid, func, req|
83
83
  if func == 6
84
84
  puts "#{Time.now} ===== write register to #{uid}:"
85
85
  registers = { req[:addr] => req[:val] }
@@ -104,9 +104,9 @@ server.request_callback = lambda { |uid, func, req|
104
104
  else
105
105
  puts "#{Time.now} **** new func #{func}"
106
106
  end
107
- }
107
+ end
108
108
 
109
- server.response_callback = lambda { |uid, func, res, req|
109
+ server.response_callback = lambda do |uid, func, res, req|
110
110
  if func == 3 && res.is_a?(Array) && req
111
111
  unless req[:quant] == res.length
112
112
  puts "wrong number of results"
@@ -138,7 +138,7 @@ server.response_callback = lambda { |uid, func, res, req|
138
138
  else
139
139
  puts "#{Time.now} **** new func #{func}"
140
140
  end
141
- }
141
+ end
142
142
 
143
143
  server.send(:serve, server.instance_variable_get(:@sp))
144
144
  loop { nil }
@@ -3,6 +3,7 @@
3
3
 
4
4
  require "aurora"
5
5
  require "homie-mqtt"
6
+ require "mqtt/home_assistant"
6
7
  require "ccutrer-serialport"
7
8
  require "uri"
8
9
  require "optparse"
@@ -79,7 +80,7 @@ class MQTTBridge
79
80
  end
80
81
  end
81
82
  end
82
- rescue StandardError => e
83
+ rescue => e
83
84
  warn "failed processing message: #{e}\n#{e.backtrace}"
84
85
  end
85
86
 
@@ -123,41 +124,44 @@ class MQTTBridge
123
124
  end
124
125
 
125
126
  def publish_basic_attributes
126
- @homie_abc = @homie.node("abc", "Aurora Basic Control", "ABC") do |node|
127
+ @homie_abc = @homie.node("abc", "Heat Pump", "ABC") do |node|
127
128
  allowed_modes = %w[lockout standby blower heating cooling eh1 eh2 emergency waiting]
128
129
  allowed_modes << "dehumidify" if @abc.compressor.is_a?(Aurora::Compressor::VSDrive)
129
130
  node.property("current-mode", "Current Heating/Cooling Mode", :enum, @abc.current_mode,
130
131
  format: allowed_modes)
131
132
  node.property("entering-air-temperature", "Entering Air Temperature", :float, @abc.entering_air_temperature,
132
- unit: "ºF")
133
+ unit: "°F")
133
134
  node.property("entering-water-temperature", "Entering Water Temperature", :float,
134
- @abc.entering_water_temperature, unit: "ºF")
135
+ @abc.entering_water_temperature, unit: "°F")
135
136
  node.property("leaving-air-temperature", "Leaving Air Temperature", :float, @abc.leaving_air_temperature,
136
- unit: "ºF")
137
+ unit: "°F")
137
138
  node.property("leaving-water-temperature", "Leaving Water Temperature", :float, @abc.leaving_water_temperature,
138
- unit: "ºF")
139
+ unit: "°F")
139
140
  unless @abc.outdoor_temperature.zero? # TODO: figure out the config if this actually exists
140
- node.property("outdoor-temperature", "Outdoor Temperature", :float, @abc.outdoor_temperature, unit: "ºF")
141
+ node.property("outdoor-temperature", "Outdoor Temperature", :float, @abc.outdoor_temperature, unit: "°F")
141
142
  end
142
143
 
143
- node.property("fp1", "FP1 Sensor", :float, @abc.fp1, unit: "ºF")
144
- node.property("fp2", "FP2 Sensor", :float, @abc.fp2, unit: "ºF")
144
+ node.property("fp1", "FP1 Sensor", :float, @abc.fp1, unit: "°F")
145
+ node.property("fp2", "FP2 Sensor", :float, @abc.fp2, unit: "°F")
145
146
  %i[aux_heat total].each do |component|
146
147
  component = "#{component}_watts"
147
- node.property(component.tr("_", "-"), component.tr("_", " ").titleize, :integer,
148
- @abc.public_send(component), unit: "W")
148
+ node.property(component.tr("_", "-"),
149
+ component.sub("_watts", " Power Usage").tr("_", " ").titleize,
150
+ :integer,
151
+ @abc.public_send(component),
152
+ unit: "W")
149
153
  end
150
154
  end
151
155
 
152
156
  @compressor = @homie.node("compressor", "Compressor", @abc.compressor.type) do |node|
153
- node.property("speed", "Current compressor speed", :integer, @abc.compressor.speed,
157
+ node.property("speed", "Current Speed", :integer, @abc.compressor.speed,
154
158
  format: @abc.compressor.speed_range)
155
- node.property("watts", "Energy Usage", :integer, @abc.compressor.watts, unit: "W") if @abc.energy_monitoring?
159
+ node.property("watts", "Power Usage", :integer, @abc.compressor.watts, unit: "W") if @abc.energy_monitoring?
156
160
 
157
161
  next unless @abc.compressor.is_a?(Aurora::Compressor::VSDrive)
158
162
 
159
- node.property("ambient-temperature", "Compressor ambient temperature", :float,
160
- @abc.compressor.ambient_temperature, unit: "ºF")
163
+ node.property("ambient-temperature", "Ambient Temperature", :float,
164
+ @abc.compressor.ambient_temperature, unit: "°F")
161
165
 
162
166
  next unless @abc.iz2?
163
167
 
@@ -166,19 +170,19 @@ class MQTTBridge
166
170
  end
167
171
 
168
172
  @blower = @homie.node("blower", "Blower", @abc.blower.type) do |node|
169
- node.property("running", "Blower is running", :boolean, @abc.blower.running?)
173
+ node.property("running", "Running", :boolean, @abc.blower.running?)
170
174
  if @abc.blower.respond_to?(:speed)
171
- node.property("speed", "Current blower speed", :integer, @abc.blower.speed, format: @abc.blower.speed_range)
175
+ node.property("speed", "Current Speed", :integer, @abc.blower.speed, format: @abc.blower.speed_range)
172
176
  end
173
- node.property("watts", "Energy Usage", :integer, @abc.blower.watts, unit: "W") if @abc.energy_monitoring?
177
+ node.property("watts", "Power Usage", :integer, @abc.blower.watts, unit: "W") if @abc.energy_monitoring?
174
178
 
175
179
  next unless @abc.blower.is_a?(Aurora::Blower::ECM)
176
180
 
177
181
  presets = %w[blower-only aux-heat]
178
182
  presets.concat %w[low-compressor high-compressor] unless @abc.iz2?
179
183
  presets.each do |setting|
180
- field = "#{setting.tr('-', '_')}_speed"
181
- node.property("#{setting}-speed", "#{setting.tr('-', ' ').titleize} Preset Speed", :integer,
184
+ field = "#{setting.tr("-", "_")}_speed"
185
+ node.property("#{setting}-speed", "#{setting.tr("-", " ").titleize} Preset Speed", :integer,
182
186
  @abc.blower.public_send(field), format: 1..12) do |value, property|
183
187
  @mutex.synchronize { property.value = @abc.blower.public_send("#{field}=", value) }
184
188
  end
@@ -192,23 +196,23 @@ class MQTTBridge
192
196
 
193
197
  @pump = @homie.node("pump", "Loop Pump", @abc.pump.type) do |node|
194
198
  node.property("waterflow", "Waterflow", :float, @abc.pump.waterflow, unit: "gpm")
195
- node.property("watts", "Energy Usage", :integer, @abc.pump.watts, unit: "W") if @abc.energy_monitoring?
199
+ node.property("watts", "Power Usage", :integer, @abc.pump.watts, unit: "W") if @abc.energy_monitoring?
196
200
 
197
201
  next unless @abc.pump.is_a?(Aurora::Pump::VSPump)
198
202
 
199
- node.property("running", "Pump is running", :boolean, @abc.pump.running)
203
+ node.property("running", "Running", :boolean, @abc.pump.running)
200
204
  node.property("speed", "Speed", :integer, @abc.pump.speed, format: 0..100, unit: "%") do |value, property|
201
205
  @mutex.synchronize { property.value = @abc.pump.speed = value }
202
206
  end
203
- node.property("manual-control", "If manual control is enabled", :boolean,
207
+ node.property("manual-control", "Manual Control", :boolean,
204
208
  @abc.pump.manual_control?) do |value, property|
205
209
  @mutex.synchronize { property.value = @abc.pump.manual_control = value }
206
210
  end
207
- node.property("minimum-speed", "Speed pump runs at compressor speed 0", :integer, @abc.pump.minimum_speed,
211
+ node.property("minimum-speed", "Actual Minimum Speed", :integer, @abc.pump.minimum_speed,
208
212
  format: 0..100, unit: "%") do |value, property|
209
213
  @mutex.synchronize { property.value = @abc.pump.minimum_speed = value }
210
214
  end
211
- node.property("maximum-speed", "Speed pump runs at compressor speed 12", :integer, @abc.pump.minimum_speed,
215
+ node.property("maximum-speed", "Actual Maximum Speed", :integer, @abc.pump.minimum_speed,
212
216
  format: 0..100, unit: "%") do |value, property|
213
217
  @mutex.synchronize { property.value = @abc.pump.maximum_speed = value }
214
218
  end
@@ -219,11 +223,11 @@ class MQTTBridge
219
223
  node.property("enabled", "Enabled", :boolean, @abc.dhw.enabled) do |value, property|
220
224
  @mutex.synchronize { property.value = @abc.dhw.enabled = value }
221
225
  end
222
- node.property("running", "DHW Pump is running", :boolean, @abc.dhw.running?)
226
+ node.property("running", "Pump Running", :boolean, @abc.dhw.running?)
223
227
  node.property("water-temperature", "Water Temperature", :float,
224
- @abc.dhw.water_temperature, unit: "ºF")
228
+ @abc.dhw.water_temperature, unit: "°F")
225
229
  node.property("set-point", "Set Point", :float, @abc.dhw.set_point, format: 100..140,
226
- unit: "ºF") do |value, property|
230
+ unit: "°F") do |value, property|
227
231
  @mutex.synchronize { property.value = @abc.dhw.set_point = value }
228
232
  end
229
233
  end
@@ -233,12 +237,12 @@ class MQTTBridge
233
237
  node.property("relative-humidity", "Relative Humidity", :integer, @abc.humidistat.relative_humidity,
234
238
  unit: "%", format: 0..100)
235
239
  if @abc.humidistat.humidifier?
236
- node.property("humidifier-running", "Humidifier is running", :boolean, @abc.humidistat.humidifier_running?)
240
+ node.property("humidifier-running", "Humidifier Running", :boolean, @abc.humidistat.humidifier_running?)
237
241
  node.property("humidifier-mode", "Humidifier Mode", :enum, @abc.humidistat.humidifier_mode,
238
242
  format: %i[auto manual]) do |value, property|
239
243
  @mutex.synchronize { property.value = @abc.humidistat.humidifier_mode = value.to_sym }
240
244
  end
241
- node.property("humidification-target", "Humidification target relative humidity", :integer,
245
+ node.property("humidification-target", "Humidification Target Relative Humidity", :integer,
242
246
  @abc.humidistat.humidification_target, unit: "%", format: 15..50) do |value, property|
243
247
  @mutex.synchronize { property.value = @abc.humidistat.humidification_target = value }
244
248
  end
@@ -250,7 +254,7 @@ class MQTTBridge
250
254
  format: %i[auto manual]) do |value, property|
251
255
  @mutex.synchronize { property.value = @abc.humidistat.dehumidifier_mode = value.to_sym }
252
256
  end
253
- node.property("dehumidification-target", "Dehumidification target relative humidity", :integer,
257
+ node.property("dehumidification-target", "Dehumidification Target Relative Humidity", :integer,
254
258
  @abc.humidistat.dehumidification_target, unit: "%", format: 35..65) do |value, property|
255
259
  @mutex.synchronize { property.value = @abc.humidistat.dehumidification_target = value }
256
260
  end
@@ -258,11 +262,11 @@ class MQTTBridge
258
262
 
259
263
  next unless @abc.humidistat.dehumidifier?
260
264
 
261
- node.property("dehumidifier-running", "Dehumidifier is running", :boolean, @abc.humidistat.dehumidifier_running?)
265
+ node.property("dehumidifier-running", "Dehumidifier Running", :boolean, @abc.humidistat.dehumidifier_running?)
262
266
  end
263
267
 
264
268
  @faults = @homie.node("faults", "Fault History", "ABC") do |node|
265
- node.property("clear-history", "Reset fault counts", :enum, retained: false, format: "clear") do |_|
269
+ node.property("clear-history", "Reset Fault Counts", :enum, retained: false, format: "clear") do |_|
266
270
  @mutex.synchronize { @abc.clear_fault_history }
267
271
  end
268
272
  @abc.faults.each_with_index do |count, i|
@@ -302,13 +306,13 @@ class MQTTBridge
302
306
  node.property("size", "Size", :enum, zone.size, format: %w[0 25 45 70])
303
307
  node.property("normalized-size", "Normalized Size", :integer, zone.normalized_size, unit: "%", format: 0..100)
304
308
  end
305
- node.property("ambient-temperature", "Ambient Temperature", :float, zone.ambient_temperature, unit: "ºF")
309
+ node.property("ambient-temperature", "Ambient Temperature", :float, zone.ambient_temperature, unit: "°F")
306
310
  node.property("heating-target-temperature", "Heating Target Temperature", :integer,
307
- zone.heating_target_temperature, unit: "ºF", format: 40..90) do |value, property|
311
+ zone.heating_target_temperature, unit: "°F", format: 40..90) do |value, property|
308
312
  @mutex.synchronize { property.value = zone.heating_target_temperature = value }
309
313
  end
310
314
  node.property("cooling-target-temperature", "Cooling Target Temperature", :integer,
311
- zone.cooling_target_temperature, unit: "ºF", format: 54..99) do |value, property|
315
+ zone.cooling_target_temperature, unit: "°F", format: 54..99) do |value, property|
312
316
  @mutex.synchronize { property.value = zone.cooling_target_temperature = value }
313
317
  end
314
318
  end
@@ -318,7 +322,175 @@ class MQTTBridge
318
322
  @homie.mqtt.subscribe("#{@homie.topic}/$modbus")
319
323
  @homie.mqtt.subscribe("#{@homie.topic}/$modbus/getregs")
320
324
  @homie.mqtt.subscribe("#{@homie.topic}/$modbus/+/set")
321
- @homie.publish
325
+ @homie.publish do
326
+ # do HASS publishes in this block so they're done in bulk
327
+
328
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["current-mode"],
329
+ device_class: :power)
330
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["entering-air-temperature"],
331
+ device_class: :temperature,
332
+ entity_category: :diagnostic)
333
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["entering-water-temperature"],
334
+ device_class: :temperature,
335
+ entity_category: :diagnostic)
336
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["leaving-air-temperature"],
337
+ device_class: :temperature,
338
+ entity_category: :diagnostic)
339
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["leaving-water-temperature"],
340
+ device_class: :temperature,
341
+ entity_category: :diagnostic)
342
+ unless @abc.outdoor_temperature.zero?
343
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["outdoor-temperature"],
344
+ device_class: :temperature)
345
+ end
346
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["fp1"],
347
+ device_class: :temperature,
348
+ entity_category: :diagnostic)
349
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["fp2"],
350
+ device_class: :temperature,
351
+ entity_category: :diagnostic)
352
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["aux-heat-watts"],
353
+ device_class: :power)
354
+ MQTT::HomeAssistant.publish_sensor(@homie["abc"]["total-watts"],
355
+ device_class: :power)
356
+
357
+ MQTT::HomeAssistant.publish_sensor(@homie["compressor"]["speed"])
358
+ MQTT::HomeAssistant.publish_sensor(@homie["compressor"]["watts"],
359
+ device_class: :power)
360
+
361
+ if @abc.compressor.is_a?(Aurora::Compressor::VSDrive)
362
+ MQTT::HomeAssistant.publish_sensor(@homie["compressor"]["ambient-temperature"],
363
+ device_class: :temperature,
364
+ entity_category: :diagnostic)
365
+
366
+ if @abc.iz2?
367
+ MQTT::HomeAssistant.publish_sensor(@homie["compressor"]["iz2-desired-speed"],
368
+ entity_category: :diagnostic)
369
+ end
370
+ end
371
+
372
+ MQTT::HomeAssistant.publish_binary_sensor(@homie["blower"]["running"],
373
+ device_class: :running)
374
+ MQTT::HomeAssistant.publish_sensor(@homie["blower"]["speed"]) if @abc.blower.respond_to?(:speed)
375
+ MQTT::HomeAssistant.publish_sensor(@homie["blower"]["watts"],
376
+ device_class: :power)
377
+ MQTT::HomeAssistant.publish_number(@homie["blower"]["blower-only-speed"],
378
+ entity_category: :config)
379
+ MQTT::HomeAssistant.publish_number(@homie["blower"]["aux-heat-speed"],
380
+ entity_category: :config)
381
+ if @abc.iz2?
382
+ MQTT::HomeAssistant.publish_sensor(@homie["blower"]["iz2-desired-speed"])
383
+ else
384
+ MQTT::HomeAssistant.publish_number(@homie["blower"]["low-compressor-speed"],
385
+ entity_category: :config)
386
+ MQTT::HomeAssistant.publish_number(@homie["blower"]["high-compressor-speed"],
387
+ entity_category: :config)
388
+ end
389
+
390
+ MQTT::HomeAssistant.publish_sensor(@homie["pump"]["waterflow"],
391
+ entity_category: :diagnostic)
392
+ MQTT::HomeAssistant.publish_sensor(@homie["pump"]["watts"],
393
+ device_class: :power)
394
+
395
+ if @abc.pump.is_a?(Aurora::Pump::VSPump)
396
+ MQTT::HomeAssistant.publish_binary_sensor(@homie["pump"]["running"],
397
+ device_class: :running)
398
+ MQTT::HomeAssistant.publish_number(@homie["pump"]["speed"],
399
+ entity_category: :diagnostic)
400
+
401
+ MQTT::HomeAssistant.publish_switch(@homie["pump"]["manual-control"],
402
+ entity_category: :diagnostic)
403
+ MQTT::HomeAssistant.publish_number(@homie["pump"]["minimum-speed"],
404
+ entity_category: :config)
405
+ MQTT::HomeAssistant.publish_number(@homie["pump"]["maximum-speed"],
406
+ entity_category: :config)
407
+ end
408
+
409
+ MQTT::HomeAssistant.publish_scene(@homie["faults"]["clear-history"])
410
+ @homie["faults"].each do |property|
411
+ next if property.id == "clear-history"
412
+
413
+ MQTT::HomeAssistant.publish_sensor(property,
414
+ entity_category: :diagnostic)
415
+ end
416
+
417
+ if @abc.dhw
418
+ MQTT::HomeAssistant.publish_switch(@homie["dhw"]["enabled"],
419
+ icon: "mdi:water-boiler")
420
+ MQTT::HomeAssistant.publish_binary_sensor(@homie["dhw"]["running"],
421
+ device_class: :running)
422
+ MQTT::HomeAssistant.publish_sensor(@homie["dhw"]["water-temperature"],
423
+ device_class: :temperature)
424
+ MQTT::HomeAssistant.publish_number(@homie["dhw"]["set-point"])
425
+ end
426
+
427
+ MQTT::HomeAssistant.publish_sensor(@homie["humidistat"]["relative-humidity"],
428
+ device_class: :humidity)
429
+ if @abc.humidistat.humidifier?
430
+ MQTT::HomeAssistant.publish_humidifier(
431
+ @homie["humidistat"]["humidifier-running"],
432
+ device_class: :humidifier,
433
+ name: "Humidifier",
434
+ id: "humidifier",
435
+ target_property: @homie["humidistat"]["humidification-target"],
436
+ mode_property: @homie["humidistat"]["humidifier-mode"]
437
+ )
438
+ end
439
+ if @abc.humidistat.dehumidifier? || @abc.compressor.is_a?(Aurora::Compressor::VSDrive)
440
+ property = if @abc.humidistat.dehumidifier?
441
+ @homie["humidistat"]["dehumidifier-running"]
442
+ else
443
+ # yeah, this isn't right, but we have to give HASS _something_
444
+ @homie["humidistat"]["humidifier-running"]
445
+ end
446
+ MQTT::HomeAssistant.publish_humidifier(
447
+ property,
448
+ device_class: :dehumidifier,
449
+ name: "Dehumidifier",
450
+ id: "dehumidifier",
451
+ target_property: @homie["humidistat"]["dehumidification-target"],
452
+ mode_property: @homie["humidistat"]["dehumidifier-mode"]
453
+ )
454
+ end
455
+
456
+ @abc.zones.each_with_index do |zone, i|
457
+ homie_zone = @homie["zone#{i + 1}"]
458
+ MQTT::HomeAssistant.publish_climate(
459
+ action_property: homie_zone["current-mode"],
460
+ current_temperature_property: homie_zone["ambient-temperature"],
461
+ fan_mode_property: homie_zone["target-fan-mode"],
462
+ mode_property: homie_zone["target-mode"],
463
+ temperature_high_property: homie_zone["cooling-target-temperature"],
464
+ temperature_low_property: homie_zone["heating-target-temperature"],
465
+ templates: {
466
+ action_template: <<~JINJA
467
+ {% if value.startswith('h') %}
468
+ heating
469
+ {% elif value.startswith('c') %}
470
+ cooling
471
+ {% elif value == 'standby' %}
472
+ idle
473
+ {% endif %}
474
+ JINJA
475
+ }
476
+ )
477
+ MQTT::HomeAssistant.publish_binary_sensor(homie_zone["current-fan-mode"],
478
+ device_class: :running)
479
+ MQTT::HomeAssistant.publish_select(homie_zone["fan-intermittent-on"],
480
+ entity_category: :config)
481
+ MQTT::HomeAssistant.publish_select(homie_zone["fan-intermittent-off"],
482
+ entity_category: :config)
483
+
484
+ next unless zone.is_a?(Aurora::IZ2Zone)
485
+
486
+ MQTT::HomeAssistant.publish_sensor(homie_zone["priority"],
487
+ entity_category: :diagnostic)
488
+ MQTT::HomeAssistant.publish_sensor(homie_zone["size"],
489
+ entity_category: :diagnostic)
490
+ MQTT::HomeAssistant.publish_sensor(homie_zone["normalized-size"],
491
+ entity_category: :diagnostic)
492
+ end
493
+ end
322
494
  end
323
495
  end
324
496
 
@@ -328,7 +500,7 @@ logger.level = log_level
328
500
  abc.modbus_slave.logger = logger
329
501
 
330
502
  device = "aurora-#{abc.serial_number}"
331
- homie = MQTT::Homie::Device.new(device, "Aurora MQTT Bridge", mqtt: mqtt_uri)
503
+ homie = MQTT::Homie::Device.new(device, "WaterFurnace", mqtt: mqtt_uri)
332
504
  homie.logger = logger
333
505
 
334
506
  MQTTBridge.new(abc, homie)
@@ -92,14 +92,14 @@ module Aurora
92
92
  when 3 then Blower::FiveSpeed.new(self, registers[404])
93
93
  else; Blower::PSC.new(self, registers[404])
94
94
  end
95
- @pump = if (3..5).include?(raw_registers[413])
95
+ @pump = if (3..5).cover?(raw_registers[413])
96
96
  Pump::VSPump.new(self,
97
97
  registers[413])
98
98
  else
99
99
  Pump::GenericPump.new(self,
100
100
  registers[413])
101
101
  end
102
- @dhw = DHW.new(self) if (-999..999).include?(registers[1114])
102
+ @dhw = DHW.new(self) if (-999..999).cover?(registers[1114])
103
103
  @humidistat = Humidistat.new(self,
104
104
  @abc_dipswitches[:accessory_relay] == :humidifier,
105
105
  @axb_dipswitches[:accessory_relay2] == :dehumidifier)
@@ -171,7 +171,7 @@ module Aurora
171
171
  @fp2 = registers[20]
172
172
  @locked_out = registers[25] & 0x8000
173
173
  @error = registers[25] & 0x7fff
174
- @derated = (41..46).include?(@error)
174
+ @derated = (41..46).cover?(@error)
175
175
  @safe_mode = [47, 48, 49, 72, 74].include?(@error)
176
176
  @aux_heat_watts = registers[1151]
177
177
  @total_watts = registers[1153]
@@ -212,7 +212,7 @@ module Aurora
212
212
  end
213
213
 
214
214
  def line_voltage=(value)
215
- raise ArgumentError unless (90..635).include?(value)
215
+ raise ArgumentError unless (90..635).cover?(value)
216
216
 
217
217
  @modbus_slave.holding_registers[112] = value
218
218
  end
@@ -227,13 +227,13 @@ module Aurora
227
227
  pump_speed: :with_compressor,
228
228
  aux_heat: false)
229
229
  raise ArgumentError, "mode must be :off, :heating, or :cooling" unless %i[off heating cooling].include?(mode)
230
- raise ArgumentError, "compressor speed must be between 0 and 12" unless (0..12).include?(compressor_speed)
230
+ raise ArgumentError, "compressor speed must be between 0 and 12" unless (0..12).cover?(compressor_speed)
231
231
 
232
- unless blower_speed == :with_compressor || (0..12).include?(blower_speed)
232
+ unless blower_speed == :with_compressor || (0..12).cover?(blower_speed)
233
233
  raise ArgumentError,
234
234
  "blower speed must be :with_compressor or between 0 and 12"
235
235
  end
236
- unless pump_speed == :with_compressor || (0..100).include?(pump_speed)
236
+ unless pump_speed == :with_compressor || (0..100).cover?(pump_speed)
237
237
  raise ArgumentError,
238
238
  "pump speed must be :with_compressor or between 0 and 100"
239
239
  end
@@ -273,7 +273,7 @@ module Aurora
273
273
  def inspect
274
274
  "#<Aurora::ABCClient #{(instance_variables - [:@modbus_slave]).map do |iv|
275
275
  "#{iv}=#{instance_variable_get(iv).inspect}"
276
- end.join(', ')}>"
276
+ end.join(", ")}>"
277
277
  end
278
278
  end
279
279
  end
data/lib/aurora/blower.rb CHANGED
@@ -6,7 +6,7 @@ module Aurora
6
6
  module Blower
7
7
  class PSC < Component
8
8
  attr_reader :type, :watts, :running
9
- alias running? running
9
+ alias_method :running?, :running
10
10
 
11
11
  def initialize(abc, type)
12
12
  super(abc)
@@ -9,7 +9,7 @@ module Aurora
9
9
  def inspect
10
10
  "#<Aurora::#{self.class.name} #{(instance_variables - [:@abc]).map do |iv|
11
11
  "#{iv}=#{instance_variable_get(iv).inspect}"
12
- end.join(', ')}>"
12
+ end.join(", ")}>"
13
13
  end
14
14
 
15
15
  private
@@ -13,7 +13,7 @@ module Aurora
13
13
  end
14
14
 
15
15
  def type
16
- "#{@stages == 2 ? 'Dual' : 'Single'} Stage Compressor"
16
+ "#{@stages == 2 ? "Dual" : "Single"} Stage Compressor"
17
17
  end
18
18
 
19
19
  def speed_range
data/lib/aurora/dhw.rb CHANGED
@@ -5,7 +5,7 @@ require "aurora/component"
5
5
  module Aurora
6
6
  class DHW < Component
7
7
  attr_reader :enabled, :running, :set_point, :water_temperature
8
- alias running? running
8
+ alias_method :running?, :running
9
9
 
10
10
  def registers_to_read
11
11
  [400..401, 1114]
@@ -23,7 +23,7 @@ module Aurora
23
23
  end
24
24
 
25
25
  def set_point=(value) # rubocop:disable Naming/AccessorMethodName
26
- raise ArgumentError unless (100..140).include?(value)
26
+ raise ArgumentError unless (100..140).cover?(value)
27
27
 
28
28
  raw_value = (value * 10).to_i
29
29
  holding_registers[401] = raw_value
@@ -7,8 +7,8 @@ module Aurora
7
7
  attr_reader :humidifier_running, :humidifier_mode, :humidification_target,
8
8
  :dehumidifier_running, :dehumidifier_mode, :dehumidification_target,
9
9
  :relative_humidity
10
- alias humidifier_running? humidifier_running
11
- alias dehumidifer_running? dehumidifier_running
10
+ alias_method :humidifier_running?, :humidifier_running
11
+ alias_method :dehumidifer_running?, :dehumidifier_running
12
12
 
13
13
  def initialize(abc, has_humidifier, has_dehumidifier)
14
14
  super(abc)
@@ -82,8 +82,8 @@ module Aurora
82
82
  end
83
83
 
84
84
  def set_humidistat_targets(humidification_target, dehumidification_target)
85
- raise ArgumentError unless (15..50).include?(humidification_target)
86
- raise ArgumentError unless (35..65).include?(dehumidification_target)
85
+ raise ArgumentError unless (15..50).cover?(humidification_target)
86
+ raise ArgumentError unless (35..65).cover?(dehumidification_target)
87
87
 
88
88
  holding_registers[abc.iz2? ? 21_115 : 12_310] = (humidification_target << 8) + dehumidification_target
89
89
  @humidification_target = humidification_target
@@ -15,18 +15,18 @@ module Aurora
15
15
  end
16
16
 
17
17
  def registers_to_read
18
- base1 = 21_203 + (zone_number - 1) * 9
19
- base2 = 31_007 + (zone_number - 1) * 3
20
- base3 = 31_200 + (zone_number - 1) * 3
18
+ base1 = 21_203 + ((zone_number - 1) * 9)
19
+ base2 = 31_007 + ((zone_number - 1) * 3)
20
+ base3 = 31_200 + ((zone_number - 1) * 3)
21
21
  [base1..(base1 + 1), base2..(base2 + 2), base3]
22
22
  end
23
23
 
24
24
  def refresh(registers)
25
- @ambient_temperature = registers[31_007 + (zone_number - 1) * 3]
25
+ @ambient_temperature = registers[31_007 + ((zone_number - 1) * 3)]
26
26
 
27
- config1 = registers[31_008 + (zone_number - 1) * 3]
28
- config2 = registers[31_009 + (zone_number - 1) * 3]
29
- config3 = registers[31_200 + (zone_number - 1) * 3]
27
+ config1 = registers[31_008 + ((zone_number - 1) * 3)]
28
+ config2 = registers[31_009 + ((zone_number - 1) * 3)]
29
+ config3 = registers[31_200 + ((zone_number - 1) * 3)]
30
30
 
31
31
  @target_fan_mode = config1[:fan]
32
32
  @fan_intermittent_on = config1[:on_time]
@@ -45,28 +45,28 @@ module Aurora
45
45
  def target_mode=(value)
46
46
  return unless (raw_value = Aurora::HEATING_MODE.invert[value])
47
47
 
48
- holding_registers[21_202 + (zone_number - 1) * 9] = raw_value
48
+ holding_registers[21_202 + ((zone_number - 1) * 9)] = raw_value
49
49
  @target_mode = value
50
50
  end
51
51
 
52
52
  def target_fan_mode=(value)
53
53
  return unless (raw_value = Aurora::FAN_MODE.invert[value])
54
54
 
55
- holding_registers[21_205 + (zone_number - 1) * 9] = raw_value
55
+ holding_registers[21_205 + ((zone_number - 1) * 9)] = raw_value
56
56
  @target_fan_mode = value
57
57
  end
58
58
 
59
59
  def fan_intermittent_on=(value)
60
60
  return unless value >= 0 && value <= 25 && (value % 5).zero?
61
61
 
62
- holding_registers[21_206 + (zone_number - 1) * 9] = value
62
+ holding_registers[21_206 + ((zone_number - 1) * 9)] = value
63
63
  @fan_intermittent_on = value
64
64
  end
65
65
 
66
66
  def fan_intermittent_off=(value)
67
67
  return unless value >= 0 && value <= 40 && (value % 5).zero?
68
68
 
69
- holding_registers[21_207 + (zone_number - 1) * 9] = value
69
+ holding_registers[21_207 + ((zone_number - 1) * 9)] = value
70
70
  @fan_intermittent_off = value
71
71
  end
72
72
 
@@ -74,7 +74,7 @@ module Aurora
74
74
  return unless value >= 40 && value <= 90
75
75
 
76
76
  raw_value = (value * 10).to_i
77
- holding_registers[21_203 + (zone_number - 1) * 9] = raw_value
77
+ holding_registers[21_203 + ((zone_number - 1) * 9)] = raw_value
78
78
  @heating_target_temperature = value
79
79
  end
80
80
 
@@ -82,7 +82,7 @@ module Aurora
82
82
  return unless value >= 54 && value <= 99
83
83
 
84
84
  raw_value = (value * 10).to_i
85
- holding_registers[21_204 + (zone_number - 1) * 9] = raw_value
85
+ holding_registers[21_204 + ((zone_number - 1) * 9)] = raw_value
86
86
  @cooling_target_temperature = value
87
87
  end
88
88
  end
@@ -44,6 +44,6 @@ module Aurora
44
44
  def write_holding_register(addr, value)
45
45
  @registers[addr] = value
46
46
  end
47
- alias []= write_holding_register
47
+ alias_method :[]=, :write_holding_register
48
48
  end
49
49
  end
@@ -4,14 +4,14 @@ module Aurora
4
4
  module ModBus
5
5
  module Slave
6
6
  def read_multiple_holding_registers(*ranges)
7
- values = if ranges.any? { |r| r.is_a?(Range) }
7
+ values = if ranges.any?(Range)
8
8
  addrs_and_lengths = ranges.map do |r|
9
9
  r = Array(r)
10
10
  [r.first, r.last - r.first + 1]
11
11
  end.flatten
12
- query("A#{addrs_and_lengths.pack('n*')}").unpack("n*")
12
+ query("A#{addrs_and_lengths.pack("n*")}").unpack("n*")
13
13
  else
14
- query("B#{ranges.pack('n*')}").unpack("n*")
14
+ query("B#{ranges.pack("n*")}").unpack("n*")
15
15
  end
16
16
  ranges.map { |r| Array(r) }.flatten.zip(values).to_h
17
17
  end
data/lib/aurora/pump.rb CHANGED
@@ -6,7 +6,7 @@ module Aurora
6
6
  module Pump
7
7
  class GenericPump < Component
8
8
  attr_reader :type, :watts, :waterflow, :running
9
- alias running? running
9
+ alias_method :running?, :running
10
10
 
11
11
  def initialize(abc, type)
12
12
  super(abc)
@@ -28,7 +28,7 @@ module Aurora
28
28
 
29
29
  class VSPump < GenericPump
30
30
  attr_reader :speed, :minimum_speed, :maximum_speed, :manual_control
31
- alias manual_control? manual_control
31
+ alias_method :manual_control?, :manual_control
32
32
 
33
33
  def registers_to_read
34
34
  super + [321..325]
@@ -108,7 +108,7 @@ module Aurora
108
108
  48 => "EEV OD Comm Error", # Com with EEV is interupted EEV has gone independent mode
109
109
  49 => "Cabinet Temperature Sensor", # Ambient Temperature (Tamb) is <-76 or > 212 F and out of range or invalid
110
110
  51 => "Discharge Temp Sensor", # Discharge Sensor (Sd) is > 280 F or invalid (-76 to 392 F)
111
- 52 => "Suction Presure Sensor", # Suction Pressure (P0) is invalid (0 to 232 psi)
111
+ 52 => "Suction Pressure Sensor", # Suction Pressure (P0) is invalid (0 to 232 psi)
112
112
  53 => "Condensing Pressure Sensor", # Low condensing pressure (PD) or invalid (0 to 870 psi) Retry 10x.
113
113
  54 => "Low Supply Voltage", # Supply Voltage is <180 V (190V to reset) or powered off/on too quickly (<30 sec.).
114
114
  55 => "Out of Envelope", # Comp Operating out of envelope (P0) more than 90 sec. Retry 10x.
@@ -550,7 +550,7 @@ module Aurora
550
550
  REGISTER_FORMATS = {
551
551
  "%ds" => [1, 6, 9, 15, 84, 85, 110],
552
552
  "%dV" => [16, 112, 3331, 3424, 3523],
553
- "%0.1fºF" => [19, 20, 401, 501, 502, 567, 740, 745, 746, 747, 900, 903,
553
+ "%0.1f°F" => [19, 20, 401, 501, 502, 567, 740, 745, 746, 747, 900, 903,
554
554
  1109, 1110, 1111, 1112, 1113, 1114, 1124, 1125, 1134, 1135, 1136,
555
555
  3325, 3326, 3327, 3330, 3522, 3903, 3905, 3906,
556
556
  12_619, 12_620,
@@ -587,9 +587,9 @@ module Aurora
587
587
 
588
588
  def zone_registers
589
589
  (1..6).map do |i|
590
- base1 = 21_202 + (i - 1) * 9
591
- base2 = 31_007 + (i - 1) * 3
592
- base3 = 31_200 + (i - 1) * 3
590
+ base1 = 21_202 + ((i - 1) * 9)
591
+ base2 = 31_007 + ((i - 1) * 3)
592
+ base3 = 31_200 + ((i - 1) * 3)
593
593
  {
594
594
  base1 => "Zone #{i} Heating Mode (write)",
595
595
  (base1 + 1) => "Zone #{i} Heating Setpoint (write)",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aurora
4
- VERSION = "0.6.4"
4
+ VERSION = "0.7.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waterfurnace_aurora
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-08 00:00:00.000000000 Z
11
+ date: 2021-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ccutrer-serialport
@@ -25,25 +25,25 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: homie-mqtt
28
+ name: mqtt-homeassistant
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.4'
33
+ version: '0'
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: 1.4.5
36
+ version: 0.0.2
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: '1.4'
43
+ version: '0'
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 1.4.5
46
+ version: 0.0.2
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: net-telnet-rfc2217
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -98,28 +98,56 @@ dependencies:
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '9.0'
101
+ version: '11.0'
102
102
  type: :development
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - "~>"
107
107
  - !ruby/object:Gem::Version
108
- version: '9.0'
108
+ version: '11.0'
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: rubocop
111
111
  requirement: !ruby/object:Gem::Requirement
112
112
  requirements:
113
113
  - - "~>"
114
114
  - !ruby/object:Gem::Version
115
- version: '1.19'
115
+ version: '1.23'
116
116
  type: :development
117
117
  prerelease: false
118
118
  version_requirements: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - "~>"
121
121
  - !ruby/object:Gem::Version
122
- version: '1.19'
122
+ version: '1.23'
123
+ - !ruby/object:Gem::Dependency
124
+ name: rubocop-performance
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '1.12'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '1.12'
137
+ - !ruby/object:Gem::Dependency
138
+ name: rubocop-rake
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '0.6'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '0.6'
123
151
  description:
124
152
  email: cody@cutrer.com'
125
153
  executables:
@@ -157,7 +185,8 @@ files:
157
185
  homepage: https://github.com/ccutrer/waterfurnace_aurora
158
186
  licenses:
159
187
  - MIT
160
- metadata: {}
188
+ metadata:
189
+ rubygems_mfa_required: 'true'
161
190
  post_install_message:
162
191
  rdoc_options: []
163
192
  require_paths: