2022-09-03 03:04:57 +00:00
/*
2022-11-07 00:10:35 +00:00
; Project : ESP GLCD SOLAR MONITOR
2022-09-03 03:04:57 +00:00
; Date : 3 rd Sep 2022
;
; ( C ) 2022 Carsten Schmiemann
;
; Permission is hereby granted , free of charge , to any person obtaining a copy
; of this software and associated documentation files ( the " Software " ) , to deal
; in the Software without restriction , including without limitation the rights
; to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
; copies of the Software , and to permit persons to whom the Software is
; furnished to do so , subject to the following conditions :
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software .
;
; THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
; IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
; LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE .
*/
2022-11-08 22:30:13 +00:00
//#include <Arduino.h>
2022-09-03 03:04:57 +00:00
# include <logger.h>
2022-11-07 02:54:48 +00:00
# ifdef ESP32
# include <SPIFFS.h>
2022-11-08 22:30:13 +00:00
# define Flash SPIFFS
2022-11-07 02:54:48 +00:00
# include <WiFi.h>
# endif
# ifdef ESP8266
2022-11-08 22:30:13 +00:00
# include <LittleFS.h>
# define Flash LittleFS
2022-11-07 02:54:48 +00:00
# include <ESP8266WiFi.h>
# endif
2022-11-08 22:30:13 +00:00
2022-11-06 13:15:16 +00:00
# include <DNSServer.h>
# include <ESP8266WebServer.h>
# include <WiFiManager.h>
2022-09-03 03:04:57 +00:00
# include <PubSubClient.h>
# include <ArduinoJson.h>
2022-08-21 23:54:57 +00:00
# include <Wire.h>
2022-09-03 03:04:57 +00:00
# include <U8g2lib.h>
2022-11-13 03:16:51 +00:00
# include "time.h"
2022-09-03 03:04:57 +00:00
//Program parts
2022-08-21 23:54:57 +00:00
# include <pins.h>
2022-11-12 23:13:16 +00:00
# include <lang.h>
2022-09-03 03:04:57 +00:00
# include <display.h>
2022-11-13 18:52:44 +00:00
char VERSION [ 6 ] = " v0.9a " ;
2022-08-21 23:54:57 +00:00
2022-11-07 02:54:48 +00:00
//Defaults
2022-11-08 18:50:36 +00:00
char mqtt_server [ 15 ] = " " ;
char gx_vrm_id [ 20 ] = " " ;
2022-11-07 02:54:48 +00:00
char disp_refresh_interval [ 6 ] = " 500 " ;
char disp_screen_interval [ 6 ] = " 10000 " ;
2022-11-08 18:50:36 +00:00
char address_pv_charger [ 6 ] = " " ;
char address_grid_meter [ 6 ] = " " ;
char address_inverter [ 6 ] = " " ;
char address_battery [ 6 ] = " " ;
char address_outside_temperature [ 6 ] = " " ;
2022-11-13 02:27:03 +00:00
char display_lang [ 6 ] = " " ;
2022-11-13 10:47:38 +00:00
char time_zone [ 40 ] = " CET-1CEST,M3.5.0,M10.5.0/3 " ; // Europe/Berlin
2022-11-13 18:57:10 +00:00
char time_server [ 20 ] = " " ;
char show_graph [ 4 ] = " " ;
char show_statistics [ 4 ] = " " ;
2022-11-07 02:54:48 +00:00
long unsigned int DISPLAY_REFRESH_INTERVAL ;
long unsigned int DISPLAY_SCREEN_INTERVAL ;
//MQTT connect strings
char mqtt_pv_voltage [ 80 ] ;
char mqtt_pv_power [ 80 ] ;
char mqtt_pv_yield [ 80 ] ;
char mqtt_pv_bat_current [ 80 ] ;
char mqtt_grid_power [ 80 ] ;
char mqtt_inv_power [ 80 ] ;
char mqtt_inv_current [ 80 ] ;
char mqtt_bat_soc [ 80 ] ;
char mqtt_bat_voltage [ 80 ] ;
char mqtt_bat_current [ 80 ] ;
char mqtt_bat_power [ 80 ] ;
char mqtt_bat_max_cell_volt [ 80 ] ;
char mqtt_bat_min_cell_volt [ 80 ] ;
char mqtt_temp_outside [ 80 ] ;
char mqtt_grid_power_l1 [ 80 ] ;
char mqtt_grid_power_l2 [ 80 ] ;
char mqtt_grid_power_l3 [ 80 ] ;
2022-11-13 16:59:41 +00:00
//Display config
bool display_conf_temp_oa_present = false ;
bool display_conf_time_present = false ;
bool display_conf_dc_pvcharger_present = false ;
bool display_conf_graph_pv_present = false ;
bool display_conf_statistics_present = false ;
2022-11-13 19:48:46 +00:00
float display_graph_power [ 100 ] = { 0 } ;
2022-11-13 21:53:59 +00:00
int display_refresh_counter = 0 ;
int display_refresh_time ;
2022-11-13 16:59:41 +00:00
2022-11-07 02:54:48 +00:00
//WiFiManager flag for saving data
bool shouldSaveConfig = false ;
//WiFiManager callback notifying us of the need to save config
void saveConfigCallback ( ) {
Serial . println ( " Should save config " ) ;
shouldSaveConfig = true ;
}
2022-08-21 23:54:57 +00:00
2022-09-03 03:04:57 +00:00
//Library setup
2022-08-21 23:54:57 +00:00
WiFiClient espClient ;
PubSubClient client ( espClient ) ;
2022-09-03 03:04:57 +00:00
2022-11-13 03:16:51 +00:00
//Time library setup
time_t now ;
tm tm ;
2022-09-03 03:04:57 +00:00
//Globals
2022-08-21 23:54:57 +00:00
long lastMsg = 0 ;
char msg [ 50 ] ;
2022-11-12 23:41:57 +00:00
float pv_v = 0 , pv_w = 0 , pv_i = 0 , pv_kwh = 0 , inv_p = 0 , inv_i = 0 , batt_v = 0 , batt_i = 0 , batt_p = 0 , batt_c_min = 0 , batt_c_max = 0 , grid_p = 0 , batt_soc = 0 , load_ph1 = 0 , load_ph2 = 0 , load_ph3 = 0 ;
2022-11-08 22:43:28 +00:00
bool lastButtonRotationState = HIGH , lastButtonSetupState = HIGH ;
bool currentButtonRotationState , currentButtonSetupState ;
2022-11-13 21:59:17 +00:00
static unsigned long lastDispRefreshTime = 0 ;
static unsigned long lastScreenChangeTime = 0 ;
2022-09-03 03:04:57 +00:00
int display_screen = 0 ;
2022-08-21 23:54:57 +00:00
2022-09-03 03:04:57 +00:00
//MQTT topics
2022-08-21 23:54:57 +00:00
void callback ( char * topic , byte * message , unsigned int length ) {
logPrintlnD ( " Message arrived on topic: " ) ;
logPrintlnD ( topic ) ;
logPrintlnD ( " Message: " ) ;
2022-09-03 03:04:57 +00:00
String messageTemp ;
2022-08-21 23:54:57 +00:00
2022-11-09 01:34:27 +00:00
//Status LED flash on receive
digitalWrite ( STATUS_LED , ! digitalRead ( STATUS_LED ) ) ;
2022-09-03 03:04:57 +00:00
for ( byte i = 0 ; i < length ; i + + ) {
char tmp = char ( message [ i ] ) ;
messageTemp + = tmp ;
2022-08-21 23:54:57 +00:00
}
2022-09-03 03:04:57 +00:00
logPrintlnD ( messageTemp ) ;
//PV Charger - solar voltage
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_pv_voltage ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
pv_v = json [ " value " ] ;
}
//PV Charger - solar power
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_pv_power ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
pv_w = json [ " value " ] ;
}
//PV Charger - solar yield
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_pv_yield ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
pv_kwh = json [ " value " ] ;
}
//PV Charger - bat charge current
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_pv_bat_current ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
pv_i = json [ " value " ] ;
}
//Grid meter - power
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_grid_power ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
grid_p = json [ " value " ] ;
}
//Inverter - power
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_inv_power ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
inv_p = json [ " value " ] ;
}
//Inverter - current
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_inv_current ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
inv_i = json [ " value " ] ;
}
//Battery - SOC
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_bat_soc ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
batt_soc = json [ " value " ] ;
}
//Battery - voltage
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_bat_voltage ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
batt_v = json [ " value " ] ;
}
//Battery - current
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_bat_current ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
batt_i = json [ " value " ] ;
}
//Battery - power
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_bat_power ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
batt_p = json [ " value " ] ;
}
2022-09-03 19:01:56 +00:00
//Battery - max cell volts
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_bat_max_cell_volt ) {
2022-09-03 19:01:56 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
batt_c_max = json [ " value " ] ;
}
//Battery - min cell volts
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_bat_min_cell_volt ) {
2022-09-03 19:01:56 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
batt_c_min = json [ " value " ] ;
}
2022-09-03 03:04:57 +00:00
//Temperature - outside
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_temp_outside ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
2022-11-13 02:27:03 +00:00
display_temp_outside ( json [ " value " ] ) ;
2022-09-03 03:04:57 +00:00
}
//System - AC Load Phase 1
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_grid_power_l1 ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
load_ph1 = json [ " value " ] ;
}
//System - AC Load Phase 2
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_grid_power_l2 ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
load_ph2 = json [ " value " ] ;
}
//System - AC Load Phase 3
2022-11-07 02:54:48 +00:00
if ( String ( topic ) = = mqtt_grid_power_l3 ) {
2022-09-03 03:04:57 +00:00
DynamicJsonDocument json ( 512 ) ;
deserializeJson ( json , messageTemp ) ;
load_ph3 = json [ " value " ] ;
2022-08-21 23:54:57 +00:00
}
}
2022-09-03 03:04:57 +00:00
//Wifi re-/connect
2022-08-21 23:54:57 +00:00
void reconnect ( ) {
// Loop until we're reconnected
while ( ! client . connected ( ) ) {
logPrintlnI ( " Attempting MQTT connection... " ) ;
2022-11-08 22:30:13 +00:00
display_text ( ( char * ) " Connect to GX MQTT... " , mqtt_server ) ;
2022-11-08 00:17:15 +00:00
delay ( 2000 ) ;
2022-08-21 23:54:57 +00:00
// Attempt to connect
2022-09-03 03:04:57 +00:00
if ( client . connect ( " PV_solar_monitor " ) ) {
logPrintlnI ( " connected " ) ;
2022-08-21 23:54:57 +00:00
// Subscribe
2022-11-13 16:59:41 +00:00
if ( display_conf_dc_pvcharger_present )
{
client . subscribe ( mqtt_pv_voltage ) ;
client . subscribe ( mqtt_pv_power ) ;
client . subscribe ( mqtt_pv_yield ) ;
client . subscribe ( mqtt_pv_bat_current ) ;
}
2022-11-07 02:54:48 +00:00
client . subscribe ( mqtt_grid_power ) ;
client . subscribe ( mqtt_inv_power ) ;
client . subscribe ( mqtt_inv_current ) ;
client . subscribe ( mqtt_bat_soc ) ;
client . subscribe ( mqtt_bat_voltage ) ;
client . subscribe ( mqtt_bat_current ) ;
client . subscribe ( mqtt_bat_power ) ;
client . subscribe ( mqtt_bat_max_cell_volt ) ;
client . subscribe ( mqtt_bat_min_cell_volt ) ;
2022-11-13 16:59:41 +00:00
if ( display_conf_temp_oa_present )
{
client . subscribe ( mqtt_temp_outside ) ;
}
2022-11-07 02:54:48 +00:00
client . subscribe ( mqtt_grid_power_l1 ) ;
client . subscribe ( mqtt_grid_power_l2 ) ;
client . subscribe ( mqtt_grid_power_l3 ) ;
logPrintlnI ( " subscribed to topics " ) ;
2022-08-21 23:54:57 +00:00
} else {
logPrintlnE ( " failed, rc= " ) ;
logPrintlnE ( ( char * ) client . state ( ) ) ;
2022-11-08 22:30:13 +00:00
logPrintlnE ( " try again in 10 seconds " ) ;
String msg = " MQTT Error rc= " + ( String ) client . state ( ) ;
display_text_fullscreen ( ( char * ) " MQTT Connection Error " , ( char * ) " Did you enable MQTT " , ( char * ) " on your GX device? " , ( char * ) msg . c_str ( ) , ( char * ) " " , ( char * ) " Retry in 10 seconds... " ) ;
// Wait 10 seconds before retrying
2022-08-21 23:54:57 +00:00
delay ( 5000 ) ;
}
}
}
2022-08-21 21:32:23 +00:00
void setup ( ) {
2022-08-21 23:54:57 +00:00
Serial . begin ( 115200 ) ;
2022-11-06 13:15:16 +00:00
Serial . println ( " Booting... " ) ;
2022-11-08 23:02:20 +00:00
pinMode ( BUTTON_ROTATION , INPUT_PULLUP ) ;
pinMode ( BUTTON_SETUP , INPUT_PULLUP ) ;
2022-11-09 01:34:27 +00:00
pinMode ( STATUS_LED , OUTPUT ) ;
2022-09-03 03:04:57 +00:00
display_begin ( ) ;
2022-11-06 13:15:16 +00:00
Serial . println ( " Display init... " ) ;
2022-11-08 22:30:13 +00:00
display_init ( VERSION ) ;
2022-11-08 20:14:51 +00:00
delay ( 2000 ) ;
2022-11-07 02:54:48 +00:00
2022-11-08 22:30:13 +00:00
//read configuration from Flash json
Serial . println ( " mounting Flash... " ) ;
if ( Flash . begin ( ) ) {
2022-11-07 02:54:48 +00:00
Serial . println ( " mounted file system " ) ;
2022-11-08 22:30:13 +00:00
if ( Flash . exists ( " /config.json " ) ) {
2022-11-07 02:54:48 +00:00
//file exists, reading and loading
Serial . println ( " reading config file " ) ;
2022-11-08 22:30:13 +00:00
File configFile = Flash . open ( " /config.json " , " r " ) ;
2022-11-07 02:54:48 +00:00
if ( configFile ) {
Serial . println ( " opened config file " ) ;
size_t size = configFile . size ( ) ;
// Allocate a buffer to store contents of the file.
std : : unique_ptr < char [ ] > buf ( new char [ size ] ) ;
configFile . readBytes ( buf . get ( ) , size ) ;
# if defined(ARDUINOJSON_VERSION_MAJOR) && ARDUINOJSON_VERSION_MAJOR >= 6
DynamicJsonDocument json ( 1024 ) ;
auto deserializeError = deserializeJson ( json , buf . get ( ) ) ;
serializeJson ( json , Serial ) ;
if ( ! deserializeError ) {
# else
DynamicJsonBuffer jsonBuffer ;
JsonObject & json = jsonBuffer . parseObject ( buf . get ( ) ) ;
json . printTo ( Serial ) ;
if ( json . success ( ) ) {
# endif
Serial . println ( " \n parsed json " ) ;
strcpy ( mqtt_server , json [ " mqtt_server " ] ) ;
strcpy ( gx_vrm_id , json [ " gx_vrm_id " ] ) ;
strcpy ( disp_refresh_interval , json [ " disp_refresh_interval " ] ) ;
strcpy ( disp_screen_interval , json [ " disp_screen_interval " ] ) ;
strcpy ( address_pv_charger , json [ " address_pv_charger " ] ) ;
strcpy ( address_grid_meter , json [ " address_grid_meter " ] ) ;
strcpy ( address_inverter , json [ " address_inverter " ] ) ;
strcpy ( address_battery , json [ " address_battery " ] ) ;
strcpy ( address_outside_temperature , json [ " address_outside_temperature " ] ) ;
2022-11-12 23:13:16 +00:00
strcpy ( display_lang , json [ " display_language " ] ) ;
2022-11-13 10:47:38 +00:00
strcpy ( time_zone , json [ " time_zone " ] ) ;
strcpy ( time_server , json [ " time_server " ] ) ;
2022-11-13 16:59:41 +00:00
strcpy ( show_graph , json [ " show_graph " ] ) ;
strcpy ( show_statistics , json [ " show_statistics " ] ) ;
2022-11-07 02:54:48 +00:00
} else {
Serial . println ( " failed to load json config " ) ;
}
configFile . close ( ) ;
}
}
} else {
2022-11-08 22:30:13 +00:00
Serial . println ( " failed to mount Flash " ) ;
2022-11-07 02:54:48 +00:00
}
2022-09-03 03:04:57 +00:00
delay ( 2000 ) ;
2022-11-08 22:30:13 +00:00
String bootmsg = " Booting solar monitor app... " + ( String ) VERSION ;
logPrintlnI ( bootmsg . c_str ( ) ) ;
2022-11-08 22:43:28 +00:00
display_text ( ( char * ) " Connect to AP:PV_Mon " , ( char * ) " for configuration " ) ;
2022-11-09 01:10:55 +00:00
# ifdef ESP8266
WiFi . hostname ( " ESP_Solar_Monitor " ) ;
# endif
# ifdef ESP32
WiFi . setHostname ( " ESP_Solar_Monitor " ) ;
# endif
2022-11-07 02:54:48 +00:00
//Wifi Manager parameters
WiFiManagerParameter custom_mqtt_server ( " mqtt_server " , " IP adress of GX Device (MQTT No SSL) " , mqtt_server, 15) ;
WiFiManagerParameter custom_gx_vrm_id ( " gx_vrm_id " , " VRM ID of GX device " , gx_vrm_id , 20 ) ;
WiFiManagerParameter custom_disp_refresh_interval ( " disp_refresh_interval " , " Refresh cycle of display in ms " , disp_refresh_interval , 6 ) ;
WiFiManagerParameter custom_disp_screen_interval ( " disp_screen_interval " , " Rotation time of screens in ms " , disp_screen_interval , 6 ) ;
WiFiManagerParameter custom_address_pv_charger ( " address_pv_charger " , " Address of pv charger " , address_pv_charger , 6 ) ;
WiFiManagerParameter custom_address_grid_meter ( " address_grid_meter " , " Address of grid meter " , address_grid_meter , 6 ) ;
WiFiManagerParameter custom_address_inverter ( " address_inverter " , " Address of vebus inverter " , address_inverter , 6 ) ;
WiFiManagerParameter custom_address_battery ( " address_battery " , " Address of can battery " , address_battery , 6 ) ;
WiFiManagerParameter custom_address_outside_temperature ( " address_outside_temperature " , " Address of outside temperature " , address_outside_temperature , 6 ) ;
2022-11-13 02:27:03 +00:00
WiFiManagerParameter custom_display_lang ( " display_lang " , " Display language en, de " , display_lang , 6 ) ;
2022-11-13 10:47:38 +00:00
WiFiManagerParameter custom_time_zone ( " time_zone " , " Set timezone string " , time_zone , 40 ) ;
WiFiManagerParameter custom_time_server ( " time_server " , " Set time server " , time_server , 20 ) ;
2022-11-13 18:57:10 +00:00
WiFiManagerParameter custom_show_graph ( " show_graph " , " Show PV graph yes=enable " , show_graph , 4 ) ;
WiFiManagerParameter custom_show_statistics ( " show_statistics " , " Show statistics screen yes=enable " , show_statistics , 4 ) ;
2022-11-07 02:54:48 +00:00
WiFiManager wm ;
wm . setSaveConfigCallback ( saveConfigCallback ) ;
wm . addParameter ( & custom_mqtt_server ) ;
wm . addParameter ( & custom_gx_vrm_id ) ;
wm . addParameter ( & custom_disp_refresh_interval ) ;
wm . addParameter ( & custom_disp_screen_interval ) ;
wm . addParameter ( & custom_address_pv_charger ) ;
wm . addParameter ( & custom_address_grid_meter ) ;
wm . addParameter ( & custom_address_inverter ) ;
wm . addParameter ( & custom_address_battery ) ;
wm . addParameter ( & custom_address_outside_temperature ) ;
2022-11-12 23:13:16 +00:00
wm . addParameter ( & custom_display_lang ) ;
2022-11-13 10:47:38 +00:00
wm . addParameter ( & custom_time_zone ) ;
wm . addParameter ( & custom_time_server ) ;
2022-11-13 16:59:41 +00:00
wm . addParameter ( & custom_show_graph ) ;
wm . addParameter ( & custom_show_statistics ) ;
2022-11-07 02:54:48 +00:00
2022-11-09 01:10:55 +00:00
//Start wifi manager configuration if BUTTON_SETUP is pressed on start-up
currentButtonSetupState = digitalRead ( BUTTON_SETUP ) ;
if ( lastButtonSetupState = = HIGH & & currentButtonSetupState = = LOW )
{
display_text ( ( char * ) " Connect to AP:PV_Mon " , ( char * ) " for re-configuration " ) ;
wm . startConfigPortal ( " PV_Mon " ) ;
} else
{
wm . autoConnect ( " PV_Mon " ) ;
}
2022-11-08 22:30:13 +00:00
display_text ( ( char * ) " Connecting wifi... " , ( char * ) " " ) ;
2022-11-08 00:17:15 +00:00
delay ( 500 ) ;
2022-11-06 13:15:16 +00:00
logPrintlnI ( " Connecting wifi... " ) ;
2022-08-21 23:54:57 +00:00
IPAddress ip = WiFi . localIP ( ) ;
2022-11-07 02:54:48 +00:00
strcpy ( mqtt_server , custom_mqtt_server . getValue ( ) ) ;
strcpy ( gx_vrm_id , custom_gx_vrm_id . getValue ( ) ) ;
strcpy ( disp_refresh_interval , custom_disp_refresh_interval . getValue ( ) ) ;
strcpy ( disp_screen_interval , custom_disp_screen_interval . getValue ( ) ) ;
strcpy ( address_pv_charger , custom_address_pv_charger . getValue ( ) ) ;
strcpy ( address_grid_meter , custom_address_grid_meter . getValue ( ) ) ;
strcpy ( address_inverter , custom_address_inverter . getValue ( ) ) ;
strcpy ( address_battery , custom_address_battery . getValue ( ) ) ;
strcpy ( address_outside_temperature , custom_address_outside_temperature . getValue ( ) ) ;
2022-11-12 23:13:16 +00:00
strcpy ( display_lang , custom_display_lang . getValue ( ) ) ;
2022-11-13 10:47:38 +00:00
strcpy ( time_zone , custom_time_zone . getValue ( ) ) ;
strcpy ( time_server , custom_time_server . getValue ( ) ) ;
2022-11-13 16:59:41 +00:00
strcpy ( show_graph , custom_show_graph . getValue ( ) ) ;
strcpy ( show_statistics , custom_show_statistics . getValue ( ) ) ;
2022-11-07 02:54:48 +00:00
DISPLAY_REFRESH_INTERVAL = strtol ( disp_refresh_interval , NULL , 10 ) ;
DISPLAY_SCREEN_INTERVAL = strtol ( disp_screen_interval , NULL , 10 ) ;
2022-11-13 21:53:59 +00:00
display_refresh_time = DISPLAY_SCREEN_INTERVAL / DISPLAY_REFRESH_INTERVAL ;
2022-11-07 02:54:48 +00:00
2022-11-13 17:18:43 +00:00
//parse config and set display parameter
2022-11-12 23:41:57 +00:00
if ( strtol ( address_outside_temperature , NULL , 10 ) ! = 0 )
{
2022-11-13 16:59:41 +00:00
display_conf_temp_oa_present = true ;
2022-11-13 01:47:22 +00:00
}
else
{
2022-11-13 16:59:41 +00:00
display_conf_temp_oa_present = false ;
2022-11-12 23:41:57 +00:00
}
2022-11-13 18:37:29 +00:00
if ( strcmp ( time_server , " " ) ! = 0 )
2022-11-13 17:18:43 +00:00
{
display_conf_time_present = true ;
}
else
{
display_conf_time_present = false ;
}
if ( strtol ( address_pv_charger , NULL , 10 ) ! = 0 )
{
display_conf_dc_pvcharger_present = true ;
}
else
{
display_conf_dc_pvcharger_present = false ;
}
if ( strcmp ( show_graph , " yes " ) = = 0 )
{
display_conf_graph_pv_present = true ;
}
else
{
display_conf_graph_pv_present = false ;
}
if ( strcmp ( show_statistics , " yes " ) = = 0 )
{
display_conf_statistics_present = true ;
}
else
{
display_conf_statistics_present = false ;
}
2022-11-12 23:41:57 +00:00
2022-11-13 17:55:28 +00:00
display_setup ( display_lang , display_conf_temp_oa_present , display_conf_time_present , display_conf_dc_pvcharger_present , display_conf_graph_pv_present , display_conf_statistics_present ) ;
2022-11-06 13:15:16 +00:00
client . setServer ( mqtt_server , 1883 ) ;
client . setCallback ( callback ) ;
2022-08-21 23:54:57 +00:00
char * ip_address = new char [ 40 ] ( ) ;
sprintf ( ip_address , " %d.%d.%d.%d " , ip [ 0 ] , ip [ 1 ] , ip [ 2 ] , ip [ 3 ] ) ;
2022-11-08 00:17:15 +00:00
display_text ( ( char * ) " Connected. IP: " , ip_address ) ;
2022-11-08 22:30:13 +00:00
//save the custom parameters to Flash
2022-11-07 02:54:48 +00:00
if ( shouldSaveConfig ) {
Serial . println ( " saving config " ) ;
# if defined(ARDUINOJSON_VERSION_MAJOR) && ARDUINOJSON_VERSION_MAJOR >= 6
DynamicJsonDocument json ( 1024 ) ;
# else
DynamicJsonBuffer jsonBuffer ;
JsonObject & json = jsonBuffer . createObject ( ) ;
# endif
json [ " mqtt_server " ] = mqtt_server ;
json [ " gx_vrm_id " ] = gx_vrm_id ;
json [ " disp_refresh_interval " ] = disp_refresh_interval ;
json [ " disp_screen_interval " ] = disp_screen_interval ;
json [ " address_pv_charger " ] = address_pv_charger ;
json [ " address_grid_meter " ] = address_grid_meter ;
json [ " address_inverter " ] = address_inverter ;
json [ " address_battery " ] = address_battery ;
json [ " address_outside_temperature " ] = address_outside_temperature ;
2022-11-12 23:59:30 +00:00
json [ " display_language " ] = display_lang ;
2022-11-13 10:47:38 +00:00
json [ " time_zone " ] = time_zone ;
json [ " time_server " ] = time_server ;
2022-11-13 18:20:46 +00:00
json [ " show_graph " ] = show_graph ;
json [ " show_statistics " ] = show_statistics ;
2022-11-07 02:54:48 +00:00
2022-11-08 22:30:13 +00:00
File configFile = Flash . open ( " /config.json " , " w " ) ;
2022-11-07 02:54:48 +00:00
if ( ! configFile ) {
Serial . println ( " failed to open config file for writing " ) ;
}
# if defined(ARDUINOJSON_VERSION_MAJOR) && ARDUINOJSON_VERSION_MAJOR >= 6
serializeJson ( json , Serial ) ;
serializeJson ( json , configFile ) ;
# else
json . printTo ( Serial ) ;
json . printTo ( configFile ) ;
# endif
configFile . close ( ) ;
//end save
}
2022-11-08 00:17:15 +00:00
2022-11-13 18:20:46 +00:00
if ( display_conf_time_present )
{
//NTP setup
# ifdef ESP32
configTime ( 0 , 0 , time_server ) ;
setenv ( " TZ " , time_zone , 1 ) ;
tzset ( ) ;
# endif
# ifdef ESP8266
configTime ( time_zone , time_server ) ;
# endif
}
2022-11-13 03:16:51 +00:00
2022-11-08 00:17:15 +00:00
delay ( 1000 ) ; //for screen display
2022-11-07 02:54:48 +00:00
//Generate mqtt topics from id and address
Serial . println ( ) ;
Serial . println ( " -------------- MQTT topic list -------------- " ) ;
sprintf ( mqtt_pv_voltage , " N/%s/solarcharger/%s/Pv/V " , gx_vrm_id , address_pv_charger ) ;
Serial . println ( mqtt_pv_voltage ) ;
sprintf ( mqtt_pv_power , " N/%s/solarcharger/%s/Yield/Power " , gx_vrm_id , address_pv_charger ) ;
Serial . println ( mqtt_pv_power ) ;
sprintf ( mqtt_pv_yield , " N/%s/solarcharger/%s/History/Daily/0/Yield " , gx_vrm_id , address_pv_charger ) ;
Serial . println ( mqtt_pv_yield ) ;
sprintf ( mqtt_pv_bat_current , " N/%s/solarcharger/%s/Dc/0/Current " , gx_vrm_id , address_pv_charger ) ;
Serial . println ( mqtt_pv_bat_current ) ;
sprintf ( mqtt_grid_power , " N/%s/grid/%s/Ac/Power " , gx_vrm_id , address_grid_meter ) ;
Serial . println ( mqtt_grid_power ) ;
sprintf ( mqtt_inv_power , " N/%s/vebus/%s/Ac/ActiveIn/L1/P " , gx_vrm_id , address_inverter ) ;
Serial . println ( mqtt_inv_power ) ;
sprintf ( mqtt_inv_current , " N/%s/vebus/%s/Dc/0/Current " , gx_vrm_id , address_inverter ) ;
Serial . println ( mqtt_inv_current ) ;
sprintf ( mqtt_bat_soc , " N/%s/battery/%s/Soc " , gx_vrm_id , address_battery ) ;
Serial . println ( mqtt_bat_soc ) ;
sprintf ( mqtt_bat_voltage , " N/%s/battery/%s/Dc/0/Voltage " , gx_vrm_id , address_battery ) ;
Serial . println ( mqtt_bat_voltage ) ;
sprintf ( mqtt_bat_current , " N/%s/battery/%s/Dc/0/Current " , gx_vrm_id , address_battery ) ;
Serial . println ( mqtt_bat_current ) ;
sprintf ( mqtt_bat_power , " N/%s/battery/%s/Dc/0/Power " , gx_vrm_id , address_battery ) ;
Serial . println ( mqtt_bat_power ) ;
sprintf ( mqtt_bat_max_cell_volt , " N/%s/battery/%s/System/MaxCellVoltage " , gx_vrm_id , address_battery ) ;
Serial . println ( mqtt_bat_max_cell_volt ) ;
sprintf ( mqtt_bat_min_cell_volt , " N/%s/battery/%s/System/MinCellVoltage " , gx_vrm_id , address_battery ) ;
Serial . println ( mqtt_bat_min_cell_volt ) ;
sprintf ( mqtt_temp_outside , " N/%s/temperature/%s/Temperature " , gx_vrm_id , address_outside_temperature ) ;
Serial . println ( mqtt_temp_outside ) ;
sprintf ( mqtt_grid_power_l1 , " N/%s/system/0/Ac/ConsumptionOnInput/L1/Power " , gx_vrm_id ) ;
Serial . println ( mqtt_grid_power_l1 ) ;
sprintf ( mqtt_grid_power_l2 , " N/%s/system/0/Ac/ConsumptionOnInput/L2/Power " , gx_vrm_id ) ;
Serial . println ( mqtt_grid_power_l2 ) ;
sprintf ( mqtt_grid_power_l3 , " N/%s/system/0/Ac/ConsumptionOnInput/L3/Power " , gx_vrm_id ) ;
Serial . println ( mqtt_grid_power_l3 ) ;
Serial . println ( ) ;
Serial . println ( " -------------- Settings -------------- " ) ;
Serial . print ( " mqtt server: " ) ; Serial . println ( mqtt_server ) ;
Serial . print ( " gx_vrm_id: " ) ; Serial . println ( gx_vrm_id ) ;
Serial . print ( " disp_refresh_interval: " ) ; Serial . println ( DISPLAY_REFRESH_INTERVAL ) ;
2022-11-08 00:17:15 +00:00
Serial . print ( " disp_screen_interval: " ) ; Serial . println ( DISPLAY_SCREEN_INTERVAL ) ;
2022-11-13 18:37:29 +00:00
Serial . print ( " display language: " ) ; Serial . println ( display_lang ) ;
Serial . print ( " display temp present: " ) ; Serial . println ( display_conf_temp_oa_present ) ;
Serial . print ( " display time present: " ) ; Serial . println ( display_conf_time_present ) ;
Serial . print ( " display dc pc chg present: " ) ; Serial . println ( display_conf_dc_pvcharger_present ) ;
Serial . print ( " display graph present: " ) ; Serial . println ( display_conf_graph_pv_present ) ;
Serial . print ( " display stats present: " ) ; Serial . println ( display_conf_statistics_present ) ;
2022-11-09 01:37:09 +00:00
display_text_fullscreen ( ( char * ) " Configuration summary " , ( char * ) " GX MQTT Server IP: " , mqtt_server , ( char * ) " GX VRM ID: " , gx_vrm_id , ( char * ) " 1/2 " ) ;
2022-11-08 22:30:13 +00:00
delay ( 3000 ) ;
2022-11-09 01:37:09 +00:00
display_text_fullscreen ( ( char * ) " Configuration summary " , ( char * ) " Disp. Refresh: " , disp_refresh_interval , ( char * ) " Disp. rotation: " , disp_screen_interval , ( char * ) " 2/2 " ) ;
2022-11-08 22:30:13 +00:00
delay ( 3000 ) ;
2022-11-13 21:59:17 +00:00
lastDispRefreshTime = millis ( ) ;
lastScreenChangeTime = millis ( ) ;
2022-08-21 21:32:23 +00:00
}
2022-11-13 21:59:17 +00:00
void loop ( ) {
2022-09-03 03:04:57 +00:00
//Refresh display values
if ( millis ( ) - lastDispRefreshTime > = DISPLAY_REFRESH_INTERVAL )
{
2022-11-09 01:34:27 +00:00
digitalWrite ( STATUS_LED , LOW ) ; //Turn Status LED ON again
lastDispRefreshTime + = DISPLAY_REFRESH_INTERVAL ;
2022-11-13 19:48:46 +00:00
2022-11-13 21:53:59 +00:00
if ( display_refresh_counter < = display_refresh_time )
{
2022-11-13 19:48:46 +00:00
display_screen_grid ( grid_p , inv_p , inv_i , pv_w ) ;
2022-09-03 03:04:57 +00:00
}
2022-11-13 21:53:59 +00:00
if ( display_refresh_counter > = display_refresh_time & & display_refresh_counter < = ( display_refresh_time * 2 ) )
{
2022-11-12 23:13:16 +00:00
display_screen_battery ( batt_v , batt_i , batt_p , batt_soc , batt_c_min , batt_c_max ) ;
2022-09-03 03:04:57 +00:00
}
2022-11-13 21:53:59 +00:00
if ( display_refresh_counter > = ( display_refresh_time * 2 ) & & display_refresh_counter < = ( display_refresh_time * 3 ) )
{
if ( display_conf_dc_pvcharger_present )
{
display_screen_pv ( pv_v , pv_w , batt_v , pv_i , pv_kwh ) ;
}
else
{
display_refresh_counter = ( display_refresh_time * 3 ) + 1 ;
}
}
if ( display_refresh_counter > = ( display_refresh_time * 3 ) & & display_refresh_counter < = ( display_refresh_time * 4 ) )
{
if ( display_conf_graph_pv_present )
{
display_screen_graph ( display_graph_power ) ;
}
else
{
display_refresh_counter = ( display_refresh_time * 4 ) + 1 ;
}
}
if ( display_refresh_counter > = ( display_refresh_time * 4 ) & & display_refresh_counter < = ( display_refresh_time * 5 ) )
{
if ( display_conf_statistics_present )
{
//To Do: display_screen_statistics(mqtt_grid_power_l1, mqtt_grid_power_l2, mqtt_grid_power_l3);
}
else
{
display_refresh_counter = ( display_refresh_time * 5 ) + 1 ;
}
}
display_refresh_counter + + ;
if ( display_refresh_counter > ( display_refresh_time * 5 ) )
{
display_refresh_counter = 0 ;
}
2022-09-03 03:04:57 +00:00
}
2022-11-08 22:43:28 +00:00
//Change screen after time if intervall setting not zero
2022-11-08 23:00:24 +00:00
if ( DISPLAY_SCREEN_INTERVAL ! = 0 )
2022-11-08 22:43:28 +00:00
{
if ( millis ( ) - lastScreenChangeTime > = DISPLAY_SCREEN_INTERVAL )
{
2022-11-13 03:16:51 +00:00
time ( & now ) ; localtime_r ( & now , & tm ) ; //Get local time
2022-11-13 19:48:46 +00:00
2022-11-13 21:53:59 +00:00
display_time ( tm . tm_hour , tm . tm_min ) ;
2022-11-08 22:43:28 +00:00
lastScreenChangeTime + = DISPLAY_SCREEN_INTERVAL ;
2022-11-13 19:48:46 +00:00
}
}
2022-11-13 21:53:59 +00:00
2022-11-08 22:43:28 +00:00
//Rotate screen if BUTTON_ROTATION is pressed
currentButtonRotationState = digitalRead ( BUTTON_ROTATION ) ;
2022-11-09 01:10:55 +00:00
if ( lastButtonRotationState = = HIGH & & currentButtonRotationState = = LOW )
2022-11-08 22:43:28 +00:00
{
2022-09-03 03:04:57 +00:00
display_screen + + ;
2022-11-13 21:53:59 +00:00
lastButtonRotationState = currentButtonRotationState ;
2022-09-03 03:04:57 +00:00
}
2022-11-08 22:43:28 +00:00
2022-11-09 01:10:55 +00:00
if ( ! client . connected ( ) ) {
reconnect ( ) ;
2022-09-03 03:04:57 +00:00
}
2022-11-09 01:10:55 +00:00
client . loop ( ) ;
2022-08-21 21:32:23 +00:00
}