balboa_worldwide_app 1.3.0 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/bwa/client.rb CHANGED
@@ -1,28 +1,59 @@
1
- require 'uri'
1
+ # frozen_string_literal: true
2
2
 
3
- require 'bwa/logger'
4
- require 'bwa/message'
3
+ require "forwardable"
4
+ require "uri"
5
+
6
+ require "bwa/logger"
7
+ require "bwa/message"
5
8
 
6
9
  module BWA
7
10
  class Client
8
- attr_reader :last_status, :last_control_configuration, :last_control_configuration2, :last_filter_configuration
11
+ extend Forwardable
12
+
13
+ attr_reader :status, :control_configuration, :configuration, :filter_cycles
14
+
15
+ delegate model: :control_configuration
16
+ delegate %i[hold
17
+ hold?
18
+ priming
19
+ priming?
20
+ heating_mode
21
+ temperature_scale
22
+ twenty_four_hour_time
23
+ twenty_four_hour_time?
24
+ heating
25
+ heating?
26
+ temperature_range
27
+ current_temperature
28
+ target_temperature
29
+ circulation_pump
30
+ blower
31
+ mister
32
+ pumps
33
+ lights
34
+ aux] => :status
9
35
 
10
36
  def initialize(uri)
11
37
  uri = URI.parse(uri)
12
- if uri.scheme == 'tcp'
13
- require 'socket'
38
+ case uri.scheme
39
+ when "tcp"
40
+ require "socket"
14
41
  @io = TCPSocket.new(uri.host, uri.port || 4257)
15
- elsif uri.scheme == 'telnet' || uri.scheme == 'rfc2217'
16
- require 'net/telnet/rfc2217'
17
- @io = Net::Telnet::RFC2217.new("Host" => uri.host, "Port" => uri.port || 23, "baud" => 115200)
42
+ when "telnet", "rfc2217"
43
+ require "net/telnet/rfc2217"
44
+ @io = Net::Telnet::RFC2217.new("Host" => uri.host, "Port" => uri.port || 23, "baud" => 115_200)
18
45
  @queue = []
19
46
  else
20
- require 'ccutrer-serialport'
21
- @io = CCutrer::SerialPort.new(uri.path, baud: 115200)
47
+ require "ccutrer-serialport"
48
+ @io = CCutrer::SerialPort.new(uri.path, baud: 115_200)
22
49
  @queue = []
23
50
  end
24
51
  @src = 0x0a
25
- @buffer = ""
52
+ @buffer = +""
53
+ end
54
+
55
+ def full_configuration?
56
+ status && control_configuration && configuration && filter_cycles
26
57
  end
27
58
 
28
59
  def poll
@@ -45,18 +76,20 @@ module BWA
45
76
  end
46
77
 
47
78
  if message.is_a?(Messages::Ready) && (msg = @queue&.shift)
48
- BWA.logger.debug "wrote: #{BWA.raw2str(msg)}" unless BWA.verbosity < 1 && msg[3..4] == Messages::ControlConfigurationRequest::MESSAGE_TYPE
79
+ unless BWA.verbosity < 1 && msg[3..4] == Messages::ControlConfigurationRequest::MESSAGE_TYPE
80
+ BWA.logger.debug "wrote: #{BWA.raw2str(msg)}"
81
+ end
49
82
  @io.write(msg)
50
83
  end
51
- @last_status = message.dup if message.is_a?(Messages::Status)
52
- @last_filter_configuration = message.dup if message.is_a?(Messages::FilterCycles)
53
- @last_control_configuration = message.dup if message.is_a?(Messages::ControlConfiguration)
54
- @last_control_configuration2 = message.dup if message.is_a?(Messages::ControlConfiguration2)
84
+ @status = message.dup if message.is_a?(Messages::Status)
85
+ @filter_cycles = message.dup if message.is_a?(Messages::FilterCycles)
86
+ @control_configuration = message.dup if message.is_a?(Messages::ControlConfiguration)
87
+ @configuration = message.dup if message.is_a?(Messages::ControlConfiguration2)
55
88
  message
56
89
  end
57
90
 
58
91
  def messages_pending?
59
- !!IO.select([@io], nil, nil, 0)
92
+ !!@io.wait_readable(0)
60
93
  end
61
94
 
62
95
  def drain_message_queue
@@ -65,12 +98,16 @@ module BWA
65
98
 
66
99
  def send_message(message)
67
100
  message.src = @src
68
- BWA.logger.info " to spa: #{message.inspect}" unless BWA.verbosity < 1 && message.is_a?(Messages::ControlConfigurationRequest)
69
101
  full_message = message.serialize
102
+ unless BWA.verbosity < 1 && message.is_a?(Messages::ControlConfigurationRequest)
103
+ BWA.logger.info " to spa: #{message.inspect}"
104
+ end
70
105
  if @queue
71
106
  @queue.push(full_message)
72
107
  else
73
- BWA.logger.debug "wrote: #{BWA.raw2str(full_message)}" unless BWA.verbosity < 1 && message.is_a?(Messages::ControlConfigurationRequest)
108
+ unless BWA.verbosity < 1 && message.is_a?(Messages::ControlConfigurationRequest)
109
+ BWA.logger.debug "wrote: #{BWA.raw2str(full_message)}"
110
+ end
74
111
  @io.write(full_message)
75
112
  end
76
113
  end
@@ -95,12 +132,16 @@ module BWA
95
132
  send_message(Messages::ToggleItem.new(item))
96
133
  end
97
134
 
98
- def toggle_pump(i)
99
- toggle_item(i + 3)
135
+ def toggle_pump(index)
136
+ toggle_item(index + 0x04)
100
137
  end
101
138
 
102
- def toggle_light(i)
103
- toggle_item(i + 0x10)
139
+ def toggle_light(index)
140
+ toggle_item(index + 0x11)
141
+ end
142
+
143
+ def toggle_aux(index)
144
+ toggle_item(index + 0x16)
104
145
  end
105
146
 
106
147
  def toggle_mister
@@ -115,90 +156,79 @@ module BWA
115
156
  toggle_item(:hold)
116
157
  end
117
158
 
118
- def set_pump(i, desired)
119
- return unless last_status && last_control_configuration2
120
- times = (desired - last_status.pumps[i - 1]) % (last_control_configuration2.pumps[i - 1] + 1)
159
+ def set_pump(index, desired)
160
+ return unless status && configuration
161
+
162
+ desired = 0 if desired == false
163
+ desired = 1 if desired == true
164
+ times = (desired - status.pumps[index]) % (configuration.pumps[index] + 1)
121
165
  times.times do
122
- toggle_pump(i)
166
+ toggle_pump(index)
123
167
  sleep(0.1)
124
168
  end
125
169
  end
126
170
 
127
- %w{light aux}.each do |type|
171
+ %i[light aux].each do |type|
172
+ suffix = "s" if type == :light
128
173
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
129
- def set_#{type}(i, desired)
130
- return unless last_status
131
- return if last_status.#{type}s[i - 1] == desired
132
- toggle_#{type}(i)
174
+ def set_#{type}(index, desired)
175
+ return unless status
176
+ return if status.#{type}#{suffix}[index] == desired
177
+
178
+ toggle_#{type}(index)
133
179
  end
134
180
  RUBY
135
181
  end
136
182
 
137
- def set_mister(desired)
138
- return unless last_status
139
- return if last_status.mister == desired
183
+ def mister=(desired)
184
+ return unless status
185
+ return if status.mister == desired
186
+
140
187
  toggle_mister
141
188
  end
142
189
 
143
- def set_blower(desired)
144
- return unless last_status && last_control_configuration2
145
- times = (desired - last_status.blower) % (last_control_configuration2.blower + 1)
190
+ def blower=(desired)
191
+ return unless status && configuration
192
+
193
+ desired = 0 if desired == false
194
+ desired = 1 if desired == true
195
+ times = (desired - status.blower) % (configuration.blower + 1)
146
196
  times.times do
147
197
  toggle_blower
148
198
  sleep(0.1)
149
199
  end
150
200
  end
151
201
 
152
- def set_hold(desired)
153
- return unless last_status
154
- return if last_status.hold == desired
202
+ def hold=(desired)
203
+ return unless status
204
+ return if status.hold == desired
205
+
155
206
  toggle_hold
156
207
  end
157
208
 
158
209
  # high range is 80-106 for F, 26-40 for C (by 0.5)
159
210
  # low range is 50-99 for F, 10-26 for C (by 0.5)
160
- def set_temperature(desired)
161
- return unless last_status
162
- return if last_status.set_temperature == desired
211
+ def target_temperature=(desired)
212
+ return unless status
213
+ return if status.target_temperature == desired
163
214
 
164
- desired *= 2 if last_status && last_status.temperature_scale == :celsius || desired < 50
165
- send_message(Messages::SetTemperature.new(desired.round))
215
+ desired *= 2 if (status && status.temperature_scale == :celsius) || desired < 50
216
+ send_message(Messages::SetTargetTemperature.new(desired.round))
166
217
  end
167
218
 
168
- def set_time(hour, minute, twenty_four_hour_time = false)
219
+ def set_time(hour, minute, twenty_four_hour_time: false)
169
220
  send_message(Messages::SetTime.new(hour, minute, twenty_four_hour_time))
170
221
  end
171
222
 
172
- def set_temperature_scale(scale)
173
- raise ArgumentError, "scale must be :fahrenheit or :celsius" unless %I{fahrenheit :celsius}.include?(scale)
223
+ def temperature_scale=(scale)
224
+ raise ArgumentError, "scale must be :fahrenheit or :celsius" unless %I[fahrenheit celsius].include?(scale)
225
+
174
226
  send_message(Messages::SetTemperatureScale.new(scale))
175
227
  end
176
228
 
177
- def set_filtercycles(changedItem, changedValue)
178
- #changedItem - String name of item that was changed
179
- #changedValue - String value of the item that changed
180
- if @last_filter_configuration
181
- messagedata = if changedItem == "filter1hour" then changedValue.to_i.chr else @last_filter_configuration.filter1_hour.chr end
182
- messagedata += if changedItem == "filter1minute" then changedValue.to_i.chr else @last_filter_configuration.filter1_minute.chr end
183
- messagedata += if changedItem == "filter1durationhours" then changedValue.to_i.chr else @last_filter_configuration.filter1_duration_hours.chr end
184
- messagedata += if changedItem == "filter1durationminutes" then changedValue.to_i.chr else @last_filter_configuration.filter1_duration_minutes.chr end
185
-
186
- #The filter2 start hour is merged with the filter2 enable (who thought that was a good idea?) The high order bit of the byte is a flag
187
- #to indicate this so we have to do a bit of different processing to do that
188
- #Get the filter 2 start hour
189
- starthour = if changedItem == "filter2hour" then changedValue.to_i else @last_filter_configuration.filter2_hour end
190
- #Check to see if we want filter 2 enabled (either because it changed or from the current configuration)
191
- #If it is something that changed, we have to convert to boolean, if it is from the current config it already is a boolean
192
- starthour |= 0x80 if (if changedItem == "filter2enabled" then (changedValue == "true" ? true : false) else @last_filter_configuration.filter2_enabled end)
193
-
194
- messagedata += starthour.chr
195
-
196
- messagedata += if changedItem == "filter2minute" then changedValue.to_i.chr else @last_filter_configuration.filter2_minute.chr end
197
- messagedata += if changedItem == "filter2durationhours" then changedValue.to_i.chr else @last_filter_configuration.filter2_duration_hours.chr end
198
- messagedata += if changedItem == "filter2durationminutes" then changedValue.to_i.chr else @last_filter_configuration.filter2_duration_minutes.chr end
199
-
200
- send_message("\x0a\xbf\x23".force_encoding(Encoding::ASCII_8BIT) + messagedata)
201
- end
229
+ def update_filter_cycles(new_filter_cycles)
230
+ send_message(new_filter_cycles)
231
+ @filter_cycles = new_filter_cycles.dup
202
232
  request_filter_configuration
203
233
  end
204
234
 
@@ -206,9 +236,10 @@ module BWA
206
236
  toggle_item(0x50)
207
237
  end
208
238
 
209
- def set_temperature_range(desired)
210
- return unless last_status
211
- return if last_status.temperature_range == desired
239
+ def temperature_range=(desired)
240
+ return unless status
241
+ return if status.temperature_range == desired
242
+
212
243
  toggle_temperature_range
213
244
  end
214
245
 
@@ -216,19 +247,20 @@ module BWA
216
247
  toggle_item(:heating_mode)
217
248
  end
218
249
 
219
- HEATING_MODES = %I{ready rest ready_in_rest}.freeze
220
- def set_heating_mode(desired)
221
- raise ArgumentError, "heating_mode must be :ready or :rest" unless %I{ready rest}.include?(desired)
222
- return unless last_status
223
- times = if last_status.heating_mode == :ready && desired == :rest ||
224
- last_status.heating_mode == :rest && desired == :ready ||
225
- last_status.heating_mode == :ready_in_rest && desired == :rest
226
- 1
227
- elsif last_status.heating_mode == :ready_in_rest && desired == :ready
228
- 2
229
- else
230
- 0
231
- end
250
+ HEATING_MODES = %I[ready rest ready_in_rest].freeze
251
+ def heating_mode=(desired)
252
+ raise ArgumentError, "heating_mode must be :ready or :rest" unless %I[ready rest].include?(desired)
253
+ return unless status
254
+
255
+ times = if (status.heating_mode == :ready && desired == :rest) ||
256
+ (status.heating_mode == :rest && desired == :ready) ||
257
+ (status.heating_mode == :ready_in_rest && desired == :rest)
258
+ 1
259
+ elsif status.heating_mode == :ready_in_rest && desired == :ready
260
+ 2
261
+ else
262
+ 0
263
+ end
232
264
  times.times { toggle_heating_mode }
233
265
  end
234
266
  end
data/lib/bwa/crc.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'digest/crc'
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/crc"
2
4
 
3
5
  module BWA
4
6
  class CRC < Digest::CRC8
data/lib/bwa/discovery.rb CHANGED
@@ -1,27 +1,27 @@
1
- require 'socket'
2
- require 'bwa/logger'
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "bwa/logger"
3
5
 
4
6
  module BWA
5
7
  class Discovery
6
8
  class << self
7
- def discover(timeout = 5, exhaustive = false)
9
+ def discover(timeout = 5, exhaustive: false)
8
10
  socket = UDPSocket.new
9
11
  socket.bind("0.0.0.0", 0)
10
12
  socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
11
- socket.sendmsg("Discovery: Who is out there?", 0, Socket.sockaddr_in(30303, '255.255.255.255'))
13
+ socket.sendmsg("Discovery: Who is out there?", 0, Socket.sockaddr_in(30_303, "255.255.255.255"))
12
14
  spas = {}
13
15
  loop do
14
- if IO.select([socket], nil, nil, timeout)
15
- msg, ip = socket.recvfrom(64)
16
- ip = ip[2]
17
- name, mac = msg.split("\r\n")
18
- name.strip!
19
- if mac.start_with?("00-15-27-")
20
- spas[ip] = name
21
- break unless exhaustive
22
- end
23
- else
24
- break
16
+ break unless socket.wait_readable(timeout)
17
+
18
+ msg, ip = socket.recvfrom(64)
19
+ ip = ip[2]
20
+ name, mac = msg.split("\r\n")
21
+ name.strip!
22
+ if mac.start_with?("00-15-27-")
23
+ spas[ip] = name
24
+ break unless exhaustive
25
25
  end
26
26
  end
27
27
  spas
@@ -29,11 +29,12 @@ module BWA
29
29
 
30
30
  def advertise
31
31
  socket = UDPSocket.new
32
- socket.bind("0.0.0.0", 30303)
32
+ socket.bind("0.0.0.0", 30_303)
33
33
  msg = "BWGSPA\r\n00-15-27-00-00-01\r\n"
34
34
  loop do
35
35
  data, addr = socket.recvfrom(32)
36
- next unless data == 'Discovery: Who is out there?'
36
+ next unless data == "Discovery: Who is out there?"
37
+
37
38
  ip = addr.last
38
39
  BWA.logger.info "Advertising to #{ip}"
39
40
  socket.sendmsg(msg, 0, Socket.sockaddr_in(addr[1], ip))
data/lib/bwa/logger.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'logger'
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
2
4
 
3
5
  module BWA
4
6
  # This module logs to stdout by default, or you can provide a logger as BWA.logger.
@@ -23,10 +25,10 @@ module BWA
23
25
  attr_writer :logger, :verbosity
24
26
 
25
27
  def logger
26
- @logger ||= Logger.new(STDOUT).tap do |log|
27
- STDOUT.sync = true
28
- log.level = ENV.fetch("LOG_LEVEL","WARN")
29
- log.formatter = proc do |severity, datetime, progname, msg|
28
+ @logger ||= Logger.new($stdout).tap do |log|
29
+ $stdout.sync = true
30
+ log.level = ENV.fetch("LOG_LEVEL", "WARN")
31
+ log.formatter = proc do |severity, _datetime, _progname, msg|
30
32
  "#{severity[0..0]}, #{msg2logstr(msg)}\n"
31
33
  end
32
34
  end
@@ -42,14 +44,14 @@ module BWA
42
44
  when ::String
43
45
  msg
44
46
  when ::Exception
45
- "#{ msg.message } (#{ msg.class })\n#{ msg.backtrace.join("\n") if msg.backtrace }"
47
+ "#{msg.message} (#{msg.class})\n#{msg.backtrace&.join("\n")}"
46
48
  else
47
49
  msg.inspect
48
50
  end
49
51
  end
50
52
 
51
53
  def raw2str(data)
52
- data.unpack("H*").first.gsub!(/(..)/, "\\1 ").chop!
54
+ data.unpack1("H*").gsub!(/(..)/, "\\1 ").chop!
53
55
  end
54
56
  end
55
57
  end
data/lib/bwa/message.rb CHANGED
@@ -1,5 +1,7 @@
1
- require 'bwa/logger'
2
- require 'bwa/crc'
1
+ # frozen_string_literal: true
2
+
3
+ require "bwa/logger"
4
+ require "bwa/crc"
3
5
 
4
6
  module BWA
5
7
  class InvalidMessage < RuntimeError
@@ -19,53 +21,58 @@ module BWA
19
21
 
20
22
  class << self
21
23
  def inherited(klass)
24
+ super
25
+
22
26
  @messages ||= []
23
27
  @messages << klass
24
28
  end
25
29
 
26
30
  # Ignore (parse and throw away) messages of these types.
27
31
  IGNORED_MESSAGES = [
28
- "\xbf\x00".force_encoding(Encoding::ASCII_8BIT), # request for new clients
29
- "\xbf\xe1".force_encoding(Encoding::ASCII_8BIT),
30
- "\xbf\x07".force_encoding(Encoding::ASCII_8BIT), # nothing to send
31
- ]
32
+ (+"\xbf\x00").force_encoding(Encoding::ASCII_8BIT), # request for new clients
33
+ (+"\xbf\xe1").force_encoding(Encoding::ASCII_8BIT),
34
+ (+"\xbf\x07").force_encoding(Encoding::ASCII_8BIT) # nothing to send
35
+ ].freeze
32
36
 
33
37
  # Don't log messages of these types, even in DEBUG mode.
34
38
  # They are very frequent and would swamp the logs.
35
39
  def common_messages
36
- @COMMON_MESSAGES ||= begin
40
+ @common_messages ||= begin
37
41
  msgs = []
38
- msgs += [
39
- Messages::Status::MESSAGE_TYPE,
40
- "\xbf\xe1".force_encoding(Encoding::ASCII_8BIT),
41
- ] unless BWA.verbosity >= 1
42
- msgs += [
43
- "\xbf\x00".force_encoding(Encoding::ASCII_8BIT),
44
- "\xbf\xe1".force_encoding(Encoding::ASCII_8BIT),
45
- Messages::Ready::MESSAGE_TYPE,
46
- "\xbf\x07".force_encoding(Encoding::ASCII_8BIT),
47
- ] unless BWA.verbosity >= 2
42
+ unless BWA.verbosity >= 1
43
+ msgs += [
44
+ Messages::Status::MESSAGE_TYPE,
45
+ (+"\xbf\xe1").force_encoding(Encoding::ASCII_8BIT)
46
+ ]
47
+ end
48
+ unless BWA.verbosity >= 2
49
+ msgs += [
50
+ (+"\xbf\x00").force_encoding(Encoding::ASCII_8BIT),
51
+ (+"\xbf\xe1").force_encoding(Encoding::ASCII_8BIT),
52
+ Messages::Ready::MESSAGE_TYPE,
53
+ (+"\xbf\x07").force_encoding(Encoding::ASCII_8BIT)
54
+ ]
55
+ end
48
56
  msgs
49
57
  end
50
- @COMMON_MESSAGES
51
58
  end
52
59
 
53
60
  def parse(data)
54
61
  offset = -1
55
- message_type = length = message_class = nil
62
+ message_type = length = nil
56
63
  loop do
57
64
  offset += 1
58
65
  # Not enough data for a full message; return and hope for more
59
66
  return nil if data.length - offset < 5
60
67
 
61
68
  # Keep scanning until message start char
62
- next unless data[offset] == '~'
69
+ next unless data[offset] == "~"
63
70
 
64
71
  # Read length (safe since we have at least 5 chars)
65
72
  length = data[offset + 1].ord
66
73
 
67
74
  # No message is this short or this long; keep scanning
68
- next if length < 5 or length >= '~'.ord
75
+ next if (length < 5) || (length >= "~".ord)
69
76
 
70
77
  # don't have enough data for what this message wants;
71
78
  # return and hope for more (yes this might cause a
@@ -74,7 +81,7 @@ module BWA
74
81
  return nil if length + 2 > data.length - offset
75
82
 
76
83
  # Not properly terminated; keep scanning
77
- next unless data[offset + length + 1] == '~'
84
+ next unless data[offset + length + 1] == "~"
78
85
 
79
86
  # Not a valid checksum; keep scanning
80
87
  next unless CRC.checksum(data.slice(offset + 1, length - 1)) == data[offset + length].ord
@@ -84,8 +91,11 @@ module BWA
84
91
  end
85
92
 
86
93
  message_type = data.slice(offset + 3, 2)
87
- BWA.logger.debug "discarding invalid data prior to message #{BWA.raw2str(data[0...offset])}" unless offset == 0
88
- BWA.logger.debug " read: #{BWA.raw2str(data.slice(offset, length + 2))}" unless common_messages.include?(message_type)
94
+ BWA.logger.debug "discarding invalid data prior to message #{BWA.raw2str(data[0...offset])}" unless offset.zero?
95
+ unless common_messages.include?(message_type)
96
+ BWA.logger.debug " read: #{BWA.raw2str(data.slice(offset,
97
+ length + 2))}"
98
+ end
89
99
 
90
100
  src = data[offset + 2].ord
91
101
  klass = @messages.find { |k| k::MESSAGE_TYPE == message_type }
@@ -95,13 +105,18 @@ module BWA
95
105
 
96
106
  if klass
97
107
  valid_length = if klass::MESSAGE_LENGTH.respond_to?(:include?)
98
- klass::MESSAGE_LENGTH.include?(length - 5)
99
- else
100
- length - 5 == klass::MESSAGE_LENGTH
108
+ klass::MESSAGE_LENGTH.include?(length - 5)
109
+ else
110
+ length - 5 == klass::MESSAGE_LENGTH
111
+ end
112
+ unless valid_length
113
+ raise InvalidMessage.new("Unrecognized data length (#{length}) for message #{klass}",
114
+ data)
101
115
  end
102
- raise InvalidMessage.new("Unrecognized data length (#{length}) for message #{klass}", data) unless valid_length
103
116
  else
104
- BWA.logger.info "Unrecognized message type #{BWA.raw2str(message_type)}: #{BWA.raw2str(data.slice(offset, length + 2))}"
117
+ BWA.logger.info(
118
+ "Unrecognized message type #{BWA.raw2str(message_type)}: #{BWA.raw2str(data.slice(offset, length + 2))}"
119
+ )
105
120
  klass = Unrecognized
106
121
  end
107
122
 
@@ -113,53 +128,52 @@ module BWA
113
128
  [message, offset + length + 2]
114
129
  end
115
130
 
116
- def format_time(hour, minute, twenty_four_hour_time = true)
131
+ def format_time(hour, minute, twenty_four_hour_time: true)
117
132
  if twenty_four_hour_time
118
- print_hour = "%02d" % hour
133
+ format("%02d:%02d", hour, minute)
119
134
  else
120
135
  print_hour = hour % 12
121
- print_hour = 12 if print_hour == 0
122
- am_pm = (hour >= 12 ? "PM" : "AM")
136
+ print_hour = 12 if print_hour.zero?
137
+ format("%d:%02d%s", print_hour, minute, hour >= 12 ? "PM" : "AM")
123
138
  end
124
- "#{print_hour}:#{"%02d" % minute}#{am_pm}"
125
139
  end
126
140
 
127
- def format_duration(hours, minutes)
128
- "#{hours}:#{"%02d" % minutes}"
141
+ def format_duration(minutes)
142
+ format("%d:%02d", minutes / 60, minutes % 60)
129
143
  end
130
144
  end
131
145
 
132
- attr_reader :raw_data, :src
146
+ attr_reader :raw_data
133
147
 
134
148
  def initialize
135
149
  # most messages we're sending come from this address
136
150
  @src = 0x0a
137
151
  end
138
152
 
139
- def parse(_data)
140
- end
153
+ def parse(_data); end
141
154
 
142
155
  def serialize(message = "")
143
156
  length = message.length + 5
144
- full_message = "#{length.chr}#{src.chr}#{self.class::MESSAGE_TYPE}#{message}".force_encoding(Encoding::ASCII_8BIT)
157
+ full_message = (+"#{length.chr}#{src.chr}#{self.class::MESSAGE_TYPE}#{message}")
158
+ .force_encoding(Encoding::ASCII_8BIT)
145
159
  checksum = CRC.checksum(full_message)
146
- "\x7e#{full_message}#{checksum.chr}\x7e".force_encoding(Encoding::ASCII_8BIT)
160
+ (+"\x7e#{full_message}#{checksum.chr}\x7e").force_encoding(Encoding::ASCII_8BIT)
147
161
  end
148
162
 
149
163
  def inspect
150
- "#<#{self.class.name} #{raw_data.unpack("H*").first}>"
164
+ "#<#{self.class.name} #{raw_data.unpack1("H*")}>"
151
165
  end
152
166
  end
153
167
  end
154
168
 
155
- require 'bwa/messages/configuration'
156
- require 'bwa/messages/configuration_request'
157
- require 'bwa/messages/control_configuration'
158
- require 'bwa/messages/control_configuration_request'
159
- require 'bwa/messages/filter_cycles'
160
- require 'bwa/messages/ready'
161
- require 'bwa/messages/set_temperature'
162
- require 'bwa/messages/set_temperature_scale'
163
- require 'bwa/messages/set_time'
164
- require 'bwa/messages/status'
165
- require 'bwa/messages/toggle_item'
169
+ require "bwa/messages/configuration"
170
+ require "bwa/messages/configuration_request"
171
+ require "bwa/messages/control_configuration"
172
+ require "bwa/messages/control_configuration_request"
173
+ require "bwa/messages/filter_cycles"
174
+ require "bwa/messages/ready"
175
+ require "bwa/messages/set_target_temperature"
176
+ require "bwa/messages/set_temperature_scale"
177
+ require "bwa/messages/set_time"
178
+ require "bwa/messages/status"
179
+ require "bwa/messages/toggle_item"
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BWA
2
4
  module Messages
3
5
  class Configuration < Message
4
- MESSAGE_TYPE = "\xbf\x94".force_encoding(Encoding::ASCII_8BIT)
6
+ MESSAGE_TYPE = (+"\xbf\x94").force_encoding(Encoding::ASCII_8BIT)
5
7
  MESSAGE_LENGTH = 25
6
8
 
7
9
  def inspect
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BWA
2
4
  module Messages
3
5
  class ConfigurationRequest < Message
4
- MESSAGE_TYPE = "\xbf\x04".force_encoding(Encoding::ASCII_8BIT)
6
+ MESSAGE_TYPE = (+"\xbf\x04").force_encoding(Encoding::ASCII_8BIT)
5
7
  MESSAGE_LENGTH = 0
6
8
 
7
9
  def inspect