Skip to content

Commit 9431c57

Browse files
committed
added Web Configuration
1 parent cedb5fd commit 9431c57

13 files changed

+594
-129
lines changed

Makefile

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

4+
CXX = g++
45
CXXFLAGS = -Wall -O3 -std=c++0x -Wno-write-strings -Wno-narrowing
56
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
7+
SRC = $(wildcard *.cpp)
8+
OBJ = $(SRC:.cpp=.o)
9+
DEP = $(OBJ:.o=.d) # Add dependency files
710

8-
default: $(OBJ)
9-
g++ $(CXXFLAGS) -o pylonmonitor $(OBJ) $(LDFLAGS)
11+
.PHONY: default clean
12+
13+
default: pylonmonitor
14+
15+
pylonmonitor: $(OBJ)
16+
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
17+
18+
-include $(DEP)
19+
20+
%.o: %.cpp
21+
$(CXX) $(CXXFLAGS) -MMD -c $< -o $@
1022

1123
clean:
12-
rm -rf *.o pylonmonitor
24+
rm -rf $(OBJ) $(DEP) pylonmonitor
25+

README.md

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
# Pylontech Battery Monitor
22

33
## Supported Hardware:
4-
Raspberry PI, recommended for lowest power consumption: Raspberry PI Zero W
5-
or any other SBC
4+
Raspberry PI: recommended for lowest power consumption is the Raspberry PI Zero W,
5+
but any other SBC is also compatible.
66

77
## Connection:
8-
Connect the Console connector of the master battery via an RS-232 to TTL (3,3v) converter to the primary serial interface of the RPI
8+
Connect the Console connector of the master battery to the primary serial interface of the Raspberry Pi using an RS-232 to TTL (3.3v) converter.
99

1010
## Install required libraries:
11-
run the script: prepare
11+
Run the script named prepare to install necessary libraries.
1212

1313
## Build the software:
1414
make clean<br>
1515
make<br>
16-
this build the executable file: pylonmonitor
17-
16+
This process will create the executable file named `pylonmonitor`.
1817
## Run the software:
19-
run as root: ./pylonmonitor
18+
Run the software with root privileges by executing `./pylonmonitor`.
2019

2120
## Raspi supporting WLAN (RPI3, 4 and Zero-W) need remapping of serial port:
22-
1. Switch-off serial login shell (important !!!, double check)<br>
23-
sudo raspi-config<br>
21+
1. Disable serial login shell (important !!! Double check this step)<br>
22+
Enter `sudo raspi-config` in the terminalbr>
2423
InterfaceOptions - Serial Port:<br>
2524
login shell: NO<br>
2625
hardware enabled: YES<br>
2726
2. map primary serial port to connector pins<br>
2827
sudo nano /boot/config.txt and add at the end:<br>
2928
dtoverlay=miniuart-bt<br>
30-
3. Reboot and check if ok:<br>
29+
3. Reboot and verify configuration:<br>
3130
ls -l /dev/serial*<br>
32-
serial0 must map to ttyAMA0<br>
33-
4. to use ttyAMA0 the program must be running as root
31+
serial0 should map to ttyAMA0<br>
32+
4. Programs using `ttyAMA0` must be run with root privileges
3433

3534
## Number of Pylontech Batteries:
36-
this software detects the number of batteries automatically
35+
The software automatically detects the number of connected Pylontech batteries.
3736

3837
## Autostart (for RPI only):
39-
see file: autostart.txt
38+
Refer to the autostart.txt file for instructions on setting up the software to start automatically.
4039

4140
## Using the pylontech battery monitor:
42-
1. via Web interface: open the IP of the Raspberry PI in the browser<br>
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().
41+
1. via Web interface: Access the Raspberry Pi's IP address in a web browser.<br>
42+
2. Click on "SETUP" in the top right corner of the web interface to configure network settings and MQTT.<br>
43+
3. Use tools like MQTT Explorer to verify that everything is working as expected
4444

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

config.cpp

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#include <jansson.h>
2+
#include <fstream>
3+
#include <iostream>
4+
#include <sstream>
5+
#include "config.h"
6+
#include <unistd.h>
7+
#include <pwd.h>
8+
#include <grp.h>
9+
10+
using std::string;
11+
12+
string ssid = "*";
13+
string password = "";
14+
string mqttBrokerIP = "192.168.x.y";
15+
string brokerusername;
16+
string brokerpassword;
17+
string publishTopic = "kmpub";
18+
string responseTopic = "kmcmd";
19+
string locationTopic = "Solaranlage";
20+
string deviceTopic = "Pylontech Akku Monitor";
21+
22+
string getMQTTtopic()
23+
{
24+
// update from config
25+
readConfigFromJson();
26+
return publishTopic + "/" + locationTopic + "/" + deviceTopic;
27+
}
28+
29+
bool saveDefaultConfigToJson()
30+
{
31+
// Create a new JSON object
32+
json_t *root = json_object();
33+
34+
// Insert data into the JSON object
35+
json_object_set_new(root, "ssid", json_string(ssid.c_str()));
36+
json_object_set_new(root, "password", json_string(password.c_str()));
37+
json_object_set_new(root, "mqttBrokerIP", json_string(mqttBrokerIP.c_str()));
38+
json_object_set_new(root, "brokerusername", json_string(brokerusername.c_str()));
39+
json_object_set_new(root, "brokerpassword", json_string(brokerpassword.c_str()));
40+
json_object_set_new(root, "publishTopic", json_string(publishTopic.c_str()));
41+
json_object_set_new(root, "responseTopic", json_string(responseTopic.c_str()));
42+
json_object_set_new(root, "locationTopic", json_string(locationTopic.c_str()));
43+
json_object_set_new(root, "deviceTopic", json_string(deviceTopic.c_str()));
44+
45+
// Dump the JSON object to a string
46+
char *jsonString = json_dumps(root, JSON_INDENT(4));
47+
if (!jsonString) {
48+
// Cleanup
49+
json_decref(root);
50+
return false; // Failed to dump JSON string
51+
}
52+
53+
// Write the JSON string to a file
54+
// Check if the file already exists
55+
if (access("/var/www/html/wxdata/configData.json", F_OK) != -1) {
56+
std::cerr << "File already exists.\n";
57+
// Cleanup
58+
json_decref(root);
59+
free(jsonString);
60+
return false; // Do not overwrite the file
61+
} else {
62+
// File does not exist, proceed to create it
63+
std::ofstream outFile("/var/www/html/wxdata/configData.json");
64+
if (!outFile.is_open()) {
65+
std::cerr << "Failed to open file for writing.\n";
66+
// Cleanup
67+
json_decref(root);
68+
free(jsonString);
69+
return false;
70+
}
71+
72+
outFile << jsonString;
73+
outFile.close();
74+
75+
// Get the UID and GID for www-data
76+
struct passwd *pwd = getpwnam("www-data");
77+
struct group *grp = getgrnam("www-data");
78+
if (!pwd || !grp) {
79+
std::cerr << "Failed to get UID or GID for www-data.\n";
80+
// Cleanup
81+
json_decref(root);
82+
free(jsonString);
83+
return false;
84+
}
85+
86+
// Change file ownership to www-data:www-data
87+
if (chown("/var/www/html/wxdata/configData.json", pwd->pw_uid, grp->gr_gid) == -1) {
88+
std::cerr << "Failed to change file ownership.\n";
89+
// Cleanup, although not critical to return false here since the file was written successfully
90+
}
91+
}
92+
93+
// Cleanup JSON resources
94+
json_decref(root);
95+
free(jsonString);
96+
97+
return true; // Indicate success
98+
}
99+
100+
bool readConfigFromJson()
101+
{
102+
// Open the JSON file
103+
std::ifstream inFile("/var/www/html/wxdata/configData.json");
104+
if (!inFile.is_open()) {
105+
std::cerr << "Failed to open file for reading.\n";
106+
return false; // Failed to open file
107+
}
108+
109+
// Read file into a string
110+
std::stringstream strStream;
111+
strStream << inFile.rdbuf(); // Read the file
112+
std::string jsonString = strStream.str(); // str holds the content of the file
113+
inFile.close();
114+
115+
// Parse the JSON string
116+
json_error_t error;
117+
json_t *root = json_loads(jsonString.c_str(), 0, &error);
118+
if (!root) {
119+
std::cerr << "Error parsing JSON: " << error.text << "\n";
120+
return false; // Failed to parse JSON
121+
}
122+
123+
// Extract values
124+
ssid = json_string_value(json_object_get(root, "ssid"));
125+
password = json_string_value(json_object_get(root, "password"));
126+
mqttBrokerIP = json_string_value(json_object_get(root, "mqttBrokerIP"));
127+
brokerusername = json_string_value(json_object_get(root, "brokerusername"));
128+
brokerpassword = json_string_value(json_object_get(root, "brokerpassword"));
129+
publishTopic = json_string_value(json_object_get(root, "publishTopic"));
130+
responseTopic = json_string_value(json_object_get(root, "responseTopic"));
131+
locationTopic = json_string_value(json_object_get(root, "locationTopic"));
132+
deviceTopic = json_string_value(json_object_get(root, "deviceTopic"));
133+
134+
// Cleanup
135+
json_decref(root);
136+
137+
return true; // Success
138+
}

config.h

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <string>
2+
3+
using std::string;
4+
5+
bool saveDefaultConfigToJson();
6+
bool readConfigFromJson();
7+
string getMQTTtopic();
8+
9+
extern string ssid;
10+
extern string password;
11+
extern string mqttBrokerIP;
12+
extern string brokerusername;
13+
extern string brokerpassword;
14+
extern string publishTopic;
15+
extern string responseTopic;
16+
extern string locationTopic;
17+
extern string deviceTopic;

html/defaultdata.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
// Specify the path to the JSON file
3+
$jsonFilePath = __DIR__ . '/wxdata/configData.json';
4+
5+
// Check if the file exists
6+
if (file_exists($jsonFilePath)) {
7+
// Set the Content-Type header to application/json
8+
header('Content-Type: application/json');
9+
10+
// Read the file contents and echo them
11+
$jsonData = file_get_contents($jsonFilePath);
12+
echo $jsonData;
13+
} else {
14+
// If the file does not exist, return an error
15+
http_response_code(404);
16+
echo json_encode(array("error" => "File not found."));
17+
}
18+
?>

0 commit comments

Comments
 (0)