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) # 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 line.match(/0-1:24.2.1/) p "Gas reading found: #{line}" match = line.match(/^(0-1:24.2.1)\(([^)]+)\)\(([\d.]+)\*m3\)$/) # 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