Ok,
For anyone interested in a simple monitoring program which can be compiled with gcc on a Linux PC
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
//char modem_id[] = {0xFB, 0x04, 0x11, 0x87};
char modem_id[] = {0x19, 0x12, 0x10, 0x01};
char inverter_id[] = {0x60, 0x00, 0x03, 0xC3};
char key_id[] = {0x00, 0x00};
char parm[] = {0x00, 0x00};
char cmd1[2] = {0xF2, 0x65};
//char cmd1[2] = {0xF5, 0x68};
char cmdzero[2] = {0xF0, 0x00};
char buf[256];
int idx = 0;
int fd;
int dtr = TIOCM_DTR;
enum { HEADER1, HEADER2, CMD, TAIL1, TAIL2, DATA } state;
void r3()
{
int i;
for(i = 0; i< sizeof(modem_id); i++)
{
write(fd, &modem_id[i], 1);
}
for(i = 0; i< sizeof(key_id); i++)
{
write(fd, &key_id[i], 1);
}
for(i = 0; i< sizeof(parm); i++)
{
write(fd, &parm[i], 1);
}
for(i = 0; i< sizeof(inverter_id); i++)
{
write(fd, &inverter_id[i], 1);
}
}
int main(int argc, char* argv[])
{
int what;
int i;
int count;
struct termios SerialPortSettings;
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 3 ) // 0, 1 and 2 are stdin, stdout and stderr
{
printf("\n ERROR ! opening com port\n");
return -1;
}
tcgetattr(fd, &SerialPortSettings);
cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);
// 8N1 Mode
SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
// no handhake
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
// raw mode
SerialPortSettings.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON | BRKINT);
SerialPortSettings.c_lflag &= ~(ICANON | IEXTEN | ISIG | ECHO);
SerialPortSettings.c_oflag &= ~OPOST;
// Setting Time outs
SerialPortSettings.c_cc[VMIN] = 1; // Read at least 1 character
SerialPortSettings.c_cc[VTIME] = 0; // Wait indefinetly
if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) // TCSAFLUSH
{
printf("\n ERROR ! in Setting attributes\n");
close(fd);
return -2;
}
ioctl(fd, TIOCMBIC, &dtr); // clear DTR pin == SET pin of HC-12
if ((argc == 2) && !strcmp("zero", argv[1]))
{
printf("reset power total\n");
count = write(fd, &cmdzero[0], 1);
r3();
count = write(fd, &cmdzero[1], 1);
sleep(1);
count = write(fd, &cmdzero[0], 1);
r3();
count = write(fd, &cmdzero[1], 1);
sleep(1);
}
tcflush(fd, TCIFLUSH);
state = HEADER1;
what = fork();
if(!what) // child: only handles received bytes
{
for(;;)
{
int cnt;
ioctl(fd, FIONREAD, &cnt);
if(cnt > 0)
{
switch (state)
{
case HEADER1:
{
read(fd, buf, 1);
if (buf[0] == cmd1[0])
{
state = HEADER2;
}
}
break;
case HEADER2:
{
read(fd, &buf[1], 1);
if (buf[1] == modem_id[0])
{
state = CMD;
idx = 2;
}
else
{
state = HEADER1;
}
}
break;
case CMD:
{
read(fd, &buf[idx], 1);
if (++idx == 12)
state = TAIL1;
}
break;
case TAIL1:
{
read(fd, &buf[idx], 1);
if (buf[idx++] == inverter_id[3])
{
state = TAIL2;
}
else
{
state = HEADER1;
}
}
break;
case TAIL2:
{
read(fd, &buf[idx], 1);
if (buf[idx++] == cmd1[1])
{
state = DATA;
}
else
{
state = HEADER1;
}
}
break;
case DATA:
{
read(fd, &buf[idx++], 1);
switch (idx)
{
case 16:
{
unsigned int dc = ((buf[14] & 0xff) * 256) + (buf[15] & 0xff);
printf("DC voltage : % 4u.%02u\n", dc / 100, dc % 100);
}
break;
case 18:
{
unsigned int ac = ((buf[16] & 0xff) * 256) + (buf[17] & 0xff);
printf("AC voltage : % 4u.%02u\n", ac / 100, ac % 100);
}
break;
case 20:
{
//printf("%02X %02X ",buf[18] & 0xff, buf[19] & 0xff);
unsigned int amp = ((buf[18] & 0xff) * 256) + (buf[19] & 0xff);
printf("DC current : % 4u.%02u\n", amp / 100, amp % 100);
}
break;
case 22:
{
//printf("%02X %02X ",buf[20] & 0xff, buf[21] & 0xff);
unsigned int eng = ((buf[20] & 0xff) * 256) + (buf[21] & 0xff);
printf("Energy kWh : % 4u.%02u\n", eng / 100, eng % 100);
}
break;
/*
case 24:
{
printf("%02X %02X\n",buf[22] & 0xff, buf[23] & 0xff);
unsigned int eng = (((buf[20] & 0xff) * 256) + (buf[21] & 0xff) * 10);
printf("Energy Wh: %u\n", eng);
}
break;
*/
case 26:
{
//printf("%02X %02X ",buf[24] & 0xff, buf[25] & 0xff);
unsigned int watt = ((buf[24] & 0xff) * 256) + (buf[25] & 0xff);
printf("Output Watt : % 4u.%1u\n", watt / 10, watt % 10);
}
break;
case 28:
{
//printf("%02X %02X ",buf[26] & 0xff, buf[27] & 0xff);
unsigned int temp = ((buf[26] & 0xff) * 256) + (buf[27] & 0xff);
printf("Temperature : % 4u.%02u\n\n", temp / 100, temp % 100);
state = HEADER1;
}
break;
}
}
break;
}
}
}
}
else //parent: poll for data every 5 secs
{
for(;;)
{
write(fd, &cmd1[0], 1);
r3();
write(fd, &cmd1[1], 1);
sleep(5);
}
}
close(fd);
}