Merge branch 'development' into prerelease-14.0.0

This commit is contained in:
Theo Arends 2024-05-06 17:39:08 +02:00
commit 983694cc2b
6 changed files with 91 additions and 29 deletions

View File

@ -19,6 +19,7 @@ All notable changes to this project will be documented in this file.
- Command ``Publish3`` to send binary data encoded as Hex, disabled in safeboot (21329)
- Support for compile time hostname with `#define WIFI_DEFAULT_HOSTNAME` (#21236)
- Berry `after_teleperiod` event matching `FUNC_AFTER_TELEPERIOD` (#21351)
- GPIOViewer pin mode support
### Breaking Changed
- ESP32-C3 OTA binary name from `tasmota32c3cdc.bin` to `tasmota32c3.bin` with USB HWCDC and fallback to serial (#21212)
@ -37,6 +38,7 @@ All notable changes to this project will be documented in this file.
- Refactor Tensorflow (#21327)
- Seriallog set to `SERIAL_LOG_LEVEL` at boot (#21363)
- TLS Letsencrypt replace R3 CA with long-term ISRG_Root_X1 CA, which works with R3 and R10-R14 (#21352)
- GPIOViewer from v1.5.0 to v1.5.2
### Fixed
- HASPmota `align` attribute and expand PNG cache (#21228)

View File

@ -133,6 +133,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Support for SPL06_007 pressure and temperature sensor [#21185](https://github.com/arendst/Tasmota/issues/21185)
- Support for AHT30 Temperature and Humidity Sensor [#19922](https://github.com/arendst/Tasmota/issues/19922)
- Support for compile time hostname with `#define WIFI_DEFAULT_HOSTNAME` (#21236)[#21236](https://github.com/arendst/Tasmota/issues/21236)
- GPIOViewer pin mode support
- Zigbee support for attributes of type `uint48` used by energy monitoring [#20992](https://github.com/arendst/Tasmota/issues/20992)
- QMC5883l check for overflow and scale reading [#20643](https://github.com/arendst/Tasmota/issues/20643)
- TCP Serial bridge GPIO type `TCP Tx En` [#21269](https://github.com/arendst/Tasmota/issues/21269)
@ -168,6 +169,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- ESP32 Framework (Arduino Core) from v2.0.14 to v3.0.0
- ESP32 platform update from 2024.01.12 to 2024.05.01 [#21347](https://github.com/arendst/Tasmota/issues/21347)
- ESP32 LVGL library from v9.0.0 to v9.1.0 [#21008](https://github.com/arendst/Tasmota/issues/21008)
- GPIOViewer from v1.5.0 to v1.5.2
- Seriallog set to `SERIAL_LOG_LEVEL` at boot [#21363](https://github.com/arendst/Tasmota/issues/21363)
- TLS Letsencrypt replace R3 CA with long-term ISRG_Root_X1 CA, which works with R3 and R10-R14 [#21352](https://github.com/arendst/Tasmota/issues/21352)
- Command ``EthType`` option selection [#21317](https://github.com/arendst/Tasmota/issues/21317)

View File

@ -737,6 +737,9 @@ https://rya.nc/tasmota-fingerprint.html"
// // Both settings together allow to limit searching for INA3221 to only a subset of addresses
// #define INA3221_CALC_CHARGE_AH // calculate charge in Ah
// #define INA3221_CALC_ENERGY_WH // calculate energy in Wh
// #define INA3221_SUPPLY_SIDE 0x7777 // the driver adds the measured Shunt Voltage to the Bus Voltage
// for the cannel with a negativ shunt (shunt <0) thus showing the values of the supply side (IN+)
// additionaly the bits set (bit 0,1,2) enable the scanning of the voltage in the according channel
// #define USE_PMSA003I // [I2cDriver78] Enable PMSA003I Air Quality Sensor (I2C address 0x12) (+1k8 code)
// #define USE_GDK101 // [I2cDriver79] Enable GDK101 sensor (I2C addresses 0x18 - 0x1B) (+1k2 code)
// #define GDK101_SHOW_FW_VERSION

View File

@ -29,11 +29,21 @@
* GvUrl - Show current url
* GvUrl 1 - Select default url (GV_BASE_URL)
* GvUrl https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer_1_5/
*
* Note 20240506
* - Tasmota v14.0.0
* - GVRelease 1.5.2
* - Function pinmode is not fully implemented by gpio_viewer_1_5:
* Only INPUT_PULLUP and INPUT_PULLDOWN are reported as INPUT
* Only OUTPUT and OUTPUT_OPEN_DRAIN are reported as OUTPUT
* All other pin modes are reported as UNKNOWN
* - This driver is forcing INPUT_PULLUP for ANALOG and INPUT
* - Execute once command GvUrl https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer_1_5/
* - Clear browser cache to use new functionality
\*********************************************************************************************/
#define XDRV_121 121
//#define GV_INPUT_DETECTION // Report type of digital input
#define GV_USE_ESPINFO // Provide ESP info
#ifndef GV_PORT
@ -43,13 +53,30 @@
#define GV_SAMPLING_INTERVAL 100 // [GvSampling] milliseconds - Use Tasmota Scheduler (100) or Ticker (20..99,101..1000)
#endif
#ifndef GV_BASE_URL
//#define GV_BASE_URL "https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer_1_5/" // [GvUrl]
#define GV_BASE_URL "https://ota.tasmota.com/tasmota/gpioviewer/gpio_viewer_13_4_0/" // [GvUrl]
#define GV_BASE_URL "https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer_1_5/" // [GvUrl]
//#define GV_BASE_URL "https://ota.tasmota.com/tasmota/gpioviewer/gpio_viewer_13_4_0/" // [GvUrl]
#endif
#define GV_KEEP_ALIVE 1000 // milliseconds - If no activity after this do a heap size event anyway
const char *GVRelease = "1.5.0";
const char *GVRelease = "1.5.2";
/*********************************************************************************************/
// GPIO FUNCTIONS as defined by esp32-hal-gpio.h to be used by ESP8266 too, which uses different numbers
// Also defined in gpio_viewer_1_5 const.ts
#define GV_UNAVAILABLE -2 // Addition by gpio_viewer_1_5
#define GV_NOT_SET -1 // Addition by gpio_viewer_1_5
#define GV_NOT_USED 0 // Addition by this driver
#define GV_INPUT 0x01 // Not defined in gpio_viewer_1_5 !?!
#define GV_OUTPUT 0x03
#define GV_PULLUP 0x04
#define GV_INPUT_PULLUP 0x05
#define GV_PULLDOWN 0x08
#define GV_INPUT_PULLDOWN 0x09
#define GV_OPEN_DRAIN 0x10
#define GV_OUTPUT_OPEN_DRAIN 0x13
#define GV_ANALOG 0xC0
#ifdef USE_UNISHOX_COMPRESSION
#include "./html_compressed/HTTP_GV_PAGE.h"
@ -67,10 +94,7 @@ const char HTTP_GV_EVENT[] PROGMEM =
enum GVPinTypes {
GV_DigitalPin = 0,
GV_PWMPin = 1,
GV_AnalogPin = 2,
GV_InputPin = 3,
GV_InputPullUp = 4,
GV_InputPullDn = 5
GV_AnalogPin = 2
};
typedef struct {
@ -78,6 +102,7 @@ typedef struct {
Ticker ticker;
String baseUrl;
int lastPinStates[MAX_GPIO_PIN];
int pinmode[MAX_GPIO_PIN];
uint32_t lastSentWithNoActivity;
uint32_t freeHeap;
uint32_t freePSRAM;
@ -90,30 +115,30 @@ typedef struct {
tGV* GV = nullptr;
WiFiClient GVWebClient;
#ifdef GV_INPUT_DETECTION
/*********************************************************************************************/
int GetPinMode(uint32_t pin) {
#ifdef ESP8266
if (pin > MAX_GPIO_PIN -2) { return -1; } // Skip GPIO16 and Analog0
// if (17 == pin) { return GV_ANALOG; }
if (17 == pin) { return GV_INPUT_PULLUP; } // See Note 20240506
if (16 == pin) { return GV_NOT_USED; } // Skip GPIO16
#endif // ESP8266
#ifdef ESP32
if (pin > MAX_GPIO_PIN) { return -1; }
#endif // ESP32
uint32_t bit = digitalPinToBitMask(pin);
uint32_t port = digitalPinToPort(pin);
volatile uint32_t *reg = portModeRegister(port);
if (*reg & bit) { return OUTPUT; } // ESP8266 = 0x01, ESP32 = 0x03
if (*reg & bit) { return GV_OUTPUT; } // ESP8266 = 0x01, ESP32 = 0x03
// Detecting INPUT_PULLUP doesn't function consistently
volatile uint32_t *out = portOutputRegister(port);
return ((*out & bit) ? INPUT_PULLUP : INPUT); // ESP8266 = 0x02 : 0x00, ESP32 = 0x05 : x01
// volatile uint32_t *out = portOutputRegister(port);
// return ((*out & bit) ? GV_INPUT_PULLUP : GV_INPUT); // ESP8266 = 0x02 : 0x00, ESP32 = 0x05 : x01
return GV_INPUT_PULLUP; // ESP8266 = 0x02 : 0x00, ESP32 = 0x05 : x01
}
#endif // GV_INPUT_DETECTION
/*********************************************************************************************/
bool GVInit(void) {
if (!GV) {
GV = (tGV*)calloc(sizeof(tGV), 1);
GV = (tGV*)calloc(1, sizeof(tGV));
if (GV) {
GV->sampling = (GV_SAMPLING_INTERVAL < 20) ? 20 : GV_SAMPLING_INTERVAL;
GV->baseUrl = GV_BASE_URL;
@ -146,11 +171,14 @@ void GVBegin(void) {
GV->WebServer->on("/sampling", GVHandleSampling);
GV->WebServer->on("/espinfo", GVHandleEspInfo);
GV->WebServer->on("/partition", GVHandlePartition);
GV->WebServer->on("/pinmodes", GVHandlePinModes);
GV->WebServer->on("/events", GVHandleEvents);
GV->WebServer->begin();
}
}
/*********************************************************************************************/
void GVHandleRoot(void) {
GVCloseEvent();
@ -241,7 +269,7 @@ void GVHandlePartition(void) {
// Add comma before the next entry if it's not the first
if (!firstEntry)
{
jsonResponse += ",";
jsonResponse += ",";
}
firstEntry = false;
@ -266,6 +294,27 @@ void GVHandlePartition(void) {
GVWebserverSendJson(jsonResponse);
}
void GVHandlePinModes(void) {
String jsonResponse = "["; // Start of JSON array
bool firstEntry = true; // Used to format the JSON array correctly
for (int i = 0; i < MAX_GPIO_PIN; i++) {
if (GV->pinmode[i] != GV_NOT_USED) {
if (!firstEntry)
{
jsonResponse += ",";
}
firstEntry = false;
jsonResponse += "{";
jsonResponse += "\"pin\":\"" + String(i) + "\",";
jsonResponse += "\"mode\":\"" + String(GV->pinmode[i]) + "\"";
jsonResponse += "}";
}
}
jsonResponse += "]"; // End of JSON array
GVWebserverSendJson(jsonResponse);
}
void GVHandleEvents(void) {
GVWebClient = GV->WebServer->client();
GVWebClient.setNoDelay(true);
@ -281,6 +330,8 @@ void GVHandleEvents(void) {
AddLog(LOG_LEVEL_DEBUG, PSTR("IOV: Connected"));
}
/*********************************************************************************************/
void GVEventDisconnected(void) {
if (GV->sse_ready) {
AddLog(LOG_LEVEL_DEBUG, PSTR("IOV: Disconnected"));
@ -307,6 +358,8 @@ void GVEventSend(const char *message, const char *event, uint32_t id) {
}
}
/*********************************************************************************************/
void GVMonitorTask(void) {
// Monitor GPIO Values
if (GV->mutex) { return; }
@ -318,6 +371,7 @@ void GVMonitorTask(void) {
String jsonMessage = "{";
for (uint32_t pin = 0; pin < MAX_GPIO_PIN; pin++) {
int pinmode = GV_NOT_USED;
int currentState = 0;
#ifdef ESP32
@ -325,6 +379,7 @@ void GVMonitorTask(void) {
int pwm_resolution = ledcReadDutyResolution(pin);
if (pwm_resolution > 0) {
pintype = GV_PWMPin;
pinmode = GV_OUTPUT;
originalValue = ledcRead2(pin);
currentState = changeUIntScale(originalValue, 0, pwm_resolution, 0, 255); // Bring back to 0..255
}
@ -335,6 +390,7 @@ void GVMonitorTask(void) {
int pwm_value = AnalogRead(pin);
if (pwm_value > -1) {
pintype = GV_PWMPin;
pinmode = GV_OUTPUT;
originalValue = pwm_value;
currentState = changeUIntScale(originalValue, 0, Settings->pwm_range, 0, 255); // Bring back to 0..255
}
@ -344,6 +400,8 @@ void GVMonitorTask(void) {
else if (AdcPin(pin)) {
// Read Analog (ADC) GPIO
pintype = GV_AnalogPin;
// pinmode = GV_ANALOG;
pinmode = GV_INPUT_PULLUP; // See Note 20240506
/*
#ifdef ESP32
originalValue = AdcRead(pin, 2);
@ -367,12 +425,8 @@ void GVMonitorTask(void) {
// } else {
// currentState = 0;
}
#ifdef GV_INPUT_DETECTION
int pin_mode = GetPinMode(pin);
pintype = (INPUT == pin_mode) ? GV_InputPin : (INPUT_PULLUP == pin_mode) ? GV_InputPullUp : GV_DigitalPin;
#else
pintype = GV_DigitalPin;
#endif
pinmode = GetPinMode(pin);
}
if (GV->init_done) {
@ -380,6 +434,7 @@ void GVMonitorTask(void) {
GV->lastPinStates[pin] = (pin_type != GPIO_NONE) ? -1 : originalValue; // During init provide configured GPIOs fixing slow browsers
}
if (originalValue != GV->lastPinStates[pin]) {
GV->pinmode[pin] = pinmode;
if (hasChanges) { jsonMessage += ","; }
jsonMessage += "\"" + String(pin) + "\":{\"s\":" + currentState + ",\"v\":" + originalValue + ",\"t\":" + pintype + "}";
GV->lastPinStates[pin] = originalValue;

View File

@ -92,8 +92,7 @@ bool LoraWanLoadData(void) {
const char* app_key = nullptr;
app_key = root.getStr(PSTR(D_JSON_APPKEY), nullptr);
if (strlen(app_key)) {
size_t out_len = TAS_LORAWAN_AES128_KEY_SIZE;
HexToBytes(app_key, Lora->settings.end_node[n].AppKey, out_len);
HexToBytes(app_key, Lora->settings.end_node[n].AppKey, TAS_LORAWAN_AES128_KEY_SIZE);
}
Lora->settings.end_node[n].DevEUIh = root.getUInt(PSTR(D_JSON_DEVEUI "h"), Lora->settings.end_node[n].DevEUIh);
Lora->settings.end_node[n].DevEUIl = root.getUInt(PSTR(D_JSON_DEVEUI "l"), Lora->settings.end_node[n].DevEUIl);
@ -581,8 +580,7 @@ void CmndLoraWanAppKey(void) {
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TAS_LORAWAN_ENDNODES)) {
uint32_t node = XdrvMailbox.index -1;
if (32 == XdrvMailbox.data_len) {
size_t out_len = TAS_LORAWAN_AES128_KEY_SIZE;
HexToBytes(XdrvMailbox.data, Lora->settings.end_node[node].AppKey, out_len);
HexToBytes(XdrvMailbox.data, Lora->settings.end_node[node].AppKey, TAS_LORAWAN_AES128_KEY_SIZE);
if (0 == Lora->settings.end_node[node].name.length()) {
Lora->settings.end_node[node].name = F("0x0000");
}

View File

@ -1,7 +1,7 @@
/*
xsns_100_ina3221.ino - INA3221 3-channels Current Sensor support for Tasmota
Copyright (C) 2021 Barbudor and Theo Arends + fb-pilot 2024-4-4, 2024-4-20
Copyright (C) 2021 Barbudor and Theo Arends + fb-pilot
Based on Barbudor's CircuitPython_INA3221
This program is free software: you can redistribute it and/or modify
@ -472,12 +472,14 @@ bool Ina3221CmndSensor(void)
float shunt = CharToFloat(ArgV(argument,2+channel));
Ina3221SetShunt(device, channel, shunt);
}
#ifdef INA3221_SUPPLY_SIDE
if (!Ina3221WriteConfig(device)){
#ifdef DEBUG_TASMOTA_SENSOR
DEBUG_SENSOR_LOG(D_INA3221 "error write configuration %d", device+1);
#endif
return false;
}
#endif
}
Response_P(INA3221_SENSORCMND_START, XSNS_100, device +1, Ina3221Data[device].i2caddr);
for (int channel = 0 ; channel < INA3221_NB_CHAN ; channel++ ) {