Skip to content

Commit cedb5fd

Browse files
committed
cleanups
1 parent 4cdfc5b commit cedb5fd

17 files changed

+1138
-25
lines changed

Diff for: Makefile

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# make clean ... delete all build files
22
# make ... create the application
33

4-
CXXFLAGS = -Wall -O3 -std=c++0x -Wno-write-strings -Wno-narrowing -I /usr/include/freetype2 -I /usr/include/kmclib
5-
LDFLAGS = -pthread -lpthread -lm -lkmclib -lfreetype -lrt -lmosquitto -ljansson
6-
OBJ = pylonmonitor.o readbatt.o fifo.o mqttthread.o
4+
CXXFLAGS = -Wall -O3 -std=c++0x -Wno-write-strings -Wno-narrowing
5+
LDFLAGS = -pthread -lpthread -lm -lmosquitto -ljansson
6+
OBJ = pylonmonitor.o readbatt.o fifo.o mqttthread.o serial.o identifySerUSB.o serial_helper.o kmfifo.o helper.o
77

88
default: $(OBJ)
99
g++ $(CXXFLAGS) -o pylonmonitor $(OBJ) $(LDFLAGS)

Diff for: README.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ Connect the Console connector of the master battery via an RS-232 to TTL (3,3v)
1010
## Install required libraries:
1111
run the script: prepare
1212

13-
## Install the library: kmclib, available in my github repos
14-
1513
## Build the software:
1614
make clean<br>
1715
make<br>
@@ -42,6 +40,6 @@ see file: autostart.txt
4240

4341
## Using the pylontech battery monitor:
4442
1. via Web interface: open the IP of the Raspberry PI in the browser<br>
45-
2. via MQTT: configure the IP address of the MQTT broker in file: mqttthread.h. The topic name can be configure in readbatt.h. These settings will be done via webinterface in a later version of this software. This MQTT client does not use password or authentication. If your MQTT broker requires it, you need to add it to this code.
43+
2. via MQTT: configure the IP address of the MQTT broker in file: mqttthread.h. The topic name can be configure in readbatt.h. These settings will be done via webinterface in a later version of this software. This MQTT client does not use password or authentication. If your MQTT broker requires it, you need to activate it in file: mqttthred.cpp, function init().
4644

4745
![Screenshot of Pylontech Battery Monitor](pics/screenshot.png)

Diff for: helper.cpp

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/* this file contains various helper routines */
2+
3+
#include <signal.h>
4+
#include <ifaddrs.h>
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <string.h>
8+
#include <sys/types.h>
9+
#include <sys/socket.h>
10+
#include <netinet/in.h>
11+
#include <arpa/inet.h>
12+
#include <netdb.h>
13+
14+
#include "helper.h"
15+
16+
// check if it is already running
17+
int isRunning(char *prgname)
18+
{
19+
int num = 0;
20+
char s[256];
21+
sprintf(s,"ps -e | grep %s",prgname);
22+
23+
FILE *fp = popen(s,"r");
24+
if(fp)
25+
{
26+
// gets the output of the system command
27+
while (fgets(s, sizeof(s)-1, fp) != NULL)
28+
{
29+
if(strstr(s,prgname) && !strstr(s,"grep"))
30+
{
31+
if(++num == 2)
32+
{
33+
printf("%s is already running, do not start twice !\n",prgname);
34+
pclose(fp);
35+
return 1;
36+
}
37+
}
38+
}
39+
pclose(fp);
40+
}
41+
return 0;
42+
}
43+
44+
void (*sigfunc)();
45+
46+
// signal handler
47+
void sighandler(int signum)
48+
{
49+
printf("program stopped by signal\n");
50+
51+
(*sigfunc)();
52+
}
53+
54+
void install_signal_handler(void (*signalfunction)())
55+
{
56+
sigfunc = signalfunction;
57+
// signal handler, mainly used if the user presses Ctrl-C
58+
struct sigaction sigact;
59+
sigact.sa_handler = sighandler;
60+
sigemptyset(&sigact.sa_mask);
61+
sigact.sa_flags = 0;
62+
sigaction(SIGINT, &sigact, NULL);
63+
sigaction(SIGTERM, &sigact, NULL);
64+
sigaction(SIGQUIT, &sigact, NULL);
65+
sigaction(SIGABRT, &sigact, NULL); // assert() error
66+
67+
//sigaction(SIGSEGV, &sigact, NULL);
68+
69+
// switch off signal 13 (broken pipe)
70+
// instead handle the return value of the write or send function
71+
signal(SIGPIPE, SIG_IGN);
72+
73+
74+
}
75+
76+
// get own IP adress
77+
char* ownIP()
78+
{
79+
static char ip[20] = { 0 };
80+
81+
struct ifaddrs* ifaddr, * ifa;
82+
int s;
83+
char host[NI_MAXHOST];
84+
85+
if (getifaddrs(&ifaddr) == -1)
86+
{
87+
printf("cannot read own IP address, getifaddrs faild. Check Networking\n");
88+
exit(0);
89+
}
90+
91+
92+
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
93+
{
94+
if (ifa->ifa_addr == NULL)
95+
continue;
96+
97+
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
98+
99+
if (ifa->ifa_addr->sa_family == AF_INET)
100+
{
101+
if (s != 0)
102+
{
103+
printf("getnameinfo() failed: %s\n", gai_strerror(s));
104+
printf("cannot read own IP address, getnameinfo failed: %s. Check Networking\n", gai_strerror(s));
105+
exit(0);
106+
}
107+
if (strncmp(host, "127", 3) != 0)
108+
{
109+
strcpy(ip, host);
110+
break;
111+
}
112+
}
113+
}
114+
115+
freeifaddrs(ifaddr);
116+
return ip;
117+
}

Diff for: helper.h

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
char* ownIP();
2+
void install_signal_handler(void (*signalfunction)());
3+
void sighandler(int signum);
4+
int isRunning(char *prgname);

Diff for: html/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@
246246
row.appendChild(chargeCell);
247247

248248
var balCell = document.createElement("td");
249-
balCell.textContent = battery.bal[j];
249+
balCell.textContent = battery.bal[j]==78?0:1;
250250
row.appendChild(balCell);
251251

252252
if (battery.bal[j] == 1) {

Diff for: identifySerUSB.cpp

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* identify a serial-USB adapter
3+
*
4+
* by DJ0ABR
5+
*
6+
* function:
7+
* 1. find which /dev/ttyU* adapters are available
8+
* 2. get their attributes using this command line function:
9+
* udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB0) | grep '{serial}' | cut -d \" -f2 | head -n 1
10+
* 3. get the Vendor ID using this command line function:
11+
* udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB0) | grep '{idVendor}' | cut -d \" -f2 | head -n 1
12+
*
13+
* udevadm.... gets the complete information
14+
* grep ... checks for lines with serial
15+
* cut ... extracts the first line, which contains the ID
16+
*
17+
* Enter the first line of the result into :
18+
#define SERID_serial "xxxxx"
19+
#define SERID_idVendor "yyyy"
20+
*
21+
*
22+
* 3. this function comparse this ID with an specified ID, if equal, we found the right serial port
23+
*
24+
*/
25+
26+
#include <stdio.h>
27+
#include <string.h>
28+
#include "identifySerUSB.h"
29+
30+
void scan_serial_devices();
31+
void get_serial_IDs();
32+
33+
#define SERDEVNAMELEN 50
34+
#define SERDEVIDLEN 50
35+
char serdev_name[MAXSERIALDEVICES][SERDEVNAMELEN];
36+
char serdev_id[MAXSERIALDEVICES][SERDEVIDLEN];
37+
char serdev_idVendor[MAXSERIALDEVICES][SERDEVIDLEN];
38+
39+
char *get_serial_device_name(char *SERID_serial, char *SERID_idVendor)
40+
{
41+
// if SERID_serial starts with tty, then it is the device name already, so no search
42+
if(strncmp(SERID_serial,"/dev/tty",8) == 0)
43+
{
44+
return SERID_serial;
45+
}
46+
47+
scan_serial_devices();
48+
get_serial_IDs();
49+
50+
// check which adapter has the requested ID
51+
for(int i=0; i<MAXSERIALDEVICES; i++)
52+
{
53+
if(serdev_name[i][0] == 0)
54+
break; // nothing found
55+
56+
if(strstr(serdev_id[i],SERID_serial) && strstr(serdev_idVendor[i],SERID_idVendor))
57+
{
58+
printf("serial-USB adapter found: %s with serial:%s and idVendor:%s",serdev_name[i],serdev_id[i],serdev_idVendor[i]);
59+
return serdev_name[i];
60+
}
61+
}
62+
return NULL;
63+
}
64+
65+
// fill serdev_name with all serUSB devices names available on the computer
66+
void scan_serial_devices()
67+
{
68+
// clear storage
69+
memset(serdev_name,0,sizeof(char)*MAXSERIALDEVICES*SERDEVNAMELEN);
70+
memset(serdev_id,0,sizeof(char)*MAXSERIALDEVICES*SERDEVIDLEN);
71+
72+
printf("scan for serial ports\n");
73+
char s[50];
74+
snprintf(s,49,"ls -1 /dev/ttyU*");
75+
s[49] = 0;
76+
int serportnum = 0;
77+
FILE *fp = popen(s,"r");
78+
if(fp)
79+
{
80+
while (fgets(s, sizeof(s)-1, fp) != NULL)
81+
{
82+
// delete \n
83+
if(strlen(s) > 5 && s[strlen(s)-1] == '\n')
84+
s[strlen(s)-1] = 0;
85+
strcpy(serdev_name[serportnum++],s);
86+
if(serportnum >= MAXSERIALDEVICES) break;
87+
}
88+
pclose(fp);
89+
}
90+
else
91+
printf("ERROR: cannot execute ls command\n");
92+
}
93+
94+
// fill serdev_id with the IDs of the devices
95+
void get_serial_IDs()
96+
{
97+
char s[1000];
98+
FILE *fp;
99+
100+
for(int i=0; i<MAXSERIALDEVICES; i++)
101+
{
102+
if(serdev_name[i][0] == 0) break;
103+
104+
// read serial string
105+
snprintf(s,999,"udevadm info -a -p $(udevadm info -q path -n %s) | grep '{serial}' | cut -d \\\" -f2 | head -n 1",serdev_name[i]);
106+
//printf("%s\n",s);
107+
s[999] = 0;
108+
fp = popen(s,"r");
109+
if(fp)
110+
{
111+
while (fgets(s, sizeof(s)-1, fp) != NULL)
112+
{
113+
// delete \n
114+
if(strlen(s) > 5 && s[strlen(s)-1] == '\n')
115+
s[strlen(s)-1] = 0;
116+
strcpy(serdev_id[i],s);
117+
//printf("%s\n",s);
118+
break;
119+
}
120+
pclose(fp);
121+
}
122+
else
123+
printf("ERROR: cannot execute udevadm... command\n");
124+
125+
126+
// read idVendor string
127+
snprintf(s,999,"udevadm info -a -p $(udevadm info -q path -n %s) | grep '{idVendor}' | cut -d \\\" -f2 | head -n 1",serdev_name[i]);
128+
//printf("%s\n",s);
129+
s[999] = 0;
130+
fp = popen(s,"r");
131+
if(fp)
132+
{
133+
while (fgets(s, sizeof(s)-1, fp) != NULL)
134+
{
135+
// delete \n
136+
if(strlen(s) > 5 && s[strlen(s)-1] == '\n')
137+
s[strlen(s)-1] = 0;
138+
strcpy(serdev_idVendor[i],s);
139+
//printf("%s\n",s);
140+
break;
141+
}
142+
pclose(fp);
143+
}
144+
else
145+
printf("ERROR: cannot execute udevadm... command\n");
146+
}
147+
}

Diff for: identifySerUSB.h

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#define MAXSERIALDEVICES 10
2+
3+
char *get_serial_device_name(char *SERID_serial, char *SERID_idVendor);

0 commit comments

Comments
 (0)