#!/usr/bin/perl
use warnings;
use strict;
use Device::SerialPort;
use Data::Dump qw(dump);
use Time::HiRes qw(time);
use LWP::UserAgent;

my $read_len = 255;

my $path = shift @ARGV || '/dev/serial/by-path/platform-20980000.usb-usb-0:1.2:1.0-port0';

$|=1;

my $ua = LWP::UserAgent->new;

connect_again:

my $s = new Device::SerialPort( $path ) || die $!;
$s->baudrate(2400);
$s->databits(8); # 7
$s->parity('none');
$s->stopbits(1);
$s->handshake('none');
$s->read_char_time(2);
$s->read_const_time(3);

#$s->write('o');

my $t = time();

my $sym;

sub _mqtt_pub {
	my ( $t, $m ) = @_;
	my $cmd = "mosquitto_pub -h rpi2 -t '$t' -m '$m'";
	#warn "# _mqtt_pub [$t] = [$m]\n";
	#warn "## $cmd";
	system $cmd;
}

while (1) {
	my ($len, $string) = $s->read($read_len);
	goto connect_again if ! defined $len;
	my $ts = time();

	if ( $len > 0 ) {
		my $hex = unpack('H*',$string);
		$hex =~ s/(..)/$1 /g;

		my $temp = `curl --silent localhost:3000/temp.txt`;
		$temp =~ s/\s+/ /gs;
		$temp =~ s/^\s+//;

		#printf "%s %2d  %s\n", time(), $len, $hex;
		printf "%8.4f %6.2f %2d  %s | %s\n", $ts, $ts - $t, $len, $hex, $temp;
		$t = time();

		if ( $hex =~ m/^.+aa fc 39 aa (.+)/ ) {
			my @l = split(/\s+/,$1);
			my @d = (
				hex( $l[0] . $l[1] ),
				hex( $l[3] . $l[4] ),
				hex( $l[6] ),
				hex( $l[12] ),
				hex( $l[14] ), # * 300,
				hex( $l[15] ), # * 400,
				hex( $l[18] ),
			);

			_mqtt_pub "stat/boiler/" . chr(ord('a') + $_) => $d[$_] foreach 0 .. $#d;
		}

		my @v = split(/\s+/, $temp, 4);
		my @n = qw( DS18B20/temperature DHT22/temperature DHT22/humidity DHT22/errors );
		   @n = qw( DS18B20/temperature DHT22/temperature DHT22/humidity DHT22/errors ) if $#v == 1; # no DS18B20
		foreach (@v) {
			_mqtt_pub "stat/boiler/" . shift(@n) => $_;
		}

		my $t = int( $ts * 1_000_000_000 );
		my @a = split(/ /, $hex);
		if ( $#a == 66 ) {
			my $measurement = "boiler " . join(',',
				"o19=".hex( $a[19] ),
				"o25=".hex( $a[35] . $a[36] ),
				"o30=".hex( $a[38] . $a[39] ),
				"o41=".hex( $a[41] ),
				"o47=".hex( $a[47] ),
				"o49=".hex( $a[49] ),
				"o50=".hex( $a[50] ),
				"o51=".hex( $a[51] ),
				"o53=".hex( $a[53] ),
				"ds18b20_temp=$v[0]", "dht22_temp=$v[1]", "dht22_hum=$v[2]"
			);
			my $response = $ua->post( "http://10.60.0.92:8086/write?db=rot13", Content => $measurement );
			chomp(my $content = $response->content());
			if ($response->is_success()) {
				#warn "OK $content\n";
			} else {
				warn "ERROR $content\n";
				die $response->status_line;
			}
		}
	}
}

$s->close;
