diff --git a/sources/inverter-cli/inverter.cpp b/sources/inverter-cli/inverter.cpp index 45711f4..81de0ac 100644 --- a/sources/inverter-cli/inverter.cpp +++ b/sources/inverter-cli/inverter.cpp @@ -6,7 +6,6 @@ #include "tools.h" #include "main.h" -#include #include cInverter::cInverter(std::string devicename, int qpiri, int qpiws, int qmod, int qpigs) { @@ -198,14 +197,15 @@ void cInverter::poll() { ups_qpiws_changed = true; } } + if (quit_thread) return; sleep(5); } } -void cInverter::ExecuteCmd(const string cmd) { +void cInverter::ExecuteCmd(const string cmd, int replylen) { // Sending any command raw - if (query(cmd.data(), 7)) { + if (query(cmd.data(), replylen)) { m.lock(); strcpy(status2, (const char*)buf+1); m.unlock(); diff --git a/sources/inverter-cli/inverter.h b/sources/inverter-cli/inverter.h index 3501b6b..dcaf10c 100644 --- a/sources/inverter-cli/inverter.h +++ b/sources/inverter-cli/inverter.h @@ -1,6 +1,7 @@ #ifndef ___INVERTER_H #define ___INVERTER_H +#include #include #include @@ -16,6 +17,8 @@ class cInverter { std::string device; std::mutex m; + std::thread t1; + std::atomic_bool quit_thread{false}; void SetMode(char newmode); bool CheckCRC(unsigned char *buff, int len); @@ -26,8 +29,11 @@ class cInverter { cInverter(std::string devicename, int qpiri, int qpiws, int qmod, int qpigs); void poll(); void runMultiThread() { - std::thread t1(&cInverter::poll, this); - t1.detach(); + t1 = std::thread(&cInverter::poll, this); + } + void terminateThread() { + quit_thread = true; + t1.join(); } string *GetQpiriStatus(); @@ -35,7 +41,7 @@ class cInverter { string *GetWarnings(); int GetMode(); - void ExecuteCmd(const std::string cmd); + void ExecuteCmd(const std::string cmd, int); }; #endif // ___INVERTER_H diff --git a/sources/inverter-cli/main.cpp b/sources/inverter-cli/main.cpp index 3632e7b..527a121 100644 --- a/sources/inverter-cli/main.cpp +++ b/sources/inverter-cli/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "main.h" #include "tools.h" @@ -15,6 +16,7 @@ #include #include +#include #include #include @@ -169,20 +171,40 @@ int main(int argc, char* argv[]) { runOnce = true; } lprintf("INVERTER: Debug set"); + const char *settings; // Get the rest of the settings from the conf file if( access( "./inverter.conf", F_OK ) != -1 ) { // file exists - getSettingsFile("./inverter.conf"); + settings = "./inverter.conf"; } else { // file doesn't exist - getSettingsFile("/etc/inverter/inverter.conf"); + settings = "/etc/inverter/inverter.conf"; } + getSettingsFile(settings); + int fd = open(settings, O_RDWR); + while (flock(fd, LOCK_EX)) sleep(1); bool ups_status_changed(false); ups = new cInverter(devicename,qpiri,qpiws,qmod,qpigs); // Logic to send 'raw commands' to the inverter.. if (!rawcmd.empty()) { - ups->ExecuteCmd(rawcmd); + int replylen; + if (!strcmp(rawcmd.c_str(), "QPI")) + replylen = 8; + else if (!strcmp(rawcmd.c_str(), "QID")) + replylen = 18; + else if (!strcmp(rawcmd.c_str(), "QVFW")) + replylen = 18; + else if (!strcmp(rawcmd.c_str(), "QVFW2")) + replylen = 19; + else if (!strcmp(rawcmd.c_str(), "QFLAG")) + replylen = 15; + else if (!strcmp(rawcmd.c_str(), "QBOOT")) + replylen = 5; + else if (!strcmp(rawcmd.c_str(), "QOPM")) + replylen = 6; + else replylen = 7; + ups->ExecuteCmd(rawcmd, replylen); // We're piggybacking off the qpri status response... printf("Reply: %s\n", ups->GetQpiriStatus()->c_str()); exit(0); @@ -215,7 +237,9 @@ int main(int argc, char* argv[]) { // Parse and display values sscanf(reply1->c_str(), "%f %f %f %f %d %d %d %d %f %d %d %d %f %f %f %d %s", &voltage_grid, &freq_grid, &voltage_out, &freq_out, &load_va, &load_watt, &load_percent, &voltage_bus, &voltage_batt, &batt_charge_current, &batt_capacity, &temp_heatsink, &pv_input_current, &pv_input_voltage, &scc_voltage, &batt_discharge_current, &device_status); - sscanf(reply2->c_str(), "%f %f %f %f %f %d %d %f %f %f %f %f %d %d %d %d %d %d - %d %d %d %f", &grid_voltage_rating, &grid_current_rating, &out_voltage_rating, &out_freq_rating, &out_current_rating, &out_va_rating, &out_watt_rating, &batt_rating, &batt_recharge_voltage, &batt_under_voltage, &batt_bulk_voltage, &batt_float_voltage, &batt_type, &max_grid_charge_current, &max_charge_current, &in_voltage_range, &out_source_priority, &charger_source_priority, &machine_type, &topology, &out_mode, &batt_redischarge_voltage); + char parallel_max_num; + sscanf(reply2->c_str(), "%f %f %f %f %f %d %d %f %f %f %f %f %d %d %d %d %d %d %c %d %d %d %f", + &grid_voltage_rating, &grid_current_rating, &out_voltage_rating, &out_freq_rating, &out_current_rating, &out_va_rating, &out_watt_rating, &batt_rating, &batt_recharge_voltage, &batt_under_voltage, &batt_bulk_voltage, &batt_float_voltage, &batt_type, &max_grid_charge_current, &max_charge_current, &in_voltage_range, &out_source_priority, &charger_source_priority, ¶llel_max_num, &machine_type, &topology, &out_mode, &batt_redischarge_voltage); // There appears to be a discrepancy in actual DMM measured current vs what the meter is // telling me it's getting, so lets add a variable we can multiply/divide by to adjust if @@ -280,6 +304,7 @@ int main(int argc, char* argv[]) { delete reply2; if(runOnce) { + ups->terminateThread(); // Do once and exit instead of loop endlessly lprintf("INVERTER: All queries complete, exiting loop."); exit(0); @@ -290,7 +315,9 @@ int main(int argc, char* argv[]) { sleep(1); } - if (ups) + if (ups) { + ups->terminateThread(); delete ups; + } return 0; } diff --git a/sources/inverter-mqtt/mqtt-push.sh b/sources/inverter-mqtt/mqtt-push.sh index e931de0..1b2cb72 100755 --- a/sources/inverter-mqtt/mqtt-push.sh +++ b/sources/inverter-mqtt/mqtt-push.sh @@ -1,14 +1,21 @@ #!/bin/bash INFLUX_ENABLED=`cat /etc/inverter/mqtt.json | jq '.influx.enabled' -r` +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` +MQTT_CLIENTID=`cat /etc/inverter/mqtt.json | jq '.clientid' -r` + 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` - MQTT_CLIENTID=`cat /etc/inverter/mqtt.json | jq '.clientid' -r` + param=$1 + value=`echo $INVERTER_DATA| sed --expression "sK.*\"$param\":\([^,}]*\).*K\1K"` + + if test -z $value; then + return + fi mosquitto_pub \ -h $MQTT_SERVER \ @@ -16,11 +23,11 @@ pushMQTTData () { -u "$MQTT_USERNAME" \ -P "$MQTT_PASSWORD" \ -i $MQTT_CLIENTID \ - -t "$MQTT_TOPIC/sensor/"$MQTT_DEVICENAME"_$1" \ - -m "$2" + -t "$MQTT_TOPIC/sensor/"$MQTT_DEVICENAME"_$param" \ + -m "$value" if [[ $INFLUX_ENABLED == "true" ]] ; then - pushInfluxData $1 $2 + pushInfluxData $param $value fi } @@ -39,106 +46,8 @@ pushInfluxData () { INVERTER_DATA=`timeout 10 /opt/inverter-cli/bin/inverter_poller -1` ##################################################################################### +# Inverter_Mode: 1 = Power_On, 2 = Standby, 3 = Line, 4 = Battery, 5 = Fault, 6 = Power_Saving, 7 = Unknown -Inverter_mode=`echo $INVERTER_DATA | jq '.Inverter_mode' -r` - - # 1 = Power_On, 2 = Standby, 3 = Line, 4 = Battery, 5 = Fault, 6 = Power_Saving, 7 = Unknown - -[ ! -z "$Inverter_mode" ] && pushMQTTData "Inverter_mode" "$Inverter_mode" - -AC_grid_voltage=`echo $INVERTER_DATA | jq '.AC_grid_voltage' -r` -[ ! -z "$AC_grid_voltage" ] && pushMQTTData "AC_grid_voltage" "$AC_grid_voltage" - -AC_grid_frequency=`echo $INVERTER_DATA | jq '.AC_grid_frequency' -r` -[ ! -z "$AC_grid_frequency" ] && pushMQTTData "AC_grid_frequency" "$AC_grid_frequency" - -AC_out_voltage=`echo $INVERTER_DATA | jq '.AC_out_voltage' -r` -[ ! -z "$AC_out_voltage" ] && pushMQTTData "AC_out_voltage" "$AC_out_voltage" - -AC_out_frequency=`echo $INVERTER_DATA | jq '.AC_out_frequency' -r` -[ ! -z "$AC_out_frequency" ] && pushMQTTData "AC_out_frequency" "$AC_out_frequency" - -PV_in_voltage=`echo $INVERTER_DATA | jq '.PV_in_voltage' -r` -[ ! -z "$PV_in_voltage" ] && pushMQTTData "PV_in_voltage" "$PV_in_voltage" - -PV_in_current=`echo $INVERTER_DATA | jq '.PV_in_current' -r` -[ ! -z "$PV_in_current" ] && pushMQTTData "PV_in_current" "$PV_in_current" - -PV_in_watts=`echo $INVERTER_DATA | jq '.PV_in_watts' -r` -[ ! -z "$PV_in_watts" ] && pushMQTTData "PV_in_watts" "$PV_in_watts" - -PV_in_watthour=`echo $INVERTER_DATA | jq '.PV_in_watthour' -r` -[ ! -z "$PV_in_watthour" ] && pushMQTTData "PV_in_watthour" "$PV_in_watthour" - -SCC_voltage=`echo $INVERTER_DATA | jq '.SCC_voltage' -r` -[ ! -z "$SCC_voltage" ] && pushMQTTData "SCC_voltage" "$SCC_voltage" - -Load_pct=`echo $INVERTER_DATA | jq '.Load_pct' -r` -[ ! -z "$Load_pct" ] && pushMQTTData "Load_pct" "$Load_pct" - -Load_watt=`echo $INVERTER_DATA | jq '.Load_watt' -r` -[ ! -z "$Load_watt" ] && pushMQTTData "Load_watt" "$Load_watt" - -Load_watthour=`echo $INVERTER_DATA | jq '.Load_watthour' -r` -[ ! -z "$Load_watthour" ] && pushMQTTData "Load_watthour" "$Load_watthour" - -Load_va=`echo $INVERTER_DATA | jq '.Load_va' -r` -[ ! -z "$Load_va" ] && pushMQTTData "Load_va" "$Load_va" - -Bus_voltage=`echo $INVERTER_DATA | jq '.Bus_voltage' -r` -[ ! -z "$Bus_voltage" ] && pushMQTTData "Bus_voltage" "$Bus_voltage" - -Heatsink_temperature=`echo $INVERTER_DATA | jq '.Heatsink_temperature' -r` -[ ! -z "$Heatsink_temperature" ] && pushMQTTData "Heatsink_temperature" "$Heatsink_temperature" - -Battery_capacity=`echo $INVERTER_DATA | jq '.Battery_capacity' -r` -[ ! -z "$Battery_capacity" ] && pushMQTTData "Battery_capacity" "$Battery_capacity" - -Battery_voltage=`echo $INVERTER_DATA | jq '.Battery_voltage' -r` -[ ! -z "$Battery_voltage" ] && pushMQTTData "Battery_voltage" "$Battery_voltage" - -Battery_charge_current=`echo $INVERTER_DATA | jq '.Battery_charge_current' -r` -[ ! -z "$Battery_charge_current" ] && pushMQTTData "Battery_charge_current" "$Battery_charge_current" - -Battery_discharge_current=`echo $INVERTER_DATA | jq '.Battery_discharge_current' -r` -[ ! -z "$Battery_discharge_current" ] && pushMQTTData "Battery_discharge_current" "$Battery_discharge_current" - -Load_status_on=`echo $INVERTER_DATA | jq '.Load_status_on' -r` -[ ! -z "$Load_status_on" ] && pushMQTTData "Load_status_on" "$Load_status_on" - -SCC_charge_on=`echo $INVERTER_DATA | jq '.SCC_charge_on' -r` -[ ! -z "$SCC_charge_on" ] && pushMQTTData "SCC_charge_on" "$SCC_charge_on" - -AC_charge_on=`echo $INVERTER_DATA | jq '.AC_charge_on' -r` -[ ! -z "$AC_charge_on" ] && pushMQTTData "AC_charge_on" "$AC_charge_on" - -Battery_recharge_voltage=`echo $INVERTER_DATA | jq '.Battery_recharge_voltage' -r` -[ ! -z "$Battery_recharge_voltage" ] && pushMQTTData "Battery_recharge_voltage" "$Battery_recharge_voltage" - -Battery_under_voltage=`echo $INVERTER_DATA | jq '.Battery_under_voltage' -r` -[ ! -z "$Battery_under_voltage" ] && pushMQTTData "Battery_under_voltage" "$Battery_under_voltage" - -Battery_bulk_voltage=`echo $INVERTER_DATA | jq '.Battery_bulk_voltage' -r` -[ ! -z "$Battery_bulk_voltage" ] && pushMQTTData "Battery_bulk_voltage" "$Battery_bulk_voltage" - -Battery_float_voltage=`echo $INVERTER_DATA | jq '.Battery_float_voltage' -r` -[ ! -z "$Battery_float_voltage" ] && pushMQTTData "Battery_float_voltage" "$Battery_float_voltage" - -Max_grid_charge_current=`echo $INVERTER_DATA | jq '.Max_grid_charge_current' -r` -[ ! -z "$Max_grid_charge_current" ] && pushMQTTData "Max_grid_charge_current" "$Max_grid_charge_current" - -Max_charge_current=`echo $INVERTER_DATA | jq '.Max_charge_current' -r` -[ ! -z "$Max_charge_current" ] && pushMQTTData "Max_charge_current" "$Max_charge_current" - -Out_source_priority=`echo $INVERTER_DATA | jq '.Out_source_priority' -r` -[ ! -z "$Out_source_priority" ] && pushMQTTData "Out_source_priority" "$Out_source_priority" - -Charger_source_priority=`echo $INVERTER_DATA | jq '.Charger_source_priority' -r` -[ ! -z "$Charger_source_priority" ] && pushMQTTData "Charger_source_priority" "$Charger_source_priority" - -Battery_redischarge_voltage=`echo $INVERTER_DATA | jq '.Battery_redischarge_voltage' -r` -[ ! -z "$Battery_redischarge_voltage" ] && pushMQTTData "Battery_redischarge_voltage" "$Battery_redischarge_voltage" - -Warnings=`echo $INVERTER_DATA | jq '.Warnings' -r` -[ ! -z "$Warnings" ] && pushMQTTData "Warnings" "$Warnings" - +for w in Inverter_mode AC_grid_voltage AC_grid_frequency AC_out_voltage AC_out_frequency PV_in_voltage PV_in_current PV_in_watts PV_in_watthour SCC_voltage Load_pct Load_watt Load_watthour Load_va Bus_voltage Heatsink_temperature Battery_capacity Battery_voltage Battery_charge_current Battery_discharge_current Load_status_on SCC_charge_on AC_charge_on Battery_recharge_voltage Battery_under_voltage Battery_bulk_voltage Battery_float_voltage Max_grid_charge_current Max_charge_current Out_source_priority Charger_source_priority Battery_redischarge_voltage Warnings; do + pushMQTTData $w +done