53 |
54 |
55 |
ESP-ECU JOURNAL
56 |
57 |
58 |
59 | Time Type Description
60 | %rows%
61 |
62 | )=====";
63 |
64 | // ************************************************************************************
65 | // U P D A T E L O G
66 | // ************************************************************************************
67 | void Update_Log(int what, const char* message) {
68 | char nu[14];
69 | // when the log is full we start overwriting with the first row
70 | sprintf(nu,"%d-%d:%d:%d ", day(), hour(), minute(), second());
71 |
72 | strcpy( Log_Events[logNr].date, nu );
73 |
74 | Log_Events[logNr].kind = what;
75 |
76 | strcpy( Log_Events[logNr].message, message );
77 |
78 | logNr++;
79 |
80 | if (logNr >= Log_MaxEvents)
81 | {
82 | logNr = 0;//start again
83 | Log_MaxReached = true;
84 | }
85 | }
86 |
87 |
88 | //void Clear_Log(AsyncWebServerRequest *request) {
89 | //
90 | // if(!checkRemote( request->client()->remoteIP().toString()) ) {
91 | // if(logNr != 0) {
92 | //// for (int i=0; i <= Log_MaxEvents; i++) {
93 | //// Log_date[20][0] = '\0';
94 | //// Log_kind[20][0] = '\0';
95 | //// Log_message[20][0] = '\0';
96 | //// }
97 | // logNr = 0;//start again
98 | // Log_MaxReached = false;
99 | // //Serial.println("log cleared");
100 | // }
101 | // }
102 | //}
103 |
104 |
105 |
106 | String putList(const String& var)
107 | {
108 |
109 | if(var == "rows")
110 | {
111 | Serial.println("found rows, logNr = " + String(logNr));
112 |
113 | char content[1536] = {0};
114 | char temp1[80]={0}; // 14 +
115 | char temp2[8]={0};
116 | //char temp2[13];
117 | byte Log_Count = 0;
118 | Log_MaxReached ? Log_Count = Log_MaxEvents : Log_Count = logNr; // determine if the max number of event is reached
119 | int j = logNr;
120 | // the rows 0-logNr are the recent updates, are printed from logNr to 0
121 | // so first we print the recent from logNr -> null (j=logNr)
122 | // and next the old ones from maxnr -> logNr
123 | for ( int i = 1; i <= Log_Count; i++ ) {
124 | j--; // this is the index of the newest record in the array
125 | if (j ==-1) j = Log_MaxEvents - 1; // if we are below the first index of the array ,we start at the last
126 |
127 | switch ( Log_Events[j].kind ) {
128 | case 1:
129 | strncpy( temp2, "system\0", 7 ) ;
130 | break;
131 | case 2:
132 | strncpy( temp2, "zigbee\0", 7 ) ;
133 | break;
134 | case 3:
135 | strncpy( temp2, "mqtt\0", 5 ) ;
136 | break;
137 | case 4:
138 | strncpy( temp2, "pairing\0", 8 ) ;
139 | }
140 | // One table line
141 | sprintf(temp1,"
%s %s %s ", Log_Events[j].date, temp2, Log_Events[j].message );
142 | strcat(content, temp1);
143 | }
144 |
145 | return content;
146 | }
147 | return String();
148 | }
149 |
--------------------------------------------------------------------------------
/AAA_MENUPAGE.h:
--------------------------------------------------------------------------------
1 | const char MENUPAGE[] PROGMEM = R"=====(
2 |
3 | ESP32-ECU
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
19 |
20 |
ESP32 ECU MENU
21 |
22 |
41 |
42 | )=====";
43 |
--------------------------------------------------------------------------------
/ABOUT.ino:
--------------------------------------------------------------------------------
1 | const char ABOUT [] PROGMEM = R"=====(
2 |
3 |
4 |
5 |
6 |
7 | ESP32-ECU
8 |
14 |
15 |
16 |
17 |
18 |
19 |
ESP-ECU SYSTEM DATA
20 |
21 | )=====";
22 |
23 | void handleAbout(AsyncWebServerRequest *request) {
24 | char page[1536] = {0};
25 | char temp[100]={0};
26 | strcpy_P(page, ABOUT);
27 |
28 | int minutens = millis()/60000;
29 | int urens = minutens/60;
30 | int dagen = urens/24;
31 |
32 | strcat(page, "
SYSTEM INFORMATION " );
33 | strcat(page, "firmware version ESP32-ECU-v1_4b ");
34 | if ( timeRetrieved ) strcat(page,"time retrieved yes "); else strcat(page,"time retrieved n ");
35 | sprintf(temp, "systemtime %d:%d " , hour(), minute());
36 | switch (dst) {
37 | case 1: strncat(temp, "summertime ", 19 ); break;
38 | case 2: strncat(temp, "wintertime", 19 ); break;
39 | case 0: strncat(temp, "no dst set", 19 );
40 | }
41 | strcat(page, temp);
42 |
43 | sprintf(temp, "system uptime %d d %d h %d m ", dagen, urens-dagen*24, minutens-urens*60);
44 | strcat(page, temp);
45 | sprintf(temp, "wifi signalstrength %lddB ", WiFi.RSSI());
46 | strcat(page, temp);
47 |
48 | sprintf(temp, "ESP CHIP ID %s ", getChipId(true).c_str() );
49 | strcat(page, temp);
50 | sprintf(temp, "Free heap %ld bytes ", esp_get_free_heap_size() );
51 | strcat(page, temp);
52 | if ( Mqtt_Format != 0 ) { //bool == y en er is een mqtt adres, ja kijk dan of er een sensor is ingesteld
53 | sprintf( temp,"mqtt clientId %ld ", getChipId(false).c_str());
54 | strcat(page, temp);
55 | // check if connected
56 | if ( MQTT_Client.connected() ) { //: add a dot
57 | sprintf(temp, "mqtt connected %s ", Mqtt_Broker );
58 | } else {
59 | sprintf(temp, "mqtt status not connected ");
60 | }
61 | } else {
62 | sprintf(temp, "mqtt status not configured ");
63 | }
64 | strcat(page, temp);
65 |
66 | if(minute(switchonTime) < 10 ) {
67 | sprintf(temp,"polling from 0%d:0%d hr", hour(switchonTime), minute(switchonTime) );
68 | } else {
69 | sprintf(temp," polling from 0%d:%d hr", hour(switchonTime), minute(switchonTime) );
70 | }
71 |
72 | if( minute(switchoffTime) < 10 ) {
73 | sprintf(temp," polling to %d:0%d hr", hour(switchoffTime), minute(switchoffTime) );
74 | } else {
75 | sprintf(temp," polling to %d:%d hr", hour(switchoffTime), minute(switchoffTime) );
76 | }
77 |
78 | sprintf(temp, " securityLevel %d " , securityLevel );
79 | strcat(page, temp);
80 |
81 | sprintf(temp, "ZB resetCounter %d
" , resetCounter );
82 | strcat(page, temp);
83 |
84 | //Serial.println("page = " + String(page));
85 | Serial.println("length = " + String(strlen(page)));
86 |
87 | request->send(200, "text/html", page); //send the html code to the client
88 | memset(page, 0, sizeof(page));
89 | }
90 |
--------------------------------------------------------------------------------
/Async_TCP.h:
--------------------------------------------------------------------------------
1 | /*
2 | Asynchronous TCP library for Espressif MCUs
3 |
4 | Copyright (c) 2016 Hristo Gochkov. All rights reserved.
5 | This file is part of the esp8266 core for Arduino environment.
6 |
7 | This library is free software; you can redistribute it and/or
8 | modify it under the terms of the GNU Lesser General Public
9 | License as published by the Free Software Foundation; either
10 | version 2.1 of the License, or (at your option) any later version.
11 |
12 | This library is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | Lesser General Public License for more details.
16 |
17 | You should have received a copy of the GNU Lesser General Public
18 | License along with this library; if not, write to the Free Software
19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 | */
21 |
22 | #ifndef ASYNCTCP_H_
23 | #define ASYNCTCP_H_
24 |
25 | #include "IPAddress.h"
26 | #include "sdkconfig.h"
27 | #include
28 | extern "C" {
29 | #include "freertos/semphr.h"
30 | #include "lwip/pbuf.h"
31 | }
32 |
33 | //If core is not defined, then we are running in Arduino or PIO
34 | #ifndef CONFIG_ASYNC_TCP_RUNNING_CORE
35 | #define CONFIG_ASYNC_TCP_RUNNING_CORE -1 //any available core
36 | #define CONFIG_ASYNC_TCP_USE_WDT 0 //if enabled, adds between 33us and 200us per event HA adapt
37 | #endif
38 |
39 | class AsyncClient;
40 |
41 | #define ASYNC_MAX_ACK_TIME 5000
42 | #define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given)
43 | #define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react.
44 |
45 | typedef std::function AcConnectHandler;
46 | typedef std::function AcAckHandler;
47 | typedef std::function AcErrorHandler;
48 | typedef std::function AcDataHandler;
49 | typedef std::function AcPacketHandler;
50 | typedef std::function AcTimeoutHandler;
51 |
52 | struct tcp_pcb;
53 | struct ip_addr;
54 |
55 | class AsyncClient {
56 | public:
57 | AsyncClient(tcp_pcb* pcb = 0);
58 | ~AsyncClient();
59 |
60 | AsyncClient & operator=(const AsyncClient &other);
61 | AsyncClient & operator+=(const AsyncClient &other);
62 |
63 | bool operator==(const AsyncClient &other);
64 |
65 | bool operator!=(const AsyncClient &other) {
66 | return !(*this == other);
67 | }
68 | bool connect(IPAddress ip, uint16_t port);
69 | bool connect(const char* host, uint16_t port);
70 | void close(bool now = false);
71 | void stop();
72 | int8_t abort();
73 | bool free();
74 |
75 | bool canSend();//ack is not pending
76 | size_t space();//space available in the TCP window
77 | size_t add(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY);//add for sending
78 | bool send();//send all data added with the method above
79 |
80 | //write equals add()+send()
81 | size_t write(const char* data);
82 | size_t write(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY); //only when canSend() == true
83 |
84 | uint8_t state();
85 | bool connecting();
86 | bool connected();
87 | bool disconnecting();
88 | bool disconnected();
89 | bool freeable();//disconnected or disconnecting
90 |
91 | uint16_t getMss();
92 |
93 | uint32_t getRxTimeout();
94 | void setRxTimeout(uint32_t timeout);//no RX data timeout for the connection in seconds
95 |
96 | uint32_t getAckTimeout();
97 | void setAckTimeout(uint32_t timeout);//no ACK timeout for the last sent packet in milliseconds
98 |
99 | void setNoDelay(bool nodelay);
100 | bool getNoDelay();
101 |
102 | uint32_t getRemoteAddress();
103 | uint16_t getRemotePort();
104 | uint32_t getLocalAddress();
105 | uint16_t getLocalPort();
106 |
107 | //compatibility
108 | IPAddress remoteIP();
109 | uint16_t remotePort();
110 | IPAddress localIP();
111 | uint16_t localPort();
112 |
113 | void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
114 | void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
115 | void onAck(AcAckHandler cb, void* arg = 0); //ack received
116 | void onError(AcErrorHandler cb, void* arg = 0); //unsuccessful connect or error
117 | void onData(AcDataHandler cb, void* arg = 0); //data received (called if onPacket is not used)
118 | void onPacket(AcPacketHandler cb, void* arg = 0); //data received
119 | void onTimeout(AcTimeoutHandler cb, void* arg = 0); //ack timeout
120 | void onPoll(AcConnectHandler cb, void* arg = 0); //every 125ms when connected
121 |
122 | void ackPacket(struct pbuf * pb);//ack pbuf from onPacket
123 | size_t ack(size_t len); //ack data that you have not acked using the method below
124 | void ackLater(){ _ack_pcb = false; } //will not ack the current packet. Call from onData
125 |
126 | const char * errorToString(int8_t error);
127 | const char * stateToString();
128 |
129 | //Do not use any of the functions below!
130 | static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb);
131 | static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err);
132 | static int8_t _s_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
133 | static int8_t _s_lwip_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
134 | static void _s_error(void *arg, int8_t err);
135 | static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
136 | static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
137 | static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg);
138 |
139 | int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err);
140 | tcp_pcb * pcb(){ return _pcb; }
141 |
142 | protected:
143 | tcp_pcb* _pcb;
144 | int8_t _closed_slot;
145 |
146 | AcConnectHandler _connect_cb;
147 | void* _connect_cb_arg;
148 | AcConnectHandler _discard_cb;
149 | void* _discard_cb_arg;
150 | AcAckHandler _sent_cb;
151 | void* _sent_cb_arg;
152 | AcErrorHandler _error_cb;
153 | void* _error_cb_arg;
154 | AcDataHandler _recv_cb;
155 | void* _recv_cb_arg;
156 | AcPacketHandler _pb_cb;
157 | void* _pb_cb_arg;
158 | AcTimeoutHandler _timeout_cb;
159 | void* _timeout_cb_arg;
160 | AcConnectHandler _poll_cb;
161 | void* _poll_cb_arg;
162 |
163 | bool _pcb_busy;
164 | uint32_t _pcb_sent_at;
165 | bool _ack_pcb;
166 | uint32_t _rx_ack_len;
167 | uint32_t _rx_last_packet;
168 | uint32_t _rx_since_timeout;
169 | uint32_t _ack_timeout;
170 | uint16_t _connect_port;
171 |
172 | int8_t _close();
173 | void _free_closed_slot();
174 | void _allocate_closed_slot();
175 | int8_t _connected(void* pcb, int8_t err);
176 | void _error(int8_t err);
177 | int8_t _poll(tcp_pcb* pcb);
178 | int8_t _sent(tcp_pcb* pcb, uint16_t len);
179 | int8_t _fin(tcp_pcb* pcb, int8_t err);
180 | int8_t _lwip_fin(tcp_pcb* pcb, int8_t err);
181 | void _dns_found(struct ip_addr *ipaddr);
182 |
183 | public:
184 | AsyncClient* prev;
185 | AsyncClient* next;
186 | };
187 |
188 | class AsyncServer {
189 | public:
190 | AsyncServer(IPAddress addr, uint16_t port);
191 | AsyncServer(uint16_t port);
192 | ~AsyncServer();
193 | void onClient(AcConnectHandler cb, void* arg);
194 | void begin();
195 | void end();
196 | void setNoDelay(bool nodelay);
197 | bool getNoDelay();
198 | uint8_t status();
199 |
200 | //Do not use any of the functions below!
201 | static int8_t _s_accept(void *arg, tcp_pcb* newpcb, int8_t err);
202 | static int8_t _s_accepted(void *arg, AsyncClient* client);
203 |
204 | protected:
205 | uint16_t _port;
206 | IPAddress _addr;
207 | bool _noDelay;
208 | tcp_pcb* _pcb;
209 | AcConnectHandler _connect_cb;
210 | void* _connect_cb_arg;
211 |
212 | int8_t _accept(tcp_pcb* newpcb, int8_t err);
213 | int8_t _accepted(AsyncClient* client);
214 | };
215 |
216 |
217 | #endif /* ASYNCTCP_H_ */
218 |
--------------------------------------------------------------------------------
/CONFIG_BASIS.ino:
--------------------------------------------------------------------------------
1 | const char BASISCONFIG[] PROGMEM = R"=====(
2 |
3 |
4 |
8 |
9 |
ECU GENERAL SETTINGS
10 |
11 |
23 |
24 |
25 | )=====";
26 |
27 | void zendPageBasis(AsyncWebServerRequest *request) {
28 | String(webPage)="";
29 | //DebugPrintln("we zijn nu op zendPageBasis");
30 | webPage = FPSTR(HTML_HEAD);
31 | webPage += FPSTR(BASISCONFIG);
32 |
33 | // replace data
34 | webPage.replace("'{id}'" , "'" + String(ECU_ID) + "'") ;
35 | webPage.replace( "'{pw1}'" , "'" + String(userPwd) + "'") ;
36 | webPage.replace( "'{of}'" , "'" + String(pollOffset) + "'") ;
37 | if (Polling) {
38 | webPage.replace("#check", "checked");
39 | }
40 | request->send(200, "text/html", webPage);
41 | webPage=""; // free up
42 | }
43 |
44 |
45 | void handleBasisconfig(AsyncWebServerRequest *request) { // form action = handleConfigsave
46 | // verzamelen van de serverargumenten
47 | strcpy(ECU_ID, request->arg("ecuid").c_str());
48 | strcpy(userPwd, request->arg("pw1").c_str());
49 | // pollRes = request->arg("pr").toInt();
50 | // hc_IDX = request->arg("hcidx").toInt();
51 | pollOffset = request->arg("offs").toInt();
52 | // this value gets currupted when it is negative, we get 256 -/- the number
53 | // so -2 becomes 254
54 | // if (po > 200) { pollOffset = po - 256; } else { pollOffset = po; }
55 |
56 |
57 | // calliBration = request->arg("cali").toFloat();
58 | //BEWARE CHECKBOX
59 | String dag = "";
60 | if(request->hasParam("pL")) {
61 | dag = request->getParam("pL")->value();
62 | }
63 | if (dag == "on") { Polling = true; } else { Polling = false;}
64 | //toSend = FPSTR(CONFIRM);
65 | basisConfigsave(); // alles opslaan
66 | // request->send_P(200, "text/html", CONFIRM); //send the html code to the client
67 |
68 | //DebugPrintln("basisconfig saved");
69 | actionFlag=25; // recalculates the time with these new values
70 | }
71 |
--------------------------------------------------------------------------------
/CONFIG_GEO.ino:
--------------------------------------------------------------------------------
1 | const char GEOCONFIG[] PROGMEM = R"=====(
2 |
3 |
4 |
8 |
GEOGRAPHICAL SETTINGS
9 |
18 |
19 | )=====";
20 |
21 |
22 |
23 | void zendPageGEOconfig( AsyncWebServerRequest *request ) {
24 |
25 | String webPage = FPSTR(HTML_HEAD);
26 | webPage += FPSTR(GEOCONFIG);
27 |
28 | // put back the data
29 |
30 | webPage.replace("{le}", String(longi,3) );
31 | webPage.replace("{be}", String(lati,3) );
32 |
33 | webPage.replace("{tz}", String(gmtOffset) );
34 |
35 | if (zomerTijd) {
36 | // Serial.println("zomerTijd = true");
37 | webPage.replace("#check", "checked");
38 | }
39 |
40 | request->send(200, "text/html", webPage);
41 | webPage="";
42 | }
43 |
44 | //void handleGEOconfig(AsyncWebServerRequest *request) {
45 | ////char static_ip2[16] = "";
46 | //
47 | // //de serverargumenten verzamelen
48 | ////strcpy(lengte, request->getParam("le")->value().c_str());
49 | //
50 | //longi = request->getParam("le")->value().toFloat();
51 | //
52 | ////strcpy(breedte, request->getParam("be")->value().c_str());
53 | //
54 | //lati = request->getParam("be")->value().toFloat();
55 | //
56 | //strcpy(gmtOffset, request->getParam("tz")->value().c_str());
57 | //
58 | //
59 | ////BEWARE CHECKBOX
60 | //if(request->hasParam("ts")) { zomerTijd = true; } else { zomerTijd = false;}
61 | //
62 | //
63 | // wifiConfigsave();
64 | //
65 | // actionFlag=25; // recalculate with these settings
66 | //}
67 |
--------------------------------------------------------------------------------
/DETAILSPAGE.h:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | const char DETAILSPAGE [] PROGMEM = R"=====(
4 |
5 |
6 | ESP-ECU
7 |
13 |
14 |
77 |
78 |
79 |
80 |
84 |
ESP-ECU INVERTER :
85 |
86 | Type n/a
87 | serialnr n/a
88 | ID n/a
89 | signal quality n/a
90 | ac voltage n/a
91 | temperature n/a
92 | frequency n/a
93 | throttle
94 |
95 |
96 |
INVERTER OUTPUT
97 | unit panel 0 panel 1 panel 2 panel 3
98 |
99 | dc voltage n/a n/a n/a n/a
100 | dc current n/a n/a n/a n/a
101 |
this inverter is not paired! this inverter is not polled!
102 | )=====";
103 |
104 | // this is the old script
105 | //function loadScript() {
106 | // loadData();
107 | // setInterval(function ld() {
108 | // loadData();
109 | // },90000);
110 | //}
111 | //function loadData() {
112 | // console.log("function loadData");
113 | // var xhttp = new XMLHttpRequest();
114 | // xhttp.onreadystatechange = function() {
115 | // if (this.readyState == 4 && this.status == 200) {
116 | // var antwoord = this.responseText;
117 | // var obj = JSON.parse(antwoord);
118 | //
119 | // document.getElementById("ivn").innerHTML = obj.inv;
120 | // document.getElementById("nm").innerHTML = "
" + obj.name + " ";
121 | // document.getElementById("snr").innerHTML = obj.serial;
122 | // var sid = obj.sid; //if 0000 not paired
123 | // document.getElementById("sid").innerHTML = sid;
124 | // var t = obj.type;
125 | // var type ="YC600";
126 | // if(t=="1"){type="QS1";} if(t=="2") {type = "DS3";}
127 | // document.getElementById("tp").innerHTML = type;
128 | //
129 | // if(sid != "0000" || sid == "") {
130 | //
131 | // var polled = obj.polled;
132 | // if( polled=="1" ) {
133 | //
134 | // document.getElementById("dcvc").style.display = "block";
135 | // document.getElementById("npo").style.display = "none";
136 | //
137 | // document.getElementById("sq").innerHTML = obj.sq + " %";
138 | // document.getElementById("acv").innerHTML = obj.acv + " V";
139 | // document.getElementById("tmp").innerHTML = obj.temp + " ℃"
140 | // document.getElementById("fr").innerHTML = obj.freq + " Hz";
141 | // // round the values if they are not n/a or n/e)
142 | // for(let z=0; z < 4 ; z++) {;
143 | // if( obj.dcv[z] != "n/e" && obj.dcv[z] != "n/a" ) {obj.dcv[z] = obj.dcv[z].toFixed(1);}
144 | // if( obj.dcc[z] != "n/e" && obj.dcc[z] != "n/a" ) {obj.dcc[z] = obj.dcc[z].toFixed(1);}
145 | // }
146 | // document.getElementById("v0").innerHTML = obj.dcv[0];
147 | // document.getElementById("v1").innerHTML = obj.dcv[1];
148 | // document.getElementById("v2").innerHTML = obj.dcv[2];
149 | // document.getElementById("v3").innerHTML = obj.dcv[3];
150 | // document.getElementById("c0").innerHTML = obj.dcc[0];
151 | // document.getElementById("c1").innerHTML = obj.dcc[1];
152 | // document.getElementById("c2").innerHTML = obj.dcc[2];
153 | // document.getElementById("c3").innerHTML = obj.dcc[3];
154 | //
155 | // paintCells()
156 | // } else {
157 | //
158 | // document.getElementById("npo").style.display = "block";
159 | // document.getElementById("dcvc").style.display = "none";
160 | // }
161 | // } else {
162 | // document.getElementById("npa").style.display = "block";
163 | // }
164 | //
165 | // }
166 | // };
167 | // xhttp.open("GET", "get.Inverter", true);
168 | // xhttp.send();
169 | //}
170 | //
171 | //function paintCells() {
172 | // for(let z=0; z<4 ; z++) {
173 | // v = "v" + z;
174 | // c = "c" + z;
175 | // if(document.getElementById(v).innerHTML=="n/e") {
176 | // document.getElementById(v).style = "background-color:#a6a6a6";
177 | // }
178 | // if(document.getElementById(c).innerHTML=="n/e") {
179 | // document.getElementById(c).style = "background-color:#a6a6a6";
180 | // }
181 | // }
182 | //}
183 | //
184 | //)=====";
185 |
186 |
--------------------------------------------------------------------------------
/ESP32-ECU_v0-9a.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patience4711/ESP32-read-APS-inverters/77020fe28af890070bfc76cb23d4c04ad3dd0cf8/ESP32-ECU_v0-9a.bin
--------------------------------------------------------------------------------
/ESP32_ECU_v1_3c.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patience4711/ESP32-read-APS-inverters/77020fe28af890070bfc76cb23d4c04ad3dd0cf8/ESP32_ECU_v1_3c.bin
--------------------------------------------------------------------------------
/ESP32_ECU_v1_4b.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patience4711/ESP32-read-APS-inverters/77020fe28af890070bfc76cb23d4c04ad3dd0cf8/ESP32_ECU_v1_4b.bin
--------------------------------------------------------------------------------
/ESP32_ECU_v1_4c.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patience4711/ESP32-read-APS-inverters/77020fe28af890070bfc76cb23d4c04ad3dd0cf8/ESP32_ECU_v1_4c.bin
--------------------------------------------------------------------------------
/EXTERNAL.ino:
--------------------------------------------------------------------------------
1 | // find out if the request comes from inside the network
2 | bool checkRemote(String url) {
3 | //check if the first 9 characters of the router 192.168.0
4 | if(securityLevel == 0) return false; // never remote
5 | if ( url.indexOf(WiFi.gatewayIP().toString().substring(0, securityLevel)) == -1 ) return true; else return false;
6 | }
7 |
8 | // we come here when an unknown request is done
9 | void handleNotFound(AsyncWebServerRequest *request)
10 | {
11 |
12 | bool intern = false;
13 | if(!checkRemote( request->client()->remoteIP().toString()) ) intern = true;
14 |
15 | // **************************************************************************
16 | // R E S T R I C T E D A R E A
17 | // **************************************************************************
18 | // access only from inside the network
19 | if ( intern ) { //DebugPrintln("the request comes from inside the network");
20 | String serverUrl = request->url().c_str();
21 | Serial.println("serverUrl = " + serverUrl);
22 |
23 | if ( serverUrl.indexOf("SENDZIGBEE") > -1)
24 | {
25 | strcpy( txBuffer, request->arg("mes").c_str());
26 | diagNose = 10; // consoleOut logs the output
27 | debugLog = "debug send zigbee command\n";
28 | actionFlag = 45;
29 | String term = "sending zigbee message";
30 | if(diagNose == 10) term += "
view log ";
31 | request->send ( 200, "text/html", term );
32 | return;
33 | } else
34 | // /SHOWFILE?file=/wificonfig.json
35 | if ( serverUrl.indexOf("SHOWFILES") > -1)
36 | {
37 | loginBoth(request, "admin"); // we need to be logged in
38 | //String file = request->arg("file").c_str();
39 | //const char* file = request->arg("file").c_str();
40 | diagNose = 3; // consoleOut logs the output
41 | // debugLog = "debug send SHOWFILE\n";
42 | // //actionFlag = ;
43 | String term = "printing all files in SPIFFS\n ";
44 | // if( file_open_for_read(file) ) {
45 | // consoleOut("read "+ String(file));
46 | // } else {
47 | // consoleOut(String(file) + " not opened\n");
48 | // }
49 | SPIFFS_read();
50 | printInverters(); // show all the inverter files
51 | term += "
view log ";
52 | request->send ( 200, "text/html", term );
53 | return;
54 | } else
55 |
56 |
57 | //say we have a request
/TROTTLE?debug=1&inv=1&val=500
58 | //say we have a request ip_of_ecu/TROTTLE0=300
59 | if ( serverUrl.indexOf("THROTTLE") > -1)
60 | {
61 | int Invert = request->arg("inv").toInt();
62 | int throtVal = request->arg("val").toInt();
63 | if (request->hasParam("debug")) diagNose = 10;
64 |
65 | debugLog = "debug throttlecommand\n";
66 | if (Invert > inverterCount) Invert = 10;
67 | if (throtVal == 0) throtVal = 800;
68 |
69 | Serial.println("inv = " + String(Invert));
70 | Serial.println("val = " + String(throtVal));
71 | //write the desired throttle value to preferences
72 |
73 | if(Invert > inverterCount || Invert < 0 || throtVal > 700 || throtVal < 20 )
74 | {
75 | request->send ( 200, "text/plain", "invalid value(s)" );
76 | return;
77 | }
78 | desiredThrottle[Invert] = throtVal;
79 | actionFlag = 240+Invert;
80 |
81 | String term = "attempt throttling inverter " + String(Invert) + " to " + String(throtVal);
82 | if(diagNose==10) term += " see the log read log ";
83 | request->send ( 200, "text/html", term );
84 |
85 | return;
86 | } else
87 | ///QUERY?inv=0
88 | if ( serverUrl.indexOf("QUERY") > -1)
89 | {
90 | int inv = request->arg("inv").toInt();
91 | diagNose = 10;
92 | debugLog = "debug query command inverter " + String(inv) + "\n ";
93 | if(inv > inverterCount || inv < 0 )
94 | {
95 | request->send ( 200, "text/plain", "invalid inverter" );
96 | return;
97 | }
98 | actionFlag = inv + 210;
99 |
100 | String term = "query inverter " + String(inv) + "\n ";
101 | term += "view debug log ";
102 | request->send ( 200, "text/html", term );
103 | return;
104 | } else
105 |
106 | if ( serverUrl.indexOf("TESTMQTT") > -1)
107 | {
108 | if (request->hasParam("debug")) diagNose = 10;
109 |
110 | if (diagNose == 10) debugLog = "debug test mosquitto\n ";
111 | actionFlag = 49;
112 |
113 | String term = "test message mosquitto\n ";
114 | if (diagNose == 10) term += "view debug log ";
115 | request->send ( 200, "text/html", term );
116 | return;
117 | } else
118 |
119 |
120 | if ( serverUrl.indexOf("readDebug") > -1) {
121 | debugLog += "\nlength log: " + String(debugLog.length());
122 | request->send(200, "text/html", "" + debugLog + " ");
123 | debugLog="";
124 | return;
125 | } else
126 |
127 | if ( serverUrl.indexOf("INVERTERPOLL") > -1)
128 | {
129 |
130 | if (request->hasParam("debug")) diagNose = 3;
131 | debugLog = "debug poll command\n";
132 | int inv = request->arg("inv").toInt();
133 |
134 | if(Polling || !dayTime || inv > inverterCount-1)
135 | {
136 | request->send ( 200, "text/plain", "error check dayTime, Polling, inverter#" ); //zend bevestiging
137 | return;
138 | }
139 |
140 | actionFlag = 220+inv; // takes care for the polling
141 | String term = "polling inverter " + String(inv);
142 | if(diagNose==3) term += "view the log ";
143 | request->send ( 200, "text/html", term );
144 | return;
145 | }
146 |
147 | // if we are here, no valid api was found
148 | request->send ( 200, "text/plain", "ERROR this link is invalid, go back <--" );//send not found message
149 | }
150 | else
151 | { // not intern
152 | //DebugPrint("\t\t\t\t unauthorized, not from inside the network : ");
153 | request->send ( 200, "text/plain", "ERROR you are not authorised, go back <--" );//send not found message
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/FORCE.ino:
--------------------------------------------------------------------------------
1 | /* char freq[5] = "00.0";
2 | char sigQ[5] = "00.0";
3 | char heath[6] = "000.0";
4 | char acv[6] = "000.0";
5 | char dcc[4][5] = {"00.0", "00.0", "00.0", "00.0"}; // ampere <100
6 | char dcv[4][5] = {"00.0", "00.0", "00.0", "00.0"}; // volt <100
7 | char power[5][6]={"000.0", "000.0", "000.0", "000.0", "000.0"}; //watt < 1000
8 | float en_total = 0;
9 | dtostrf(float_value, min_width, num_digits_after_decimal, where_to_store_string)
10 |
11 | */
12 | void force_values() {
13 | for(int z=0; z
3 | //
4 | //
5 | //
6 | //ESP32-ECU
7 | //
11 | //
30 | //
31 | //
32 | //)=====";
33 | //
34 | //void handleInfo(AsyncWebServerRequest *request) {
35 | ////DebugPrintln("we are at handleInfopage() ");
36 | //
37 | //String pageSend = FPSTR(INFOPAGE);
38 | ////pageSend.replace("tieTel", swName );
39 | //
40 | //pageSend += "Hansiart ECU STATUS INFORMATION ";
41 | //
42 | //pageSend += "";
43 | //
44 | //String zt = "summertime";
45 | //switch (dst) {
46 | // case 2: zt="wintertime"; break;
47 | // case 0: zt="no dst set"; break;
48 | //}
49 | //
50 | //pageSend += " system time = hr.   " + zt + " ";
51 | //
52 | //pageSend += "firmware version : " + String(VERSION) + " ";
53 | //
54 | //pageSend += "time retrieved today : "; if ( timeRetrieved ) { pageSend += "yes "; } else { pageSend += "no "; }
55 | //
56 | ////
57 | //long rssi = WiFi.RSSI();
58 | //pageSend += "the wifi signalstrength (rssi) = " + String(rssi) + " ";
59 | //
60 | //if ( Mqtt_Format != 0 ) { //bool == y en er is een mqtt adres, ja kijk dan of er een sensor is ingesteld
61 | //// check if connected
62 | // //String clientId = "ESPClient#";
63 | // //String clientId = "ESP32-ECU";
64 | // String clientId = getChipId() ;
65 | // pageSend += "de mqtt clientId = : " + clientId + " ";
66 | // if ( MQTT_Client.connected() ) {
67 | // pageSend += "status mqtt : connected to " + Mqtt_Broker + " ";
68 | // } else {
69 | // pageSend += "status mqtt : not connected ";
70 | // }
71 | // } else {
72 | // pageSend += "mosquitto not configured ";
73 | // pageSend += "check the mosquitto settings ";
74 | //}
75 | //
76 | // int minutens = millis()/60000;
77 | // int urens = minutens/60;
78 | // int dagen = urens/24;
79 | // pageSend += "system up time: " + String(dagen) + " days " + String(urens-dagen*24) + " hrs " + String(minutens - urens*60) + " min. ";
80 | // pageSend += "current errorCode = " + String(errorCode) + " ";
81 | //
82 | //
83 | //
84 | //pageSend += " ESP INFORMATION ";
85 | //pageSend += "ESP CHIP ID nr: " + getChipId().substring(10);
86 | //pageSend += " min. heap size " + String(esp_get_minimum_free_heap_size()) + " bytes ";
87 | //pageSend += "Free heap " + String(esp_get_free_heap_size()) + " bytes remote IP " + request->client()->remoteIP().toString() + "
";
88 | //
89 | //pageSend += "variables dump ";
90 | //pageSend += "value=" + String(value) + " inverterCount=" + String(inverterCount) + " zigbeeUp=" + String(zigbeeUp) + " ";
91 | //pageSend += "switchonTime=" + String(switchonTime) + " switchoffTime=" + String(switchoffTime)+ " ";
92 | //pageSend += "unixtime=" + String(now()) + " ";
93 | //pageSend += "polled = " + String(polled[0]) + String(polled[1]) + String(polled[2]) + String(polled[3]) + String(polled[4]) + String(polled[5]) + String(polled[6]) + String(polled[7]) + String(polled[8]) + " ";
94 | //pageSend += "ZB resetCounter = " + String(resetCounter);
95 | //pageSend += " pollOffset = " + String(pollOffset) + " Mqtt_Format = " + String(Mqtt_Format) + " ";
96 | //pageSend += " Polling = " + String(Polling) + " ";
97 | //#ifdef TEST
98 | //pageSend += " testCounter = " + String(testCounter) + " inv0 type = " + String(Inv_Prop[0].invType);
99 | //#endif
100 | //pageSend += "Content filesystem : ";
101 | //
102 | //File root = SPIFFS.open("/");
103 | //File file = root.openNextFile();
104 | //while (file) {
105 | // pageSend += String(file.name()) + " size ";
106 | // pageSend += String(file.size()) + " ";
107 | // file = root.openNextFile();
108 | //}
109 | //
110 | // //DebugPrintln("end infopage ");
111 | // //DebugPrint("de lengte van pageSend na de infopage = "); //DebugPrintln( pageSend.length() );
112 | // request->send(200, "text/html", pageSend); //send the html code to the client
113 | //}
114 |
--------------------------------------------------------------------------------
/ISR.ino:
--------------------------------------------------------------------------------
1 | // *******************************************************************************************
2 | // interrupt service routine
3 | // *******************************************************************************************
4 | // this routine is called when the button is pressed
5 | // the first part is a debouncer and takes care for the case of grid failure
6 | // when the program would think that a button has been pressed.
7 | // next we check if the button was short or long pressed.
8 |
9 | // *******************************************************************************************
10 | // interrupt service routine
11 | // *******************************************************************************************
12 | // this routine is called when the button is pressed
13 | // the first part is a debouncer and takes care for the case of grid failure
14 | // when the program would think that a button has been pressed.
15 | // next we check if the button was short or long pressed.
16 |
17 | IRAM_ATTR void isr() {
18 | actionFlag = 15;
19 | }
20 |
21 | void buttonPressed() {
22 | int val = 0;
23 | detachInterrupt(knop); // prevent interrupts during the isr
24 | Serial.println("interrupt");
25 | //DebugPrintln(value);
26 | //we came here because the button was pressed. Now we check asfer a few
27 | //miliseconds if it still is, otherwise it was a not a manual press
28 | unsigned long starttime = millis(); // save the current time in currentMillis
29 | unsigned long endtime = millis();
30 | while (endtime - starttime <= 50)
31 | { //2000 millis = 2 sec
32 | endtime = millis();
33 | }
34 | val = digitalRead(knop);
35 | if (val == 1) { // means the button is released
36 | //DebugPrintln("button was pressed too short, accidental spike ");
37 | attachInterrupt(digitalPinToInterrupt(knop), isr, FALLING);
38 | return; // jump out, the button is high so it was a coincidence
39 | }
40 | //if we are here we passed the debounce
41 | digitalWrite(led_onb, HIGH); // led on
42 | //we wait again but longer
43 | Serial.println("button still pressed, so not accidentally");
44 | // first the led is flashed
45 | while (endtime - starttime <= 500) { //2000 millis = 2 sec
46 | endtime = millis();
47 | }
48 | digitalWrite(led_onb, LOW); // led off
49 | while (endtime - starttime <= 1500)
50 | { //2000 millis = 2 sec
51 | endtime = millis();
52 | }
53 |
54 | // Now test the button again
55 | val = digitalRead(knop);
56 | if (val == 0) // still pressed
57 | {
58 | // we wait another time, somewhat longer
59 | Serial.println("button still pressed");
60 | while (endtime - starttime <= 6000) //2000 millis = 2 sec
61 | {
62 | endtime = millis();
63 | }
64 | // wdt_disable(); //othersise it's going to reset
65 | //first test if the button is still pressed
66 | //otherwise it's going to reset after a clumpsy operation
67 | val = digitalRead(knop);
68 | if (val == 1) // means the button is released
69 | {
70 | attachInterrupt(digitalPinToInterrupt(knop), isr, FALLING);
71 | return; // jump out, the button is high so it was a clumpsiness
72 | }
73 | digitalWrite(led_onb, HIGH); //de onboard led aan
74 | //Serial.println(F("button still pressed, onboard led on"));
75 | //next we wait some time again
76 | while (endtime - starttime <= 9000) //2000 millis = 2 sec
77 | {
78 | endtime = millis();
79 | }
80 |
81 | digitalWrite(led_onb, LOW); //the onboard led off
82 | // we test the button again,
83 | val = digitalRead(knop);
84 | if (val == 0) // still pressed
85 | {
86 | Serial.println(F("button still pressed, open accesspoint"));
87 | actionFlag = 11;
88 | //attachInterrupt(digitalPinToInterrupt(knop), isr, FALLING);
89 | return;
90 |
91 | }
92 | else
93 | {
94 | Serial.println("button finally released, reboot");
95 | ESP.restart(); // reboot
96 | }
97 | }
98 | else
99 | { //
100 | // the button was release after the seccond evaluation
101 | // so it was a switch command
102 | // if the switch is off it should go on or reversed
103 | // put here your switch logic
104 | // if(some evaluation){
105 | // // here we can put our switch off command
106 | // ledsOffNow(true, true, "button");
107 | // }
108 | // else
109 | // { // ledState = was 0 so switched off
110 | // // here we can put our switch on command
111 | // ledsOnNow(true, false, "button");
112 | // }
113 | // attach the interrupt again
114 | attachInterrupt(digitalPinToInterrupt(knop), isr, FALLING);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 patience4711
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LOGPAGE.ino:
--------------------------------------------------------------------------------
1 | //const char HTML_LOGPAGE[] PROGMEM = R"=====(
2 | //
3 | //ESP32-ECU
4 | //
5 | //
6 | //
7 | //
36 | //
37 | //
38 | //
39 | //
40 | //
45 | //ECU LOG
46 | //
47 | //
Last refresh : !@@!
48 | //
49 | //Refresh
50 | //
51 | //
52 | //Time
53 | //Type
54 | //Command
55 | //
56 | //
57 | //
58 | //
59 | //
60 | //
61 | //)=====";
62 | //// date system 192.168.0.aaa.sss.ddd
63 | //
64 | //void zendPageLog( AsyncWebServerRequest *request ) {
65 | //
66 | // String uur = String(hour());
67 | // if(hour() < 10) {
68 | // uur = "0" + String(hour());
69 | // }
70 | // String minuten = String(minute());
71 | // if(minute() < 10) {
72 | // minuten = "0" + String(minute());
73 | // }
74 | //
75 | //String cont = "";
76 | //cont += uur + " : " + minuten + " hr.";
77 | // char page[1536] = {0};
78 | // char temp[100]={0};
79 | // strcpy_P(page, ABOUT);
80 | //char toSEND=FPSTR(HTML_LOGPAGE);
81 | //
82 | ////toSEND.replace("HANSIART" , String(swName));
83 | //
84 | //toSEND.replace("!@@!", cont);
85 | //
86 | ////DebugPrintln(" zendlogpage :build eventlist");
87 | // byte Log_Count = 0;
88 | // Log_MaxReached ? Log_Count = Log_MaxEvents : Log_Count = logNr; // determine if the max number of event is already reached
89 | //
90 | // int j = logNr;
91 | // String content = "";
92 | // for ( int i = 1; i <= Log_Count; i++ ) {
93 | // //Serial.println("een regel van de lijst, nummer i = "); //Serial.println(i);
94 | // j--; // we get the index of the last record in the array
95 | // //Serial.println("een regel van de lijst, nummer j = "); //Serial.println(j);
96 | // if (j ==-1) j = Log_MaxEvents - 1; // if we are under the first index of the array ,we go to the last
97 | // ////////////////// One table line ///////////////////
98 | //sprintf(temp,"
%s %s %s ", Log_list[j].Log_date, Log_list[j].Log_kind, Log_list[j].Log_message);
99 | //
100 | // ////////////////// One table line ///////////////////
101 | // }
102 | // //Serial.print(content);
103 | // toSEND.replace("", content);
104 | // request->send(200, "text/html", toSEND);
105 | //}
106 | //
107 | // void //Update_log(String what, String message) {
108 | // String nu;
109 | // //DebugPrintln("updating the log");
110 | // if(what != "clear") {
111 | // nu = String(day()) + "-" + String(hour()) + ":" + String(minute()) + ":" + String(second());
112 | // } else {
113 | // nu = "";
114 | // what = "";}
115 | // //DebugPrint("nu = "); DebugPrintln(nu);
116 | // Log_list[logNr].Log_date = nu;
117 | // Log_list[logNr].Log_kind = what;
118 | // //Log_list[logNr].Log_issued = who;
119 | // Log_list[logNr].Log_message = message;
120 | // logNr++;
121 | // if (logNr >= Log_MaxEvents)
122 | // {
123 | // logNr = 0;//start again
124 | // Log_MaxReached = true;
125 | // }
126 | //}
127 | ////void //Update_log(String what, String message) {
128 | //// String nu;
129 | //// //DebugPrintln("updating the log");
130 | //// if(what != "clear") {
131 | //// nu = String(day()) + "-" + String(hour()) + ":" + String(minute()) + ":" + String(second());
132 | //// } else {
133 | //// nu = "";
134 | //// what = "";}
135 | //// //DebugPrint("nu = "); DebugPrintln(nu);
136 | //// Log_list[logNr].Log_date = nu;
137 | //// Log_list[logNr].Log_kind = what;
138 | //// //Log_list[logNr].Log_issued = who;
139 | //// Log_list[logNr].Log_message = message;
140 | //// logNr++;
141 | //// if (logNr >= Log_MaxEvents)
142 | //// {
143 | //// logNr = 0;//start again
144 | //// Log_MaxReached = true;
145 | //// }
146 | ////}
147 | //
148 | //void Clear_Log() {
149 | // //Serial.println("clearing the log");
150 | // if(logNr != 0) {
151 | // String nu="";
152 | // String what="";
153 | // String message="";
154 | // for (int i=0; i <= Log_MaxEvents; i++) {
155 | // Update_Log("clear", "");
156 | // }
157 | // logNr = 0;//start again
158 | // Log_MaxReached = false;
159 | // //Serial.println("log cleared");
160 | // }
161 | //}
162 |
--------------------------------------------------------------------------------
/MQTT.ino:
--------------------------------------------------------------------------------
1 | bool mqttConnect() { //
2 | /* this function checks if we are connected to the broker, if not connect anyway */
3 | if( MQTT_Client.connected() ) {
4 | consoleOut("mqtt was connected");
5 | return true;
6 | }
7 | // we are here because w'r not connected. Signal with the LED
8 | consoleOut("mqtt connecting");
9 | ledblink(2,70);
10 |
11 | if (Mqtt_Port[0] == '\0' ) strcpy(Mqtt_Port, "1883"); // just in case ....
12 | uint8_t retry = 3;
13 |
14 | //String Clientid = getChipId(false);
15 |
16 | while (!MQTT_Client.connected()) {
17 |
18 | if ( MQTT_Client.connect( getChipId(false).c_str(), Mqtt_Username, Mqtt_Password) )
19 | {
20 | //connected, so subscribe to inTopic (not for thingspeak)
21 | if(Mqtt_Format != 5 ) {
22 | String clientid = getChipId(false) + "/in";
23 | if( MQTT_Client.subscribe ( clientid.c_str() ) ) {
24 | //if( MQTT_Client.subscribe ( Mqtt_inTopic ) ) {
25 | //if(diagNose) ws.textAll("subscribed to " + String(Mqtt_inTopic ));
26 | consoleOut("subscribed to " + clientid);
27 | }
28 | }
29 | consoleOut(F("mqtt connected"));
30 | Update_Log(3, "connected");
31 |
32 | return true;
33 |
34 | } else {
35 | //String term = "connection failed state: " + String(MQTT_Client.state());
36 | Update_Log(3, "failed");
37 | if (!--retry) break; // stop when tried 3 times
38 | delay(500);
39 | }
40 | }
41 | // if we are here , no connection was made.
42 |
43 | consoleOut(F("mqtt connection failed"));
44 | return false;
45 | }
46 |
47 | // *************************************************************************
48 | // process received mqtt
49 | // *************************************************************************
50 |
51 | void MQTT_Receive_Callback(char *topic, byte *payload, unsigned int length)
52 | {
53 |
54 | // String Payload = ""; // convert the payload to a String...
55 | // for (int i = 0; i < length; i++)
56 | // {
57 | // Payload += (char)payload[i]; // convert to char, needed???
58 | // }
59 |
60 | // ws.textAll("mqtt received " + Payload);
61 |
62 | JsonDocument doc; // We use json library to parse the payload
63 | // The function deserializeJson() parses a JSON input and puts the result in a JsonDocument.
64 | // DeserializationError error = deserializeJson(doc, Payload); // Deserialize the JSON document
65 | DeserializationError error = deserializeJson(doc, payload); // Deserialize the JSON document
66 | if (error) // Test if parsing succeeds.
67 | {
68 | consoleOut("mqtt no valid json ");
69 | return;
70 | }
71 | consoleOut("Deserialized JSON:");
72 | serializeJson(doc, Serial); // Print in one line
73 | Serial.println();
74 | // We check the kind of command format received with MQTT
75 | // if( doc["throttle"] != 0 )
76 | //if(doc.containsKey("throttle"))
77 | if (!doc["throttle"].isNull())
78 | {
79 | int Invert = doc["throttle"].as();
80 | int throtVal = doc["val"].as();
81 | String term = "mqtt got message {\"throttle\":" + String(Invert) + ",\"val\":" + String(throtVal) + "}";
82 | consoleOut(term);
83 | if(Invert > inverterCount || Invert < 0 || throtVal > 700 || throtVal < 20 )
84 | {
85 | consoleOut("invalid value(s), skipping");
86 | return;
87 | }
88 | // write the desired throtval
89 | desiredThrottle[Invert] = throtVal;
90 | //Inv_Prop[invert].maxPower = throtVal;
91 | actionFlag = 240 + Invert;
92 | }
93 |
94 | if (!doc["poll"].isNull())
95 | {
96 | //now we have a payload like {"poll",1}
97 | int inv = doc["poll"].as();
98 | consoleOut( "got message {\"poll\":" + String(inv) + "}" );
99 |
100 | if( !Polling && dayTime )
101 | {
102 |
103 | //ws.textAll( "found {\"poll\" " + String(inv) + "}\"" );
104 |
105 | iKeuze = inv;
106 | if(iKeuze == 99) {
107 | actionFlag = 48; // takes care for the polling of all inverters
108 | return;
109 | }
110 |
111 | if ( iKeuze < inverterCount )
112 | {
113 | actionFlag = 220+inv; // takes care for the polling
114 | return;
115 | } else {
116 | consoleOut("mqtt error no inv " + String(iKeuze));
117 | return;
118 | }
119 | }
120 | else
121 | {
122 | consoleOut("autopolling set or nightTime, skipping");
123 | }
124 | consoleOut("nothing familiair found in mqtt");
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/MQTT_CONFIG.ino:
--------------------------------------------------------------------------------
1 | const char MQTTCONFIG[] PROGMEM = R"=====(
2 |
3 |
8 |
9 |
14 |
MOSQUITTO CONFIGURATION
15 |
36 |
37 |
38 |
39 | )=====";
40 | //test
41 |
42 | void zendPageMQTTconfig(AsyncWebServerRequest *request) {
43 | //DebugPrintln("we are at zendPageMQTTconfig");
44 | //webPage = FPSTR(HTML_HEAD);
45 | //webPage.replace("tieTel", swname );
46 | String webPage;
47 | webPage = FPSTR(HTML_HEAD);
48 | webPage += FPSTR(MQTTCONFIG);
49 |
50 | //altijd de mqtt gegevens terugzetten
51 | String Mqtt_inTopic=getChipId(false) + "/in";
52 | webPage.replace("{mqttAdres}", String(Mqtt_Broker) );
53 | webPage.replace("{mqttPort}", String(Mqtt_Port) );
54 | //webPage.replace("{mqttinTopic}", String(Mqtt_inTopic) );
55 | webPage.replace("{mqttoutTopic}", String(Mqtt_outTopic) );
56 | webPage.replace("{mqttinTopic}", String(Mqtt_inTopic) );
57 | webPage.replace("{mqtu}", String(Mqtt_Username) );
58 | webPage.replace("{mqtp}", String(Mqtt_Password) );
59 | webPage.replace("{idx}" , String(Mqtt_stateIDX) );
60 |
61 | //String Mqtt_Clientid = getChipid(false);
62 | webPage.replace("{mqtc}" , getChipId(false));
63 | switch (Mqtt_Format) {
64 | case 0:
65 | webPage.replace("fm_0", "selected");
66 | break;
67 | case 1:
68 | webPage.replace("fm_1", "selected");
69 | break;
70 | case 2:
71 | webPage.replace("fm_2", "selected");
72 | break;
73 | case 3:
74 | webPage.replace("fm_3", "selected");
75 | break;
76 | case 4:
77 | webPage.replace("fm_4", "selected");
78 | break;
79 | case 5:
80 | webPage.replace("fm_5", "selected");
81 | break;
82 | }
83 | request->send(200, "text/html", webPage);
84 | webPage="";
85 | }
86 |
87 | //void handleMQTTconfig(AsyncWebServerRequest *request) {
88 | // //collect serverarguments
89 | // strcpy( Mqtt_Broker , request->getParam("mqtAdres") ->value().c_str() );
90 | // strcpy( Mqtt_Port , request->getParam("mqtPort") ->value().c_str() );
91 | // strcpy( Mqtt_outTopic, request->getParam("mqtoutTopic")->value().c_str() );
92 | // strcpy( Mqtt_Username, request->getParam("mqtUser") ->value().c_str() );
93 | // strcpy( Mqtt_Password, request->getParam("mqtPas") ->value().c_str() );
94 | // strcpy( Mqtt_Clientid, request->getParam("mqtCi") ->value().c_str() );
95 | // Mqtt_stateIDX = request->arg("mqidx").toInt(); //values are 0 1 2
96 | // Mqtt_Format = request->arg("fm").toInt(); //values are 0 1 2 3 4 5
97 | //
98 | // //DebugPrintln("saved mqttconfig");
99 | // mqttConfigsave(); //
100 | // actionFlag=24; // reconnect with these settings
101 | //
102 | //}
103 |
--------------------------------------------------------------------------------
/OTA.H:
--------------------------------------------------------------------------------
1 | const char otaIndex[] PROGMEM = R"=====(
2 |
3 |
4 |
9 |
10 |
16 |
17 |
18 | ESP32 ECU FIRMWARE UPDATE
19 | if the upload was successful the reboot button will appear.
20 |
24 | progress: 0%
25 | REBOOT
26 |
27 | CANCEL
28 |
29 |
59 |
60 | )=====";
61 |
62 | ////void esp32ota() {
63 | //
64 | //
65 | ////WebServer server(80);
66 | //
67 | ///*
68 | // * Login page
69 | // */
70 | //
71 | ////const char* loginIndex =
72 | //// ""
99 | ////"";
112 | //
113 | ///*
114 | // * Server Index Page
115 | // */
116 | //
117 | //
118 | //
119 | /////*
120 | //// * setup function
121 | //// */
122 | ////void setup(void) {
123 | //// Serial.begin(115200);
124 | ////
125 | //// // Connect to WiFi network
126 | //// WiFi.begin(ssid, password);
127 | //// Serial.println("");
128 | ////
129 | //// // Wait for connection
130 | //// while (WiFi.status() != WL_CONNECTED) {
131 | //// delay(500);
132 | //// Serial.print(".");
133 | //// }
134 | //// Serial.println("");
135 | //// Serial.print("Connected to ");
136 | //// Serial.println(ssid);
137 | //// Serial.print("IP address: ");
138 | //// Serial.println(WiFi.localIP());
139 | ////
140 | //// /*use mdns for host name resolution*/
141 | //// if (!MDNS.begin(host)) { //http://esp32.local
142 | //// Serial.println("Error setting up MDNS responder!");
143 | //// while (1) {
144 | //// delay(1000);
145 | //// }
146 | //// }
147 | //// Serial.println("mDNS responder started");
148 | //// /*return index page which is stored in serverIndex */
149 | //// server.on("/", HTTP_GET, []() {
150 | //// server.sendHeader("Connection", "close");
151 | //// server.send(200, "text/html", loginIndex);
152 | //// });
153 | //// server.on("/serverIndex", HTTP_GET, []() {
154 | //// server.sendHeader("Connection", "close");
155 | //// server.send(200, "text/html", serverIndex);
156 | //// });
157 | //// /*handling uploading firmware file */
158 | //// server.on("/update", HTTP_POST, []() {
159 | //// server.sendHeader("Connection", "close");
160 | //// server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
161 | //// ESP.restart();
162 | //// }, []() {
163 | //// HTTPUpload& upload = server.upload();
164 | //// if (upload.status == UPLOAD_FILE_START) {
165 | //// Serial.printf("Update: %s\n", upload.filename.c_str());
166 | //// if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
167 | //// Update.printError(Serial);
168 | //// }
169 | //// } else if (upload.status == UPLOAD_FILE_WRITE) {
170 | //// /* flashing firmware to ESP*/
171 | //// if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
172 | //// Update.printError(Serial);
173 | //// }
174 | //// } else if (upload.status == UPLOAD_FILE_END) {
175 | //// if (Update.end(true)) { //true to set the size to the current progress
176 | //// Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
177 | //// } else {
178 | //// Update.printError(Serial);
179 | //// }
180 | //// }
181 | //// });
182 | //// server.begin();
183 | ////}
184 | //
185 | ////void otaloop(void) {
186 | //// server.handleClient();
187 | //// delay(1);
188 | ////}
189 |
--------------------------------------------------------------------------------
/OTA.h:
--------------------------------------------------------------------------------
1 | const char otaIndex[] PROGMEM = R"=====(
2 |
3 |
4 |
9 |
10 |
16 |
17 |
18 | ESP32 ECU FIRMWARE UPDATE
19 | if the upload was successful the reboot button will appear.
20 |
24 | progress: 0%
25 | REBOOT
26 |
27 | CANCEL
28 |
29 |
59 |
60 | )=====";
61 |
62 | ////void esp32ota() {
63 | //
64 | //
65 | ////WebServer server(80);
66 | //
67 | ///*
68 | // * Login page
69 | // */
70 | //
71 | ////const char* loginIndex =
72 | //// ""
99 | ////"";
112 | //
113 | ///*
114 | // * Server Index Page
115 | // */
116 | //
117 | //
118 | //
119 | /////*
120 | //// * setup function
121 | //// */
122 | ////void setup(void) {
123 | //// Serial.begin(115200);
124 | ////
125 | //// // Connect to WiFi network
126 | //// WiFi.begin(ssid, password);
127 | //// Serial.println("");
128 | ////
129 | //// // Wait for connection
130 | //// while (WiFi.status() != WL_CONNECTED) {
131 | //// delay(500);
132 | //// Serial.print(".");
133 | //// }
134 | //// Serial.println("");
135 | //// Serial.print("Connected to ");
136 | //// Serial.println(ssid);
137 | //// Serial.print("IP address: ");
138 | //// Serial.println(WiFi.localIP());
139 | ////
140 | //// /*use mdns for host name resolution*/
141 | //// if (!MDNS.begin(host)) { //http://esp32.local
142 | //// Serial.println("Error setting up MDNS responder!");
143 | //// while (1) {
144 | //// delay(1000);
145 | //// }
146 | //// }
147 | //// Serial.println("mDNS responder started");
148 | //// /*return index page which is stored in serverIndex */
149 | //// server.on("/", HTTP_GET, []() {
150 | //// server.sendHeader("Connection", "close");
151 | //// server.send(200, "text/html", loginIndex);
152 | //// });
153 | //// server.on("/serverIndex", HTTP_GET, []() {
154 | //// server.sendHeader("Connection", "close");
155 | //// server.send(200, "text/html", serverIndex);
156 | //// });
157 | //// /*handling uploading firmware file */
158 | //// server.on("/update", HTTP_POST, []() {
159 | //// server.sendHeader("Connection", "close");
160 | //// server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
161 | //// ESP.restart();
162 | //// }, []() {
163 | //// HTTPUpload& upload = server.upload();
164 | //// if (upload.status == UPLOAD_FILE_START) {
165 | //// Serial.printf("Update: %s\n", upload.filename.c_str());
166 | //// if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
167 | //// Update.printError(Serial);
168 | //// }
169 | //// } else if (upload.status == UPLOAD_FILE_WRITE) {
170 | //// /* flashing firmware to ESP*/
171 | //// if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
172 | //// Update.printError(Serial);
173 | //// }
174 | //// } else if (upload.status == UPLOAD_FILE_END) {
175 | //// if (Update.end(true)) { //true to set the size to the current progress
176 | //// Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
177 | //// } else {
178 | //// Update.printError(Serial);
179 | //// }
180 | //// }
181 | //// });
182 | //// server.begin();
183 | ////}
184 | //
185 | ////void otaloop(void) {
186 | //// server.handleClient();
187 | //// delay(1);
188 | ////}
189 |
--------------------------------------------------------------------------------
/PORTAL_HTML.h:
--------------------------------------------------------------------------------
1 |
2 | /* the portal consists of 2 pages starting with portal homepage
3 | * this page has 3 buttons that are hidden or shown when applicable
4 | * it depends om event 101 or 100 how this page looks
5 | * the 2th page is the wifiform, when filled in and saved, we get the
6 | * 1st page, the ok buttom is shown
7 | * when we click it we return to the 1st page with the close button shown
8 | * and the ip info
9 | * after clicking the close button, we get the last page, the confirmation that
10 | * a restart is taking place.
11 | *
12 | */
13 |
14 | const char PORTAL_HOMEPAGE[] PROGMEM = R"=====(
15 |
20 |
25 |
26 | HANSIART WIFI CONFIG
27 |
28 | device mac adres : {ma}
29 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | )=====";
44 |
45 |
46 |
47 |
48 |
49 | // below here was tested allright
50 |
51 | // ******************************************************************************************
52 | // THE WIFI FORM
53 | // ******************************************************************************************
54 | const char PORTAL_WIFIFORM[] PROGMEM = R"=====(
55 |
56 |
63 |
70 |
71 |
72 |
73 |
trying to connect..
74 |
75 |
76 | HANSIART CONFIG PORTAL
77 |
78 |
79 |
80 | aplijst
81 |
82 |
92 |