waterfurnace_aurora 0.2.0 → 0.2.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: 1bbf110fc6004aa69327e04b6a778fb2b59db4357cbd4c9f519805b581a2d505
4
+ data.tar.gz: dc95dcbaa26625f59b3822adae5c1e1e0dc38483df90d8ba10b5f417824d845f
5
5
  SHA512:
6
- metadata.gz: cce5f85f7b11c6910b294511faa7ea13b0319e58523cd8e42832f03983870296659286aa071db9761cd5c33df3a107d2ae9d6d5b33e430a96daf07b9366111eb
7
- data.tar.gz: 5f8affbb114893a9a67accd843b70f1a328b54d9c1485b455740e056b5f1d465f86e20a86e1d13b6c3cd7e2a9ddeabef5d6d72771c811cb5101b57bdfd881379
6
+ metadata.gz: f82a6d294a7643c0cfcc504a7e78f3eced539579d950d70f2ceb66f144891af71269c05c2cdffa2c505ae03175220317cd0b3cfffcedc092e1b3d014ede2a847
7
+ data.tar.gz: 486d293ef3021d2c0342cfaa4a7286eef0e7e0854cbaa79be1d453c274d492f94c2bb78ae920bf6442ccc7c90b4b4cae416b67d0ccb9ca3d9c539fcd8c890497
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 }
@@ -1,27 +1,28 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'aurora'
4
- require 'ccutrer-serialport'
5
- require 'socket'
6
- require 'uri'
4
+ require "aurora"
5
+ require "ccutrer-serialport"
6
+ require "socket"
7
+ require "uri"
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
  server = ModBus::RTUServer.new(*args)
21
22
  server.promiscuous = true
22
23
  server.debug = true
23
24
 
24
- server.request_callback = ->(uid, func, req) do
25
+ server.request_callback = lambda { |uid, func, req|
25
26
  if func == 68
26
27
  puts "===== no idea to #{uid}: #{req.inspect}"
27
28
  elsif func == 67
@@ -33,12 +34,13 @@ server.request_callback = ->(uid, func, req) do
33
34
  registers = Range.new(req[:addr], req[:addr] + req[:quant] - 1).zip(req[:val]).to_h
34
35
  puts Aurora.print_registers(registers)
35
36
  elsif [3, 65, 66].include?(func)
37
+ # no output
36
38
  else
37
39
  puts "**** new func #{func}"
38
40
  end
39
- end
41
+ }
40
42
 
41
- server.response_callback = ->(uid, func, res, req) do
43
+ server.response_callback = lambda { |uid, func, res, req|
42
44
  if func == 3 && res.is_a?(Array) && req
43
45
  unless req[:quant] == res.length
44
46
  puts "wrong number of results"
@@ -66,11 +68,12 @@ server.response_callback = ->(uid, func, res, req) do
66
68
  registers = req.zip(res).to_h
67
69
  puts Aurora.print_registers(registers)
68
70
  elsif [16, 67, 68].include?(func)
71
+ # no output
69
72
  else
70
73
  puts "**** new func #{func}"
71
74
  end
72
- end
75
+ }
73
76
 
74
- require 'byebug'
77
+ require "byebug"
75
78
  server.send(:serve, server.instance_variable_get(:@sp))
76
- loop {}
79
+ loop { nil }
@@ -1,22 +1,23 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'aurora'
4
- require 'homie-mqtt'
5
- require 'ccutrer-serialport'
6
- require 'uri'
4
+ require "aurora"
5
+ require "homie-mqtt"
6
+ require "ccutrer-serialport"
7
+ require "uri"
7
8
 
8
9
  uri = URI.parse(ARGV[0])
9
10
  mqtt_uri = ARGV[1]
10
11
 
11
12
  args = if uri.scheme == "telnet" || uri.scheme == "rfc2217"
12
- require 'net/telnet/rfc2217'
13
- [Net::Telnet::RFC2217.new('Host' => uri.host,
14
- 'Port' => uri.port || 23,
15
- 'baud' => 19200,
16
- 'parity' => Net::Telnet::RFC2217::EVEN)]
17
- else
18
- [CCutrer::SerialPort.new(uri.path, baud: 19200, parity: :even)]
19
- end
13
+ require "net/telnet/rfc2217"
14
+ [Net::Telnet::RFC2217.new("Host" => uri.host,
15
+ "Port" => uri.port || 23,
16
+ "baud" => 19_200,
17
+ "parity" => Net::Telnet::RFC2217::EVEN)]
18
+ else
19
+ [CCutrer::SerialPort.new(uri.path, baud: 19_200, parity: :even)]
20
+ end
20
21
 
21
22
  slave = ModBus::RTUClient.new(*args).with_slave(1)
22
23
  abc = Aurora::ABCClient.new(slave)
@@ -27,14 +28,15 @@ class MQTTBridge
27
28
  @homie = homie
28
29
  @mutex = Mutex.new
29
30
 
30
- @homie.instance_variable_set(:@block, ->(topic, value) do
31
+ @homie.instance_variable_set(:@block, lambda do |topic, value|
31
32
  @mutex.synchronize do
32
33
  case topic
33
34
  when /\$modbus$/
34
- query = value.split(',').map do |addr|
35
- if addr == 'known'
35
+ query = value.split(",").map do |addr|
36
+ case addr
37
+ when "known"
36
38
  Aurora::REGISTER_NAMES.keys
37
- elsif addr =~ /^(\d+)\.\.(\d+)$/
39
+ when /^(\d+)\.\.(\d+)$/
38
40
  Regexp.last_match(1).to_i..Regexp.last_match(2).to_i
39
41
  else
40
42
  addr.to_i
@@ -42,8 +44,8 @@ class MQTTBridge
42
44
  end
43
45
  queries = Aurora.normalize_ranges(query)
44
46
  registers = {}
45
- queries.each do |query|
46
- registers.merge!(@abc.modbus_slave.read_multiple_holding_registers(*query))
47
+ queries.each do |subquery|
48
+ registers.merge!(@abc.modbus_slave.read_multiple_holding_registers(*subquery))
47
49
  end
48
50
  result = Aurora.print_registers(registers)
49
51
  @homie.mqtt.publish("#{@home.topic}/$modbus/response", result, retain: false, qos: 1)
@@ -106,64 +108,62 @@ class MQTTBridge
106
108
  end
107
109
  end
108
110
 
109
- def publish(topic, value)
110
- @mqtt.publish("#{@base_topic}/#{topic}", value, true, 1)
111
- end
112
-
113
- def publish_attribute(attr, value)
114
- if !@attributes.key?(attr) || @attributes[attr] != value
115
- publish(attr, value.to_s)
116
- @attributes[attr] = value
117
- end
118
- end
119
-
120
- def subscribe(topic)
121
- @mqtt.subscribe("#{@base_topic}/#{topic}")
122
- end
123
-
124
111
  def publish_basic_attributes
125
112
  @homie_abc = @homie.node("abc", "Aurora Basic Control", "ABC") do |node|
126
113
  node.property("compressor-speed", "Compressor Speed", :integer, @abc.compressor_speed, format: 0..1)
127
- node.property("current-mode", "Current Heating/Cooling Mode", :enum, @abc.current_mode, format: %w[lockout standby blower h1 h2 c1 c2 eh1 eh2])
114
+ node.property("current-mode", "Current Heating/Cooling Mode", :enum, @abc.current_mode,
115
+ format: %w[lockout standby blower h1 h2 c1 c2 eh1 eh2])
128
116
  node.property("dhw-water-temperature", "DHW Water Temperature", :float, @abc.dhw_water_temperature, unit: "ºF")
129
- node.property("entering-air-temperature", "Entering Air Temperature", :float, @abc.entering_air_temperature, unit: "ºF")
130
- node.property("entering-water-temperature", "Entering Water Temperature", :float, @abc.entering_water_temperature, unit: "ºF")
117
+ node.property("entering-air-temperature", "Entering Air Temperature", :float, @abc.entering_air_temperature,
118
+ unit: "ºF")
119
+ node.property("entering-water-temperature", "Entering Water Temperature", :float,
120
+ @abc.entering_water_temperature, unit: "ºF")
131
121
  node.property("fan-speed", "Fan Speed", :integer, @abc.fan_speed, format: 0..11)
132
- node.property("leaving-air-temperature", "Leaving Air Temperature", :float, @abc.leaving_air_temperature, unit: "ºF")
133
- node.property("leaving-water-temperature", "Leaving Water Temperature", :float, @abc.leaving_water_temperature, unit: "ºF")
122
+ node.property("leaving-air-temperature", "Leaving Air Temperature", :float, @abc.leaving_air_temperature,
123
+ unit: "ºF")
124
+ node.property("leaving-water-temperature", "Leaving Water Temperature", :float, @abc.leaving_water_temperature,
125
+ unit: "ºF")
134
126
  node.property("outdoor-temperature", "Outdoor Temperature", :float, @abc.outdoor_temperature, unit: "ºF")
135
- node.property("relative-humidity", "Relative Humidity", :integer, @abc.relative_humidity, unit: "%", format: 0..100)
127
+ node.property("relative-humidity", "Relative Humidity", :integer, @abc.relative_humidity, unit: "%",
128
+ format: 0..100)
136
129
  node.property("waterflow", "Waterflow", :float, unit: "gpm")
137
130
  node.property("fp1", "FP1 Sensor", :float, @abc.fp1, unit: "ºF")
138
131
  node.property("fp2", "FP2 Sensor", :float, @abc.fp2, unit: "ºF")
139
132
  end
140
133
 
141
- @abc.iz2_zones.each_with_index do |zone|
134
+ @abc.iz2_zones.each do |zone|
142
135
  @homie.node("zone#{zone.zone_number}", "Zone #{zone.zone_number}", "IntelliZone 2 Zone") do |node|
143
136
  allowed_modes = %w[off auto cool heat]
144
137
  allowed_modes << "eheat" if zone.zone_number == 1
145
- node.property("target-mode", "Target Heating/Cooling Mode", :enum, zone.target_mode, format: allowed_modes) do |value, property|
138
+ node.property("target-mode", "Target Heating/Cooling Mode", :enum, zone.target_mode,
139
+ format: allowed_modes) do |value, property|
146
140
  @mutex.synchronize { property.value = zone.target_mode = value.to_sym }
147
141
  end
148
- node.property("current-mode", "Current Heating/Cooling Mode Requested", :enum, zone.current_mode, format: %w[standby h1 h2 h3 c1 c2])
149
- node.property("target-fan-mode", "Target Fan Mode", :enum, zone.target_fan_mode, format: %w[auto continuous intermittent]) do |value, property|
142
+ node.property("current-mode", "Current Heating/Cooling Mode Requested", :enum, zone.current_mode,
143
+ format: %w[standby h1 h2 h3 c1 c2])
144
+ node.property("target-fan-mode", "Target Fan Mode", :enum, zone.target_fan_mode,
145
+ format: %w[auto continuous intermittent]) do |value, property|
150
146
  @mutex.synchronize { property.value = zone.target_fan_mode = value.to_sym }
151
147
  end
152
148
  node.property("current-fan-mode", "Current Fan Status", :boolean, zone.current_fan_mode)
153
- node.property("fan-intermittent-on", "Fan Intermittent Mode On Duration", :enum, zone.fan_intermittent_on, unit: "M", format: %w[0 5 10 15 20]) do |value, property|
149
+ node.property("fan-intermittent-on", "Fan Intermittent Mode On Duration", :enum, zone.fan_intermittent_on,
150
+ unit: "M", format: %w[0 5 10 15 20]) do |value, property|
154
151
  @mutex.synchronize { property.value = zone.fan_intermittent_on = value.to_i }
155
152
  end
156
- node.property("fan-intermittent-off", "Fan Intermittent Mode Off Duration", :enum, zone.fan_intermittent_on, unit: "M", format: %w[0 5 10 15 20 25 30 35 40]) do |value, property|
153
+ node.property("fan-intermittent-off", "Fan Intermittent Mode Off Duration", :enum, zone.fan_intermittent_on,
154
+ unit: "M", format: %w[0 5 10 15 20 25 30 35 40]) do |value, property|
157
155
  @mutex.synchronize { property.value = zone.fan_intermittent_on = value.to_i }
158
156
  end
159
157
  node.property("priority", "Zone Priority", :enum, zone.priority, format: %w[economy comfort])
160
158
  node.property("size", "Size", :enum, zone.size, format: %w[0 25 45 70])
161
159
  node.property("normalized-size", "Normalized Size", :integer, zone.normalized_size, unit: "%", format: 0..100)
162
160
  node.property("ambient-temperature", "Ambient Temperature", :float, zone.ambient_temperature, unit: "ºF")
163
- node.property("heating-target-temperature", "Heating Target Temperature", :integer, zone.heating_target_temperature, unit: "ºF", format: 40..90) do |value, property|
161
+ node.property("heating-target-temperature", "Heating Target Temperature", :integer,
162
+ zone.heating_target_temperature, unit: "ºF", format: 40..90) do |value, property|
164
163
  @mutex.synchronize { property.value = zone.heating_target_temperature = value }
165
164
  end
166
- node.property("cooling-target-temperature", "Cooling Target Temperature", :integer, zone.cooling_target_temperature, unit: "ºF", format: 54..99) do |value, property|
165
+ node.property("cooling-target-temperature", "Cooling Target Temperature", :integer,
166
+ zone.cooling_target_temperature, unit: "ºF", format: 54..99) do |value, property|
167
167
  @mutex.synchronize { property.value = zone.cooling_target_temperature = value }
168
168
  end
169
169
  end
File without changes
@@ -1,20 +1,22 @@
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
+ :iz2_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
18
20
 
19
21
  def initialize(modbus_slave)
20
22
  @modbus_slave = modbus_slave
@@ -25,12 +27,12 @@ module Aurora
25
27
  end
26
28
 
27
29
  def refresh
28
- registers_to_read = [19..20, 30, 344, 740..741, 900, 1110..1111, 1114, 1117, 3027, 31003]
30
+ registers_to_read = [19..20, 30, 344, 740..741, 900, 1110..1111, 1114, 1117, 3027, 31_003]
29
31
  # IZ2 zones
30
32
  iz2_zones.each_with_index do |_z, i|
31
- base1 = 21203 + i * 9
32
- base2 = 31007 + i * 3
33
- base3 = 31200 + i * 3
33
+ base1 = 21_203 + i * 9
34
+ base2 = 31_007 + i * 3
35
+ base3 = 31_200 + i * 3
34
36
  registers_to_read << (base1..(base1 + 1))
35
37
  registers_to_read << (base2..(base2 + 2))
36
38
  registers_to_read << base3
@@ -48,27 +50,27 @@ module Aurora
48
50
  @dhw_water_temperature = registers[1114]
49
51
  @waterflow = registers[1117]
50
52
  @compressor_speed = registers[3027]
51
- @outdoor_temperature = registers[31003]
53
+ @outdoor_temperature = registers[31_003]
52
54
  @fp1 = registers[19]
53
55
  @fp2 = registers[20]
54
56
  @locked_out = registers[1117]
55
57
 
56
58
  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
59
+ @current_mode = if outputs.include?(:lockout)
60
+ :lockout
61
+ elsif outputs.include?(:cc2)
62
+ outputs.include?(:rv) ? :c2 : :h2
63
+ elsif outputs.include?(:cc)
64
+ outputs.include?(:rv) ? :c1 : :h1
65
+ elsif outputs.include?(:eh2)
66
+ :eh2
67
+ elsif outputs.include?(:eh1)
68
+ :eh1
69
+ elsif outputs.include?(:blower)
70
+ :blower
71
+ else
72
+ :standby
73
+ end
72
74
 
73
75
  iz2_zones.each do |z|
74
76
  z.refresh(registers)
@@ -76,7 +78,9 @@ module Aurora
76
78
  end
77
79
 
78
80
  def inspect
79
- "#<Aurora::ABCClient #{(instance_variables - [:@modbus_slave]).map { |iv| "#{iv}=#{instance_variable_get(iv).inspect}" }.join(', ')}>"
81
+ "#<Aurora::ABCClient #{(instance_variables - [:@modbus_slave]).map do |iv|
82
+ "#{iv}=#{instance_variable_get(iv).inspect}"
83
+ end.join(', ')}>"
80
84
  end
81
85
  end
82
86
  end