108 lines
3.8 KiB
Ruby
108 lines
3.8 KiB
Ruby
require "socket"
|
|
|
|
class InSyncState < StatePattern::State
|
|
|
|
END_OF_FRAME = "!****\n"
|
|
|
|
# def initialize(stateful, previous_state)
|
|
# # open socket to EmonHub
|
|
# @hub = TCPSocket.new 'raspberrypi.lan', 5050
|
|
# @hub.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
|
# super(stateful, previous_state)
|
|
# end
|
|
|
|
|
|
def handle_byte_stream(bytes)
|
|
idx = 0
|
|
#sync_pattern_length = Synchronizer::SYNC_PATTERN.length
|
|
sync_pattern_length = END_OF_FRAME.length
|
|
#p "Sync length: #{sync_length}"
|
|
|
|
frame = ""
|
|
|
|
while (idx+sync_pattern_length < bytes.length && !new_frame_starts(bytes,idx,sync_pattern_length)) do
|
|
frame = frame + bytes[idx]
|
|
idx = idx +1
|
|
end
|
|
|
|
# did we reach the end of the frame?
|
|
if new_frame_starts(bytes,idx,sync_pattern_length)
|
|
frame_lines = frame.split("\n")
|
|
puts "--- FRAME ---"
|
|
# p frame_lines
|
|
# p "##################"
|
|
reading = handle_frame(frame_lines)
|
|
p reading
|
|
return bytes[idx+sync_pattern_length..-1] || ""
|
|
else
|
|
return bytes
|
|
end
|
|
end
|
|
|
|
private
|
|
def new_frame_starts(bytes,idx,sync_pattern_length)
|
|
#return bytes[idx..idx+sync_pattern_length-1].eql?(Synchronizer::SYNC_PATTERN)
|
|
#return bytes[idx..idx+sync_pattern_length-1].eql?(END_OF_FRAME)
|
|
return bytes[idx].eql?(END_OF_FRAME[0])
|
|
end
|
|
|
|
def handle_frame(frame_lines)
|
|
gas_pattern = /^([0-1:24\.2\.1]+)\((\d{12}[SW])\)\((\d{5}\.\d{3})\*m3\)$/
|
|
|
|
# prepare DB record
|
|
last_reading = Reading.last
|
|
reading = Reading.new
|
|
|
|
frame_lines.each {| line|
|
|
if line.match(/1-0:1.8.1/) # Verbruik hoog tarief
|
|
reading.total_kwh_consumed_high = line.split(/1-0:1.8.1\(|\*kWh\)/).join.to_f
|
|
# p "Total kwh consumed (high): #{total_kwh_consumed_high}."
|
|
end
|
|
if line.match(/1-0:1.8.2/) # Verbruik laag tarief
|
|
reading.total_kwh_consumed_low = line.split(/1-0:1.8.2\(|\*kWh\)/).join.to_f
|
|
# p "Total kwh consumed (low): #{total_kwh_consumed_low}."
|
|
end
|
|
if line.match(/1-0:2.8.1/) # Teruglevering hoog tarief
|
|
reading.total_kwh_produced_high = line.split(/1-0:2.8.1\(|\*kWh\)/).join.to_f
|
|
# p "Total kwh produced (high): #{total_kwh_produced_high}."
|
|
end
|
|
if line.match(/1-0:2.8.2/) # Teruglevering laag tarief
|
|
reading.total_kwh_produced_low = line.split(/1-0:2.8.2\(|\*kWh\)/).join.to_f
|
|
# p "Total kwh produced (low): #{total_kwh_produced_low}."
|
|
end
|
|
if line.match(/1-0:1.7.0/) # Actueel verbruik
|
|
reading.current_kw_consumed = line.split(/1-0:1.7.0\(|\*kW\)/).join.to_f
|
|
#p "Current kW consumed: #{current_kw_consumed}."
|
|
end
|
|
if line.match(/1-0:2.7.0/) # Actueel terug
|
|
reading.current_kw_produced = line.split(/1-0:2.7.0\(|\*kW\)/).join.to_f
|
|
end
|
|
if line.match(/0-0:96.14.0/) # Hoog/laag tarief
|
|
reading.high_tarif = line.split(/0-0:96.14.0\(|\)/).join.eql?("0002")
|
|
end
|
|
if match = line.match(/0-1:24.3.0/) # Gas verbruik (1x per uur een nieuwe stand)
|
|
p "Gas reading: #{match[1]} (#{match[2]})"
|
|
reading.total_m3_gas_consumed = match[3].to_f
|
|
end
|
|
}
|
|
|
|
if last_reading && last_reading.eql_reading?(reading)
|
|
p "Nothing changed. Do not add to the database"
|
|
else
|
|
reading.save
|
|
end
|
|
|
|
# Write to EmonHub
|
|
begin
|
|
TCPSocket.open("printserver",5050){|s|
|
|
s.write(sprintf("8 %d %d\r\n", reading.current_kw_consumed*1000, reading.current_kw_produced*1000))
|
|
}
|
|
rescue
|
|
p "Socket problem."
|
|
end
|
|
# Result
|
|
return reading
|
|
|
|
end
|
|
end
|