@@ -115,6 +115,7 @@ uint16_t GridRelayMaxSumMains = GRID_RELAY_MAX_SUMMAINS; // M
115115 // When the relay opens its contacts, power will be reduced to 4.2kW
116116 // The relay is only allowed on the Master
117117bool GridRelayOpen = false ; // The read status of the relay
118+ bool CustomButton = false ; // The status of the custom button
118119uint16_t MaxCurrent = MAX_CURRENT; // Max Charge current (A)
119120uint16_t MinCurrent = MIN_CURRENT; // Minimal current the EV is happy with (A)
120121uint8_t Mode = MODE; // EVSE mode (0:Normal / 1:Smart / 2:Solar)
@@ -135,7 +136,8 @@ uint16_t MaxCircuit = MAX_CIRCUIT; // M
135136uint8_t Config = CONFIG; // Configuration (0:Socket / 1:Fixed Cable)
136137uint8_t LoadBl = LOADBL; // Load Balance Setting (0:Disable / 1:Master / 2-8:Node)
137138uint8_t Switch = SWITCH; // External Switch (0:Disable / 1:Access B / 2:Access S /
138- // 3:Smart-Solar B / 4:Smart-Solar S / 5: Grid Relay)
139+ // 3:Smart-Solar B / 4:Smart-Solar S / 5: Grid Relay
140+ // 6:Custom B / 7:Custom S)
139141 // B=momentary push <B>utton, S=toggle <S>witch
140142uint8_t RCmon = RC_MON; // Residual Current Monitor (0:Disable / 1:Enable)
141143uint8_t AutoUpdate = AUTOUPDATE; // Automatic Firmware Update (0:Disable / 1:Enable)
@@ -261,6 +263,7 @@ uint8_t ColorOff[3] = {0, 0, 0}; // off
261263uint8_t ColorNormal[3 ] = {0 , 255 , 0 }; // Green
262264uint8_t ColorSmart[3 ] = {0 , 255 , 0 }; // Green
263265uint8_t ColorSolar[3 ] = {255 , 170 , 0 }; // Orange
266+ uint8_t ColorCustom[3 ] = {0 , 0 , 255 }; // Blue
264267
265268// #define FW_UPDATE_DELAY 30 //DINGO TODO // time between detection of new version and actual update in seconds
266269#define FW_UPDATE_DELAY 3600 // time between detection of new version and actual update in seconds
@@ -415,14 +418,18 @@ void BlinkLed(void * parameter) {
415418 if (LedCount > 230 ) LedPwm = WAITING_LED_BRIGHTNESS; // LED 10% of time on, full brightness
416419 else LedPwm = 0 ;
417420
418- if (Mode == MODE_SOLAR) { // Orange for Solar, unless configured otherwise
421+ if (CustomButton) { // Blue for Custom, unless configured otherwise
422+ RedPwm = LedPwm * ColorCustom[0 ] / 255 ;
423+ GreenPwm = LedPwm * ColorCustom[1 ] / 255 ;
424+ BluePwm = LedPwm * ColorCustom[2 ] / 255 ;
425+ } else if (Mode == MODE_SOLAR) { // Orange for Solar, unless configured otherwise
419426 RedPwm = LedPwm * ColorSolar[0 ] / 255 ;
420427 GreenPwm = LedPwm * ColorSolar[1 ] / 255 ;
421428 BluePwm = LedPwm * ColorSolar[2 ] / 255 ;
422429 } else if (Mode == MODE_SMART) { // Green for Smart, unless configured otherwise
423- RedPwm = LedPwm * ColorNormal [0 ] / 255 ;
424- GreenPwm = LedPwm * ColorNormal [1 ] / 255 ;
425- BluePwm = LedPwm * ColorNormal [2 ] / 255 ;
430+ RedPwm = LedPwm * ColorSmart [0 ] / 255 ;
431+ GreenPwm = LedPwm * ColorSmart [1 ] / 255 ;
432+ BluePwm = LedPwm * ColorSmart [2 ] / 255 ;
426433 } else { // Green for Normal, unless configured otherwise
427434 RedPwm = LedPwm * ColorNormal[0 ] / 255 ;
428435 GreenPwm = LedPwm * ColorNormal[1 ] / 255 ;
@@ -466,6 +473,10 @@ void BlinkLed(void * parameter) {
466473 GreenPwm = 0 ;
467474 BluePwm = 0 ;
468475#endif // ENABLE_OCPP
476+ } else if (Access_bit == 0 && CustomButton) {
477+ RedPwm = ColorCustom[0 ];
478+ GreenPwm = ColorCustom[1 ];
479+ BluePwm = ColorCustom[2 ];
469480 } else if (Access_bit == 0 || State == STATE_MODEM_DENIED) {
470481 RedPwm = ColorOff[0 ];
471482 GreenPwm = ColorOff[1 ];
@@ -485,14 +496,18 @@ void BlinkLed(void * parameter) {
485496 LedPwm = ease8InOutQuad (triwave8 (LedCount)); // pre calculate new LedPwm value
486497 }
487498
488- if (Mode == MODE_SOLAR) { // Orange for Solar, unless configured otherwise
499+ if (CustomButton) { // Blue for Custom, unless configured otherwise
500+ RedPwm = LedPwm * ColorCustom[0 ] / 255 ;
501+ GreenPwm = LedPwm * ColorCustom[1 ] / 255 ;
502+ BluePwm = LedPwm * ColorCustom[2 ] / 255 ;
503+ } else if (Mode == MODE_SOLAR) { // Orange for Solar, unless configured otherwise
489504 RedPwm = LedPwm * ColorSolar[0 ] / 255 ;
490505 GreenPwm = LedPwm * ColorSolar[1 ] / 255 ;
491506 BluePwm = LedPwm * ColorSolar[2 ] / 255 ;
492507 } else if (Mode == MODE_SMART) { // Green for Smart, unless configured otherwise
493- RedPwm = LedPwm * ColorNormal [0 ] / 255 ;
494- GreenPwm = LedPwm * ColorNormal [1 ] / 255 ;
495- BluePwm = LedPwm * ColorNormal [2 ] / 255 ;
508+ RedPwm = LedPwm * ColorSmart [0 ] / 255 ;
509+ GreenPwm = LedPwm * ColorSmart [1 ] / 255 ;
510+ BluePwm = LedPwm * ColorSmart [2 ] / 255 ;
496511 } else { // Green for Normal, unless configured otherwise
497512 RedPwm = LedPwm * ColorNormal[0 ] / 255 ;
498513 GreenPwm = LedPwm * ColorNormal[1 ] / 255 ;
@@ -2090,6 +2105,12 @@ void CheckSwitch(bool force = false)
20902105 case 5 : // Grid relay
20912106 GridRelayOpen = false ;
20922107 break ;
2108+ case 6 : // Custom button B
2109+ CustomButton = !CustomButton;
2110+ break ;
2111+ case 7 : // Custom button S
2112+ CustomButton = true ;
2113+ break ;
20932114 default :
20942115 if (State == STATE_C) { // Menu option Access is set to Disabled
20952116 setState (STATE_C1);
@@ -2134,6 +2155,11 @@ void CheckSwitch(bool force = false)
21342155 case 5 : // Grid relay
21352156 GridRelayOpen = true ;
21362157 break ;
2158+ case 6 : // Custom button B
2159+ break ;
2160+ case 7 : // Custom button S
2161+ CustomButton = false ;
2162+ break ;
21372163 default :
21382164 break ;
21392165 }
@@ -2772,6 +2798,12 @@ void mqtt_receive_callback(const String topic, const String payload) {
27722798 OverrideCurrent = 0 ;
27732799 setMode (MODE_SMART);
27742800 }
2801+ } else if (topic == MQTTprefix + " /Set/CustomButton" ) {
2802+ if (payload == " On" ) {
2803+ CustomButton = true ;
2804+ } else {
2805+ CustomButton = false ;
2806+ }
27752807 } else if (topic == MQTTprefix + " /Set/CurrentOverride" ) {
27762808 uint16_t RequestedCurrent = payload.toInt ();
27772809 if (RequestedCurrent == 0 ) {
@@ -2862,7 +2894,7 @@ void mqtt_receive_callback(const String topic, const String payload) {
28622894 }
28632895 } else if (topic == MQTTprefix + " /Set/ColorOff" ) {
28642896 int32_t R, G, B;
2865- int n = sscanf (payload.c_str (), " %d:%d: %d" , &R, &G, &B);
2897+ int n = sscanf (payload.c_str (), " %d,%d, %d" , &R, &G, &B);
28662898
28672899 // R,G,B is between 0..255
28682900 if (n == 3 && (R >= 0 && R < 256 ) && (G >= 0 && G < 256 ) && (B >= 0 && B < 256 )) {
@@ -2872,7 +2904,7 @@ void mqtt_receive_callback(const String topic, const String payload) {
28722904 }
28732905 } else if (topic == MQTTprefix + " /Set/ColorNormal" ) {
28742906 int32_t R, G, B;
2875- int n = sscanf (payload.c_str (), " %d:%d: %d" , &R, &G, &B);
2907+ int n = sscanf (payload.c_str (), " %d,%d, %d" , &R, &G, &B);
28762908
28772909 // R,G,B is between 0..255
28782910 if (n == 3 && (R >= 0 && R < 256 ) && (G >= 0 && G < 256 ) && (B >= 0 && B < 256 )) {
@@ -2882,7 +2914,7 @@ void mqtt_receive_callback(const String topic, const String payload) {
28822914 }
28832915 } else if (topic == MQTTprefix + " /Set/ColorSmart" ) {
28842916 int32_t R, G, B;
2885- int n = sscanf (payload.c_str (), " %d:%d: %d" , &R, &G, &B);
2917+ int n = sscanf (payload.c_str (), " %d,%d, %d" , &R, &G, &B);
28862918
28872919 // R,G,B is between 0..255
28882920 if (n == 3 && (R >= 0 && R < 256 ) && (G >= 0 && G < 256 ) && (B >= 0 && B < 256 )) {
@@ -2892,14 +2924,24 @@ void mqtt_receive_callback(const String topic, const String payload) {
28922924 }
28932925 } else if (topic == MQTTprefix + " /Set/ColorSolar" ) {
28942926 int32_t R, G, B;
2895- int n = sscanf (payload.c_str (), " %d:%d: %d" , &R, &G, &B);
2927+ int n = sscanf (payload.c_str (), " %d,%d, %d" , &R, &G, &B);
28962928
28972929 // R,G,B is between 0..255
28982930 if (n == 3 && (R >= 0 && R < 256 ) && (G >= 0 && G < 256 ) && (B >= 0 && B < 256 )) {
28992931 ColorSolar[0 ] = R;
29002932 ColorSolar[1 ] = G;
29012933 ColorSolar[2 ] = B;
29022934 }
2935+ } else if (topic == MQTTprefix + " /Set/ColorCustom" ) {
2936+ int32_t R, G, B;
2937+ int n = sscanf (payload.c_str (), " %d,%d,%d" , &R, &G, &B);
2938+
2939+ // R,G,B is between 0..255
2940+ if (n == 3 && (R >= 0 && R < 256 ) && (G >= 0 && G < 256 ) && (B >= 0 && B < 256 )) {
2941+ ColorCustom[0 ] = R;
2942+ ColorCustom[1 ] = G;
2943+ ColorCustom[2 ] = B;
2944+ }
29032945 }
29042946
29052947 // Make sure MQTT updates directly to prevent debounces
@@ -3041,6 +3083,22 @@ void SetupMQTTClient() {
30413083 announce (" State" , " sensor" );
30423084 announce (" RFID" , " sensor" );
30433085 announce (" RFIDLastRead" , " sensor" );
3086+
3087+ optional_payload = jsna (" state_topic" , String (MQTTprefix + " /LEDColorOff" )) + jsna (" command_topic" , String (MQTTprefix + " /Set/ColorOff" ));
3088+ announce (" LED Color Off" , " text" );
3089+ optional_payload = jsna (" state_topic" , String (MQTTprefix + " /LEDColorNormal" )) + jsna (" command_topic" , String (MQTTprefix + " /Set/ColorNormal" ));
3090+ announce (" LED Color Normal" , " text" );
3091+ optional_payload = jsna (" state_topic" , String (MQTTprefix + " /LEDColorSmart" )) + jsna (" command_topic" , String (MQTTprefix + " /Set/ColorSmart" ));
3092+ announce (" LED Color Smart" , " text" );
3093+ optional_payload = jsna (" state_topic" , String (MQTTprefix + " /LEDColorSolar" )) + jsna (" command_topic" , String (MQTTprefix + " /Set/ColorSolar" ));
3094+ announce (" LED Color Solar" , " text" );
3095+ optional_payload = jsna (" state_topic" , String (MQTTprefix + " /LEDColorCustom" )) + jsna (" command_topic" , String (MQTTprefix + " /Set/ColorCustom" ));
3096+ announce (" LED Color Custom" , " text" );
3097+
3098+ optional_payload = jsna (" state_topic" , String (MQTTprefix + " /CustomButton" )) + jsna (" command_topic" , String (MQTTprefix + " /Set/CustomButton" ));
3099+ optional_payload += String (R"( , "options" : ["On", "Off"])" );
3100+ announce (" Custom Button" , " select" );
3101+
30443102#if ENABLE_OCPP
30453103 announce (" OCPP" , " sensor" );
30463104 announce (" OCPPConnection" , " sensor" );
@@ -3097,6 +3155,7 @@ void mqttPublishData() {
30973155 MQTTclient.publish (MQTTprefix + " /ESPTemp" , TempEVSE, false , 0 );
30983156 MQTTclient.publish (MQTTprefix + " /Mode" , Access_bit == 0 ? " Off" : Mode > 3 ? " N/A" : StrMode[Mode], true , 0 );
30993157 MQTTclient.publish (MQTTprefix + " /MaxCurrent" , MaxCurrent * 10 , true , 0 );
3158+ MQTTclient.publish (MQTTprefix + " /CustomButton" , CustomButton ? " On" : " Off" , false , 0 );
31003159 MQTTclient.publish (MQTTprefix + " /ChargeCurrent" , Balanced[0 ], true , 0 );
31013160 MQTTclient.publish (MQTTprefix + " /ChargeCurrentOverride" , OverrideCurrent, true , 0 );
31023161 MQTTclient.publish (MQTTprefix + " /Access" , StrAccessBit[Access_bit], true , 0 );
@@ -3140,6 +3199,7 @@ void mqttPublishData() {
31403199 MQTTclient.publish (MQTTprefix + " /LEDColorNormal" , String (ColorNormal[0 ])+" ," +String (ColorNormal[1 ])+" ," +String (ColorNormal[2 ]), true , 0 );
31413200 MQTTclient.publish (MQTTprefix + " /LEDColorSmart" , String (ColorSmart[0 ])+" ," +String (ColorSmart[1 ])+" ," +String (ColorSmart[2 ]), true , 0 );
31423201 MQTTclient.publish (MQTTprefix + " /LEDColorSolar" , String (ColorSolar[0 ])+" ," +String (ColorSolar[1 ])+" ," +String (ColorSolar[2 ]), true , 0 );
3202+ MQTTclient.publish (MQTTprefix + " /LEDColorCustom" , String (ColorCustom[0 ])+" ," +String (ColorCustom[1 ])+" ," +String (ColorCustom[2 ]), true , 0 );
31433203}
31443204#endif
31453205
@@ -4782,6 +4842,7 @@ static void fn_http_server(struct mg_connection *c, int ev, void *ev_data) {
47824842 doc[" evse" ][" mode" ] = Mode;
47834843 doc[" evse" ][" loadbl" ] = LoadBl;
47844844 doc[" evse" ][" pwm" ] = CurrentPWM;
4845+ doc[" evse" ][" custombutton" ] = CustomButton;
47854846 doc[" evse" ][" solar_stop_timer" ] = SolarStopTimer;
47864847 doc[" evse" ][" state" ] = evstate;
47874848 doc[" evse" ][" state_id" ] = State;
@@ -4905,6 +4966,9 @@ static void fn_http_server(struct mg_connection *c, int ev, void *ev_data) {
49054966 doc[" color" ][" solar" ][" R" ] = ColorSolar[0 ];
49064967 doc[" color" ][" solar" ][" G" ] = ColorSolar[1 ];
49074968 doc[" color" ][" solar" ][" B" ] = ColorSolar[2 ];
4969+ doc[" color" ][" custom" ][" R" ] = ColorCustom[0 ];
4970+ doc[" color" ][" custom" ][" G" ] = ColorCustom[1 ];
4971+ doc[" color" ][" custom" ][" B" ] = ColorCustom[2 ];
49084972
49094973 String json;
49104974 serializeJson (doc, json);
@@ -4956,6 +5020,11 @@ static void fn_http_server(struct mg_connection *c, int ev, void *ev_data) {
49565020 doc[" disable_override_current" ] = " OK" ;
49575021 }
49585022
5023+ if (request->hasParam (" custombutton" )) {
5024+ CustomButton = request->getParam (" custombutton" )->value ().toInt () > 0 ;
5025+ doc[" custombutton" ] = CustomButton;
5026+ }
5027+
49595028 if (request->hasParam (" mode" )) {
49605029 String mode = request->getParam (" mode" )->value ();
49615030
@@ -5325,6 +5394,29 @@ static void fn_http_server(struct mg_connection *c, int ev, void *ev_data) {
53255394 serializeJson (doc, json);
53265395 mg_http_reply (c, 200 , " Content-Type: application/json\r\n " , " %s\r\n " , json.c_str ()); // Yes. Respond JSON
53275396
5397+ } else if (mg_http_match_uri (hm, " /color_custom" ) && !memcmp (" POST" , hm->method .buf , hm->method .len )) {
5398+ DynamicJsonDocument doc (200 );
5399+
5400+ if (request->hasParam (" R" ) && request->hasParam (" G" ) && request->hasParam (" B" )) {
5401+ int32_t R = request->getParam (" R" )->value ().toInt ();
5402+ int32_t G = request->getParam (" G" )->value ().toInt ();
5403+ int32_t B = request->getParam (" B" )->value ().toInt ();
5404+
5405+ // R,G,B is between 0..255
5406+ if ((R >= 0 && R < 256 ) && (G >= 0 && G < 256 ) && (B >= 0 && B < 256 )) {
5407+ ColorCustom[0 ] = R;
5408+ ColorCustom[1 ] = G;
5409+ ColorCustom[2 ] = B;
5410+ doc[" color" ][" custom" ][" R" ] = ColorCustom[0 ];
5411+ doc[" color" ][" custom" ][" G" ] = ColorCustom[1 ];
5412+ doc[" color" ][" custom" ][" B" ] = ColorCustom[2 ];
5413+ }
5414+ }
5415+
5416+ String json;
5417+ serializeJson (doc, json);
5418+ mg_http_reply (c, 200 , " Content-Type: application/json\r\n " , " %s\r\n " , json.c_str ()); // Yes. Respond JSON
5419+
53285420 } else if (mg_http_match_uri (hm, " /currents" ) && !memcmp (" POST" , hm->method .buf , hm->method .len )) {
53295421 DynamicJsonDocument doc (200 );
53305422
0 commit comments