From a44b81589bfeee8b61f68f5c4d677b05521b0224 Mon Sep 17 00:00:00 2001 From: Nathael Pajani Date: Thu, 11 Jun 2020 21:02:51 +0200 Subject: [PATCH] Communication (data) decoding app for scialys module --- host/scialys_decode/.gitignore | 1 + host/scialys_decode/Makefile | 32 ++++ host/scialys_decode/main.c | 234 +++++++++++++++++++++++++ host/scialys_decode/scyalys_info_armhf | Bin 0 -> 13356 bytes host/scialys_decode/serial_utils.c | 59 +++++++ host/scialys_decode/serial_utils.h | 32 ++++ host/scialys_decode/sin.pl | 34 ++++ 7 files changed, 392 insertions(+) create mode 100644 host/scialys_decode/.gitignore create mode 100644 host/scialys_decode/Makefile create mode 100644 host/scialys_decode/main.c create mode 100755 host/scialys_decode/scyalys_info_armhf create mode 100644 host/scialys_decode/serial_utils.c create mode 100644 host/scialys_decode/serial_utils.h create mode 100755 host/scialys_decode/sin.pl diff --git a/host/scialys_decode/.gitignore b/host/scialys_decode/.gitignore new file mode 100644 index 0000000..47548e5 --- /dev/null +++ b/host/scialys_decode/.gitignore @@ -0,0 +1 @@ +protocol_bridge diff --git a/host/scialys_decode/Makefile b/host/scialys_decode/Makefile new file mode 100644 index 0000000..f67101a --- /dev/null +++ b/host/scialys_decode/Makefile @@ -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 index 0000000..c108487 --- /dev/null +++ b/host/scialys_decode/main.c @@ -0,0 +1,234 @@ +/**************************************************************************** + * Get data from sensors and decode + * + * main.c + * + * + * Copyright 2013-2014 Nathael Pajani + * + * + * 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 . + * + ****************************************************************************/ + + +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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(""); /* Goto terminal home (top left) */ + printf("Mode: %c, Loop: %d, ZC: %d\n", mode, loop, zc_cnt); + printf("Prod: % 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("Cmd: %03d/%03d, Fan:%d/%d\n", command_val, act_cmd, fan_on, force_fan); + printf("Water: % 2d.%02d°C\n", (water_centi_degrees / 100), (water_centi_degrees % 100)); + printf("Internal 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("Load: %03d - %03d\n", load_power_lowest, load_power_highest); + printf("Extdis: %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("\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 index 0000000000000000000000000000000000000000..0f68033c8390986f16b4486b58a49ca66eb88407 GIT binary patch literal 13356 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 Qn@0HUcVaACM#=Ag01eF!(*OVf literal 0 HcmV?d00001 diff --git a/host/scialys_decode/serial_utils.c b/host/scialys_decode/serial_utils.c new file mode 100644 index 0000000..5e17e42 --- /dev/null +++ b/host/scialys_decode/serial_utils.c @@ -0,0 +1,59 @@ +/********************************************************************* + * + * Serial utility functions + * + * + * Copyright 2012-2014 Nathael Pajani + * + * 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 . + * + *********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 index 0000000..7c17bcf --- /dev/null +++ b/host/scialys_decode/serial_utils.h @@ -0,0 +1,32 @@ +/********************************************************************* + * + * Serial utility functions + * + * + * Copyright 2012 Nathael Pajani + * + * 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 . + * + *********************************************************************/ +#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 index 0000000..063ef81 --- /dev/null +++ b/host/scialys_decode/sin.pl @@ -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"; + + -- 2.43.0