Add displaymode 7

- Extend state JSON message with functional hostname and ipaddress which could be WiFi or Ethernet
This commit is contained in:
Theo Arends 2025-08-25 17:07:36 +02:00
parent 8f9c173ed6
commit 517eae733b
4 changed files with 84 additions and 28 deletions

View File

@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
## [15.0.1.3] ## [15.0.1.3]
### Added ### Added
- ESP32 ROM SHA Hardware Acceleration to BearSSL (#23819) - ESP32 ROM SHA Hardware Acceleration to BearSSL (#23819)
- Extend state JSON message with functional hostname and ipaddress which could be WiFi or Ethernet
### Breaking Changed ### Breaking Changed
@ -18,7 +19,7 @@ All notable changes to this project will be documented in this file.
### Fixed ### Fixed
- Syslog RFC5424 compliance (#23509) - Syslog RFC5424 compliance (#23509)
- Berry fix calling `setmember` with a function - Berry calling `setmember` with a function (#23825)
### Removed ### Removed
- `user-scalable=no` from HTTP HEADER (#23798) - `user-scalable=no` from HTTP HEADER (#23798)

View File

@ -119,6 +119,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Commands `LoRaWanDecoder "` and `LoRaWanName "` to clear name [#23394](https://github.com/arendst/Tasmota/issues/23394) - Commands `LoRaWanDecoder "` and `LoRaWanName "` to clear name [#23394](https://github.com/arendst/Tasmota/issues/23394)
- Command `I2sPause` [#23646](https://github.com/arendst/Tasmota/issues/23646) - Command `I2sPause` [#23646](https://github.com/arendst/Tasmota/issues/23646)
- Support for RV3028 RTC [#23672](https://github.com/arendst/Tasmota/issues/23672) - Support for RV3028 RTC [#23672](https://github.com/arendst/Tasmota/issues/23672)
- Extend state JSON message with functional hostname and ipaddress which could be WiFi or Ethernet
- Internal function 'WSContentSendRaw_P' [#23641](https://github.com/arendst/Tasmota/issues/23641) - Internal function 'WSContentSendRaw_P' [#23641](https://github.com/arendst/Tasmota/issues/23641)
- Universal display driver for ZJY169S0800TG01 ST7789 280x240 [#23638](https://github.com/arendst/Tasmota/issues/23638) - Universal display driver for ZJY169S0800TG01 ST7789 280x240 [#23638](https://github.com/arendst/Tasmota/issues/23638)
- NeoPool add Redox tank alarm [#19811](https://github.com/arendst/Tasmota/issues/19811) - NeoPool add Redox tank alarm [#19811](https://github.com/arendst/Tasmota/issues/19811)
@ -154,6 +155,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Berry security issues in `int64` and improve documentation [#23605](https://github.com/arendst/Tasmota/issues/23605) - Berry security issues in `int64` and improve documentation [#23605](https://github.com/arendst/Tasmota/issues/23605)
- Berry security issues in `berry_mapping` and improve documentation [#23606](https://github.com/arendst/Tasmota/issues/23606) - Berry security issues in `berry_mapping` and improve documentation [#23606](https://github.com/arendst/Tasmota/issues/23606)
- Berry Hue regression from #23429 [#23623](https://github.com/arendst/Tasmota/issues/23623) - Berry Hue regression from #23429 [#23623](https://github.com/arendst/Tasmota/issues/23623)
- Berry calling `setmember` with a function [#23825](https://github.com/arendst/Tasmota/issues/23825)
- LVGL restore `lv_chart.set_range` removed in LVGL 9.3.0 in favor of `lv_chart.set_axis_range` [#23567](https://github.com/arendst/Tasmota/issues/23567) - LVGL restore `lv_chart.set_range` removed in LVGL 9.3.0 in favor of `lv_chart.set_axis_range` [#23567](https://github.com/arendst/Tasmota/issues/23567)
### Removed ### Removed

View File

@ -907,13 +907,30 @@ void MqttShowState(void)
MqttShowPWMState(); MqttShowPWMState();
} }
char *hostname = TasmotaGlobal.hostname;
uint32_t ipaddress = 0;
#if defined(ESP32) && defined(USE_ETHERNET)
if (static_cast<uint32_t>(EthernetLocalIP()) != 0) {
hostname = EthernetHostname(); // Set ethernet as IP connection
ipaddress = (uint32_t)EthernetLocalIP();
}
#endif
if (!TasmotaGlobal.global_state.wifi_down) { if (!TasmotaGlobal.global_state.wifi_down) {
int32_t rssi = WiFi.RSSI(); int32_t rssi = WiFi.RSSI();
ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_WIFI_MODE "\":\"%s\",\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}"), ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_WIFI_MODE "\":\"%s\",\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}"),
Settings->sta_active +1, EscapeJSONString(SettingsText(SET_STASSID1 + Settings->sta_active)).c_str(), WiFi.BSSIDstr().c_str(), WiFi.channel(), Settings->sta_active +1, EscapeJSONString(SettingsText(SET_STASSID1 + Settings->sta_active)).c_str(), WiFi.BSSIDstr().c_str(), WiFi.channel(),
WifiGetPhyMode().c_str(), WifiGetRssiAsQuality(rssi), rssi, WifiGetPhyMode().c_str(), WifiGetRssiAsQuality(rssi), rssi,
WifiLinkCount(), WifiDowntime().c_str()); WifiLinkCount(), WifiDowntime().c_str());
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
hostname = TasmotaGlobal.hostname; // Overrule ethernet as primary IP connection
ipaddress = (uint32_t)WiFi.localIP();
} }
}
// I only want to show one active connection for device access
ResponseAppend_P(PSTR(",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\""),
hostname, ipaddress);
ResponseJsonEnd(); ResponseJsonEnd();
} }

View File

@ -167,6 +167,7 @@ enum DisplayModes {
DM_MQTT_SENSORS, DM_MQTT_SENSORS,
DM_TIME_MQTT_SENSORS, DM_TIME_MQTT_SENSORS,
DM_MQTT_TOPIC_UPTIME, DM_MQTT_TOPIC_UPTIME,
DM_MQTT_HOSTNAME_IPADDRESS,
DM_MAX DM_MAX
}; };
@ -1801,9 +1802,58 @@ void DisplayAnalyzeJson(char *topic, const char *json) {
} }
} }
void DisplayState(char *topic, const char *json) { void DisplayState(const char *topic, const char *json) {
// Impact DisplayCols1 and DisplayCols2:
// 12345678901234567890123456 = DisplayCols1 = 26 - Visible display columns
// leftitem rightitem DisplayCols2 = 3 - Display both left and rightaligned item
// leftitem right DisplayCols2 = 2 - Display both left and truncated rightaligned item
// leftitem DisplayCols2 = 1 - Display left item only
static uint32_t minute = 61; static uint32_t minute = 61;
String jsonStr = json; // {"Time":"2025-08-24T14:34:59","Uptime":"0T00:05:10","UptimeSec":310,"Heap":49,...
JsonParser parser((char*)jsonStr.c_str());
JsonParserObject root = parser.getRootObject();
if (!root) { return; } // Did JSON parsing went ok?
const char *leftitem = EmptyStr;
const char *rightitem = EmptyStr;
if (DM_MQTT_TOPIC_UPTIME == Settings->display_mode) {
leftitem = topic;
if (Settings->display_cols[1] > 1) { // Need space for displaying topic and uptime
rightitem = root.getStr(PSTR(D_JSON_UPTIME), EmptyStr);
if (strlen(rightitem) && (2 == Settings->display_cols[1])) {
char *eol = (char*)rightitem + strlen(rightitem) -3;
*eol = '\0'; // Remove uptime seconds
}
}
}
else if (DM_MQTT_HOSTNAME_IPADDRESS == Settings->display_mode) {
leftitem = root.getStr(PSTR(D_CMND_HOSTNAME), EmptyStr);
if (Settings->display_cols[1] > 1) { // Need space for displaying hostname and ipaddress
rightitem = root.getStr(PSTR(D_CMND_IPADDRESS), EmptyStr);
if (strlen(rightitem) && (2 == Settings->display_cols[1])) {
uint32_t netmask = Settings->ipv4_address[2]; // Assume WiFi netmask = Ethernet netmask
#if defined(ESP32) && defined(USE_ETHERNET)
if (0 == netmask) { // Assume Ethernet netmask = WiFi netmask
netmask = Settings->eth_ipv4_address[2];
}
#endif
if (netmask != 0) {
for (uint32_t i = 0; i < 3; i++) {
if (netmask >= 0x000000FF) {
rightitem = strchr(rightitem +1, '.'); // Skip network IP address octets
}
netmask >>= 8;
}
} else {
rightitem = strrchr(rightitem, '.'); // last IP address octet assuming netmask 255.255.255.0
}
}
}
}
if (strlen(leftitem)) {
char buffer[Settings->display_cols[0] +1]; // Max sized buffer string char buffer[Settings->display_cols[0] +1]; // Max sized buffer string
if (minute != RtcTime.minute) { if (minute != RtcTime.minute) {
minute = RtcTime.minute; minute = RtcTime.minute;
@ -1813,27 +1863,12 @@ void DisplayState(char *topic, const char *json) {
snprintf_P(buffer, sizeof(buffer), PSTR("- %02d" D_HOUR_MINUTE_SEPARATOR "%02d %s"), RtcTime.hour, RtcTime.minute, buffer2); snprintf_P(buffer, sizeof(buffer), PSTR("- %02d" D_HOUR_MINUTE_SEPARATOR "%02d %s"), RtcTime.hour, RtcTime.minute, buffer2);
DisplayLogBufferAdd(buffer); DisplayLogBufferAdd(buffer);
} }
int spaces = Settings->display_cols[0] - strlen(leftitem) - strlen(rightitem); // Right align on DisplayCols1
const char *uptime = EmptyStr;
if (Settings->display_cols[0] > 20) { // Need space for displaying topic and uptime
String jsonStr = json; // {"Time":"2025-08-24T14:34:59","Uptime":"0T00:05:10","UptimeSec":310,"Heap":49,...
JsonParser parser((char*)jsonStr.c_str());
JsonParserObject root = parser.getRootObject();
if (root) { // Did JSON parsing went ok?
uptime = root.getStr(PSTR(D_JSON_UPTIME), EmptyStr);
if (strlen(uptime) && (Settings->display_cols[0] < 24)) {
char *eol = (char*)uptime + strlen(uptime) -3;
*eol = '\0'; // Remove uptime seconds
}
}
}
// int spaces = Settings->display_cols[0] - Settings->display_cols[1] - strlen(topic); // Left align on DisplayCols2
int spaces = Settings->display_cols[0] - strlen(topic) - strlen(uptime); // Right align on DisplayCols1
if (spaces < 1) { spaces = 1; } if (spaces < 1) { spaces = 1; }
snprintf_P(buffer, sizeof(buffer), PSTR("%s%*s%s"), topic, spaces, "", uptime); snprintf_P(buffer, sizeof(buffer), PSTR("%s%*s%s"), leftitem, spaces, "", rightitem);
DisplayLogBufferAdd(buffer); DisplayLogBufferAdd(buffer);
} }
}
void DisplayMqttSubscribe(void) { void DisplayMqttSubscribe(void) {
/* Subscribe to tele messages only /* Subscribe to tele messages only
@ -1880,7 +1915,8 @@ bool DisplayMqttData(void) {
char *sensor = strstr_P(tp, PSTR("SENSOR")); char *sensor = strstr_P(tp, PSTR("SENSOR"));
char *topic = strtok(tp, "/"); // tasmota char *topic = strtok(tp, "/"); // tasmota
if (topic) { if (topic) {
if (DM_MQTT_TOPIC_UPTIME == Settings->display_mode) { if ((DM_MQTT_TOPIC_UPTIME == Settings->display_mode) ||
(DM_MQTT_HOSTNAME_IPADDRESS == Settings->display_mode)) {
if (state) { if (state) {
DisplayState(topic, XdrvMailbox.data); DisplayState(topic, XdrvMailbox.data);
} }