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") p "------ 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) end def handle_frame(frame_lines) # gas flag next_is_gas = false # 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 next_is_gas && line.match(/\(/) next_is_gas = false reading.total_m3_gas_consumed = line.split(/\(|\)/).join.to_f end if line.match(/0-1:24.3.0/) # Gas verbruik (1x per uur een nieuwe stand) next_is_gas = true # the usage is on the next line 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("raspberrypi.home.local",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