Communication (data) decoding app for scialys module
authorNathael Pajani <nathael.pajani@ed3l.fr>
Thu, 11 Jun 2020 19:02:51 +0000 (21:02 +0200)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 17:24:30 +0000 (18:24 +0100)
host/scialys_decode/.gitignore [new file with mode: 0644]
host/scialys_decode/Makefile [new file with mode: 0644]
host/scialys_decode/main.c [new file with mode: 0644]
host/scialys_decode/scyalys_info_armhf [new file with mode: 0755]
host/scialys_decode/serial_utils.c [new file with mode: 0644]
host/scialys_decode/serial_utils.h [new file with mode: 0644]
host/scialys_decode/sin.pl [new file with mode: 0755]

diff --git a/host/scialys_decode/.gitignore b/host/scialys_decode/.gitignore
new file mode 100644 (file)
index 0000000..47548e5
--- /dev/null
@@ -0,0 +1 @@
+protocol_bridge
diff --git a/host/scialys_decode/Makefile b/host/scialys_decode/Makefile
new file mode 100644 (file)
index 0000000..f67101a
--- /dev/null
@@ -0,0 +1,32 @@
+#CROSS_COMPILE ?= arm-linux-gnueabihf-
+CC = $(CROSS_COMPILE)gcc
+
+CFLAGS = -Wall -O2 -Wextra
+
+EXEC = scyalys_info
+
+all: $(EXEC)
+
+
+OBJDIR = objs
+SRC = $(shell find . -name \*.c)
+OBJS = ${SRC:%.c=${OBJDIR}/%.o}
+INCLUDES = includes/
+
+${OBJDIR}/%.o: %.c
+       @mkdir -p $(dir $@)
+       @echo "-- compiling" $<
+       @$(CC) -MMD -MP -MF ${OBJDIR}/$*.d $(CFLAGS) $< -c -o $@ -I$(INCLUDES)
+
+$(EXEC): $(OBJS)
+       @echo "Linking $@ ..."
+       @$(CC) $(LDFLAGS) -o $@ $(OBJS)
+       @echo Done.
+
+
+clean:
+       find ${OBJDIR} -name "*.o" -exec rm {} \;
+       find ${OBJDIR} -name "*.d" -exec rm {} \;
+
+mrproper: clean
+       rm -f $(EXEC)
diff --git a/host/scialys_decode/main.c b/host/scialys_decode/main.c
new file mode 100644 (file)
index 0000000..c108487
--- /dev/null
@@ -0,0 +1,234 @@
+/****************************************************************************
+ *  Get data from sensors and decode
+ *
+ *   main.c
+ *
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+
+/* this protocol handler is designed to run on a host replacing the DTPlug,
+ * but should be easy to use as a source for the protocol handling code for
+ * the DTPlug itself.
+ */
+
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include "serial_utils.h"
+
+
+#define BUF_SIZE  100
+
+#define PROG_NAME  "Sensors polling and decode"
+#define VERSION  "0.1"
+
+
+void help(char *prog_name)
+{
+       fprintf(stderr, "---------------- "PROG_NAME" --------------------------------\n");
+       fprintf(stderr, "Usage: %s [options]\n" \
+               "  Available options:\n" \
+               "  \t -d | --device : Serial device to use for serial communication with the module\n" \
+               "  \t -h | --help : Print this help\n" \
+               "  \t -v | --version : Print programm version\n" \
+               "  All other arguments are data for the command, handled depending on the command.\n", prog_name);
+       fprintf(stderr, "-----------------------------------------------------------------------\n");
+}
+
+#define MSG_LEN  150
+char data[MSG_LEN];
+int data_idx = 0;
+
+
+int protocol_decode(char c)
+{
+       if (data_idx == 0) {
+               if (c == '#') {
+                       data[0] = c;
+                       data_idx = 1;
+               }
+               return 0;
+       }
+       if (data_idx > 0) {
+               data[data_idx] = c;
+               if (c == '$') {
+                       data_idx = 0;
+                       return 1;
+               }
+               data_idx++;
+               if (data_idx >= MSG_LEN) {
+                       data_idx = 0;
+               }
+       }
+       return 0;
+}
+
+int main(int argc, char* argv[])
+{
+       /* Serial */
+       char* device = NULL;
+       int slave_fd = 0;
+
+       while(1) {
+               int option_index = 0;
+               int c = 0;
+
+               struct option long_options[] = {
+                       {"device", required_argument, 0, 'd'},
+                       {"help", no_argument, 0, 'h'},
+                       {"version", no_argument, 0, 'v'},
+                       {0, 0, 0, 0}
+               };
+
+               c = getopt_long(argc, argv, "d:hv", long_options, &option_index);
+
+               /* no more options to parse */
+               if (c == -1) break;
+               switch (c) {
+
+                       /* d, device */
+                       case 'd':
+                               device = optarg;
+                               break;
+
+                       /* v, version */
+                       case 'v':
+                               printf("%s Version %s\n", PROG_NAME, VERSION);
+                               return 0;
+                               break;
+
+                       /* h, help */
+                       case 'h':
+                       default:
+                               help(argv[0]);
+                               return 0;
+               }
+       }
+
+
+       /* Need Serial port as parameter */
+       if (device == NULL) {
+               printf("Error, need serial (tty) device\n");
+               help(argv[0]);
+               return -1;
+       }
+
+       /* Open tty */
+       slave_fd = serial_setup(device);
+       if (slave_fd < 0) {
+               printf("Unable to open specified serial port %s\n", device);
+               return -2;
+       }
+
+       /* ************************************************* */
+       /* And never stop handling data ! */
+       while (1) {
+               int len = 0, ret = 0;
+               struct timeval now;
+               char buf[BUF_SIZE];
+               int idx = 0;
+
+               /* Send periodic requests for temperature */
+               gettimeofday(&now, NULL);
+
+               memset(buf, 0, BUF_SIZE);
+               /* Get serial data and try to build a packet */
+               len = read(slave_fd, buf, BUF_SIZE);
+               if (len <= 0) {
+                       if (len < 0) {
+                               perror("serial read error");
+                       } else {
+                               /* Read returnd 0 ... EOF */
+                               printf("Serial disapeared ... closing and re-opening\n");
+                       }
+                       close(slave_fd);
+                       do {
+                               slave_fd = serial_setup(device);
+                               if (slave_fd < 0) {
+                                       printf("Waiting for serial port %s\n", device);
+                                       usleep(10 * 1000);
+                               }
+                       } while (slave_fd < 0);
+                       continue;
+               } else {
+                       write(2, buf, len);
+               }
+               while (idx < len) {
+                       ret = protocol_decode(buf[idx]);
+                       /* Check return code to know if we have a valid packet */
+                       if (ret == 1) {
+                               /* Valid packet received, parse data */
+                               char mode;
+                               int loop, solar_prod_value, home_conso_value;
+                               float diff;
+                               int water_centi_degrees, deci_degrees_power, deci_degrees_disp;
+                               int load_power_lowest, load_power_highest, zc_cnt, command_val;
+                               int act_cmd, fan_on, force_fan;
+                               int error_shutdown, temp_shutdown, overvoltage;
+                               int external_disable, forced_heater_mode, manual_activation_request;
+
+                               sscanf(data, "#%c:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d$",
+                                               &mode, &loop, &solar_prod_value, &home_conso_value,
+                                               &water_centi_degrees, &deci_degrees_power, &deci_degrees_disp,
+                                               &load_power_lowest, &load_power_highest, &zc_cnt, &command_val,
+                                               &act_cmd, &fan_on, &force_fan, &error_shutdown, &temp_shutdown, &overvoltage,
+                                               &external_disable, &forced_heater_mode, &manual_activation_request);
+                               diff = ((float)(solar_prod_value - home_conso_value) / 1000);
+                                       
+                               /* Display data */
+                               printf("\e[H"); /* Goto terminal home (top left) */
+                               printf("\e[KMode: %c, Loop: %d, ZC: %d\n", mode, loop, zc_cnt);
+                               printf("\e[KProd: % 2d.%02dA, Conso: % 2d.%02dA, delta: %.2fA\n",
+                                                       (solar_prod_value / 1000), ((solar_prod_value % 1000) / 10),
+                                                       (home_conso_value / 1000), ((home_conso_value % 1000) / 10),
+                                                       diff);
+                               printf("\e[KCmd: %03d/%03d, Fan:%d/%d\n", command_val, act_cmd, fan_on, force_fan);
+                               printf("\e[KWater: % 2d.%02d°C\n", (water_centi_degrees / 100), (water_centi_degrees % 100));
+                               printf("\e[KInternal TempP: % 2d.%d°C, TempD: % 2d.%d°C\n",
+                                                       (deci_degrees_power / 10), (deci_degrees_power % 10),
+                                                       (deci_degrees_disp / 10), (deci_degrees_disp % 10));
+                               printf("\e[KLoad: %03d - %03d\n", load_power_lowest, load_power_highest);
+                               printf("\e[KExtdis: %d, Forced: %d, Manual: %d, ErrSD: %d, TempSD: %d, OverV: %d\n",
+                                                       external_disable, forced_heater_mode, manual_activation_request,
+                                                       error_shutdown, temp_shutdown, overvoltage);
+                               printf("\e[K\n");
+                       }
+
+                       idx++;
+               }
+
+       } /* End of infinite loop */
+
+       close(slave_fd);
+       return 0;
+}
+
+
diff --git a/host/scialys_decode/scyalys_info_armhf b/host/scialys_decode/scyalys_info_armhf
new file mode 100755 (executable)
index 0000000..0f68033
Binary files /dev/null and b/host/scialys_decode/scyalys_info_armhf differ
diff --git a/host/scialys_decode/serial_utils.c b/host/scialys_decode/serial_utils.c
new file mode 100644 (file)
index 0000000..5e17e42
--- /dev/null
@@ -0,0 +1,59 @@
+/*********************************************************************
+ *
+ *   Serial utility functions
+ *
+ *
+ * Copyright 2012-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+
+#define SERIAL_BAUD  B115200
+
+
+int serial_setup(char* name)
+{
+       struct termios tio;
+       int fd = -1;
+
+       /* Open serial port */
+       fd = open(name, O_RDWR);
+       if (fd < 0) {
+               perror("Unable to open communication with companion chip");
+               return -1;
+       }
+       /* Setup serial port */
+       memset(&tio, 0, sizeof(tio));
+       tio.c_cflag = CS8 | CREAD | CLOCAL;     /* 8n1, see termios.h for more information */
+       tio.c_cc[VMIN] = 1;
+       tio.c_cc[VTIME] = 5;
+       cfsetospeed(&tio, SERIAL_BAUD);
+       cfsetispeed(&tio, SERIAL_BAUD);
+       tcsetattr(fd, TCSANOW, &tio);
+
+       return fd;
+}
+
diff --git a/host/scialys_decode/serial_utils.h b/host/scialys_decode/serial_utils.h
new file mode 100644 (file)
index 0000000..7c17bcf
--- /dev/null
@@ -0,0 +1,32 @@
+/*********************************************************************
+ *
+ *   Serial utility functions
+ *
+ *
+ * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *********************************************************************/
+#ifndef SERIAL_UTILS_H
+#define SERIAL_UTILS_H
+
+/* Setup serial comunication, using name if given or saved name if name is NULL
+ *  SERIAL_BAUD  B38400
+ *  c_cflag  (CS7 | PARENB | CREAD | CLOCAL) (7e1)
+ */
+int serial_setup(char* name);
+
+#endif /* SERIAL_UTILS_H */
+
diff --git a/host/scialys_decode/sin.pl b/host/scialys_decode/sin.pl
new file mode 100755 (executable)
index 0000000..063ef81
--- /dev/null
@@ -0,0 +1,34 @@
+#! /usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use Math::Trig;
+
+my ($clocks, $outfile) = @ARGV;
+my ($fh, $angle, $v, $w, $idx);
+
+if (defined $outfile) {
+       open($fh, '>', $outfile);
+       print $fh "#include \"lib/stdint.h\"\n\n";
+       print $fh "uint32_t power_delay[101] = {\n";
+}
+
+for (my $i = 0; $i <= 100; $i++) {
+       $angle = $i * 0.02;
+       $v = (acos(1 - $angle) / pi * 100);
+       $w = int($v * $clocks);
+       if (not defined $outfile) {
+               print "$v - [$i] = $w,\n";
+       } else {
+               print $fh "\t[$i] = $w,\n";
+       }
+}
+
+if (defined $outfile) {
+       print $fh "};\n";
+       close($fh);
+}
+print "Done\n";
+
+