waterfurnace_aurora 0.3.2 → 0.3.6

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: 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