Omniksol-4k-TL wifi kit

Capture inverter data yourself? Or want to process generated data? Instead of using the Omnik Portal App?

I found out that it is possible to configure the wifi kit to send TCP/UDP packets to an remote server. After that i started googling around. With some minimal data i started write a small C program.

Some other related project on the internet:

  1. GitHub – Woutrrr / Omnik-Data-Logger | Language: Python | Found first
  2. GitHub – micromys / Omnik | Language: PHP
  3. GitHub – arjenv / omnikstatus | Language: C | Found after completing my own script 🙁

Those scripts are polling the inverter each few minutes. When my research started, i found out, by configuring the web interface, that Omnik also offers the possibility to push TCP or UDP packets to an specified server. With this enabled i started testing en developing.

Reading the message (which byte means what?) was based on the GitHub projects. So someone else did the hard work 😉

Getting started… (read on)

Use a webbrowser to login on the inverter management interface, the navigate to ‘Advanced / Remote server’

omnik_interface_statusomnik_interface_advancedYou are free to fill in servers B and C. Server A seems to point to the Omnik Portal and cannot be disabled. Some more advanced users can make some firewall tricks to block this behavior. (if wished).

Setting up…

  1. Have a debian 8 machine
  2. Download and unzip OmnikListenerTCP to your machine (or compile your own)
  3. Make it executeable
    # chmod +x OmnikListenerTCP 
  4. Execute
    # ./OmnikListenerTCP --csv-file=./output.csv 
  5. Ensure your port 8989 is opened, on this port OmnikListerenTCP is listening. (change in source code and recompile)
  6. Fill in your machine IP/hostname into the Omnik Inverter Management interface (see above) and choose port TCP 8989
  7. Wait for the sun 🙂

 Usage (csv output)


to enable csv output and write to "output.csv" start with

# ./OmnikListenerTCP --csv-file=output.csv

to enable mysql output

Usage (mysql output)


# ./OmnikListenerTCP \ 
  --mysql-host=127.0.0.1 \
  --mysql-user=omnikdata \
  --mysql-pass=mysqlpassword \
  --mysql-db=omnikdata

-- Required table

CREATE TABLE `omnikdata` (
`inverterid` VARCHAR(16) NOT NULL,
`moment` DATETIME NOT NULL,
`temperature` DECIMAL(5,2) NOT NULL,
`p_today` DECIMAL(5,2) UNSIGNED NOT NULL,
`p_total` DECIMAL(10,2) UNSIGNED NOT NULL,
`h_total` SMALLINT(5) UNSIGNED NOT NULL,
`pv1_u` DECIMAL(5,2) NOT NULL,
`pv1_i` DECIMAL(5,2) NOT NULL,
`pv2_u` DECIMAL(5,2) NOT NULL,
`pv2_i` DECIMAL(5,2) NOT NULL,
`pv3_u` DECIMAL(5,2) NOT NULL,
`pv3_i` DECIMAL(5,2) NOT NULL,
`ac1_u` DECIMAL(5,2) NOT NULL,
`ac1_i` DECIMAL(5,2) NOT NULL,
`ac1_f` DECIMAL(5,2) NOT NULL,
`ac1_p` SMALLINT(6) NOT NULL,
`ac2_u` DECIMAL(5,2) NOT NULL,
`ac2_i` DECIMAL(5,2) NOT NULL,
`ac2_f` DECIMAL(5,2) NOT NULL,
`ac2_p` SMALLINT(6) NOT NULL,
`ac3_u` DECIMAL(5,2) NOT NULL,
`ac3_i` DECIMAL(5,2) NOT NULL,
`ac3_f` DECIMAL(5,2) NOT NULL,
`ac3_p` SMALLINT(6) NOT NULL,
INDEX `inverterid` (`inverterid`),
INDEX `inverterid_moment` (`inverterid`, `moment`)
);

 

OmnikListenerTCP_c_source

/*
 * I used Eclipse IDE to help me compile and debug. Eclipse compiles with:
 * gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.c"
 * gcc -L/usr/lib -L/usr/lib/mysql -o "OmnikListenerTCP"  ./main.o ./readconfig.o   -lmysqlclient
 */

/*
 * main.c
 *
 *  Beej's Guide to Network Programming
 *  http://beej.us/guide/bgnet/output/html/multipage/index.html
 *  http://beej.us/guide/bgnet/output/html/multipage/clientserver.html
 *
 *  MySQL and C
 *  http://zetcode.com/db/mysqlc/
 *  http://www.kitebird.com/mysql-book/ch06-3ed.pdf
 *
 *  Omnik message info found here:
 *  Written in PHP
 *  https://github.com/micromys/Omnik
 *  Written in Python
 *  https://github.com/Woutrrr/Omnik-Data-Logger/blob/master/InverterMsg.py
 *  Written in C
 *  https://github.com/arjenv/omnikstats
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <mysql/mysql.h>

#define OMNIKPORTAL_PULL "8899"
#define PORT_LISTEN "8989"
#define BACKLOG 10

FILE * fp;

MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;

unsigned char mysql_enabled = 0;
char mysql_host[100] = "";
char mysql_user[32] = "omniklistener";
char mysql_pass[32] = "";
char mysql_db[100] = "energyportal";
unsigned int mysql_port = 3306;
unsigned char csv_enabled = 0;
char csvfile[250] = "";
unsigned char silent = 0;

void doChildProcess(int fd_client);
void printMessage(unsigned char *message, int length);

void sigchld_handler(int s){
    while(waitpid(-1, NULL,WNOHANG) > 0);
}

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int startswith(const char *prefix, const char *string){
    size_t lenstring = strlen(string);
    size_t lenprefix = strlen(prefix);
    if(lenstring < lenprefix){
        return 0;
    }
    else{
        return (strncmp(string,prefix,lenprefix) == 0);
    }
}

int main(int argc, char *argv[]){
    int fd_server;    //Listening socket
    int fd_client;  //Client connected socket
    struct addrinfo hints, *res, *p;
    struct sockaddr_storage their_addr;
    struct sigaction sa;
    int status;
    char ipstr[INET6_ADDRSTRLEN];
    socklen_t addr_size;
    char s[INET6_ADDRSTRLEN];
    pid_t pid;

    //Loop through command line arguments
    int i = 0;
    for(i = 0; i < argc; i++){
        if(startswith("--mysql-host=",argv[i])){
            strcpy(mysql_host,argv[i]+strlen("--mysql-host="));
        }
        if(startswith("--mysql-user=",argv[i])){
            strcpy(mysql_user,argv[i]+strlen("--mysql-user="));
        }
        if(startswith("--mysql-pass=",argv[i])){
            strcpy(mysql_pass,argv[i]+strlen("--mysql-pass="));
        }
        if(startswith("--mysql-db=",argv[i])){
            strcpy(mysql_db,argv[i]+strlen("--mysql-db="));
        }
        if(startswith("--mysql-port=",argv[i])){
            sscanf(argv[i]+strlen("--mysql-port="),"%d",&mysql_port);
        }
        if(startswith("--csv-file=",argv[i])){
            strcpy(csvfile,argv[i]+strlen("--csv-file="));
        }
        if(startswith("--silent",argv[i])){
            silent = 1;
        }
    }

    //When --mysql-host is filled, then enable mysql export
    if(strlen(mysql_host) > 0){
        mysql_enabled = 1;
    }
    //When --csv-file is filled, then enable csv export
    if(strlen(csvfile) > 0){
        csv_enabled = 1;
    }

    //Print out active configuration
    printf("OmnikListenerTCP\n");
    printf(" MySQL enabled : %d\n",mysql_enabled);
    if(mysql_enabled){
        printf(" MySQL host    : %s\n",mysql_host);
        printf(" MySQL port    : %d\n",mysql_port);
        printf(" MySQL user    : %s\n",mysql_user);
        //Maybe hide password? ;)
        //printf(" MySQL pass    : %s\n",mysql_pass);
        printf(" MySQL db      : %s\n",mysql_db);
    }
    printf(" CSV enabled   : %d\n",csv_enabled);
    if(csv_enabled){
        printf(" CSV file      : %s\n",csvfile);
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    if((status = getaddrinfo(NULL, PORT_LISTEN, &hints, &res))!=0){
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
        return 2;
    }

    for(p = res; p != NULL; p=p->ai_next){
        void *addr;
        char *ipver;

        if(p->ai_family == AF_INET){
            struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
            addr = &(ipv4->sin_addr);
            ipver = "IPv4";
        }
        else{
            struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
            addr = &(ipv6->sin6_addr);
            ipver = "IPv6";
        }
        inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
        //printf(" %s: %s\n",ipver,ipstr);
    }

    fd_server = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

    if(fd_server == -1){
        perror("socket");
        return 3;
    }
    else{
        printf("Socket opened %d\n",fd_server);
    }

    if(bind(fd_server, res->ai_addr, res->ai_addrlen) == -1){
        perror("bind");
        return 4;
    }

    if(listen(fd_server,BACKLOG) == -1){
        perror("listen");
        return 5;
    }

    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if(sigaction(SIGCHLD, &sa, NULL) == -1){
        perror("sigaction");
        exit(1);
    }

    printf("server: waiting for connections...\n");

    while(1){
        addr_size = sizeof their_addr;
        fd_client = accept(fd_server, (struct sockaddr *)&their_addr, &addr_size);
        if(fd_client == -1){
            perror("accept");
            continue;
        }
        else{
            printf("Socket accepted %d\n",fd_client);
        }

        inet_ntop(their_addr.ss_family,
            get_in_addr((struct sockaddr *)&their_addr),
            s, sizeof s);

        printf("server: get connection from %s\n",s);

        pid = fork();
        if(pid == 0){
            close(fd_server); //child doesn't need the listener
            doChildProcess(fd_client);
        }
        close(fd_client);
    }

    return 0;
}

void doChildProcess(int fd_client)
{
    int numbytes;
    unsigned char recvbuf[512];

    if((numbytes = recv(fd_client, recvbuf, 511, 0)) == -1){
        perror("recv");
        exit(1);
    }
    printf("client: received bytes %d \n",numbytes);

    printMessage(recvbuf,numbytes);

    close(fd_client);
    exit(0);
}

void printMessage(unsigned char *message, int length){
    time_t timer;
    char timebuffer[26];
    struct tm* tm_info;
    int i = 0;
    unsigned char byte;

    char p_id[17];
    short p_temp;
    long p_etoday;
    long p_etotal;
    long p_htotal;
    short p_vpv1;
    short p_vpv2;
    short p_vpv3;
    short p_ipv1;
    short p_ipv2;
    short p_ipv3;
    short p_vac1;
    short p_vac2;
    short p_vac3;
    short p_iac1;
    short p_iac2;
    short p_iac3;
    short p_fac1;
    short p_fac2;
    short p_fac3;
    short p_pac1;
    short p_pac2;
    short p_pac3;

    time(&timer);
    tm_info = localtime(&timer);

    if(length < 143)
    {
        printf("Message to short? Do not process.\n");
        return;
    }

    for(i = 0; i < length; i++){
        byte = message[i];
        printf("%02X ",byte);
        if((i + 1) % 8 == 0){
            printf("\n");
        }
    }
    printf("\n");

    if(message[0] == 0x68 && message[1] == 0x81 && message[2] == 0x41 && message[3] == 0xB0){
        //OK
    }
    else{
        printf("Header does not match hex: 68 81 41 B0\n");
        printf("Skip message");
        return;
    }

    for(i = 0; i < length; i++){
        byte = message[i];

        //Byte 15, start of SerialNumber
        if(i >= 15 && i <= 30){
            p_id[i-15]=byte;
        }

        //Byte 31-32 contain temperature
        if(i == 31){
            p_temp = 0;
            p_temp = byte << 8;
        }
        if(i == 32){
            p_temp = p_temp | byte;
        }

        //Byte 33-34 PV 1 input voltage
        if(i == 33){
            p_vpv1 = 0;
            p_vpv1 = byte << 8;
        }
        if(i == 34){
            p_vpv1 = p_vpv1 | byte;
        }

        //Byte 35-36 PV 2 input voltage
        if(i == 35){
            p_vpv2 = 0;
            p_vpv2 = byte << 8;
        }
        if(i == 36){
            p_vpv2 = p_vpv2 | byte;
        }

        //Byte 37-38 PV 3 input voltage
        if(i == 37){
            p_vpv3 = 0;
            p_vpv3 = byte << 8;
        }
        if(i == 38){
            p_vpv3 = p_vpv3 | byte;
        }

        //Byte 39-40 PV 1 input current
        if(i == 39){
            p_ipv1 = 0;
            p_ipv1 = byte << 8;
        }
        if(i == 40){
            p_ipv1 = p_ipv1 | byte;
        }

        //Byte 41-42 PV 2 input current
        if(i == 41){
            p_ipv2 = 0;
            p_ipv2 = byte << 8;
        }
        if(i == 42){
            p_ipv2 = p_ipv2 | byte;
        }

        //Byte 43-44 PV 3 input current
        if(i == 43){
            p_ipv3 = 0;
            p_ipv3 = byte << 8;
        }
        if(i == 44){
            p_ipv3 = p_ipv3 | byte;
        }

        //Byte 45-46 AC output current phase 1
        if(i == 45){
            p_iac1 = 0;
            p_iac1 = byte << 8;
        }
        if(i == 46){
            p_iac1 = p_iac1 | byte;
        }
        //Byte 47-48 AC output current phase 2
        if(i == 47){
            p_iac2 = 0;
            p_iac2 = byte << 8;
        }
        if(i == 48){
            p_iac2 = p_iac2 | byte;
        }
        //Byte 49-50 AC output current phase 3
        if(i ==49){
            p_iac3 = 0;
            p_iac3 = byte << 8;
        }
        if(i == 50){
            p_iac3 = p_iac3 | byte;
        }

        //Byte 51-52 AC output voltage phase 1
        if(i == 51){
            p_vac1 = 0;
            p_vac1 = byte << 8;
        }
        if(i == 52){
            p_vac1 = p_vac1 | byte;
        }
        //Byte 53-54 AC output voltage phase 2
        if(i == 53){
            p_vac2 = 0;
            p_vac2 = byte << 8;
        }
        if(i == 54){
            p_vac2 = p_vac2 | byte;
        }
        //Byte 55-56 AC output voltage phase 3
        if(i == 55){
            p_vac3 = 0;
            p_vac3 = byte << 8;
        }
        if(i == 56){
            p_vac3 = p_vac3 | byte;
        }

        //Byte 57-58 AC output ??what?? phase 1
        if(i == 57){
            p_fac1 = 0;
            p_fac1 = byte << 8;
        }
        if(i == 58){
            p_fac1 = p_fac1 | byte;
        }
        //Byte 59-60 AC output power phase 1
        if(i == 59){
            p_pac1 = 0;
            p_pac1 = byte << 8;
        }
        if(i == 60){
            p_pac1 = p_pac1 | byte;
        }
        //Byte 61-62 AC output ??what?? phase 2
        if(i == 61){
            p_fac2 = 0;
            p_fac2 = byte << 8;
        }
        if(i == 62){
            p_fac2 = p_fac2 | byte;
        }
        //Byte 63-64 AC output power phase 2
        if(i == 63){
            p_pac2 = 0;
            p_pac2 = byte << 8;
        }
        if(i == 64){
            p_pac2 = p_pac2 | byte;
        }
        //Byte 63-64 AC output ??what?? phase 3
        if(i == 65){
            p_fac3 = 0;
            p_fac3 = byte << 8;
        }
        if(i == 66){
            p_fac3 = p_fac3 | byte;
        }
        //Byte 67-68 AC output power phase 3
        if(i == 67){
            p_pac3 = 0;
            p_pac3 = byte << 8;
        }
        if(i == 68){
            p_pac3 = p_pac3 | byte;
        }

        //Byte 69-70 contain total kwh of today
        if(i == 69){
            p_etoday = 0;
            p_etoday = byte << 8;
        }
        if(i == 70){
            p_etoday = p_etoday | byte;
        }

        //Byte 71-74 contain total kwh
        if(i == 71){
            p_etotal = 0;
            p_etotal = p_etotal | (byte << 24);
        }
        if(i == 72){
            p_etotal = p_etotal | (byte << 16);
        }
        if(i == 73){
            p_etotal = p_etotal | (byte << 8);
        }
        if(i == 74){
            p_etotal = p_etotal | byte;
        }

        //Byte 75-78 contain hours online
        if(i == 75){
            p_htotal = 0;
            p_htotal = p_htotal | (byte << 24);
        }
        if(i == 76){
            p_htotal = p_htotal | (byte << 16);
        }
        if(i == 77){
            p_htotal = p_htotal | (byte << 8);
        }
        if(i == 78){
            p_htotal = p_htotal | byte;
        }
    }

    p_id[16] = 0;

    if(!silent){
        strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %H:%M:%S", tm_info);
        printf("Time    : %s \n", timebuffer);
        printf("Serial  : %s     \n", p_id);
        printf("Temp    : %f     \n", ((double) p_temp / 10));
        printf("E-Today : %f kWh \n", ((double) p_etoday / 100));
        printf("E-Total : %f kWh \n", ((double) p_etotal / 10));
        printf("H-Total : %ld H   \n", p_htotal);

        printf("PV 1 U  : %f V \n", ((double) p_vpv1 / 10));
        printf("PV 1 I  : %f A \n", ((double) p_ipv1 / 10));
        printf("PV 2 U  : %f V \n", ((double) p_vpv2 / 10));
        printf("PV 2 I  : %f A \n", ((double) p_ipv2 / 10));
        printf("PV 3 U  : %f V \n", ((double) p_vpv3 / 10));
        printf("PV 3 I  : %f A \n", ((double) p_ipv3 / 10));

        printf("AC1 U   : %f V \n", ((double) p_vac1 / 10));
        printf("AC1 I   : %f A \n", ((double) p_iac1 / 10));
        printf("AC1 ?   : %f ? \n", ((double) p_fac1 / 100));
        printf("AC1 P   : %d W \n", p_pac1);
        printf("AC2 U   : %f V \n", ((double) p_vac2 / 10));
        printf("AC2 I   : %f A \n", ((double) p_iac2 / 10));
        printf("AC2 ?   : %f ? \n", ((double) p_fac2 / 100));
        printf("AC2 P   : %d W \n", p_pac2);
        printf("AC3 V   : %f V \n", ((double) p_vac3 / 10));
        printf("AC3 I   : %f A \n", ((double) p_iac3 / 10));
        printf("AC3 ?   : %f ? \n", ((double) p_fac3 / 100));
        printf("AC3 P   : %d W \n", p_pac3);

        strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %H:%M:%S", tm_info);
        printf("%s,%s,%f,%f,%f,%ld,%f,%f,%f,%f,%f,%f,%f,%f,%f,%d,%f,%f,%f,%d,%f,%f,%f,%d\n",
            timebuffer,
            p_id,
            ((double) p_temp / 10),
            ((double) p_etoday / 100),
            ((double) p_etotal / 10),
            p_htotal,
            ((double) p_vpv1 / 10),
            ((double) p_ipv1 / 10),
            ((double) p_vpv2 / 10),
            ((double) p_ipv2 / 10),
            ((double) p_vpv3 / 10),
            ((double) p_ipv3 / 10),
            ((double) p_vac1 / 10),
            ((double) p_iac1 / 10),
            ((double) p_fac1 / 100),
            p_pac1,
            ((double) p_vac2 / 10),
            ((double) p_iac2 / 10),
            ((double) p_fac2 / 100),
            p_pac2,
            ((double) p_vac3 / 10),
            ((double) p_iac3 / 10),
            ((double) p_fac3 / 100),
            p_pac3);
    } //END !silent

    if(csv_enabled){
        fp = fopen(csvfile,"a");
        if(fp == NULL){
            perror("fopen");
        }
        else{
            printf("Opened file for appending\n");
            strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %H:%M:%S", tm_info);
            fprintf(fp, "%s,%s,%f,%f,%f,%ld,%f,%f,%f,%f,%f,%f,%f,%f,%f,%d,%f,%f,%f,%d,%f,%f,%f,%d\n",
                timebuffer,
                p_id,
                ((double) p_temp / 10),
                ((double) p_etoday / 100),
                ((double) p_etotal / 10),
                p_htotal,
                ((double) p_vpv1 / 10),
                ((double) p_ipv1 / 10),
                ((double) p_vpv2 / 10),
                ((double) p_ipv2 / 10),
                ((double) p_vpv3 / 10),
                ((double) p_ipv3 / 10),
                ((double) p_vac1 / 10),
                ((double) p_iac1 / 10),
                ((double) p_fac1 / 100),
                p_pac1,
                ((double) p_vac2 / 10),
                ((double) p_iac2 / 10),
                ((double) p_fac2 / 100),
                p_pac2,
                ((double) p_vac3 / 10),
                ((double) p_iac3 / 10),
                ((double) p_fac3 / 100),
                p_pac3);
            fflush(fp);
            fclose(fp);
        }
    }

    if(mysql_enabled){
        //Try to write to mysql
        conn = mysql_init(NULL);
        if(conn == NULL){
            perror("mysql_init");
        }
        else{

            if(!mysql_real_connect(conn,mysql_host,mysql_user,mysql_pass,mysql_db,mysql_port,NULL,0)){
                fprintf(stderr, "%s\n",mysql_error(conn));
            }
            else{
                char stmt_buf[1024];
                sprintf(stmt_buf,""
                    "INSERT INTO `omnikdata` ("
                    "`inverterid`,`moment`,`temperature`,`p_today`,`p_total`,`h_total`,"
                    "`pv1_u`,`pv1_i`,`pv2_u`,`pv2_i`,`pv3_u`,`pv3_i`,"
                    "`ac1_u`,`ac1_i`,`ac1_f`,`ac1_p`,"
                    "`ac2_u`,`ac2_i`,`ac2_f`,`ac2_p`,"
                    "`ac3_u`,`ac3_i`,`ac3_f`,`ac3_p`) "
                    " VALUES ("
                    "'%s',NOW(),%f,%f,%f,%ld,%f,%f,%f,%f,%f,%f,%f,%f,%f,%d,%f,%f,%f,%d,%f,%f,%f,%d);",
                    p_id,
                    ((double) p_temp / 10),
                    ((double) p_etoday / 100),
                    ((double) p_etotal / 10),
                    p_htotal,
                    ((double) p_vpv1 / 10),
                    ((double) p_ipv1 / 10),
                    ((double) p_vpv2 / 10),
                    ((double) p_ipv2 / 10),
                    ((double) p_vpv3 / 10),
                    ((double) p_ipv3 / 10),
                    ((double) p_vac1 / 10),
                    ((double) p_iac1 / 10),
                    ((double) p_fac1 / 100),
                    p_pac1,
                    ((double) p_vac2 / 10),
                    ((double) p_iac2 / 10),
                    ((double) p_fac2 / 100),
                    p_pac2,
                    ((double) p_vac3 / 10),
                    ((double) p_iac3 / 10),
                    ((double) p_fac3 / 100),
                    p_pac3);

                int nQueryResult = mysql_query(conn,stmt_buf);
                if (nQueryResult > 0){
                    fprintf(stdout,"%s\n",mysql_error(conn));
                }
                else{

                }

                //res = mysql_use_result(conn);

                //while((row = mysql_fetch_row(res)) != NULL){
                //    printf("Database: %s\n",row[0]);
                //    //int dumpresult = system("")
                //}

                //mysql_free_result(res);
                mysql_close(conn);

            } //END mysql_real_connect
        } //END mysql_init
    } //END mysql_enabled
}

 

OmnikListenerTCP_c_source
14.8 KiB
1745 Downloads
Details...
OmnikListenerTCP
OmnikListenerTCP
OmnikListenerTCP_x68_64.7z
41.4 KiB
959 Downloads
Details...

2 gedachten over “Omniksol-4k-TL wifi kit

  1. niels

    Super handig. Ik stond op het punt om zelf te beginnen toen ik jouw werk tegenkwam. Binnen 5 minuten lopend.
    Ik wil de data integreren met andere verbruiksgegevens in Openhab, dus ik moet de C skills weer eens oppoetsen (of via csv.)

    Bedankt
    Niels

    1. Robin Bericht auteur

      Goed om te horen dat er binnen 5 minuten resultaten geboekt kunnen worden.

      Met openHAB ben ik niet bekend (wel interessant om later eens verder naar te kijken). Ik heb even kort onderzoek gedaan en wellicht kun je een deel code samenvoegen uit het volgende project:
      https://github.com/openhab/openhab/wiki/Open-Energy-Monitor-Binding

      Ik kan er compleet naast zitten, maar het lijkt er op dat deze Open-Energy-Monitor addon een udp connectie naar localhost (openHab) legt om data aan te bieden.
      Dan hoef je in de OmnikListener.c alleen maar een extra udp connectie te openen en een beetje dataformatting te doen. Heel simpel gezegd 🙂

      Mvgr,
      Robin

Laat een antwoord achter aan niels Reactie annuleren

Het e-mailadres wordt niet gepubliceerd.

Deze site gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.