|
@@ -0,0 +1,540 @@
|
|
|
|
+/*
|
|
|
|
+ * WebSocketClient.ino
|
|
|
|
+ *
|
|
|
|
+ * Created on: 24.05.2015
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+//#include <Arduino.h>
|
|
|
|
+#include <M5Stack.h>
|
|
|
|
+#include <ArduinoJson.h>
|
|
|
|
+#include <WiFi.h>
|
|
|
|
+#include <WiFiMulti.h>
|
|
|
|
+#include <WiFiClientSecure.h>
|
|
|
|
+
|
|
|
|
+#include <HttpClient.h>
|
|
|
|
+
|
|
|
|
+#include <WebSocketsClient.h>
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+WiFiMulti WiFiMulti;
|
|
|
|
+WebSocketsClient webSocket;
|
|
|
|
+
|
|
|
|
+HttpClient htclient;
|
|
|
|
+
|
|
|
|
+bool localTesting = true;
|
|
|
|
+bool genRandomVals = false;
|
|
|
|
+
|
|
|
|
+const char* OVMSUSER = "admin";
|
|
|
|
+const char* OVMSPASS = "OVMSP455w0rd"; // Change this to your password
|
|
|
|
+
|
|
|
|
+const int LCDBrightnessSteps[] = {60, 120, 250};
|
|
|
|
+int LCDBrightnessStep = 0;
|
|
|
|
+
|
|
|
|
+const int heightBarGraphSOC = 72;
|
|
|
|
+const int widthBarGraphSOC = 300;
|
|
|
|
+const int leftBarGraphSOC = (320-widthBarGraphSOC-4)/2;
|
|
|
|
+const int topBarGraphSOC = 0;
|
|
|
|
+const int SOCtextSize = 7;
|
|
|
|
+const int SOCtextWidth = M5.Lcd.textWidth("99%")*SOCtextSize;
|
|
|
|
+
|
|
|
|
+const int heightBarGraphPWR = 32;
|
|
|
|
+const int widthBarGraphPWR = 220;
|
|
|
|
+const int PWRtextSize = 3;
|
|
|
|
+const int PWRtextWidth = M5.Lcd.textWidth("100kW")*PWRtextSize;
|
|
|
|
+const int leftBarGraphPWR = (320-widthBarGraphPWR-4);
|
|
|
|
+const int topBarGraphPWR = 80;
|
|
|
|
+
|
|
|
|
+const int topTextLineRange = topBarGraphPWR + heightBarGraphPWR + 16;
|
|
|
|
+const int topTextLineConsumption = topTextLineRange + 32;
|
|
|
|
+const int topTextLineTemps = topTextLineConsumption + 32;
|
|
|
|
+
|
|
|
|
+const float MAXINPOWER = 100;
|
|
|
|
+const float MAXOUTPOWER = 200;
|
|
|
|
+const float MAXRANGEPWR = 300;
|
|
|
|
+
|
|
|
|
+float vbsoc = 90.5;
|
|
|
|
+float vbrangeideal = 402 ;
|
|
|
|
+float vbrangefull = 450 ;
|
|
|
|
+float vetemp = 13 ;
|
|
|
|
+float vbtemp = 15 ;
|
|
|
|
+float xknbinlettemp = 14 ;
|
|
|
|
+float vbpower = 1 ;
|
|
|
|
+float vbconsumption = 160 ;
|
|
|
|
+
|
|
|
|
+const uint16_t DARKERCYAN = 0x0124;
|
|
|
|
+
|
|
|
|
+const size_t jsonCapacity = JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(38) + 910;
|
|
|
|
+DynamicJsonDocument jsonDoc(jsonCapacity);
|
|
|
|
+DeserializationError payloadDecodeError;
|
|
|
|
+uint8_t M5triggerUpdate = 0;
|
|
|
|
+
|
|
|
|
+uint8_t dummyCounter = 0;
|
|
|
|
+
|
|
|
|
+unsigned long prevTimer = millis();
|
|
|
|
+unsigned long displayTimer = millis();
|
|
|
|
+unsigned long spentTimer = 0;
|
|
|
|
+bool slowRefreshTrigger = false;
|
|
|
|
+unsigned long slowRefreshTimer = 0;
|
|
|
|
+unsigned long slowRefreshMax = 5000;
|
|
|
|
+bool mildRefreshTrigger = false;
|
|
|
|
+unsigned long mildRefreshTimer = 0;
|
|
|
|
+unsigned long mildRefreshMax = 2000;
|
|
|
|
+bool fastRefreshTrigger = false;
|
|
|
|
+unsigned long fastRefreshTimer = 0;
|
|
|
|
+unsigned long fastRefreshMax = 100;
|
|
|
|
+
|
|
|
|
+#define USE_SERIAL Serial
|
|
|
|
+
|
|
|
|
+void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
|
|
|
|
+ const uint8_t* src = (const uint8_t*) mem;
|
|
|
|
+ USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
|
|
|
|
+ for(uint32_t i = 0; i < len; i++) {
|
|
|
|
+ if(i % cols == 0) {
|
|
|
|
+ USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
|
|
|
|
+ }
|
|
|
|
+ USE_SERIAL.printf("%02X ", *src);
|
|
|
|
+ src++;
|
|
|
|
+ }
|
|
|
|
+ USE_SERIAL.printf("\n");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void draw_vbsoc(float vbsoc) {
|
|
|
|
+ M5.Lcd.setTextSize(SOCtextSize);
|
|
|
|
+ uint16_t SOCcolor = GREEN;
|
|
|
|
+ uint16_t SOCtextColor = 0x0720; // Slightly Darker Green
|
|
|
|
+ uint16_t BorderColor = WHITE;
|
|
|
|
+ uint16_t BGcolor = 0x2970; //BLUE;
|
|
|
|
+ if(vbsoc<25){ SOCcolor = YELLOW; SOCtextColor = YELLOW; BorderColor = YELLOW; }
|
|
|
|
+ if(vbsoc<10){ SOCcolor = RED; SOCtextColor = RED; BorderColor = RED; BGcolor = MAROON; }
|
|
|
|
+ M5.Lcd.fillRoundRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+6, heightBarGraphSOC+4 , 6, BGcolor);
|
|
|
|
+ //M5.Lcd.fillRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+4, heightBarGraphSOC+4 , BGcolor);
|
|
|
|
+ M5.Lcd.drawRoundRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+4, heightBarGraphSOC+4 , 6, BorderColor);
|
|
|
|
+ M5.Lcd.fillRoundRect(leftBarGraphSOC+2, topBarGraphSOC+2, widthBarGraphSOC*(vbsoc/100), heightBarGraphSOC , 4, SOCcolor);
|
|
|
|
+ if(vbsoc>=50){
|
|
|
|
+ M5.Lcd.setTextColor(BLACK);
|
|
|
|
+ M5.Lcd.setCursor(leftBarGraphSOC+6+3*vbsoc-SOCtextWidth-6, topBarGraphSOC+14);
|
|
|
|
+ M5.Lcd.print(vbsoc,0); M5.Lcd.print('%');
|
|
|
|
+ }else{
|
|
|
|
+ M5.Lcd.setTextColor(SOCtextColor);
|
|
|
|
+ M5.Lcd.setCursor(leftBarGraphSOC+6+3*vbsoc+8, topBarGraphSOC+12);
|
|
|
|
+ M5.Lcd.print(vbsoc,0); M5.Lcd.print('%');
|
|
|
|
+ }
|
|
|
|
+ //M5.Lcd.printf("%*s", 5, vbsoc);
|
|
|
|
+ M5triggerUpdate++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void draw_vbpower(float vbpower) {
|
|
|
|
+ M5.Lcd.setTextSize(PWRtextSize);
|
|
|
|
+ uint16_t PWRcolor;
|
|
|
|
+
|
|
|
|
+ uint16_t BorderColor = LIGHTGREY; //WHITE;
|
|
|
|
+ uint16_t BGcolor = 0x528A;
|
|
|
|
+
|
|
|
|
+ // Draw empty full bar
|
|
|
|
+ M5.Lcd.fillRoundRect(leftBarGraphPWR, topBarGraphPWR, widthBarGraphPWR+6, heightBarGraphPWR+4 , 6, BGcolor);
|
|
|
|
+ //M5.Lcd.fillRect(leftBarGraphSOC, topBarGraphSOC, widthBarGraphSOC+4, heightBarGraphSOC+4 , BGcolor);
|
|
|
|
+ M5.Lcd.drawRoundRect(leftBarGraphPWR, topBarGraphPWR, widthBarGraphPWR+4, heightBarGraphPWR+4 , 6, BorderColor);
|
|
|
|
+ float barOffset;
|
|
|
|
+ float barWidth;
|
|
|
|
+
|
|
|
|
+ if(vbpower>0){
|
|
|
|
+ PWRcolor = YELLOW; if(vbpower>25) PWRcolor = RED;
|
|
|
|
+ barWidth = (widthBarGraphPWR*vbpower)/MAXRANGEPWR;
|
|
|
|
+ // (220*140)/220
|
|
|
|
+ barOffset = (widthBarGraphPWR*(float)MAXINPOWER)/MAXRANGEPWR;
|
|
|
|
+ } else {
|
|
|
|
+ PWRcolor = GREEN;
|
|
|
|
+ barWidth = (widthBarGraphPWR*-vbpower)/MAXRANGEPWR;
|
|
|
|
+ barOffset = (widthBarGraphPWR*((float)MAXINPOWER+vbpower))/MAXRANGEPWR;
|
|
|
|
+ }
|
|
|
|
+ // USE_SERIAL.print(barOffset); USE_SERIAL.print(" "); USE_SERIAL.println(barWidth);
|
|
|
|
+
|
|
|
|
+ // Draw Power Bar
|
|
|
|
+ //M5.Lcd.fillRoundRect(leftBarGraphPWR+2+barOffset, topBarGraphPWR+2, barWidth, heightBarGraphPWR , 4, PWRcolor);
|
|
|
|
+ M5.Lcd.fillRect(leftBarGraphPWR+2+barOffset, topBarGraphPWR+2, barWidth, heightBarGraphPWR, PWRcolor);
|
|
|
|
+
|
|
|
|
+ // Clean text
|
|
|
|
+ M5.Lcd.fillRoundRect(4, topBarGraphPWR, PWRtextWidth, heightBarGraphPWR+4 , 6, BLACK);
|
|
|
|
+
|
|
|
|
+ // Place 0 line
|
|
|
|
+ M5.Lcd.drawLine(
|
|
|
|
+ leftBarGraphPWR+2+(widthBarGraphPWR*(float)MAXINPOWER)/MAXRANGEPWR,
|
|
|
|
+ topBarGraphPWR,
|
|
|
|
+ leftBarGraphPWR+2+(widthBarGraphPWR*(float)MAXINPOWER)/MAXRANGEPWR,
|
|
|
|
+ topBarGraphPWR+heightBarGraphPWR+2,
|
|
|
|
+ BorderColor);
|
|
|
|
+
|
|
|
|
+ M5.Lcd.setCursor(4, topBarGraphPWR+8);
|
|
|
|
+ if(vbpower>0){
|
|
|
|
+ M5.Lcd.setTextColor(RED);
|
|
|
|
+ }else{
|
|
|
|
+ M5.Lcd.setTextColor(GREEN);
|
|
|
|
+ }
|
|
|
|
+ if(vbpower > 0 && vbpower < 10 ) M5.Lcd.print(" ");
|
|
|
|
+ if(vbpower > -10 && vbpower < 100 ) M5.Lcd.print(" ");
|
|
|
|
+
|
|
|
|
+ M5.Lcd.print(vbpower,0); M5.Lcd.print("kW");
|
|
|
|
+ //M5.Lcd.drawFloat(vbpower, 0, 4, topBarGraphPWR+8);
|
|
|
|
+ //M5.Lcd.drawNumber(vbpower, 4, topBarGraphPWR+8);
|
|
|
|
+ //M5.Lcd.print('kW');
|
|
|
|
+ //M5.Lcd.printf("%*s", 5, vbpower);
|
|
|
|
+ M5triggerUpdate++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void draw_vbrange() {
|
|
|
|
+ M5.Lcd.setTextSize(3);
|
|
|
|
+ M5.lcd.fillRect(0, topTextLineRange, 320,32, DARKERCYAN);
|
|
|
|
+ M5.Lcd.setCursor(4, topTextLineRange+4);
|
|
|
|
+ M5.Lcd.setTextColor(LIGHTGREY);
|
|
|
|
+ M5.Lcd.print("range: "); M5.Lcd.print(vbrangeideal,0); M5.Lcd.print("/");
|
|
|
|
+ M5.Lcd.print(vbrangefull,0); M5.Lcd.print(" km");
|
|
|
|
+ M5triggerUpdate++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void draw_vbconsumption() {
|
|
|
|
+ uint16_t textColor = GREEN;
|
|
|
|
+ if(vbconsumption>150) textColor = YELLOW;
|
|
|
|
+ if(vbconsumption>200) textColor = RED;
|
|
|
|
+ M5.Lcd.setTextSize(3);
|
|
|
|
+ M5.lcd.fillRect(0, topTextLineConsumption, 320,32, DARKERCYAN);
|
|
|
|
+ M5.Lcd.setCursor(4, topTextLineConsumption+4);
|
|
|
|
+ M5.Lcd.setTextColor(LIGHTGREY);
|
|
|
|
+ M5.Lcd.print("cons: ");
|
|
|
|
+ M5.Lcd.setTextColor(textColor);
|
|
|
|
+ M5.Lcd.print(vbconsumption,0);
|
|
|
|
+ M5.Lcd.setTextColor(LIGHTGREY);
|
|
|
|
+ M5.Lcd.print(" Wh/km");
|
|
|
|
+ M5triggerUpdate++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void draw_temps() {
|
|
|
|
+ M5.Lcd.setTextSize(2);
|
|
|
|
+ M5.lcd.fillRect(0, topTextLineTemps,320 , 24, DARKERCYAN);
|
|
|
|
+ M5.Lcd.setCursor(4, topTextLineTemps+4);
|
|
|
|
+ M5.Lcd.setTextColor(LIGHTGREY); M5.Lcd.print("temps ext:");
|
|
|
|
+ M5.Lcd.print(vetemp,0);
|
|
|
|
+ M5.Lcd.setTextColor(LIGHTGREY); M5.Lcd.print(" in:");
|
|
|
|
+ M5.Lcd.print(xknbinlettemp,0);
|
|
|
|
+ M5.Lcd.setTextColor(LIGHTGREY); M5.Lcd.print(" bt:");
|
|
|
|
+ M5.Lcd.print(vbtemp,0);
|
|
|
|
+ M5triggerUpdate++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void tickerBox(uint16_t tickerColor) {
|
|
|
|
+ M5.lcd.fillRect(0,240-6 ,4 ,4 , tickerColor);
|
|
|
|
+ M5triggerUpdate++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void changeLCDBrightness() {
|
|
|
|
+ LCDBrightnessStep++;
|
|
|
|
+ if(LCDBrightnessStep==3) LCDBrightnessStep=0;
|
|
|
|
+ M5.Lcd.setBrightness(LCDBrightnessSteps[LCDBrightnessStep]);
|
|
|
|
+ if(localTesting) USE_SERIAL.printf("[LCD] Setting Brightness to : %u (step %u)\n", LCDBrightnessSteps[LCDBrightnessStep], LCDBrightnessStep);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void sendButtonA() {
|
|
|
|
+ sendEvent("event+raise+M5.button.A");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void sendButtonB() {
|
|
|
|
+ sendEvent("event+raise+M5.button.B");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void sendEvent(char* event){
|
|
|
|
+ M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
|
|
|
|
+ M5.Lcd.setCursor(6, 222);
|
|
|
|
+ M5.Lcd.setTextColor(YELLOW);
|
|
|
|
+ M5.Lcd.setTextSize(2);
|
|
|
|
+ M5.Lcd.print(event);
|
|
|
|
+ M5.update();
|
|
|
|
+ M5triggerUpdate = 0;
|
|
|
|
+
|
|
|
|
+ WiFiClient client;
|
|
|
|
+ if (!client.connect("192.168.4.1", 80 )) {
|
|
|
|
+ Serial.println("connection failed");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ String url = "/api/execute?apikey=";
|
|
|
|
+ url += OVMSPASS;
|
|
|
|
+ url += "&command=";
|
|
|
|
+ url += event;
|
|
|
|
+ USE_SERIAL.print("Requesting URL: ");
|
|
|
|
+ USE_SERIAL.println(url);
|
|
|
|
+
|
|
|
|
+ client.print(String("GET ") + url + " HTTP/1.1\r\n" +
|
|
|
|
+ "Host: 192.168.4.1\r\n" +
|
|
|
|
+ "Connection: close\r\n\r\n");
|
|
|
|
+ unsigned long timeout = millis();
|
|
|
|
+ while (client.available() == 0) {
|
|
|
|
+ if (millis() - timeout > 5000) {
|
|
|
|
+ USE_SERIAL.println(">>> Client Timeout !");
|
|
|
|
+ client.stop();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ while(client.available()) {
|
|
|
|
+ String line = client.readStringUntil('\r');
|
|
|
|
+ USE_SERIAL.print(line);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Serial.println();
|
|
|
|
+ Serial.println("closing connection");
|
|
|
|
+
|
|
|
|
+ M5.Lcd.fillRect(0, 220, 320, 32, BLACK);
|
|
|
|
+ M5.update();
|
|
|
|
+ M5triggerUpdate = 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
|
|
|
+
|
|
|
|
+ // Timer control
|
|
|
|
+ prevTimer=displayTimer;
|
|
|
|
+ displayTimer=millis();
|
|
|
|
+ spentTimer=displayTimer-prevTimer;
|
|
|
|
+ slowRefreshTimer+=spentTimer;
|
|
|
|
+ mildRefreshTimer+=spentTimer;
|
|
|
|
+ fastRefreshTimer+=spentTimer;
|
|
|
|
+ slowRefreshTrigger = (slowRefreshTimer>=slowRefreshMax) ? true : false;
|
|
|
|
+ mildRefreshTrigger = (mildRefreshTimer>=mildRefreshMax) ? true : false;
|
|
|
|
+ fastRefreshTrigger = (fastRefreshTimer>=fastRefreshMax) ? true : false;
|
|
|
|
+
|
|
|
|
+ switch(type) {
|
|
|
|
+ case WStype_DISCONNECTED:
|
|
|
|
+ USE_SERIAL.printf("[WSc] Disconnected!\n");
|
|
|
|
+ tickerBox(RED); M5.update();
|
|
|
|
+ break;
|
|
|
|
+ case WStype_CONNECTED:
|
|
|
|
+ tickerBox(YELLOW); M5.update();
|
|
|
|
+ if(localTesting) USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
|
|
|
|
+ // send message to server when Connected
|
|
|
|
+ //webSocket.sendTXT("M5 Stack Connected");
|
|
|
|
+ sendEvent("event+raise+M5.websocket.connected");
|
|
|
|
+ break;
|
|
|
|
+ case WStype_TEXT:
|
|
|
|
+ //if(localTesting) USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
|
|
|
+
|
|
|
|
+ payloadDecodeError = deserializeJson(jsonDoc, payload);
|
|
|
|
+ // Test if parsing succeeds.
|
|
|
|
+ if (payloadDecodeError) {
|
|
|
|
+ USE_SERIAL.printf("deserializeJson() failed: \n");
|
|
|
|
+ USE_SERIAL.println(payloadDecodeError.c_str());
|
|
|
|
+ }else{
|
|
|
|
+ //USE_SERIAL.printf("parseObject() succeeded\n");
|
|
|
|
+ JsonObject metrics = jsonDoc["metrics"];
|
|
|
|
+ if (!metrics.isNull()) {
|
|
|
|
+
|
|
|
|
+ if(localTesting && genRandomVals){
|
|
|
|
+ metrics["v.b.soc"] = random(0,200)/2;
|
|
|
|
+ metrics["v.b.power"] = random(-MAXINPOWER*10,MAXOUTPOWER*10+1)/10;
|
|
|
|
+ metrics["v.b.range.ideal"] = random(360*10,400*10)/10;
|
|
|
|
+ metrics["v.b.range.ideal"] = random(360*10,400*10)/10;
|
|
|
|
+ metrics["v.e.temp"] = random(12*10,17*10)/10;
|
|
|
|
+ metrics["v.b.temp"] = random(18*10,21*10)/10;
|
|
|
|
+ metrics["xkn.b.inlet.temp"] = random(14*10,19*10)/10;
|
|
|
|
+ metrics["v.b.consumption"] = random(130,240);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // v.b.soc
|
|
|
|
+ if(metrics.containsKey("v.b.soc") && metrics["v.b.soc"]!=vbsoc){
|
|
|
|
+ vbsoc = metrics["v.b.soc"];
|
|
|
|
+ //USE_SERIAL.printf("[json] v.b.soc: %f\n", vbsoc);
|
|
|
|
+ }
|
|
|
|
+ if(slowRefreshTrigger) draw_vbsoc(vbsoc);
|
|
|
|
+
|
|
|
|
+ // v.b.range.ideal
|
|
|
|
+ if(metrics.containsKey("v.b.range.ideal") && metrics["v.b.range.ideal"]!=vbrangeideal){
|
|
|
|
+ vbrangeideal = metrics["v.b.range.ideal"];
|
|
|
|
+ }
|
|
|
|
+ // v.b.range.full
|
|
|
|
+ if(metrics.containsKey("v.b.range.full") && metrics["v.b.range.full"]!=vbrangefull){
|
|
|
|
+ vbrangefull = metrics["v.b.range.full"];
|
|
|
|
+ }
|
|
|
|
+ if(slowRefreshTrigger) draw_vbrange();
|
|
|
|
+
|
|
|
|
+ // v.e.temp
|
|
|
|
+ if(metrics.containsKey("v.e.temp") && metrics["v.e.temp"]!=vetemp){
|
|
|
|
+ vetemp = metrics["v.e.temp"];
|
|
|
|
+ }
|
|
|
|
+ // v.b.temp
|
|
|
|
+ if(metrics.containsKey("v.b.temp") && metrics["v.b.temp"]!=vbtemp){
|
|
|
|
+ vbtemp = metrics["v.b.temp"];
|
|
|
|
+ }
|
|
|
|
+ // xkn.b.inlet.temp
|
|
|
|
+ if(metrics.containsKey("xkn.b.inlet.temp") && metrics["xkn.b.inlet.temp"]!=xknbinlettemp){
|
|
|
|
+ xknbinlettemp = metrics["xkn.b.inlet.temp"];
|
|
|
|
+ }
|
|
|
|
+ if(mildRefreshTrigger) draw_temps();
|
|
|
|
+
|
|
|
|
+ // xkn.b.inlet.temp
|
|
|
|
+ if(metrics.containsKey("v.b.consumption") && metrics["v.b.consumption"]!=vbconsumption){
|
|
|
|
+ vbconsumption = metrics["v.b.consumption"];
|
|
|
|
+ }
|
|
|
|
+ if(mildRefreshTrigger) draw_vbconsumption();
|
|
|
|
+
|
|
|
|
+ // v.b.power
|
|
|
|
+ if(metrics.containsKey("v.b.power")){
|
|
|
|
+ vbpower = metrics["v.b.power"];
|
|
|
|
+ //USE_SERIAL.printf("[json] v.b.power: %f\n", vbpower);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(fastRefreshTrigger) draw_vbpower(vbpower);
|
|
|
|
+
|
|
|
|
+ if(metrics.containsKey("m.monotonic")){
|
|
|
|
+ //JsonVariant _mmonotonic=metrics["m.monotonic"];
|
|
|
|
+ //int mmonotonic=_mmonotonic.as<int>();
|
|
|
|
+ int mmonotonic=metrics["m.monotonic"].as<int>();
|
|
|
|
+ if(mmonotonic % 2){
|
|
|
|
+ tickerBox(DARKGREEN);
|
|
|
|
+ }else{
|
|
|
|
+ tickerBox(BLUE);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(M5.BtnA.wasReleased()) sendButtonA();
|
|
|
|
+ if(M5.BtnB.wasReleased()) sendButtonB();
|
|
|
|
+ if(M5.BtnC.wasReleased()) changeLCDBrightness();
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(M5triggerUpdate){
|
|
|
|
+ M5.update();
|
|
|
|
+ M5triggerUpdate = 0;
|
|
|
|
+ }
|
|
|
|
+ if(slowRefreshTrigger){
|
|
|
|
+ slowRefreshTimer=0;
|
|
|
|
+ //USE_SERIAL.printf("slowRefreshTimer reset\n");
|
|
|
|
+ }
|
|
|
|
+ if(mildRefreshTrigger){
|
|
|
|
+ mildRefreshTimer=0;
|
|
|
|
+ //USE_SERIAL.printf("mildRefreshTimer reset\n");
|
|
|
|
+ }
|
|
|
|
+ if(fastRefreshTrigger){
|
|
|
|
+ fastRefreshTimer=0;
|
|
|
|
+ //USE_SERIAL.printf("fastRefreshTimer reset\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // send message to server
|
|
|
|
+ // webSocket.sendTXT("message here");
|
|
|
|
+ break;
|
|
|
|
+ case WStype_BIN:
|
|
|
|
+ USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
|
|
|
|
+ hexdump(payload, length);
|
|
|
|
+
|
|
|
|
+ // send data to server
|
|
|
|
+ // webSocket.sendBIN(payload, length);
|
|
|
|
+ break;
|
|
|
|
+ case WStype_ERROR:
|
|
|
|
+ case WStype_FRAGMENT_TEXT_START:
|
|
|
|
+ case WStype_FRAGMENT_BIN_START:
|
|
|
|
+ case WStype_FRAGMENT:
|
|
|
|
+ case WStype_FRAGMENT_FIN:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void setup() {
|
|
|
|
+
|
|
|
|
+ M5.begin();
|
|
|
|
+ M5.Power.begin();
|
|
|
|
+ M5.Lcd.setBrightness(LCDBrightnessSteps[LCDBrightnessStep+1]);
|
|
|
|
+ // USE_SERIAL.begin(921600);
|
|
|
|
+ // USE_SERIAL.begin(115200);
|
|
|
|
+ USE_SERIAL.begin(230400);
|
|
|
|
+
|
|
|
|
+ //Serial.setDebugOutput(true);
|
|
|
|
+ USE_SERIAL.setDebugOutput(true);
|
|
|
|
+
|
|
|
|
+ USE_SERIAL.println();
|
|
|
|
+
|
|
|
|
+ //M5.Lcd.fillScreen(BLACK);
|
|
|
|
+
|
|
|
|
+ ledcDetachPin(SPEAKER_PIN);
|
|
|
|
+ pinMode(SPEAKER_PIN, INPUT);
|
|
|
|
+
|
|
|
|
+ for(uint8_t t = 5; t > 0; t--) {
|
|
|
|
+ USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
|
|
|
+ USE_SERIAL.flush();
|
|
|
|
+ delay(500);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WiFiMulti.addAP("OVMSWifi", "W1f1P4ssW0rd"); // Change This to your OVMS
|
|
|
|
+
|
|
|
|
+ USE_SERIAL.printf("[Wifi] Added APs...\n");
|
|
|
|
+
|
|
|
|
+ WiFi.disconnect();
|
|
|
|
+ if(WiFiMulti.run() != WL_CONNECTED){
|
|
|
|
+ M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
|
|
|
|
+ M5.Lcd.setCursor(6, 222);
|
|
|
|
+ M5.Lcd.setTextColor(WHITE);
|
|
|
|
+ M5.Lcd.setTextSize(2);
|
|
|
|
+ M5.Lcd.print("[Wifi] Connecting...");
|
|
|
|
+ USE_SERIAL.printf("[Wifi] Connecting...\n");
|
|
|
|
+ dummyCounter = 1;
|
|
|
|
+ tickerBox(RED);
|
|
|
|
+ while(WiFiMulti.run() != WL_CONNECTED) {
|
|
|
|
+ USE_SERIAL.printf("[Wifi] Connecting... count %d\n",dummyCounter++);
|
|
|
|
+ M5.Lcd.print(".");
|
|
|
|
+ M5.update();
|
|
|
|
+ delay(500);
|
|
|
|
+ if (M5.BtnC.wasReleased()) changeLCDBrightness();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //hexdump(WiFi.SSID().c_str(), sizeof(WiFi.SSID().c_str()));
|
|
|
|
+ USE_SERIAL.printf("[Wifi] Connected: %s\n",WiFi.SSID().c_str());
|
|
|
|
+
|
|
|
|
+ M5.Lcd.fillRect(0, 220, 320, 32, BLACK);
|
|
|
|
+ M5.update();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // server address, port and URL
|
|
|
|
+ webSocket.begin("192.168.4.1", 80, "/");
|
|
|
|
+
|
|
|
|
+ // event handler
|
|
|
|
+ webSocket.onEvent(webSocketEvent);
|
|
|
|
+
|
|
|
|
+ // use HTTP Basic Authorization this is optional remove if not needed
|
|
|
|
+ webSocket.setAuthorization(OVMSUSER, OVMSPASS);
|
|
|
|
+
|
|
|
|
+ // try ever 5000 again if connection has failed
|
|
|
|
+ webSocket.setReconnectInterval(2000);
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void loop() {
|
|
|
|
+ webSocket.loop();
|
|
|
|
+ if(WiFiMulti.run() != WL_CONNECTED){
|
|
|
|
+ M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
|
|
|
|
+ M5.Lcd.setCursor(6, 222);
|
|
|
|
+ M5.Lcd.setTextColor(WHITE);
|
|
|
|
+ M5.Lcd.setTextSize(2);
|
|
|
|
+ M5.Lcd.print("[Wifi] Reconnecting...");
|
|
|
|
+ while(WiFiMulti.run() != WL_CONNECTED) {
|
|
|
|
+ USE_SERIAL.printf("[Wifi] Connecting...\n");
|
|
|
|
+ M5.Lcd.print(".");
|
|
|
|
+ M5.update();
|
|
|
|
+ delay(500);
|
|
|
|
+ if (M5.BtnC.wasReleased()) changeLCDBrightness();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ USE_SERIAL.printf("Wifi: %s\n",WiFi.SSID().c_str());
|
|
|
|
+
|
|
|
|
+ M5.Lcd.fillRect(0, 220, 320, 32, BLUE);
|
|
|
|
+ M5.Lcd.setCursor(6, 222);
|
|
|
|
+ M5.Lcd.print("[Wifi] : ");
|
|
|
|
+ M5.Lcd.print(WiFi.SSID().c_str());
|
|
|
|
+ M5.update();
|
|
|
|
+ M5.Speaker.mute();
|
|
|
|
+ delay(500);
|
|
|
|
+ M5.Lcd.fillRect(0, 220, 320, 32, BLACK);
|
|
|
|
+ M5.update();
|
|
|
|
+ }
|
|
|
|
+ //M5.Lcd.fillScreen(BLACK);
|
|
|
|
+ if(M5triggerUpdate){
|
|
|
|
+ M5.update();
|
|
|
|
+ M5triggerUpdate = 0;
|
|
|
|
+ }
|
|
|
|
+ //USE_SERIAL.printf("end of loop\n");
|
|
|
|
+}
|