waterfurnace_aurora 0.3.2 → 0.3.6

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: 47ba3e76677f00093692ed3f75daac6629fc77c71102a200efe88a846d271045
4
- data.tar.gz: 6183cec3c273fafa6eb529e3e9fb0c6769941a51bd22d808528ffbd0f75b3fad
3
+ metadata.gz: 1e288948a5037bccfc008daaac58c7c604f2531fab6c6554c5a93c47ab8846f2
4
+ data.tar.gz: 7dde859984d21e24f3915307de12a940e17159715ae2e1047fa80c9955ed5cbf
5
5
  SHA512:
6
- metadata.gz: 6a961b2e49137c51cb888f0bf3a551c530be8eed02cc9fc978c38ab0ef3b00c582b90c1d44466f126f90bed0934632b22fe976166b3c59ded871b61b2ee6202c
7
- data.tar.gz: f275fe6dce4542e0212abd90b7346c7e6970e23af7b657bc4c05ed3dd9682b36ad87e68abcbf03644e5fff62af89d2149edc0aa16605f33021734a52c81ca263
6
+ metadata.gz: ac5d6fb9dd6812cd71903eab37f7a32c89ad5f8790956e7adb4782216d59247873be7c603e362caab4679ca489f496579564bcc683d739caeb69ef86cab103b6
7
+ data.tar.gz: 826ff34760c126c99e19c8be8a5a929938def25d5078ff7c2141c70136a1120fcc99bf997160b2002187f17bb5009a4ac2b67c433855f90c0f7a84c248ba95f1
data/exe/aurora_fetch CHANGED
@@ -7,18 +7,22 @@ require "uri"
7
7
 
8
8
  uri = URI.parse(ARGV[0])
9
9
 
10
- args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
10
+ args = case uri.scheme
11
+ when "tcp"
12
+ require "socket"
13
+ [TCPSocket.new(uri.host, uri.port)]
14
+ when "telnet", "rfc2217"
11
15
  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
+ [Net::Telnet::RFC2217.new(uri.host,
17
+ port: uri.port || 23,
18
+ baud: 19_200,
19
+ parity: :even)]
16
20
  else
17
21
  [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
18
22
  end
19
23
 
20
24
  client = ModBus::RTUClient.new(*args)
21
- client.debug = true
25
+ client.logger = Logger.new($stdout, :debug)
22
26
  slave = client.with_slave(1)
23
27
 
24
28
  registers = slave.holding_registers[ARGV[1].to_i]
data/exe/aurora_mock CHANGED
@@ -8,12 +8,16 @@ require "yaml"
8
8
 
9
9
  uri = URI.parse(ARGV[0])
10
10
 
11
- args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
11
+ args = case uri.scheme
12
+ when "tcp"
13
+ require "socket"
14
+ [TCPSocket.new(uri.host, uri.port)]
15
+ when "telnet", "rfc2217"
12
16
  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
+ [Net::Telnet::RFC2217.new(uri.host,
18
+ port: uri.port || 23,
19
+ baud: 19_200,
20
+ parity: :even)]
17
21
  else
18
22
  [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
19
23
  end
@@ -21,7 +25,7 @@ args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
21
25
  port = ARGV[1]&.to_i || 502
22
26
 
23
27
  server1 = ModBus::RTUServer.new(*args)
24
- server1.debug = true
28
+ server1.logger = Logger.new($stdout, :debug)
25
29
  # AID Tool queries slave 1, AWL queries slave 2; just use both
26
30
  slave1 = server1.with_slave(1)
27
31
  slave2 = server1.with_slave(2)
data/exe/aurora_monitor CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  require "aurora"
5
5
  require "ccutrer-serialport"
6
+ require "logger"
6
7
  require "optparse"
7
8
  require "socket"
8
9
  require "uri"
@@ -35,19 +36,24 @@ last_registers = {}
35
36
  SENSOR_REGISTERS = [16, 19, 20, 740, 900, 1109, 1105, 1106, 1107, 1108, 1110, 1111, 1114, 1117, 1134, 1147, 1149, 1151,
36
37
  1153, 1165].freeze
37
38
 
38
- args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
39
+ args = case uri.scheme
40
+ when "tcp"
41
+ require "socket"
42
+ [TCPSocket.new(uri.host, uri.port)]
43
+ when "telnet", "rfc2217"
39
44
  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)]
45
+ [Net::Telnet::RFC2217.new(uri.host,
46
+ port: uri.port || 23,
47
+ baud: 19_200,
48
+ parity: :even)]
44
49
  else
45
50
  [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
46
51
  end
47
52
 
48
53
  server = ModBus::RTUServer.new(*args)
49
54
  server.promiscuous = true
50
- server.debug = debug_modbus
55
+ server.logger = Logger.new($stdout)
56
+ server.logger.level = debug_modbus ? :debug : :warn
51
57
 
52
58
  diff_and_print = lambda do |registers|
53
59
  registers = registers.slice(*(registers.keys - SENSOR_REGISTERS)) if ignore_sensors
@@ -10,12 +10,16 @@ require "aurora/core_ext/string"
10
10
  uri = URI.parse(ARGV[0])
11
11
  mqtt_uri = ARGV[1]
12
12
 
13
- args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
13
+ args = case uri.scheme
14
+ when "tcp"
15
+ require "socket"
16
+ [TCPSocket.new(uri.host, uri.port)]
17
+ when "telnet", "rfc2217"
14
18
  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
+ [Net::Telnet::RFC2217.new(uri.host,
20
+ port: uri.port || 23,
21
+ baud: 19_200,
22
+ parity: :even)]
19
23
  else
20
24
  [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
21
25
  end
@@ -37,8 +41,8 @@ class MQTTBridge
37
41
  case addr
38
42
  when "known"
39
43
  Aurora::REGISTER_NAMES.keys
40
- when /^(\d+)\.\.(\d+)$/
41
- Regexp.last_match(1).to_i..Regexp.last_match(2).to_i
44
+ when /^(\d+)(?:\.\.|-)(\d+)$/
45
+ $1.to_i..$2.to_i
42
46
  else
43
47
  addr.to_i
44
48
  end
@@ -48,21 +52,26 @@ class MQTTBridge
48
52
  queries.each do |subquery|
49
53
  registers.merge!(@abc.modbus_slave.read_multiple_holding_registers(*subquery))
50
54
  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
+ Aurora.print_registers(registers) do |register, v|
56
+ @homie.mqtt.publish("#{@homie.topic}/$modbus/#{register}", v, retain: false, qos: 1)
57
+ end
58
+ when %r{\$modbus/(\d+)/set$}
59
+ register = $1.to_i
55
60
  value = case value
56
61
  when /\d+/
57
62
  value.to_i
58
63
  when /0x(\d+)/
59
- Regexp.last_match(1).to_i(16)
64
+ $1.to_i(16)
60
65
  end
61
66
  @abc.modbus_slave.holding_registers[register] = value if value
67
+ registers = { register => @abc.modbus_slave.holding_registers[register] }
68
+ Aurora.print_registers(registers) do |r, v|
69
+ @homie.mqtt.publish("#{@homie.topic}/$modbus/#{r}", v, retain: false, qos: 1)
70
+ end
62
71
  end
63
72
  end
64
73
  rescue StandardError => e
65
- logger.error("failed processing message: #{e}\n#{e.backtrace}")
74
+ warn "failed processing message: #{e}\n#{e.backtrace}"
66
75
  end
67
76
 
68
77
  @abc.refresh
@@ -72,25 +81,8 @@ class MQTTBridge
72
81
  begin
73
82
  @mutex.synchronize do
74
83
  @abc.refresh
75
- %i[compressor_speed
76
- current_mode
77
- dhw_water_temperature
78
- entering_air_temperature
79
- entering_water_temperature
80
- fan_speed
81
- leaving_air_temperature
82
- leaving_water_temperature
83
- outdoor_temperature
84
- relative_humidity
85
- waterflow
86
- fp1
87
- fp2
88
- compressor_watts
89
- blower_watts
90
- aux_heat_watts
91
- loop_pump_watts
92
- total_watts].each do |property|
93
- @homie_abc[property.to_s.tr("_", "-")].value = @abc.public_send(property)
84
+ @homie_abc.each do |property|
85
+ property.value = @abc.public_send(property.id.tr("-", "_"))
94
86
  end
95
87
 
96
88
  @abc.zones.each_with_index do |z, idx|
@@ -101,7 +93,7 @@ class MQTTBridge
101
93
  end
102
94
  end
103
95
  rescue => e
104
- logger.error("got garbage: #{e}; #{e.backtrace}")
96
+ warn "got garbage: #{e}; #{e.backtrace}"
105
97
  exit 1
106
98
  end
107
99
  sleep(5)
@@ -123,7 +115,9 @@ class MQTTBridge
123
115
  unit: "ºF")
124
116
  node.property("leaving-water-temperature", "Leaving Water Temperature", :float, @abc.leaving_water_temperature,
125
117
  unit: "ºF")
126
- node.property("outdoor-temperature", "Outdoor Temperature", :float, @abc.outdoor_temperature, unit: "ºF")
118
+ unless @abc.outdoor_temperature.zero? # TODO: figure out the config if this actually exists
119
+ node.property("outdoor-temperature", "Outdoor Temperature", :float, @abc.outdoor_temperature, unit: "ºF")
120
+ end
127
121
  node.property("relative-humidity", "Relative Humidity", :integer, @abc.relative_humidity, unit: "%",
128
122
  format: 0..100)
129
123
  node.property("waterflow", "Waterflow", :float, unit: "gpm")
@@ -134,6 +128,15 @@ class MQTTBridge
134
128
  node.property(component.tr("_", "-"), component.tr("_", " ").titleize, :integer,
135
129
  @abc.public_send(component), unit: "W")
136
130
  end
131
+
132
+ node.property("blower-only-ecm-speed", "Blower Only ECM Speed", :integer, @abc.blower_only_ecm_speed,
133
+ format: 1..12) do |value, property|
134
+ @mutex.synchronize { property.value = @abc.blower_only_ecm_speed = value }
135
+ end
136
+ node.property("aux-heat-ecm-speed", "Aux Heat ECM Speed", :integer, @abc.aux_heat_ecm_speed,
137
+ format: 1..12) do |value, property|
138
+ @mutex.synchronize { property.value = @abc.aux_heat_ecm_speed = value }
139
+ end
137
140
  end
138
141
 
139
142
  @abc.zones.each_with_index do |zone, i|
@@ -183,7 +186,7 @@ class MQTTBridge
183
186
 
184
187
  # direct access to modbus registers for debugging purposes
185
188
  @homie.mqtt.subscribe("#{@homie.topic}/$modbus")
186
- @homie.mqtt.subscribe("#{@homie.topic}/$modbus/+")
189
+ @homie.mqtt.subscribe("#{@homie.topic}/$modbus/+/set")
187
190
  @homie.publish
188
191
  end
189
192
  end
@@ -18,6 +18,8 @@ module Aurora
18
18
  :outdoor_temperature,
19
19
  :fp1,
20
20
  :fp2,
21
+ :blower_only_ecm_speed,
22
+ :aux_heat_ecm_speed,
21
23
  :compressor_watts,
22
24
  :blower_watts,
23
25
  :aux_heat_watts,
@@ -31,17 +33,18 @@ module Aurora
31
33
  registers_array = @modbus_slave.holding_registers[105...110]
32
34
  registers = registers_array.each_with_index.map { |r, i| [i + 105, r] }.to_h
33
35
  @serial_number = Aurora.transform_registers(registers)[105]
34
- iz2_zone_count = @modbus_slave.holding_registers[483]
35
- # TODO: better detect IZ2/Non-IZ2
36
- @zones = if iz2_zone_count > 1
37
- (0...iz2_zone_count).map { |i| IZ2Zone.new(self, i + 1) }
38
- else
36
+
37
+ @zones = if @modbus_slave.holding_registers[813].zero?
39
38
  [Thermostat.new(self)]
39
+ else
40
+ iz2_zone_count = @modbus_slave.holding_registers[483]
41
+ (0...iz2_zone_count).map { |i| IZ2Zone.new(self, i + 1) }
40
42
  end
41
43
  end
42
44
 
43
45
  def refresh
44
- registers_to_read = [19..20, 30, 344, 740..741, 900, 1110..1111, 1114, 1117, 1147..1153, 1165, 3027, 31_003]
46
+ registers_to_read = [19..20, 30, 340, 344, 347, 740..741, 900, 1110..1111, 1114, 1117, 1147..1153, 1165, 3027,
47
+ 31_003]
45
48
  if zones.first.is_a?(IZ2Zone)
46
49
  zones.each_with_index do |_z, i|
47
50
  base1 = 21_203 + i * 9
@@ -52,7 +55,7 @@ module Aurora
52
55
  registers_to_read << base3
53
56
  end
54
57
  else
55
- registers_to_read << 745..747
58
+ registers_to_read << (745..747)
56
59
  end
57
60
 
58
61
  registers = @modbus_slave.holding_registers[*registers_to_read]
@@ -71,6 +74,8 @@ module Aurora
71
74
  @fp1 = registers[19]
72
75
  @fp2 = registers[20]
73
76
  @locked_out = registers[1117]
77
+ @blower_only_ecm_speed = registers[340]
78
+ @aux_heat_ecm_speed = registers[347]
74
79
  @compressor_watts = registers[1147]
75
80
  @blower_watts = registers[1149]
76
81
  @aux_heat_watts = registers[1151]
@@ -99,6 +104,18 @@ module Aurora
99
104
  end
100
105
  end
101
106
 
107
+ def blower_only_ecm_speed=(value)
108
+ return unless (1..12).include?(value)
109
+
110
+ @modbus_slave.holding_registers[340] = value
111
+ end
112
+
113
+ def aux_heat_ecm_speed=(value)
114
+ return unless (1..12).include?(value)
115
+
116
+ @modbus_slave.holding_registers[347] = value
117
+ end
118
+
102
119
  def inspect
103
120
  "#<Aurora::ABCClient #{(instance_variables - [:@modbus_slave]).map do |iv|
104
121
  "#{iv}=#{instance_variable_get(iv).inspect}"
@@ -348,7 +348,7 @@ module Aurora
348
348
  ->(v) { from_bitmask(v, AXB_INPUTS) } => [1103],
349
349
  ->(v) { from_bitmask(v, AXB_OUTPUTS) } => [1104],
350
350
  ->(v) { TO_TENTHS.call(NEGATABLE.call(v)) } => [1136],
351
- ->(v) { HEATING_MODE[v] } => [12_602, 21_202, 21_211, 21_220, 21_229, 21_238, 21_247],
351
+ ->(v) { HEATING_MODE[v] } => [12_606, 21_202, 21_211, 21_220, 21_229, 21_238, 21_247],
352
352
  ->(v) { FAN_MODE[v] } => [12_621, 21_205, 21_214, 21_223, 21_232, 21_241, 21_250],
353
353
  ->(v) { from_bitmask(v, HUMIDIFIER_SETTINGS) } => [31_109],
354
354
  ->(v) { { humidification_target: v >> 8, dehumidification_target: v & 0xff } } => [31_110],
@@ -497,7 +497,7 @@ module Aurora
497
497
  REGISTER_NAMES = {
498
498
  1 => "Random Start Delay",
499
499
  2 => "ABC Program Version",
500
- 3 => "IZ2 Version?",
500
+ 3 => "??? Version?",
501
501
  4 => "DIP Switch Override",
502
502
  6 => "Compressor Anti-Short Cycle Delay",
503
503
  8 => "Unit Type?",
@@ -563,7 +563,7 @@ module Aurora
563
563
  746 => "Cooling Set Point",
564
564
  747 => "Ambient Temperature",
565
565
  807 => "AXB Version",
566
- 813 => "IZ2 Version?",
566
+ 813 => "IZ2 Version",
567
567
  816 => "AOC Version 1?",
568
568
  817 => "AOC Version 2?",
569
569
  819 => "MOC Version 1?",
@@ -590,7 +590,7 @@ module Aurora
590
590
  1153 => "Total Watts",
591
591
  1157 => "Ht of Rej",
592
592
  1165 => "VS Pump Watts",
593
- 12_602 => "Heating Mode (write)",
593
+ 12_606 => "Heating Mode (write)",
594
594
  12_619 => "Heating Setpoint (write)",
595
595
  12_620 => "Cooling Setpoint (write)",
596
596
  12_621 => "Fan Mode (write)",
@@ -648,7 +648,7 @@ module Aurora
648
648
  end
649
649
 
650
650
  def print_registers(registers)
651
- result = []
651
+ result = [] unless block_given?
652
652
  registers.each do |(k, value)|
653
653
  # ignored
654
654
  next if REGISTER_NAMES.key?(k) && REGISTER_NAMES[k].nil?
@@ -665,8 +665,13 @@ module Aurora
665
665
 
666
666
  name ||= "???"
667
667
 
668
- result << "#{name} (#{k}): #{value}"
668
+ full_value = "#{name} (#{k}): #{value}"
669
+ if block_given?
670
+ yield(k, full_value)
671
+ else
672
+ result << full_value
673
+ end
669
674
  end
670
- result.join("\n")
675
+ result.join("\n") unless block_given?
671
676
  end
672
677
  end
@@ -21,7 +21,7 @@ module Aurora
21
21
  def target_mode=(value)
22
22
  return unless (raw_value = HEATING_MODE.invert[value])
23
23
 
24
- @abc.modbus_slave.holding_registers[12_602] = raw_value
24
+ @abc.modbus_slave.holding_registers[12_606] = raw_value
25
25
  @target_mode = value
26
26
  end
27
27
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aurora
4
- VERSION = "0.3.2"
4
+ VERSION = "0.3.6"
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.3.2
4
+ version: 0.3.6
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-08-26 00:00:00.000000000 Z
11
+ date: 2021-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ccutrer-serialport
@@ -44,14 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.0.4
47
+ version: '1.0'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.0.1
48
51
  type: :runtime
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
55
  - - "~>"
53
56
  - !ruby/object:Gem::Version
54
- version: 0.0.4
57
+ version: '1.0'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.0.1
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: rmodbus-ccutrer
57
63
  requirement: !ruby/object:Gem::Requirement