waterfurnace_aurora 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64e8260cab984391d973114e5e09a98cc4331c166d13f1797bab6e0f292d2953
4
- data.tar.gz: b0a430cbf5310a30c839e9ca19807081aa316cffa80ce3c230fcffe5af928ab0
3
+ metadata.gz: fde3dc688654c589d5638b794484035f3ab7ca8c102fe1ef27bb6365ddd51d22
4
+ data.tar.gz: 6d679712a9375c94f8a1f7b2fe3fa6102c606a433c0449049ae289773cdaf735
5
5
  SHA512:
6
- metadata.gz: cce5f85f7b11c6910b294511faa7ea13b0319e58523cd8e42832f03983870296659286aa071db9761cd5c33df3a107d2ae9d6d5b33e430a96daf07b9366111eb
7
- data.tar.gz: 5f8affbb114893a9a67accd843b70f1a328b54d9c1485b455740e056b5f1d465f86e20a86e1d13b6c3cd7e2a9ddeabef5d6d72771c811cb5101b57bdfd881379
6
+ metadata.gz: dd90afd3a8f15ddec22ec29f23679d4def25b768b47eaf7adc37c37ab0a5b98bfb98a11811133d67dbbb1afd23b03ea5689fe4be55c2966eb19b68b9b8827667
7
+ data.tar.gz: 9c855a9730f2a86678876f3866ea7a6583925781e2397e13738b9f413e4b318a89c7860706e22e88c94d090f37afccd775b2b54242b9555530993e7021b995c6
data/exe/aurora_fetch ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "aurora"
5
+ require "ccutrer-serialport"
6
+ require "uri"
7
+
8
+ uri = URI.parse(ARGV[0])
9
+
10
+ args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
11
+ require "net/telnet/rfc2217"
12
+ [Net::Telnet::RFC2217.new("Host" => uri.host,
13
+ "Port" => uri.port || 23,
14
+ "baud" => 19_200,
15
+ "parity" => Net::Telnet::RFC2217::EVEN)]
16
+ else
17
+ [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
18
+ end
19
+
20
+ client = ModBus::RTUClient.new(*args)
21
+ client.debug = true
22
+ slave = client.with_slave(1)
23
+
24
+ registers = slave.holding_registers[ARGV[1].to_i]
25
+
26
+ puts registers.inspect
@@ -1,21 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'aurora'
4
- require 'ccutrer-serialport'
5
- require 'uri'
6
- require 'yaml'
4
+ require "aurora"
5
+ require "ccutrer-serialport"
6
+ require "uri"
7
+ require "yaml"
7
8
 
8
9
  uri = URI.parse(ARGV[0])
9
10
 
10
11
  args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
11
- require 'net/telnet/rfc2217'
12
- [Net::Telnet::RFC2217.new('Host' => uri.host,
13
- 'Port' => uri.port || 23,
14
- 'baud' => 19200,
15
- 'parity' => Net::Telnet::RFC2217::EVEN)]
16
- else
17
- [CCutrer::SerialPort.new(uri.path, baud: 19200, parity: :even)]
18
- end
12
+ require "net/telnet/rfc2217"
13
+ [Net::Telnet::RFC2217.new("Host" => uri.host,
14
+ "Port" => uri.port || 23,
15
+ "baud" => 19_200,
16
+ "parity" => Net::Telnet::RFC2217::EVEN)]
17
+ else
18
+ [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
19
+ end
19
20
 
20
21
  port = ARGV[1]&.to_i || 502
21
22
 
@@ -27,13 +28,13 @@ slave2 = server1.with_slave(2)
27
28
  server2 = ModBus::TCPServer.new(port)
28
29
  slave255 = server2.with_slave(255)
29
30
 
30
- r = slave1.holding_registers = slave2.holding_registers = slave255.holding_registers = Array.new(31473, 0)
31
+ r = slave1.holding_registers = slave2.holding_registers = slave255.holding_registers = Array.new(31_473, 0)
31
32
 
32
33
  # prepopulate some data
33
- registers = YAML.load(File.read(File.expand_path('../registers.yml', __FILE__)))
34
+ registers = YAML.safe_load(File.read(File.expand_path("registers.yml", __dir__)))
34
35
  registers.each { |(k, v)| r[k] = v }
35
36
 
36
- server1.request_callback = ->(uid, func, req) do
37
+ server1.request_callback = lambda { |uid, func, req|
37
38
  if func == 68
38
39
  puts "===== no idea to #{uid}: #{req.inspect}"
39
40
  elsif func == 67
@@ -45,12 +46,13 @@ server1.request_callback = ->(uid, func, req) do
45
46
  registers = Range.new(req[:addr], req[:addr] + req[:quant] - 1).zip(req[:val]).to_h
46
47
  puts Aurora.print_registers(registers)
47
48
  elsif [3, 65, 66].include?(func)
49
+ # no output
48
50
  else
49
51
  puts "**** new func #{func}"
50
52
  end
51
- end
53
+ }
52
54
 
53
- server1.response_callback = ->(uid, func, res, req) do
55
+ server1.response_callback = lambda { |uid, func, res, req|
54
56
  if func == 3 && res.is_a?(Array) && req
55
57
  unless req[:quant] == res.length
56
58
  puts "wrong number of results"
@@ -78,12 +80,13 @@ server1.response_callback = ->(uid, func, res, req) do
78
80
  registers = req.zip(res).to_h
79
81
  puts Aurora.print_registers(registers)
80
82
  elsif [16, 67, 68].include?(func)
83
+ # no output
81
84
  else
82
85
  puts "**** new func #{func}"
83
86
  end
84
- end
87
+ }
85
88
 
86
89
  server2.start
87
90
  server1.send(:serve, server1.instance_variable_get(:@sp))
88
- #server1.start
89
- loop {}
91
+ # server1.start
92
+ loop { nil }
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "aurora"
5
+ require "ccutrer-serialport"
6
+ require "optparse"
7
+ require "socket"
8
+ require "uri"
9
+
10
+ diff_only = debug_modbus = ignore_awl_heartbeat = ignore_sensors = false
11
+
12
+ OptionParser.new do |opts|
13
+ opts.banner = "Usage: aurora_monitor /path/to/serial/port [options]"
14
+
15
+ opts.on("-q", "--quiet",
16
+ "Enables quiet mode (--diff-only, --ignore-awl-heartbeat, --ignore-sensors) to ease in deciphering new registers") do # rubocop:disable Layout/LineLength
17
+ diff_only = true
18
+ ignore_awl_heartbeat = true
19
+ ignore_sensors = true
20
+ end
21
+ opts.on("--diff-only", "Only show registers if they've changed from their previous value") { diff_only = true }
22
+ opts.on("--debug-modbus", "Print actual protocol bytes") { debug_modbus = true }
23
+ opts.on("--ignore-awl-heartbeat", "Don't print AWL heartbeat requests") { ignore_awl_heartbeat = true }
24
+ opts.on("--ignore-sensors", "Don't print sensor registers (i.e. because they change a lot)") { ignore_sensors = true }
25
+ opts.on("-h", "--help", "Prints this help") do
26
+ puts opts
27
+ exit
28
+ end
29
+ end.parse!
30
+
31
+ uri = URI.parse(ARGV[0])
32
+
33
+ last_registers = {}
34
+
35
+ SENSOR_REGISTERS = [16, 19, 20, 740, 900, 1109, 1105, 1106, 1107, 1108, 1110, 1111, 1114, 1117, 1134, 1147, 1149, 1151,
36
+ 1153, 1165].freeze
37
+
38
+ args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
39
+ require "net/telnet/rfc2217"
40
+ [Net::Telnet::RFC2217.new("Host" => uri.host,
41
+ "Port" => uri.port || 23,
42
+ "baud" => 19_200,
43
+ "parity" => Net::Telnet::RFC2217::EVEN)]
44
+ else
45
+ [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
46
+ end
47
+
48
+ server = ModBus::RTUServer.new(*args)
49
+ server.promiscuous = true
50
+ server.debug = debug_modbus
51
+
52
+ diff_and_print = lambda do |registers|
53
+ registers = registers.slice(*(registers.keys - SENSOR_REGISTERS)) if ignore_sensors
54
+ next puts Aurora.print_registers(registers) unless diff_only
55
+
56
+ new_registers = last_registers.merge(registers)
57
+ diff = Aurora.diff_registers(last_registers, new_registers)
58
+ unless diff.empty?
59
+ puts "#{Time.now} ===== read"
60
+ puts Aurora.print_registers(diff)
61
+ end
62
+ last_registers = new_registers
63
+ end
64
+
65
+ server.request_callback = lambda { |uid, func, req|
66
+ if func == 68
67
+ puts "#{Time.now} ===== no idea to #{uid}: #{req.inspect}" unless diff_only
68
+ elsif func == 67
69
+ puts "#{Time.now} ===== write discontiguous registers to #{uid}:"
70
+ registers = req.map { |p| [p[:addr], p[:val]] }.to_h
71
+ puts Aurora.print_registers(registers)
72
+ elsif func == 16
73
+ registers = Range.new(req[:addr], req[:addr] + req[:quant] - 1).zip(req[:val]).to_h
74
+ next if ignore_awl_heartbeat && registers == { 460 => 102, 461 => 0, 462 => 5 }
75
+
76
+ puts "#{Time.now} ===== write multiple registers to #{uid}:"
77
+ puts Aurora.print_registers(registers)
78
+ elsif [3, 65, 66].include?(func)
79
+ # no output
80
+ else
81
+ puts "#{Time.now} **** new func #{func}"
82
+ end
83
+ }
84
+
85
+ server.response_callback = lambda { |uid, func, res, req|
86
+ if func == 3 && res.is_a?(Array) && req
87
+ unless req[:quant] == res.length
88
+ puts "wrong number of results"
89
+ next
90
+ end
91
+ puts "#{Time.now} ===== read registers from #{uid}" unless diff_only
92
+ registers = Range.new(req[:addr], req[:addr] + req[:quant], true).to_a.zip(res).to_h
93
+ diff_and_print.call(registers)
94
+ elsif func == 65 && res.is_a?(Array) && req
95
+ register_list = []
96
+ req.each { |params| register_list.concat(Range.new(params[:addr], params[:addr] + params[:quant], true).to_a) }
97
+ unless register_list.length == res.length
98
+ puts "wrong number of results"
99
+ next
100
+ end
101
+ puts "#{Time.now} ===== read multiple register ranges from #{uid}" unless diff_only
102
+ result = register_list.zip(res).to_h
103
+ diff_and_print.call(result)
104
+ elsif func == 66 && res.is_a?(Array) && req
105
+ unless req.length == res.length
106
+ puts "wrong number of results"
107
+ next
108
+ end
109
+ puts "#{Time.now} ===== read discontiguous registers from #{uid}" unless diff_only
110
+ registers = req.zip(res).to_h
111
+ diff_and_print.call(registers)
112
+ elsif [16, 67, 68].include?(func)
113
+ # no output
114
+ else
115
+ puts "#{Time.now} **** new func #{func}"
116
+ end
117
+ }
118
+
119
+ server.send(:serve, server.instance_variable_get(:@sp))
120
+ loop { nil }
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "aurora"
5
+ require "homie-mqtt"
6
+ require "ccutrer-serialport"
7
+ require "uri"
8
+ require "aurora/core_ext/string"
9
+
10
+ uri = URI.parse(ARGV[0])
11
+ mqtt_uri = ARGV[1]
12
+
13
+ args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
14
+ require "net/telnet/rfc2217"
15
+ [Net::Telnet::RFC2217.new("Host" => uri.host,
16
+ "Port" => uri.port || 23,
17
+ "baud" => 19_200,
18
+ "parity" => Net::Telnet::RFC2217::EVEN)]
19
+ else
20
+ [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
21
+ end
22
+
23
+ slave = ModBus::RTUClient.new(*args).with_slave(1)
24
+ abc = Aurora::ABCClient.new(slave)
25
+
26
+ class MQTTBridge
27
+ def initialize(abc, homie)
28
+ @abc = abc
29
+ @homie = homie
30
+ @mutex = Mutex.new
31
+
32
+ @homie.instance_variable_set(:@block, lambda do |topic, value|
33
+ @mutex.synchronize do
34
+ case topic
35
+ when /\$modbus$/
36
+ query = value.split(",").map do |addr|
37
+ case addr
38
+ when "known"
39
+ Aurora::REGISTER_NAMES.keys
40
+ when /^(\d+)\.\.(\d+)$/
41
+ Regexp.last_match(1).to_i..Regexp.last_match(2).to_i
42
+ else
43
+ addr.to_i
44
+ end
45
+ end
46
+ queries = Aurora.normalize_ranges(query)
47
+ registers = {}
48
+ queries.each do |subquery|
49
+ registers.merge!(@abc.modbus_slave.read_multiple_holding_registers(*subquery))
50
+ end
51
+ result = Aurora.print_registers(registers)
52
+ @homie.mqtt.publish("#{@homie.topic}/$modbus/response", result, retain: false, qos: 1)
53
+ when %r{\$modbus/(\d+)$}
54
+ register = Regexp.last_match(1).to_i
55
+ value = case value
56
+ when /\d+/
57
+ value.to_i
58
+ when /0x(\d+)/
59
+ Regexp.last_match(1).to_i(16)
60
+ end
61
+ @abc.modbus_slave.holding_registers[register] = value if value
62
+ end
63
+ end
64
+ rescue StandardError => e
65
+ puts "failed processing message: #{e}\n#{e.backtrace}"
66
+ end)
67
+
68
+ publish_basic_attributes
69
+
70
+ loop do
71
+ begin
72
+ @mutex.synchronize do
73
+ @abc.refresh
74
+ %i[compressor_speed
75
+ current_mode
76
+ dhw_water_temperature
77
+ entering_air_temperature
78
+ fan_speed
79
+ leaving_air_temperature
80
+ leaving_water_temperature
81
+ outdoor_temperature
82
+ relative_humidity
83
+ waterflow
84
+ fp1
85
+ fp2
86
+ compressor_watts
87
+ blower_watts
88
+ aux_heat_watts
89
+ loop_pump_watts
90
+ total_watts].each do |property|
91
+ @homie_abc[property.to_s.tr("_", "-")].value = @abc.public_send(property)
92
+ end
93
+
94
+ @abc.zones.each_with_index do |z, idx|
95
+ homie_zone = @homie["zone#{idx + 1}"]
96
+ homie_zone.each do |property|
97
+ property.value = z.public_send(property.id.tr("-", "_"))
98
+ end
99
+ end
100
+ end
101
+ rescue => e
102
+ puts "got garbage: #{e}; #{e.backtrace}"
103
+ exit 1
104
+ end
105
+ sleep(5)
106
+ end
107
+ end
108
+
109
+ def publish_basic_attributes
110
+ @homie_abc = @homie.node("abc", "Aurora Basic Control", "ABC") do |node|
111
+ node.property("compressor-speed", "Compressor Speed", :integer, @abc.compressor_speed, format: 0..1)
112
+ node.property("current-mode", "Current Heating/Cooling Mode", :enum, @abc.current_mode,
113
+ format: %w[lockout standby blower h1 h2 c1 c2 eh1 eh2])
114
+ node.property("dhw-water-temperature", "DHW Water Temperature", :float, @abc.dhw_water_temperature, unit: "ºF")
115
+ node.property("entering-air-temperature", "Entering Air Temperature", :float, @abc.entering_air_temperature,
116
+ unit: "ºF")
117
+ node.property("entering-water-temperature", "Entering Water Temperature", :float,
118
+ @abc.entering_water_temperature, unit: "ºF")
119
+ node.property("fan-speed", "Fan Speed", :integer, @abc.fan_speed, format: 0..11)
120
+ node.property("leaving-air-temperature", "Leaving Air Temperature", :float, @abc.leaving_air_temperature,
121
+ unit: "ºF")
122
+ node.property("leaving-water-temperature", "Leaving Water Temperature", :float, @abc.leaving_water_temperature,
123
+ unit: "ºF")
124
+ node.property("outdoor-temperature", "Outdoor Temperature", :float, @abc.outdoor_temperature, unit: "ºF")
125
+ node.property("relative-humidity", "Relative Humidity", :integer, @abc.relative_humidity, unit: "%",
126
+ format: 0..100)
127
+ node.property("waterflow", "Waterflow", :float, unit: "gpm")
128
+ node.property("fp1", "FP1 Sensor", :float, @abc.fp1, unit: "ºF")
129
+ node.property("fp2", "FP2 Sensor", :float, @abc.fp2, unit: "ºF")
130
+ %i[compressor blower aux_heat loop_pump total].each do |component|
131
+ component = "#{component}_watts"
132
+ node.property(component.tr("_", "-"), component.tr("_", " ").titleize, :integer,
133
+ @abc.public_send(component), unit: "W")
134
+ end
135
+ end
136
+
137
+ @abc.zones.each_with_index do |zone, i|
138
+ type = zone.is_a?(Aurora::IZ2Zone) ? "IntelliZone 2 Zone" : "Thermostat"
139
+ @homie.node("zone#{i + 1}", "Zone #{i + 1}", type) do |node|
140
+ allowed_modes = %w[off auto cool heat]
141
+ allowed_modes << "eheat" if i.zero?
142
+ node.property("target-mode", "Target Heating/Cooling Mode", :enum, zone.target_mode,
143
+ format: allowed_modes) do |value, property|
144
+ @mutex.synchronize { property.value = zone.target_mode = value.to_sym }
145
+ end
146
+ if zone.respond_to?(:current_mode) # TODO: implement for non-IZ2
147
+ node.property("current-mode", "Current Heating/Cooling Mode Requested", :enum, zone.current_mode,
148
+ format: %w[standby h1 h2 h3 c1 c2])
149
+ end
150
+ node.property("target-fan-mode", "Target Fan Mode", :enum, zone.target_fan_mode,
151
+ format: %w[auto continuous intermittent]) do |value, property|
152
+ @mutex.synchronize { property.value = zone.target_fan_mode = value.to_sym }
153
+ end
154
+ if zone.respond_to?(:current_fan_mode) # TODO: implement for non-IZ2
155
+ node.property("current-fan-mode", "Current Fan Status", :boolean, zone.current_fan_mode)
156
+ node.property("fan-intermittent-on", "Fan Intermittent Mode On Duration", :enum, zone.fan_intermittent_on,
157
+ unit: "M", format: %w[0 5 10 15 20]) do |value, property|
158
+ @mutex.synchronize { property.value = zone.fan_intermittent_on = value.to_i }
159
+ end
160
+ node.property("fan-intermittent-off", "Fan Intermittent Mode Off Duration", :enum, zone.fan_intermittent_on,
161
+ unit: "M", format: %w[0 5 10 15 20 25 30 35 40]) do |value, property|
162
+ @mutex.synchronize { property.value = zone.fan_intermittent_on = value.to_i }
163
+ end
164
+ end
165
+ if zone.is_a?(Aurora::IZ2Zone)
166
+ node.property("priority", "Zone Priority", :enum, zone.priority, format: %w[economy comfort])
167
+ node.property("size", "Size", :enum, zone.size, format: %w[0 25 45 70])
168
+ node.property("normalized-size", "Normalized Size", :integer, zone.normalized_size, unit: "%", format: 0..100)
169
+ end
170
+ node.property("ambient-temperature", "Ambient Temperature", :float, zone.ambient_temperature, unit: "ºF")
171
+ node.property("heating-target-temperature", "Heating Target Temperature", :integer,
172
+ zone.heating_target_temperature, unit: "ºF", format: 40..90) do |value, property|
173
+ @mutex.synchronize { property.value = zone.heating_target_temperature = value }
174
+ end
175
+ node.property("cooling-target-temperature", "Cooling Target Temperature", :integer,
176
+ zone.cooling_target_temperature, unit: "ºF", format: 54..99) do |value, property|
177
+ @mutex.synchronize { property.value = zone.cooling_target_temperature = value }
178
+ end
179
+ end
180
+ end
181
+
182
+ # direct access to modbus registers for debugging purposes
183
+ @homie.mqtt.subscribe("#{@homie.topic}/$modbus")
184
+ @homie.mqtt.subscribe("#{@homie.topic}/$modbus/+")
185
+ @homie.publish
186
+ end
187
+ end
188
+
189
+ MQTTBridge.new(abc, MQTT::Homie::Device.new("aurora", "Aurora MQTT Bridge", mqtt: mqtt_uri))
File without changes
@@ -1,39 +1,54 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aurora
2
4
  class ABCClient
3
5
  attr_reader :modbus_slave,
4
- :iz2_zones,
5
- :current_mode,
6
- :fan_speed,
7
- :entering_air_temperature,
8
- :relative_humidity,
9
- :leaving_air_temperature,
10
- :leaving_water_temperature,
11
- :entering_water_temperature,
12
- :dhw_water_temperature,
13
- :waterflow,
14
- :compressor_speed,
15
- :outdoor_temperature,
16
- :fp1,
17
- :fp2
6
+ :zones,
7
+ :current_mode,
8
+ :fan_speed,
9
+ :entering_air_temperature,
10
+ :relative_humidity,
11
+ :leaving_air_temperature,
12
+ :leaving_water_temperature,
13
+ :entering_water_temperature,
14
+ :dhw_water_temperature,
15
+ :waterflow,
16
+ :compressor_speed,
17
+ :outdoor_temperature,
18
+ :fp1,
19
+ :fp2,
20
+ :compressor_watts,
21
+ :blower_watts,
22
+ :aux_heat_watts,
23
+ :loop_pump_watts,
24
+ :total_watts
18
25
 
19
26
  def initialize(modbus_slave)
20
27
  @modbus_slave = modbus_slave
21
28
  @modbus_slave.read_retry_timeout = 15
22
29
  @modbus_slave.read_retries = 2
23
30
  iz2_zone_count = @modbus_slave.holding_registers[483]
24
- @iz2_zones = (0...iz2_zone_count).map { |i| IZ2Zone.new(self, i + 1) }
31
+ # TODO: better detect IZ2/Non-IZ2
32
+ @zones = if iz2_zone_count > 1
33
+ (0...iz2_zone_count).map { |i| IZ2Zone.new(self, i + 1) }
34
+ else
35
+ [Thermostat.new(self)]
36
+ end
25
37
  end
26
38
 
27
39
  def refresh
28
- registers_to_read = [19..20, 30, 344, 740..741, 900, 1110..1111, 1114, 1117, 3027, 31003]
29
- # IZ2 zones
30
- iz2_zones.each_with_index do |_z, i|
31
- base1 = 21203 + i * 9
32
- base2 = 31007 + i * 3
33
- base3 = 31200 + i * 3
34
- registers_to_read << (base1..(base1 + 1))
35
- registers_to_read << (base2..(base2 + 2))
36
- registers_to_read << base3
40
+ registers_to_read = [19..20, 30, 344, 740..741, 900, 1110..1111, 1114, 1117, 1147..1153, 1165, 3027, 31_003]
41
+ if zones.first.is_a?(IZ2Zone)
42
+ zones.each_with_index do |_z, i|
43
+ base1 = 21_203 + i * 9
44
+ base2 = 31_007 + i * 3
45
+ base3 = 31_200 + i * 3
46
+ registers_to_read << (base1..(base1 + 1))
47
+ registers_to_read << (base2..(base2 + 2))
48
+ registers_to_read << base3
49
+ end
50
+ else
51
+ registers_to_read << 745..747
37
52
  end
38
53
 
39
54
  registers = @modbus_slave.holding_registers[*registers_to_read]
@@ -48,35 +63,42 @@ module Aurora
48
63
  @dhw_water_temperature = registers[1114]
49
64
  @waterflow = registers[1117]
50
65
  @compressor_speed = registers[3027]
51
- @outdoor_temperature = registers[31003]
66
+ @outdoor_temperature = registers[31_003]
52
67
  @fp1 = registers[19]
53
68
  @fp2 = registers[20]
54
69
  @locked_out = registers[1117]
70
+ @compressor_watts = registers[1147]
71
+ @blower_watts = registers[1149]
72
+ @aux_heat_watts = registers[1151]
73
+ @loop_pump_watts = registers[1165]
74
+ @total_watts = registers[1153]
55
75
 
56
76
  outputs = registers[30]
57
- if outputs.include?(:lockout)
58
- @current_mode = :lockout
59
- elsif outputs.include?(:cc2)
60
- @current_mode = outputs.include?(:rv) ? :c2 : :h2
61
- elsif outputs.include?(:cc)
62
- @current_mode = outputs.include?(:rv) ? :c1 : :h1
63
- elsif outputs.include?(:eh2)
64
- @current_mode = :eh2
65
- elsif outputs.include?(:eh1)
66
- @current_mode = :eh1
67
- elsif outputs.include?(:blower)
68
- @current_mode = :blower
69
- else
70
- @current_mode = :standby
71
- end
77
+ @current_mode = if outputs.include?(:lockout)
78
+ :lockout
79
+ elsif outputs.include?(:cc2)
80
+ outputs.include?(:rv) ? :c2 : :h2
81
+ elsif outputs.include?(:cc)
82
+ outputs.include?(:rv) ? :c1 : :h1
83
+ elsif outputs.include?(:eh2)
84
+ :eh2
85
+ elsif outputs.include?(:eh1)
86
+ :eh1
87
+ elsif outputs.include?(:blower)
88
+ :blower
89
+ else
90
+ :standby
91
+ end
72
92
 
73
- iz2_zones.each do |z|
93
+ zones.each do |z|
74
94
  z.refresh(registers)
75
95
  end
76
96
  end
77
97
 
78
98
  def inspect
79
- "#<Aurora::ABCClient #{(instance_variables - [:@modbus_slave]).map { |iv| "#{iv}=#{instance_variable_get(iv).inspect}" }.join(', ')}>"
99
+ "#<Aurora::ABCClient #{(instance_variables - [:@modbus_slave]).map do |iv|
100
+ "#{iv}=#{instance_variable_get(iv).inspect}"
101
+ end.join(', ')}>"
80
102
  end
81
103
  end
82
104
  end