waterfurnace_aurora 1.0.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8311d85ee1e300bcfbb3228a65cb98a69301f25f27569c36d898faf97c25fbd5
4
- data.tar.gz: 86eab096d17d12aa01bb56f253022d64bb806d5aec3b55c6efc16a895b75d111
3
+ metadata.gz: caf73ece152211ae227b1b628572d0dc43936b600c2d41a0a534178dc74385cd
4
+ data.tar.gz: d5ed42012eb9fc1e2aca036914cfd538e3342df0f34342e2c9c37d18ad6cce29
5
5
  SHA512:
6
- metadata.gz: 7edd9fd909c0b9fe316f306bf00a56eff1108f467718d71c1645596675938abd67c5e727b4f6312d79c1d706df0f22f7d65f475c35061f7b66405add92eec342
7
- data.tar.gz: b0a6f4af036ebcd003557777e1fd276e33e56e1cbfbde268ad42a5a5bfa729c9ffa718dd3fd08917aad8beba2bf4d894519de128a5ba1519b5988ba5ddc707f7
6
+ metadata.gz: eaacad438ac440a004f8611b907f9eff3e453193884627178dc8608f66ff29640f5e355993069b34d83ef796cb6169f0d25bc4a1b06103a44194d339618f08a6
7
+ data.tar.gz: 00e3dfeba4fc12ec7804fcde37241ff93de9f60bb91f03e7182f309de383890454f83f959aeacfd5a3924874bd56ca1c5aaa853ca52b05abd56fd894aa3d0f38
data/exe/aurora_fetch CHANGED
@@ -8,20 +8,31 @@ require "optparse"
8
8
  require "uri"
9
9
  require "yaml"
10
10
 
11
- debug_modbus = yaml = false
11
+ debug_modbus = yaml = ignore_missing_registers = false
12
12
  try_individual = nil
13
13
 
14
14
  options = OptionParser.new do |opts|
15
15
  opts.banner = "Usage: aurora_fetch /path/to/serial/port REGISTERS [options]"
16
16
 
17
17
  opts.separator("")
18
- opts.separator("Use `known` to fetch all identified registers. Use `valid` to fetch all registers that will respond.")
18
+ opts.separator(<<~TEXT)
19
+ Use `known` to fetch all identified registers. Use `valid` to fetch all registers
20
+ that should respond. Use `all` to search the entire ModBus address space. Note that
21
+ logging of current progress is only periodic, and does not log every register it's
22
+ trying to fetch.
23
+ TEXT
19
24
  opts.separator("")
20
25
 
21
- opts.on("--debug-modbus", "Print actual protocol bytes") { debug_modbus = true }
26
+ opts.on("--debug-modbus", "Print actual protocol bytes") do
27
+ debug_modbus = true
28
+ end
22
29
  opts.on("--[no-]try-individual",
23
30
  "Query registers one-by-one if a range has an illegal address. " \
24
31
  "Defaults to true for `valid` and `known` special registers, false otherwise.") { |v| try_individual = v }
32
+ opts.on("--ignore-missing-registers",
33
+ "For YAML input only, just log a warning when a register doesn't exist, instead of failing") do
34
+ ignore_missing_registers = true
35
+ end
25
36
  opts.on("-y", "--yaml", "Output raw values as YAML") { yaml = true }
26
37
  opts.on("-v", "--version", "Print version") do
27
38
  puts Aurora::VERSION
@@ -40,11 +51,11 @@ unless ARGV.length == 2
40
51
  exit 1
41
52
  end
42
53
 
43
- modbus_slave = Aurora::ABCClient.open_modbus_slave(ARGV[0])
54
+ modbus_slave = Aurora::ABCClient.open_modbus_slave(ARGV[0], ignore_missing_registers: ignore_missing_registers)
44
55
  modbus_slave.read_retry_timeout = 15
45
56
  modbus_slave.read_retries = 2
46
- modbus_slave.logger = Logger.new($stdout)
47
- modbus_slave.logger.level = debug_modbus ? :debug : :warn
57
+ Aurora.logger = modbus_slave.logger = Logger.new($stderr)
58
+ modbus_slave.logger.level = debug_modbus ? :debug : :info
48
59
 
49
60
  registers = Aurora::ABCClient.query_registers(modbus_slave, ARGV[1], try_individual: try_individual)
50
61
 
@@ -90,30 +90,33 @@ class MQTTBridge
90
90
  loop do
91
91
  begin
92
92
  @mutex.synchronize do
93
- @abc.refresh
94
-
95
- components = { @homie_abc => @abc,
96
- @aux_heat => @abc.aux_heat,
97
- @compressor => @abc.compressor,
98
- @blower => @abc.blower,
99
- @pump => @abc.pump,
100
- @dhw => @abc.dhw,
101
- @humidistat => @abc.humidistat }.compact
102
- @abc.zones.each_with_index do |z, idx|
103
- homie_zone = @homie["zone#{idx + 1}"]
104
- components[homie_zone] = z
105
- end
93
+ @homie.mqtt.batch_publish do
94
+ @abc.refresh
95
+
96
+ components = { @homie_abc => @abc,
97
+ @aux_heat => @abc.aux_heat,
98
+ @compressor => @abc.compressor,
99
+ @blower => @abc.blower,
100
+ @pump => @abc.pump,
101
+ @dhw => @abc.dhw,
102
+ @humidistat => @abc.humidistat }.compact
103
+ @abc.zones.each_with_index do |z, idx|
104
+ homie_zone = @homie["zone#{idx + 1}"]
105
+ components[homie_zone] = z
106
+ end
106
107
 
107
- components.each do |(node, object)|
108
- node.each do |property|
109
- property.value = object.public_send(property.id.tr("-", "_"))
108
+ components.each do |(node, object)|
109
+ node.each do |property|
110
+ property.value = object.public_send(property.id.tr("-", "_"))
111
+ end
110
112
  end
111
- end
112
113
 
113
- @abc.faults.each_with_index do |fault_count, i|
114
- next if fault_count == 0xffff
114
+ @faults["current"].value = @abc.current_fault
115
+ @abc.faults.each_with_index do |fault_count, i|
116
+ next if fault_count == 0xffff
115
117
 
116
- @faults["e#{i + 1}"].value = fault_count
118
+ @faults["e#{i + 1}"].value = fault_count
119
+ end
117
120
  end
118
121
  end
119
122
  rescue => e
@@ -140,6 +143,31 @@ class MQTTBridge
140
143
  @abc.current_mode,
141
144
  format: allowed_modes,
142
145
  hass: { sensor: { state_class: :measurement } })
146
+ node.property("emergency-shutdown",
147
+ "Emergency Shutdown Requested",
148
+ :boolean,
149
+ @abc.emergency_shutdown?,
150
+ hass: :binary_sensor)
151
+ node.property("load-shed",
152
+ "Load Shed Requested",
153
+ :boolean,
154
+ @abc.load_shed?,
155
+ hass: :binary_sensor)
156
+ node.property("locked-out",
157
+ "Is the heat pump currently locked out?",
158
+ :boolean,
159
+ @abc.locked_out?,
160
+ hass: :binary_sensor)
161
+ node.property("derated",
162
+ "Is the compressor currently running at a derated level?",
163
+ :boolean,
164
+ @abc.derated?,
165
+ hass: :binary_sensor)
166
+ node.property("safe-mode",
167
+ "Is the heat pump currently in safe mode?",
168
+ :boolean,
169
+ @abc.safe_mode?,
170
+ hass: :binary_sensor)
143
171
  node.property("entering-air-temperature",
144
172
  "Entering Air Temperature",
145
173
  :float,
@@ -156,6 +184,17 @@ class MQTTBridge
156
184
  hass: { sensor: { device_class: :temperature,
157
185
  state_class: :measurement,
158
186
  entity_category: :diagnostic } })
187
+ node.property("low-pressure-switch",
188
+ "Low Pressure Switch Status",
189
+ :enum,
190
+ @abc.low_pressure_switch,
191
+ format: %w[open closed])
192
+ node.property("high-pressure-switch",
193
+ "High Pressure Switch Status",
194
+ :enum,
195
+ @abc.high_pressure_switch,
196
+ format: %w[open closed])
197
+
159
198
  if @abc.awl_communicating?
160
199
  node.property("leaving-air-temperature",
161
200
  "Leaving Air Temperature",
@@ -193,18 +232,10 @@ class MQTTBridge
193
232
  unit: "V") do |value|
194
233
  @mutex.synchronize { @abc.line_voltage = value }
195
234
  end
196
- node.property("fp1",
197
- "FP1 Sensor",
235
+ node.property("air-coil-temperature",
236
+ "Air Coil Temperature (FP2)",
198
237
  :float,
199
- @abc.fp1,
200
- unit: "°F",
201
- hass: { sensor: { device_class: :temperature,
202
- state_class: :measurement,
203
- entity_category: :diagnostic } })
204
- node.property("fp2",
205
- "FP2 Sensor",
206
- :float,
207
- @abc.fp2,
238
+ @abc.air_coil_temperature,
208
239
  unit: "°F",
209
240
  hass: { sensor: { device_class: :temperature,
210
241
  state_class: :measurement,
@@ -227,6 +258,22 @@ class MQTTBridge
227
258
  @abc.compressor.speed,
228
259
  format: @abc.compressor.speed_range,
229
260
  hass: { sensor: { state_class: :measurement } })
261
+ node.property("cooling-liquid-line-temperature",
262
+ "Cooling Liquid Line Temperature (FP1)",
263
+ :float,
264
+ @abc.compressor.cooling_liquid_line_temperature,
265
+ unit: "°F",
266
+ hass: { sensor: { device_class: :temperature,
267
+ state_class: :measurement,
268
+ entity_category: :diagnostic } })
269
+ node.property("saturated-condensor-discharge-temperature",
270
+ "Saturated Condensor Discharge Temperature",
271
+ :float,
272
+ @abc.compressor.saturated_condensor_discharge_temperature,
273
+ unit: "°F",
274
+ hass: { sensor: { device_class: :temperature,
275
+ state_class: :measurement,
276
+ entity_category: :diagnostic } })
230
277
  if @abc.energy_monitoring?
231
278
  node.property("watts",
232
279
  "Power Usage",
@@ -239,6 +286,12 @@ class MQTTBridge
239
286
 
240
287
  next unless @abc.compressor.is_a?(Aurora::Compressor::VSDrive)
241
288
 
289
+ node.property("desired-speed",
290
+ "Desired Speed",
291
+ :integer,
292
+ @abc.compressor.desired_speed,
293
+ format: @abc.compressor.speed_range,
294
+ hass: { sensor: { state_class: :measurement } })
242
295
  node.property("ambient-temperature",
243
296
  "Ambient Temperature",
244
297
  :float,
@@ -271,6 +324,62 @@ class MQTTBridge
271
324
  format: 0..100,
272
325
  hass: { sensor: { state_class: :measurement,
273
326
  entity_category: :diagnostic } })
327
+ node.property("discharge-temperature",
328
+ "Discharge Temperature",
329
+ :float,
330
+ @abc.compressor.discharge_temperature,
331
+ unit: "°F",
332
+ hass: { sensor: { device_class: :temperature,
333
+ state_class: :measurement,
334
+ entity_category: :diagnostic } })
335
+ node.property("discharge-pressure",
336
+ "Discharge Pressure",
337
+ :float,
338
+ @abc.compressor.discharge_pressure,
339
+ unit: "psi",
340
+ hass: { sensor: { device_class: :pressure,
341
+ state_class: :measurement,
342
+ entity_category: :diagnostic } })
343
+ node.property("suction-temperature",
344
+ "Suction Temperature",
345
+ :float,
346
+ @abc.compressor.suction_temperature,
347
+ unit: "°F",
348
+ hass: { sensor: { device_class: :temperature,
349
+ state_class: :measurement,
350
+ entity_category: :diagnostic } })
351
+ node.property("suction-pressure",
352
+ "Suction Pressure",
353
+ :float,
354
+ @abc.compressor.suction_pressure,
355
+ unit: "psi",
356
+ hass: { sensor: { device_class: :pressure,
357
+ state_class: :measurement,
358
+ entity_category: :diagnostic } })
359
+ node.property("saturated-evaporator-discharge-temperature",
360
+ "Saturated Evaporator Discharge Temperature",
361
+ :float,
362
+ @abc.compressor.saturated_evaporator_discharge_temperature,
363
+ unit: "°F",
364
+ hass: { sensor: { device_class: :temperature,
365
+ state_class: :measurement,
366
+ entity_category: :diagnostic } })
367
+ node.property("superheat-temperature",
368
+ "SuperHeat Temperature",
369
+ :float,
370
+ @abc.compressor.superheat_temperature,
371
+ unit: "°F",
372
+ hass: { sensor: { device_class: :temperature,
373
+ state_class: :measurement,
374
+ entity_category: :diagnostic } })
375
+ node.property("eev-open-percentage",
376
+ "Electronic Expansion Valve Open Percentage",
377
+ :integer,
378
+ @abc.compressor.eev_percentage,
379
+ unit: "%",
380
+ format: 0..100,
381
+ hass: { sensor: { state_class: :measurement,
382
+ entity_category: :diagnostic } })
274
383
 
275
384
  next unless @abc.iz2?
276
385
 
@@ -525,6 +634,12 @@ class MQTTBridge
525
634
  end
526
635
 
527
636
  @faults = @homie.node("faults", "Fault History", "ABC") do |node|
637
+ node.property("current",
638
+ "Current fault",
639
+ :integer,
640
+ @abc.current_fault,
641
+ format: 0..99,
642
+ hass: :sensor)
528
643
  node.property("clear-history",
529
644
  "Reset Fault Counts",
530
645
  :enum,
@@ -669,12 +784,12 @@ class MQTTBridge
669
784
  end
670
785
 
671
786
  log_level = ARGV.include?("--debug") ? :debug : :warn
672
- logger = Logger.new($stdout)
673
- logger.level = log_level
674
- abc.modbus_slave.logger = logger
787
+ Aurora.logger = Logger.new($stdout)
788
+ Aurora.logger.level = log_level
789
+ abc.modbus_slave.logger = Aurora.logger
675
790
 
676
791
  device = "aurora-#{abc.serial_number}"
677
792
  homie = MQTT::Homie::Device.new(device, "WaterFurnace", mqtt: mqtt_uri)
678
- homie.logger = logger
793
+ homie.logger = Aurora.logger
679
794
 
680
795
  MQTTBridge.new(abc, homie)
data/exe/web_aid_tool CHANGED
@@ -7,13 +7,17 @@ require "logger"
7
7
  require "optparse"
8
8
  require "yaml"
9
9
 
10
- debug_modbus = monitor = false
10
+ debug_modbus = monitor = ignore_missing_registers = false
11
11
 
12
12
  options = OptionParser.new do |opts|
13
13
  opts.banner = "Usage: web_aid_tool /path/to/serial/port [options]"
14
14
 
15
15
  opts.on("--debug-modbus", "Print actual protocol bytes") { debug_modbus = true }
16
16
  opts.on("--monitor", "Print interpreted registers as they are requested, like aurora_monitor") { monitor = true }
17
+ opts.on("--ignore-missing-registers",
18
+ "For YAML input only, just log a warning when a register doesn't exist, instead of failing") do
19
+ ignore_missing_registers = true
20
+ end
17
21
  opts.on("-v", "--version", "Print version") do
18
22
  puts Aurora::VERSION
19
23
  exit
@@ -31,7 +35,7 @@ unless ARGV.length == 1
31
35
  exit 1
32
36
  end
33
37
 
34
- slave = Aurora::ABCClient.open_modbus_slave(ARGV[0])
38
+ slave = Aurora::ABCClient.open_modbus_slave(ARGV[0], ignore_missing_registers: ignore_missing_registers)
35
39
  slave.logger = Logger.new($stdout)
36
40
  slave.logger.level = debug_modbus ? :debug : :warn
37
41
 
@@ -15,7 +15,7 @@ require "aurora/thermostat"
15
15
  module Aurora
16
16
  class ABCClient
17
17
  class << self
18
- def open_modbus_slave(uri)
18
+ def open_modbus_slave(uri, ignore_missing_registers: false)
19
19
  uri = URI.parse(uri)
20
20
 
21
21
  io = case uri.scheme
@@ -32,7 +32,10 @@ module Aurora
32
32
  require "aurora/mqtt_modbus"
33
33
  return Aurora::MQTTModBus.new(uri)
34
34
  else
35
- return Aurora::MockABC.new(YAML.load_file(uri.path)) if File.file?(uri.path)
35
+ if File.file?(uri.path)
36
+ return Aurora::MockABC.new(YAML.load_file(uri.path),
37
+ ignore_missing_registers: ignore_missing_registers)
38
+ end
36
39
 
37
40
  require "ccutrer-serialport"
38
41
  CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)
@@ -54,6 +57,10 @@ module Aurora
54
57
  implicit = true
55
58
  try_individual = true if try_individual.nil?
56
59
  break Aurora::REGISTER_RANGES
60
+ when "all"
61
+ implicit = true
62
+ try_individual = true if try_individual.nil?
63
+ break 0..65_535
57
64
  when /^(\d+)(?:\.\.|-)(\d+)$/
58
65
  $1.to_i..$2.to_i
59
66
  else
@@ -62,28 +69,48 @@ module Aurora
62
69
  end
63
70
  queries = Aurora.normalize_ranges(ranges)
64
71
  registers = {}
72
+ last_log_time = nil
65
73
  queries.each do |subquery|
74
+ last_log_time = log_query(last_log_time, subquery.inspect)
66
75
  registers.merge!(modbus_slave.read_multiple_holding_registers(*subquery))
67
- rescue ::ModBus::Errors::IllegalDataAddress, ::ModBus::Errors::IllegalFunction
76
+ rescue ::ModBus::Errors::IllegalDataAddress, ::ModBus::Errors::IllegalFunction, ::ModBus::Errors::ModBusTimeout
68
77
  # maybe this unit doesn't respond to all the addresses we want?
69
78
  raise unless implicit
70
79
 
71
80
  # try each query individually
72
81
  subquery.each do |subsubquery|
82
+ last_log_time = log_query(last_log_time, subsubquery.inspect)
73
83
  registers.merge!(modbus_slave.read_multiple_holding_registers(subsubquery))
74
- rescue ::ModBus::Errors::IllegalDataAddress, ::ModBus::Errors::IllegalFunction
84
+ rescue ::ModBus::Errors::IllegalDataAddress,
85
+ ::ModBus::Errors::IllegalFunction,
86
+ ::ModBus::Errors::ModBusTimeout => e
87
+ raise if e.is_a?(::ModBus::Errors::ModBusTimeout) && !try_individual
75
88
  next unless try_individual
76
89
 
77
90
  # seriously?? try each register individually
78
- subsubquery.each do |i|
91
+ Array(subsubquery).each do |i|
92
+ last_log_time = log_query(last_log_time, i.to_s)
79
93
  registers[i] = modbus_slave.holding_registers[i]
80
94
  rescue ::ModBus::Errors::IllegalDataAddress, ::ModBus::Errors::IllegalFunction
95
+ # don't catch ModBusTimeout here... it should have no problem responding to a single register request
81
96
  next
82
97
  end
83
98
  end
84
99
  end
85
100
  registers
86
101
  end
102
+
103
+ private
104
+
105
+ def log_query(last_log_time, query)
106
+ last_log_time ||= Process.clock_gettime(Process::CLOCK_MONOTONIC)
107
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
108
+ if now - last_log_time > 5
109
+ Aurora&.logger&.info("Fetching register(s) #{query}...")
110
+ last_log_time = now
111
+ end
112
+ last_log_time
113
+ end
87
114
  end
88
115
 
89
116
  attr_reader :modbus_slave,
@@ -97,18 +124,31 @@ module Aurora
97
124
  :pump,
98
125
  :dhw,
99
126
  :humidistat,
127
+ :current_fault,
100
128
  :faults,
129
+ :locked_out,
130
+ :derated,
131
+ :safe_mode,
101
132
  :current_mode,
133
+ :low_pressure_switch,
134
+ :high_pressure_switch,
135
+ :emergency_shutdown,
136
+ :load_shed,
102
137
  :entering_air_temperature,
103
138
  :leaving_air_temperature,
104
139
  :leaving_water_temperature,
105
140
  :entering_water_temperature,
106
141
  :outdoor_temperature,
107
- :fp1,
108
- :fp2,
142
+ :air_coil_temperature,
109
143
  :line_voltage,
110
144
  :watts
111
145
 
146
+ alias_method :emergency_shutdown?, :emergency_shutdown
147
+ alias_method :load_shed?, :load_shed
148
+ alias_method :locked_out?, :locked_out
149
+ alias_method :derated?, :derated
150
+ alias_method :safe_mode?, :safe_mode
151
+
112
152
  def initialize(uri)
113
153
  @modbus_slave = self.class.open_modbus_slave(uri)
114
154
  @modbus_slave.read_retry_timeout = 15
@@ -156,7 +196,9 @@ module Aurora
156
196
 
157
197
  @faults = []
158
198
 
159
- @registers_to_read = [6, 19..20, 25, 30, 112, 344, 567, 1104, 1110..1111, 1114, 1150..1153, 1165]
199
+ @entering_air_register = awl_axb? ? 740 : 567
200
+ @registers_to_read = [6, 19..20, 25, 30..31, 112, 344, @entering_air_register, 1104, 1110..1111, 1114, 1150..1153,
201
+ 1165]
160
202
  @registers_to_read.concat([741, 31_003]) if awl_communicating?
161
203
  @registers_to_read << 900 if awl_axb?
162
204
  zones.each do |z|
@@ -183,17 +225,20 @@ module Aurora
183
225
 
184
226
  outputs = registers[30]
185
227
 
186
- @entering_air_temperature = registers[567]
228
+ @entering_air_temperature = registers[@entering_air_register]
187
229
  @leaving_air_temperature = registers[900] if awl_axb?
188
230
  @leaving_water_temperature = registers[1110]
189
231
  @entering_water_temperature = registers[1111]
190
232
  @outdoor_temperature = registers[31_003]
191
- @fp1 = registers[19]
192
- @fp2 = registers[20]
193
- @locked_out = registers[25] & 0x8000
194
- @error = registers[25] & 0x7fff
195
- @derated = (41..46).cover?(@error)
196
- @safe_mode = [47, 48, 49, 72, 74].include?(@error)
233
+ @air_coil_temperature = registers[20]
234
+ @locked_out = !(registers[25] & 0x8000).zero?
235
+ @current_fault = registers[25] & 0x7fff
236
+ @derated = (41..46).cover?(@current_fault)
237
+ @safe_mode = [47, 48, 49, 72, 74].include?(@current_fault)
238
+ @low_pressure_switch = registers[31][:lps]
239
+ @high_pressure_switch = registers[31][:hps]
240
+ @emergency_shutdown = !!registers[31][:emergency_shutdown]
241
+ @load_shed = !!registers[31][:load_shed]
197
242
  @line_voltage = registers[112]
198
243
  @watts = registers[1153]
199
244
 
@@ -5,7 +5,7 @@ require "aurora/component"
5
5
  module Aurora
6
6
  module Compressor
7
7
  class GenericCompressor < Component
8
- attr_reader :speed, :watts
8
+ attr_reader :speed, :watts, :cooling_liquid_line_temperature, :saturated_condensor_discharge_temperature
9
9
 
10
10
  def initialize(abc, stages)
11
11
  super(abc)
@@ -21,11 +21,9 @@ module Aurora
21
21
  end
22
22
 
23
23
  def registers_to_read
24
- if abc.energy_monitoring?
25
- [1146..1147]
26
- else
27
- []
28
- end
24
+ result = [19, 1134]
25
+ result << (1146..1147) if abc.energy_monitoring?
26
+ result
29
27
  end
30
28
 
31
29
  def refresh(registers)
@@ -37,12 +35,26 @@ module Aurora
37
35
  else
38
36
  0
39
37
  end
38
+ @cooling_liquid_line_temperature = registers[19]
39
+ @saturated_condensor_discharge_temperature = registers[1134]
40
40
  @watts = registers[1146] if abc.energy_monitoring?
41
41
  end
42
42
  end
43
43
 
44
44
  class VSDrive < GenericCompressor
45
- attr_reader :drive_temperature, :inverter_temperature, :ambient_temperature, :iz2_desired_speed, :fan_speed
45
+ attr_reader :drive_temperature,
46
+ :inverter_temperature,
47
+ :ambient_temperature,
48
+ :desired_speed,
49
+ :iz2_desired_speed,
50
+ :fan_speed,
51
+ :discharge_pressure,
52
+ :discharge_temperature,
53
+ :suction_pressure,
54
+ :suction_temperature,
55
+ :saturated_evaporator_discharge_temperature,
56
+ :superheat_temperature,
57
+ :eev_percentage
46
58
 
47
59
  def initialize(abc)
48
60
  super(abc, 12)
@@ -53,7 +65,7 @@ module Aurora
53
65
  end
54
66
 
55
67
  def registers_to_read
56
- result = super + [209, 3001, 3326..3327, 3522, 3524]
68
+ result = super + [209, 3000..3001, 3322..3327, 3522, 3524, 3808, 3903..3906]
57
69
  result << 564 if abc.iz2?
58
70
  result
59
71
  end
@@ -61,11 +73,19 @@ module Aurora
61
73
  def refresh(registers)
62
74
  super
63
75
 
76
+ @desired_speed = registers[3000]
64
77
  @speed = registers[3001]
78
+ @discharge_pressure = registers[3322]
79
+ @suction_pressure = registers[3323]
80
+ @discharge_temperature = registers[3325]
65
81
  @ambient_temperature = registers[3326]
66
82
  @drive_temperature = registers[3327]
67
83
  @inverter_temperature = registers[3522]
68
84
  @fan_speed = registers[3524]
85
+ @eev_percentage = registers[3808]
86
+ @suction_temperature = registers[3903]
87
+ @saturated_evaporator_discharge_temperature = registers[3905]
88
+ @superheat_temperature = registers[3906]
69
89
 
70
90
  @iz2_desired_speed = registers[564] if abc.iz2?
71
91
  end
@@ -4,7 +4,8 @@ module Aurora
4
4
  class MockABC
5
5
  attr_accessor :logger
6
6
 
7
- def initialize(registers)
7
+ def initialize(registers, ignore_missing_registers: false)
8
+ @ignore_missing_registers = ignore_missing_registers
8
9
  @registers = registers
9
10
  end
10
11
 
@@ -59,6 +60,8 @@ module Aurora
59
60
  private
60
61
 
61
62
  def missing_register(idx)
63
+ raise ::ModBus::Errors::IllegalDataAddress unless @ignore_missing_registers
64
+
62
65
  logger.warn("missing register #{idx}")
63
66
  end
64
67
  end
@@ -60,6 +60,7 @@ module Aurora
60
60
  end
61
61
 
62
62
  def to_int32(registers, idx)
63
+ Aurora&.logger&.warn("Missing register #{idx + 1}") unless registers[idx + 1]
63
64
  (registers[idx] << 16) + registers[idx + 1]
64
65
  end
65
66
 
@@ -708,8 +709,8 @@ module Aurora
708
709
  17 => "Aux/E Heat Stage", # this is how long aux/eheat have been requested in seconds
709
710
  # when in eheat mode (explicit on the thermostat), it will stage up to eh2 after 130s
710
711
  # when in aux mode (thermostat set to heat; compressor at full capacity), it will stage up to eh2 after 310s
711
- 19 => "FP1 (Cooling Liquid Line) Temperature",
712
- 20 => "FP2",
712
+ 19 => "Cooling Liquid Line Temperature (FP1)",
713
+ 20 => "Air Coil Temperature (FP2)",
713
714
  21 => "Condensate", # >= 270 normal, otherwise fault
714
715
  25 => "Last Fault Number", # high bit set if locked out
715
716
  26 => "Last Lockout",
@@ -858,7 +859,11 @@ module Aurora
858
859
  1154 => "Heat of Extraction",
859
860
  1156 => "Heat of Rejection",
860
861
  1164 => "Pump Watts",
862
+ # this combines thermostat/iz2 desired speed with manual operation override
861
863
  3000 => "Compressor Speed Desired",
864
+ # this shows the actual speed
865
+ # it can differ from desired during a ramp to the desired speed, or
866
+ # the periodic ramp up to speed 6 that's not visible in the desired speed
862
867
  3001 => "Compressor Speed Actual",
863
868
  3002 => "Manual Operation",
864
869
  3027 => "Compressor Speed",
@@ -884,7 +889,7 @@ module Aurora
884
889
  3523 => "VS Drive UDC Voltage",
885
890
  3524 => "VS Drive Fan Speed",
886
891
  3804 => "VS Drive Details (EEV2 Ctl)",
887
- 3808 => "VS Drive SuperHeat Percent",
892
+ 3808 => "VS Drive EEV2 % Open",
888
893
  3903 => "VS Drive Suction Temperature",
889
894
  3904 => "VS Drive Leaving Air Temperature?",
890
895
  3905 => "VS Drive Saturated Evaporator Discharge Temperature",
@@ -15,9 +15,9 @@ module Aurora
15
15
  :fan_intermittent_off
16
16
 
17
17
  def registers_to_read
18
- return [31] unless @abc.awl_thermostat?
18
+ return [] unless @abc.awl_thermostat?
19
19
 
20
- [31, 502, 745..746, 12_005..12_006]
20
+ [502, 745..746, 12_005..12_006]
21
21
  end
22
22
 
23
23
  def refresh(registers)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aurora
4
- VERSION = "1.0.1"
4
+ VERSION = "1.2.2"
5
5
  end
data/lib/aurora.rb CHANGED
@@ -15,4 +15,7 @@ ModBus::Client::Slave.prepend(Aurora::ModBus::Slave)
15
15
  ModBus::RTUSlave.prepend(Aurora::ModBus::RTU)
16
16
 
17
17
  module Aurora
18
+ class << self
19
+ attr_accessor :logger
20
+ end
18
21
  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: 1.0.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-28 00:00:00.000000000 Z
11
+ date: 2022-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ccutrer-serialport