-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathimmersunproxy2mqtt.pl
executable file
·99 lines (80 loc) · 3.13 KB
/
immersunproxy2mqtt.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/perl
#
# Copyright (c) 2020 David M Brooke, [email protected]
#
#
use strict;
use warnings;
use DateTime;
use AnyEvent::MQTT;
use AnyEvent::Handle::UDP; # libanyevent-handle-udp-perl
# File-scope variables
our $mqtt;
our $logfile;
our $udp_server;
our $udp_client;
our $ob_data;
our $ob_ae_handle;
our $ob_client_addr;
# Subroutine for Outbound Callback
sub ob_rx_callback {
( $ob_data, $ob_ae_handle, $ob_client_addr ) = @_;
my $cv_mqtt;
my $bytestring;
# Generate date/timestamp for logfile
my $datetime = DateTime->now( )->iso8601( ).'Z';
# The "exporting" value is a signed Short at byte 29 & 30
my $exporting = unpack( "x28 s<", $ob_data );
# The "generating" value is a signed Short at byte 53 & 54
my $generating = unpack( "x52 s<", $ob_data );
# The "diverting" value is a signed Short at byte 55 & 56
my $diverting = unpack( "x54 s<", $ob_data );
# The "consuming" value is calculated from the others
my $consuming = 0 - ( $exporting - $generating + $diverting );
my $importing = 0 - $exporting;
# Convert data to hex for logfile
$bytestring = unpack( 'H*', $ob_data );
print $logfile "$datetime $bytestring\n";
#print "$datetime Exporting: $exporting Generating: $generating Diverting: $diverting Consuming: $consuming\n";
# Check for 'odd' datagram format - must be a better test than this but need to investigate further
if ( $generating != 0 )
{
# Publish the data to MQTT
$cv_mqtt = $mqtt->publish( topic => "raw/immersun/SERIAL/generating/power", message => $generating );
$cv_mqtt = $mqtt->publish( topic => "raw/immersun/SERIAL/exporting/power", message => $exporting );
$cv_mqtt = $mqtt->publish( topic => "raw/immersun/SERIAL/importing/power", message => $importing );
$cv_mqtt = $mqtt->publish( topic => "raw/immersun/SERIAL/diverting/power", message => $diverting );
$cv_mqtt = $mqtt->publish( topic => "raw/immersun/SERIAL/consuming/power", message => $consuming );
}
# Forward the Outbound packet to live.immersun.com
my $cv = $udp_client->push_send( $ob_data );
}
# Subroutine for Inbound Callback
sub ib_rx_callback {
my ( $data, $ae_handle, $client_addr ) = @_;
# Forward the Inbound packet to the immerLINK Bridge
my $cv = $udp_server->push_send( $data, $ob_client_addr );
}
# Main Program
# Open the logfile
open( $logfile, ">>", "/home/pi/immersun.log" )
or die "Can't open output file: $!";
$logfile->autoflush( 1 );
# Connect to the MQTT Broker
$mqtt = AnyEvent::MQTT->new( host => 'mqtt',
client_id => 'immersun2mqtt',
user_name => 'USERNAME',
password => 'PASSWORD' );
die unless defined $mqtt;
# Create the UDP Server
$udp_server = AnyEvent::Handle::UDP->new( bind => ['192.168.40.81', 87],
on_recv => \&ob_rx_callback );
die unless defined $udp_server;
# Create the UDP Client
$udp_client = AnyEvent::Handle::UDP->new( connect => ['62.30.9.158', 87],
on_recv => \&ib_rx_callback );
die unless defined $udp_client;
# Run the event loop
AnyEvent->condvar->recv;
# Shouldn't ever get here but just in case...
close( $logfile );