diff --git a/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino b/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino index b8034af98..7caa8becc 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino @@ -23,7 +23,7 @@ #define GV_BASE_URL "https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer/assets/" -const char *GVRelease = "1.0.8"; +const char *GVRelease = "1.0.7"; const char HTTP_GV_PAGE[] PROGMEM = "" @@ -69,9 +69,6 @@ const char HTTP_GV_EVENT[] PROGMEM = "Cache-Control: no-cache\n" "Access-Control-Allow-Origin: *\n\n"; -const char HTTP_BTN_MENU_GV[] PROGMEM = - "

"; - enum GVPinTypes { GV_DigitalPin = 0, GV_PWMPin = 1, @@ -81,60 +78,14 @@ enum GVPinTypes { struct { WiFiClient WebClient; ESP8266WebServer *WebServer; - uint32_t lastPinStates[MAX_GPIO_PIN]; + int lastPinStates[MAX_GPIO_PIN]; uint32_t lastSentWithNoActivity; uint32_t freeHeap; uint32_t freePSRAM; - bool sse_ready; bool active; + bool sse_ready; } GV; -int GVReadGPIO(uint32_t pin, uint32_t *pintype) { - uint32_t pin_type = GetPin(pin) / 32; -/* - if (GPIO_NONE == pin_type) { - *pintype = GV_DigitalPin; - return 0; - } -*/ -#ifdef ESP32 - int pwm_resolution = ledcReadDutyResolution(pin); - if (pwm_resolution > 0) { - *pintype = GV_PWMPin; - return ledcRead2(pin); - } -#endif // ESP32 - -#ifdef ESP8266 - int pwm_value = AnalogRead(pin); - if (pwm_value > -1) { - *pintype = GV_PWMPin; - return pwm_value; - } -#endif // ESP8266 - - else if (AdcPin(pin)) { - *pintype = GV_AnalogPin; - return AdcRead(pin, 2); - } - - *pintype = GV_DigitalPin; - int value = digitalRead(pin); - if (value == 1) { - return 256; - } - return 0; -} - -void GVResetStatePins(void) { - AddLog(LOG_LEVEL_INFO, "IOV: GPIOViewer Connected, sampling interval is " STR(GV_SAMPLING_INTERVAL) "ms"); - - uint32_t pintype; - for (uint32_t pin = 0; pin < MAX_GPIO_PIN; pin++) { - GV.lastPinStates[pin] = GVReadGPIO(pin, &pintype); - } -} - //void GVEventSend(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); void GVEventSend(const char *message, const char *event, uint32_t id) { if (GV.WebClient.connected()) { @@ -144,17 +95,61 @@ void GVEventSend(const char *message, const char *event, uint32_t id) { } } -// Monitor GPIO Values void GVMonitorTask(void) { + // Monitor GPIO Values + uint32_t originalValue; uint32_t pintype; bool hasChanges = false; + String jsonMessage = "{"; for (uint32_t pin = 0; pin < MAX_GPIO_PIN; pin++) { - int currentState = GVReadGPIO(pin, &pintype); - if (currentState != GV.lastPinStates[pin]) { + int currentState = 0; +/* + uint32_t pin_type = GetPin(pin) / 32; + if (GPIO_NONE == pin_type) { + pintype = GV_DigitalPin; + originalValue = 0; +// currentState = 0; + } +*/ +#ifdef ESP32 + int pwm_resolution = ledcReadDutyResolution(pin); + if (pwm_resolution > 0) { + pintype = GV_PWMPin; + originalValue = ledcRead2(pin); + currentState = changeUIntScale(originalValue, 0, pwm_resolution, 0, 255); // bring back to 0..255 + } +#endif // ESP32 + +#ifdef ESP8266 + int pwm_value = AnalogRead(pin); + if (pwm_value > -1) { + pintype = GV_PWMPin; + originalValue = pwm_value; + currentState = changeUIntScale(originalValue, 0, Settings->pwm_range, 0, 255); // bring back to 0..255 + } +#endif // ESP8266 + + else if (AdcPin(pin)) { + pintype = GV_AnalogPin; + originalValue = AdcRead(pin, 2); + int adc_resolution = (1 << AdcResolution()) - 1; + currentState = changeUIntScale(originalValue, 0, adc_resolution, 0, 255); // bring back to 0..255 + } else { + pintype = GV_DigitalPin; + int value = digitalRead(pin); + originalValue = value; + if (value == 1) { + currentState = 256; +// } else { +// currentState = 0; + } + } + + if (originalValue != GV.lastPinStates[pin]) { if (hasChanges) { jsonMessage += ","; } - jsonMessage += "\"" + String(pin) + "\":{\"s\":" + currentState + ",\"v\":" + GV.lastPinStates[pin] + ",\"t\":" + pintype + "}"; - GV.lastPinStates[pin] = currentState; + jsonMessage += "\"" + String(pin) + "\":{\"s\":" + currentState + ",\"v\":" + originalValue + ",\"t\":" + pintype + "}"; + GV.lastPinStates[pin] = originalValue; hasChanges = true; } } @@ -208,15 +203,11 @@ void GVBegin(void) { GV.WebServer->on("/events", GVHandleEvents); GV.WebServer->on("/", GVHandleRoot); GV.WebServer->on("/release", GVHandleRelease); -#ifdef ESP32 GV.WebServer->on("/free_psram", GVHandleFreePSRam); -#endif // ESP32 GV.WebServer->begin(); } void GVHandleEvents(void) { - GVResetStatePins(); - GV.WebClient = GV.WebServer->client(); GV.WebClient.setNoDelay(true); // GV.WebClient.setSync(true); @@ -259,6 +250,33 @@ void GVHandleFreePSRam(void) { GV.WebServer->send(200, "application/json", jsonResponse); } +/*********************************************************************************************\ + * GUI +\*********************************************************************************************/ +#ifdef USE_WEBSERVER +#define WEB_HANDLE_GV "gv1" + +const char HTTP_BTN_MENU_GV[] PROGMEM = +// "

"; + "

"; + +void GVSetupAndStart(void) { + if (!HttpCheckPriviledgedAccess()) { return; } + + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_GPIO_VIEWER)); + + if (!GV.active) { + GVBegin(); + GV.active = true; + } + + char redirect[100]; + snprintf_P(redirect, sizeof(redirect), PSTR("http://%s:" STR(GV_PORT) "/"), WiFi.localIP().toString().c_str()); + Webserver->sendHeader(F("Location"), redirect); + Webserver->send(303); +} +#endif // USE_WEBSERVER + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -266,6 +284,20 @@ void GVHandleFreePSRam(void) { bool Xdrv121(uint32_t function) { bool result = false; + switch (function) { +#ifdef USE_WEBSERVER + case FUNC_WEB_ADD_MANAGEMENT_BUTTON: + if (XdrvMailbox.index) { + XdrvMailbox.index++; + } else { + WSContentSend_PD(HTTP_BTN_MENU_GV); + } + break; + case FUNC_WEB_ADD_HANDLER: + Webserver->on(PSTR("/" WEB_HANDLE_GV), GVSetupAndStart); + break; +#endif // USE_WEBSERVER + } if (GV.active) { switch (function) { case FUNC_LOOP: @@ -274,35 +306,10 @@ bool Xdrv121(uint32_t function) { case FUNC_EVERY_100_MSECOND: if (GV.sse_ready) { GVMonitorTask(); } break; -#ifdef USE_WEBSERVER - case FUNC_WEB_ADD_MANAGEMENT_BUTTON: - if (XdrvMailbox.index) { - XdrvMailbox.index++; - } else { - WSContentSend_P(HTTP_BTN_MENU_GV, WiFi.localIP().toString().c_str()); - } - break; -#endif // USE_WEBSERVER case FUNC_ACTIVE: result = true; break; } - } else { - switch (function) { - case FUNC_EVERY_SECOND: - if (!TasmotaGlobal.global_state.network_down) { - // Add delay to finish network setup - static uint32_t gv_delay = 3; - if (gv_delay) { - gv_delay--; - } else { - GVBegin(); - GV.active = true; - } - } - break; - } - } return result; }