Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poller fix #53

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 41 additions & 20 deletions sources/inverter-cli/inverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@
#include <fcntl.h>
#include <termios.h>

cInverter::cInverter(std::string devicename, int qpiri, int qpiws, int qmod, int qpigs) {
cInverter::cInverter(std::string devicename) {
device = devicename;
status1[0] = 0;
status2[0] = 0;
warnings[0] = 0;
mode = 0;
qpiri = qpiri;
qpiws = qpiws;
qmod = qmod;
qpigs = qpigs;
}

string *cInverter::GetQpigsStatus() {
Expand Down Expand Up @@ -68,7 +64,7 @@ int cInverter::GetMode() {
return result;
}

bool cInverter::query(const char *cmd, int replysize) {
bool cInverter::query(const char *cmd) {
time_t started;
int fd;
int i=0, n;
Expand Down Expand Up @@ -109,14 +105,35 @@ bool cInverter::query(const char *cmd, int replysize) {

buf[n++] = crc >> 8;
buf[n++] = crc & 0xff;
buf[n++] = 0x0d;
buf[n++] = 0x0d; // '\r'
buf[n+1] = '\0'; // see workaround below

// send a command
int chunk_size = 8;
for (int offset = 0; offset < n; usleep(50000)) {
int left = n - offset;
int towrite = left > chunk_size ? chunk_size : left;
// WORKAROUND: For some reason, writing 1 byte causes it to error.
// However, since we padded with '\0' above, we can give it 2 instead.
// I don't know of any 6 (+ 2*CRC + '\r') byte commands to test it on
// but this at least gets it to return NAK.
if (towrite == 1) towrite = 2;
//lprintf("DEBUG: offset %d, writing %d", offset, towrite);
ssize_t written = write(fd, &buf[offset], towrite);
if (written > 0)
offset += written;
else {
lprintf("INVERTER: command write failed (written=%d, errno=%d: %s)", written, errno, strerror(errno));
break;
}
//lprintf("DEBUG: %d bytes to write, %d bytes written", n, offset);
}

//send a command
write(fd, &buf, n);
char *startbuf = 0;
char *endbuf = 0;
time(&started);

do {
n = read(fd, (void*)buf+i, replysize-i);
n = read(fd, &buf[i], 120-i);
if (n < 0) {
if (time(NULL) - started > 2) {
lprintf("INVERTER: %s read timeout", cmd);
Expand All @@ -128,10 +145,14 @@ bool cInverter::query(const char *cmd, int replysize) {
}

i += n;
} while (i<replysize);
startbuf = (char *)&buf[0];
endbuf = strchr(startbuf, '\r');
} while (endbuf == NULL);
close(fd);
buf[i] = '\0';

if (i==replysize) {
if (endbuf != NULL) {
int replysize = endbuf - startbuf + 1;

lprintf("INVERTER: %s reply size (%d bytes)", cmd, i);

Expand All @@ -144,13 +165,13 @@ bool cInverter::query(const char *cmd, int replysize) {
return false;
}

buf[i-3] = '\0'; //nullterminating on first CRC byte
buf[replysize-3] = '\0'; // null terminating on first CRC byte
lprintf("INVERTER: %s: %d bytes read: %s", cmd, i, buf);

lprintf("INVERTER: %s query finished", cmd);
return true;
} else {
lprintf("INVERTER: %s reply too short (%d bytes)", cmd, i);
lprintf("INVERTER: %s couldn't find reply <cr> (%d bytes)", cmd, i);
return false;
}
}
Expand All @@ -163,15 +184,15 @@ void cInverter::poll() {

// Reading mode
if (!ups_qmod_changed) {
if (query("QMOD", qmod)) {
if (query("QMOD")) {
SetMode(buf[1]);
ups_qmod_changed = true;
}
}

// reading status (QPIGS)
if (!ups_qpigs_changed) {
if (query("QPIGS", qpigs)) {
if (query("QPIGS")) {
m.lock();
strcpy(status1, (const char*)buf+1);
m.unlock();
Expand All @@ -181,7 +202,7 @@ void cInverter::poll() {

// Reading QPIRI status
if (!ups_qpiri_changed) {
if (query("QPIRI", qpiri)) {
if (query("QPIRI")) {
m.lock();
strcpy(status2, (const char*)buf+1);
m.unlock();
Expand All @@ -191,7 +212,7 @@ void cInverter::poll() {

// Get any device warnings...
if (!ups_qpiws_changed) {
if (query("QPIWS", qpiws)) {
if (query("QPIWS")) {
m.lock();
strcpy(warnings, (const char*)buf+1);
m.unlock();
Expand All @@ -205,7 +226,7 @@ void cInverter::poll() {

void cInverter::ExecuteCmd(const string cmd) {
// Sending any command raw
if (query(cmd.data(), 7)) {
if (query(cmd.data())) {
m.lock();
strcpy(status2, (const char*)buf+1);
m.unlock();
Expand Down
4 changes: 2 additions & 2 deletions sources/inverter-cli/inverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class cInverter {

void SetMode(char newmode);
bool CheckCRC(unsigned char *buff, int len);
bool query(const char *cmd, int replysize);
bool query(const char *cmd);
uint16_t cal_crc_half(uint8_t *pin, uint8_t len);

public:
cInverter(std::string devicename, int qpiri, int qpiws, int qmod, int qpigs);
cInverter(std::string devicename);
void poll();
void runMultiThread() {
std::thread t1(&cInverter::poll, this);
Expand Down
11 changes: 1 addition & 10 deletions sources/inverter-cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ string devicename;
int runinterval;
float ampfactor;
float wattfactor;
int qpiri, qpiws, qmod, qpigs;

// ---------------------------------------

Expand Down Expand Up @@ -91,14 +90,6 @@ void getSettingsFile(string filename) {
attemptAddSetting(&wattfactor, linepart2);
else if(linepart1 == "watt_factor")
attemptAddSetting(&wattfactor, linepart2);
else if(linepart1 == "qpiri")
attemptAddSetting(&qpiri, linepart2);
else if(linepart1 == "qpiws")
attemptAddSetting(&qpiws, linepart2);
else if(linepart1 == "qmod")
attemptAddSetting(&qmod, linepart2);
else if(linepart1 == "qpigs")
attemptAddSetting(&qpigs, linepart2);
else
continue;
}
Expand Down Expand Up @@ -180,7 +171,7 @@ int main(int argc, char* argv[]) {
}

bool ups_status_changed(false);
ups = new cInverter(devicename,qpiri,qpiws,qmod,qpigs);
ups = new cInverter(devicename);

// Logic to send 'raw commands' to the inverter..
if (!rawcmd.empty()) {
Expand Down
7 changes: 4 additions & 3 deletions sources/inverter-mqtt/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ export TERM=xterm
# Init the mqtt server for the first time, then every 5 minutes
# This will re-create the auto-created topics in the MQTT server if HA is restarted...

watch -n 300 /opt/inverter-mqtt/mqtt-init.sh > /dev/null 2>&1 &
watch -xn 300 /opt/inverter-mqtt/mqtt-init.sh &

# Run the MQTT Subscriber process in the background (so that way we can change the configuration on the inverter from home assistant)
/opt/inverter-mqtt/mqtt-subscriber.sh &
# This normally doesn't exit, but the watch is needed to handle mqtt server restarts.
watch -xn 1 /opt/inverter-mqtt/mqtt-subscriber.sh &

# execute exactly every 30 seconds...
watch -n 30 /opt/inverter-mqtt/mqtt-push.sh > /dev/null 2>&1
watch -xn 30 /opt/inverter-mqtt/mqtt-push.sh
2 changes: 1 addition & 1 deletion sources/inverter-mqtt/mqtt-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ registerTopic "Load_watt" "W" "chart-bell-curve"
registerTopic "Load_watthour" "Wh" "chart-bell-curve"
registerTopic "Load_va" "VA" "chart-bell-curve"
registerTopic "Bus_voltage" "V" "details"
registerTopic "Heatsink_temperature" "" "details"
registerTopic "Heatsink_temperature" "C" "thermometer"
registerTopic "Battery_capacity" "%" "battery-outline"
registerTopic "Battery_voltage" "V" "battery-outline"
registerTopic "Battery_charge_current" "A" "current-dc"
Expand Down
32 changes: 17 additions & 15 deletions sources/inverter-mqtt/mqtt-push.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
#!/bin/bash

MQTT_SERVER=`cat /etc/inverter/mqtt.json | jq '.server' -r`
MQTT_PORT=`cat /etc/inverter/mqtt.json | jq '.port' -r`
MQTT_TOPIC=`cat /etc/inverter/mqtt.json | jq '.topic' -r`
MQTT_DEVICENAME=`cat /etc/inverter/mqtt.json | jq '.devicename' -r`
MQTT_USERNAME=`cat /etc/inverter/mqtt.json | jq '.username' -r`
MQTT_PASSWORD=`cat /etc/inverter/mqtt.json | jq '.password' -r`

INFLUX_ENABLED=`cat /etc/inverter/mqtt.json | jq '.influx.enabled' -r`
if [[ $INFLUX_ENABLED == "true" ]] ; then
INFLUX_HOST=`cat /etc/inverter/mqtt.json | jq '.influx.host' -r`
INFLUX_USERNAME=`cat /etc/inverter/mqtt.json | jq '.influx.username' -r`
INFLUX_PASSWORD=`cat /etc/inverter/mqtt.json | jq '.influx.password' -r`
INFLUX_DEVICE=`cat /etc/inverter/mqtt.json | jq '.influx.device' -r`
INFLUX_PREFIX=`cat /etc/inverter/mqtt.json | jq '.influx.prefix' -r`
INFLUX_DATABASE=`cat /etc/inverter/mqtt.json | jq '.influx.database' -r`
INFLUX_MEASUREMENT_NAME=`cat /etc/inverter/mqtt.json | jq '.influx.namingMap.'$1'' -r`
fi

pushMQTTData () {
MQTT_SERVER=`cat /etc/inverter/mqtt.json | jq '.server' -r`
MQTT_PORT=`cat /etc/inverter/mqtt.json | jq '.port' -r`
MQTT_TOPIC=`cat /etc/inverter/mqtt.json | jq '.topic' -r`
MQTT_DEVICENAME=`cat /etc/inverter/mqtt.json | jq '.devicename' -r`
MQTT_USERNAME=`cat /etc/inverter/mqtt.json | jq '.username' -r`
MQTT_PASSWORD=`cat /etc/inverter/mqtt.json | jq '.password' -r`

mosquitto_pub \
-h $MQTT_SERVER \
-p $MQTT_PORT \
Expand All @@ -23,14 +33,6 @@ pushMQTTData () {
}

pushInfluxData () {
INFLUX_HOST=`cat /etc/inverter/mqtt.json | jq '.influx.host' -r`
INFLUX_USERNAME=`cat /etc/inverter/mqtt.json | jq '.influx.username' -r`
INFLUX_PASSWORD=`cat /etc/inverter/mqtt.json | jq '.influx.password' -r`
INFLUX_DEVICE=`cat /etc/inverter/mqtt.json | jq '.influx.device' -r`
INFLUX_PREFIX=`cat /etc/inverter/mqtt.json | jq '.influx.prefix' -r`
INFLUX_DATABASE=`cat /etc/inverter/mqtt.json | jq '.influx.database' -r`
INFLUX_MEASUREMENT_NAME=`cat /etc/inverter/mqtt.json | jq '.influx.namingMap.'$1'' -r`

curl -i -XPOST "$INFLUX_HOST/write?db=$INFLUX_DATABASE&precision=s" -u "$INFLUX_USERNAME:$INFLUX_PASSWORD" --data-binary "$INFLUX_PREFIX,device=$INFLUX_DEVICE $INFLUX_MEASUREMENT_NAME=$2"
}

Expand Down
1 change: 1 addition & 0 deletions sources/inverter-mqtt/mqtt-subscriber.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ do

echo "Incoming request send: [$rawcmd] to inverter."
/opt/inverter-cli/bin/inverter_poller -r $rawcmd;
/opt/inverter-mqtt/mqtt-push.sh

done < <(mosquitto_sub -h $MQTT_SERVER -p $MQTT_PORT -u "$MQTT_USERNAME" -P "$MQTT_PASSWORD" -t "$MQTT_TOPIC/sensor/$MQTT_DEVICENAME" -q 1)