mirror of
https://github.com/arendst/Tasmota.git
synced 2026-10-26 22:11:22 +00:00
Add BLE timeout and eQ3 TRV enhancements (#25173)
* Add BLE timeout and eQ3 TRV enhancements - Add a configurable BLE connection timeout and default it to 15 seconds (`BLEConnTimeout`) - Improve eQ3 device detection - Harden eQ3 advertising parsing - Request and report TRV firmware version - Add an option to disable the use of aliases in eQ3 MQTT topics (`TRVAliasAsTopic`) * Comment MAC prefix
This commit is contained in:
1 parent
fd390ea34f
commit
d8fe06cfe2
2 files changed
+104
-62
No files matched your search
@@ -461,6 +461,7 @@ uint8_t BLEAliasListTrigger = 0;
|
||||
uint8_t BLEPostMQTTTrigger = 0;
|
||||
int BLEMaxAge = 60*10; // 10 minutes
|
||||
int BLEAddressFilter = 0;
|
||||
uint8_t BLEConnectTimeout = 15;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
@@ -512,7 +513,7 @@ int minRSSI = -100;
|
||||
#define D_CMND_BLE "BLE"
|
||||
|
||||
const char kBLE_Commands[] PROGMEM = D_CMND_BLE "|"
|
||||
"Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved|FilterNames|MinRssiLevel|Pair";
|
||||
"Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved|FilterNames|MinRssiLevel|Pair|ConnTimeout";
|
||||
|
||||
static void CmndBLEPeriod(void);
|
||||
static void CmndBLEAdv(void);
|
||||
@@ -530,6 +531,7 @@ static void CmndBLEEnableUnsaved(void);
|
||||
static void CmndBleFilterNames(void);
|
||||
static void CmndSetMinRSSI(void);
|
||||
static void CmndPair(void);
|
||||
static void CmndConnTimeout(void);
|
||||
|
||||
void (*const BLE_Commands[])(void) PROGMEM = {
|
||||
&BLE_ESP32::CmndBLEPeriod,
|
||||
@@ -547,7 +549,8 @@ void (*const BLE_Commands[])(void) PROGMEM = {
|
||||
&BLE_ESP32::CmndBLEEnableUnsaved,
|
||||
&BLE_ESP32::CmndBleFilterNames,
|
||||
&BLE_ESP32::CmndSetMinRSSI,
|
||||
&BLE_ESP32::CmndPair
|
||||
&BLE_ESP32::CmndPair,
|
||||
&BLE_ESP32::CmndConnTimeout
|
||||
};
|
||||
|
||||
const char *successStates[] PROGMEM = {
|
||||
@@ -1997,6 +2000,7 @@ static void BLEDoPairing(NimBLEClient **ppClient) {
|
||||
BLEStoreModify(pairingAddress.getBase()->val, nullptr);
|
||||
NimBLEDevice::deleteBond(pairingAddress); // Must be executed after BLEStoreModify
|
||||
|
||||
pClient->setConnectTimeout(20000); // Always use 20 sec for pairing
|
||||
if (pClient->connect(pairingAddress, false, false, false)) {
|
||||
AddLog(LOG_LEVEL_DEBUG, "BLE: Connected for pairing. Starting crypto handshake...");
|
||||
pairingState = PAIRING_CONNECTED;
|
||||
@@ -2139,6 +2143,7 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe
|
||||
return;
|
||||
}
|
||||
|
||||
pClient->setConnectTimeout(BLEConnectTimeout * 1000);
|
||||
if (pClient->connect(op->addr, true)) {
|
||||
|
||||
// as soon as connected, start another scan if possible
|
||||
@@ -3308,6 +3313,12 @@ void CmndBLEName(void) {
|
||||
Response_P("{\"%s\":\"started\",\"MAC\":\"%s\",\"PIN\":\"%06u\"}", XdrvMailbox.command, pairingAddress.toString().c_str(), pairingPIN);
|
||||
};
|
||||
|
||||
void CmndConnTimeout(void) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
BLEConnectTimeout = tmax(tmin(XdrvMailbox.payload, 60), 5);
|
||||
}
|
||||
ResponseCmndNumber(BLEConnectTimeout);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Command to cause BLE read/write/notify operations to be run.
|
||||
|
||||
@@ -35,6 +35,7 @@ e.g. TRV 001A2216A458 settemp 21.5
|
||||
TRVPeriod <seconds> - Set the polling interval for eQ-3 TRV devices
|
||||
TRVRetries <retries> - Set the maximum number of command transmission retries (0..10)
|
||||
TRVOnlyAliased <value> - Filter device polling based on BLEAlias settings
|
||||
TRVAliasAsTopic 0|1 - Use alias as MQTT-Topic (default: 1)
|
||||
TRVMinRSSI <rssi> - Set the minimum RSSI signal strength threshold for discovering devices (-99..0)
|
||||
TRVHideFailedPoll <value> - Toggle suppression of MQTT responses when a periodic polling fails
|
||||
TRVDevList / TRVScan - Display all discovered eQ-3 TRVs (aliases)
|
||||
@@ -153,6 +154,7 @@ void CmndTrv(void);
|
||||
void CmndTrvPeriod(void);
|
||||
void CmndTrvRetries(void);
|
||||
void CmndTrvOnlyAliased(void);
|
||||
void CmndTrvAliasAsTopic(void);
|
||||
void CmndTrvMinRSSI(void);
|
||||
void CmndTrvHideFailedPoll(void);
|
||||
void CmndTrvReset(void);
|
||||
@@ -163,6 +165,7 @@ constexpr const char kEQ3_Commands[] = D_CMND_EQ3 "|"
|
||||
"Period|"
|
||||
"Retries|"
|
||||
"OnlyAliased|"
|
||||
"AliasAsTopic|"
|
||||
"MinRSSI|"
|
||||
"HideFailedPoll|"
|
||||
"Reset|"
|
||||
@@ -174,6 +177,7 @@ constexpr void (*EQ3_Commands[])(void) = {
|
||||
&CmndTrvPeriod,
|
||||
&CmndTrvRetries,
|
||||
&CmndTrvOnlyAliased,
|
||||
&CmndTrvAliasAsTopic,
|
||||
&CmndTrvMinRSSI,
|
||||
&CmndTrvHideFailedPoll,
|
||||
&CmndTrvReset,
|
||||
@@ -210,6 +214,7 @@ enum TrvSubCommand : uint8_t {
|
||||
TRV_REQPROFILE,
|
||||
TRV_SETPROFILE,
|
||||
TRV_WINDOW,
|
||||
TRV_INFO,
|
||||
TRV_COUNT, // Maxcount - Must match to TrvSubCmds
|
||||
TRV_UNKNOWN = 255 // Helper for error
|
||||
};
|
||||
@@ -242,7 +247,8 @@ constexpr const char* const TrvSubCmds[] = {
|
||||
"night",
|
||||
"reqprofile",
|
||||
"setprofile",
|
||||
"window"
|
||||
"window",
|
||||
"info"
|
||||
};
|
||||
|
||||
enum TrvResponse : uint8_t {
|
||||
@@ -286,6 +292,7 @@ constexpr const char* const mqtt_mode_names[] = {
|
||||
};
|
||||
|
||||
const uint8_t* const macprefixes[] = {
|
||||
// (uint8_t*)"\xB8\x27\xEB",
|
||||
(uint8_t*)"\x00\x1a\x22"
|
||||
};
|
||||
|
||||
@@ -295,8 +302,8 @@ constexpr const char EQ3_notify_Char[] = "d0e8434d-cd29-0996-af41-6c90f4e0eb2a";
|
||||
|
||||
constexpr const char* const EQ3Names[] = {
|
||||
"CC-RT-BLE",
|
||||
"CC-RT-BLE-EQ",
|
||||
"CC-RT-M-BLE"
|
||||
"CC-RT-M-BLE",
|
||||
"eQ3-"
|
||||
};
|
||||
|
||||
struct eq3_device_t {
|
||||
@@ -310,6 +317,7 @@ struct eq3_device_t {
|
||||
uint8_t ValvePos; // 1 Byte
|
||||
uint8_t Mode; // 1 Byte
|
||||
uint8_t lastStatusLen; // 1 Byte
|
||||
uint8_t Firmware; // 1 Byte
|
||||
uint8_t battPercent; // 1 Byte
|
||||
bool Battery; // 1 Byte 1=low
|
||||
bool Boost; // 1 Byte 1=active
|
||||
@@ -337,6 +345,7 @@ uint16_t EQ3Period = 300;
|
||||
uint8_t EQ3Retries = 4;
|
||||
uint8_t EQ3OnlyAliased = 0;
|
||||
bool opInProgress = false;
|
||||
bool EQ3AliasAsTopic = true;
|
||||
int EQ3CurrentSingleSlot = 0;
|
||||
|
||||
uint8_t EQ3TopicStyle = 1;
|
||||
@@ -394,7 +403,7 @@ const char* IdxToTrvCmd(uint8_t index) {
|
||||
|
||||
char* topicPrefix(int prefix, const uint8_t* addr, bool useAlias) {
|
||||
static char stopic[TOPSZ];
|
||||
const char* id = addrStr(addr, useAlias);
|
||||
const char* id = addrStr(addr, useAlias && EQ3AliasAsTopic);
|
||||
if (!EQ3TopicStyle) {
|
||||
GetTopic_P(stopic, prefix, TasmotaGlobal.mqtt_topic, "");
|
||||
strlcat(stopic, "EQ3/", sizeof(stopic));
|
||||
@@ -503,12 +512,10 @@ int EQ3QueueOp(const uint8_t* MAC, const uint8_t* data, int datalen, int cmdtype
|
||||
return qlen;
|
||||
}
|
||||
|
||||
int EQ3ParseOp(BLE_ESP32::generic_sensor_t* op, bool success, int retries) {
|
||||
int res = 0;
|
||||
opInProgress = false;
|
||||
|
||||
void EQ3ParseOp(BLE_ESP32::generic_sensor_t* op, bool success) {
|
||||
uint8_t addrev[6];
|
||||
const uint8_t* native = op->addr.getVal();
|
||||
|
||||
memcpy(addrev, native, 6);
|
||||
BLE_ESP32::ReverseMAC(addrev);
|
||||
|
||||
@@ -520,6 +527,7 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t* op, bool success, int retries) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!eq3) return;
|
||||
|
||||
uint8_t cmdtype = ((uintptr_t)op->context) & 0x7F;
|
||||
bool useAlias = ((uintptr_t)op->context) & 0x80;
|
||||
@@ -528,28 +536,14 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t* op, bool success, int retries) {
|
||||
ResponseAppend_P("\"cmd\":\"%s\"", IdxToTrvCmd(cmdtype));
|
||||
ResponseAppend_P(",\"result\":\"%s\",", success ? "ok" : "fail");
|
||||
|
||||
uint8_t* status = nullptr;
|
||||
uint8_t statlen = 0;
|
||||
uint32_t stattime = 0;
|
||||
uint8_t* status = eq3->lastStatus;
|
||||
uint8_t statlen = eq3->lastStatusLen;
|
||||
uint32_t stattime = eq3->lastStatusTime;
|
||||
|
||||
if (success) {
|
||||
if ((op->notifylen >= 6) && (op->dataNotify[0] == 2) && (op->dataNotify[1] == 1)) {
|
||||
if (eq3) {
|
||||
memcpy(eq3->lastStatus, op->dataNotify, (op->notifylen <= 10)?op->notifylen:16);
|
||||
eq3->lastStatusLen = (op->notifylen <= 10)?op->notifylen:16;
|
||||
eq3->lastStatusTime = UtcTime();
|
||||
}
|
||||
}
|
||||
|
||||
status = op->dataNotify;
|
||||
statlen = op->notifylen;
|
||||
stattime = UtcTime();
|
||||
}
|
||||
|
||||
if (eq3) {
|
||||
status = eq3->lastStatus;
|
||||
statlen = eq3->lastStatusLen;
|
||||
stattime = eq3->lastStatusTime;
|
||||
if (success && (op->notifylen >= 6) && (op->dataNotify[0] == 2) && (op->dataNotify[1] == 1)) {
|
||||
statlen = eq3->lastStatusLen = (op->notifylen <= 10) ? op->notifylen : 16;
|
||||
memcpy(eq3->lastStatus, op->dataNotify, statlen);
|
||||
stattime = eq3->lastStatusTime = UtcTime();
|
||||
}
|
||||
|
||||
if ((statlen >= 6) && (status[0] == 2) && (status[1] == 1)) {
|
||||
@@ -562,6 +556,10 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t* op, bool success, int retries) {
|
||||
eq3->Battery = status[2] & 128;
|
||||
}
|
||||
|
||||
if (cmdtype == TRV_INFO && op->notifylen >= 15 && op->dataNotify[0] == 1 && op->dataNotify[2] == 0 && op->dataNotify[3] == 0) {
|
||||
eq3->Firmware = op->dataNotify[1];
|
||||
}
|
||||
|
||||
EQ3publishMain(eq3);
|
||||
|
||||
if (cmdtype == TRV_RAW) {
|
||||
@@ -633,19 +631,17 @@ int EQ3ParseOp(BLE_ESP32::generic_sensor_t* op, bool success, int retries) {
|
||||
}
|
||||
ResponseAppend_P("\"");
|
||||
}
|
||||
|
||||
res = 1;
|
||||
}
|
||||
|
||||
ResponseJsonEnd();
|
||||
|
||||
if (cmdtype == TRV_POLL && EQ3HideFailedPoll && !success) {
|
||||
AddLog(LOG_LEVEL_DEBUG, "EQ3: %s: Poll fail not sent because EQ3HideFailedPoll", addrStr(addrev));
|
||||
return res;
|
||||
return;
|
||||
}
|
||||
|
||||
MqttPublish(topicPrefix((int)STAT, eq3->addr, BLE_ESP32::getAlias(eq3->addr)), false);
|
||||
return res;
|
||||
return;
|
||||
}
|
||||
|
||||
int EQ3GenericOpCompleteFn(BLE_ESP32::generic_sensor_t* op) {
|
||||
@@ -673,7 +669,7 @@ int EQ3GenericOpCompleteFn(BLE_ESP32::generic_sensor_t* op) {
|
||||
AddLog(LOG_LEVEL_DEBUG, "EQ3: %s: Operation 1/%u \"%s\" done", addrStr(addrev), opQueue.size(), IdxToTrvCmd(context & 0x7f));
|
||||
}
|
||||
|
||||
EQ3ParseOp(op, !is_failed, 0);
|
||||
EQ3ParseOp(op, !is_failed);
|
||||
retries = 0;
|
||||
opInProgress = false;
|
||||
|
||||
@@ -784,7 +780,9 @@ void TaskEQ3ParseBTHome(BLE_ESP32::ble_advertisment_t* pStruct) {
|
||||
while (pos < ServiceDataLength) {
|
||||
switch (ServiceData[pos]) {
|
||||
case 0x02: // Temp
|
||||
floatVal = (ServiceData[pos + 1] | ServiceData[pos + 2] << 8) * 0.01f;
|
||||
pos += 3;
|
||||
if (pos > ServiceDataLength) break;
|
||||
floatVal = (ServiceData[pos - 2] | ServiceData[pos - 1] << 8) * 0.01f;
|
||||
if (firstTemp) {
|
||||
eq3->Changed |= (eq3->Temperature != floatVal);
|
||||
eq3->Temperature = floatVal;
|
||||
@@ -795,58 +793,69 @@ void TaskEQ3ParseBTHome(BLE_ESP32::ble_advertisment_t* pStruct) {
|
||||
eq3->TargetTemp = floatVal;
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Target temp: %1_f", addrStr(addr), &eq3->TargetTemp);
|
||||
}
|
||||
pos += 3;
|
||||
break;
|
||||
case 0x0C: // Voltage
|
||||
floatVal = (ServiceData[pos + 1] | (ServiceData[pos + 2] << 8)) * 0.001f;
|
||||
pos += 3;
|
||||
if (pos > ServiceDataLength) break;
|
||||
floatVal = (ServiceData[pos - 2] | ServiceData[pos - 1] << 8) * 0.001f;
|
||||
eq3->Changed |= (eq3->battVolt != floatVal);
|
||||
eq3->battVolt = floatVal;
|
||||
eq3->battPercent = changeUIntScale(floatVal * 1000, 2200, 3000, 0, 100); // Map 2.2V-3.0V to 0%-100%
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Batt: %3_f (%u%%)", addrStr(addr), &eq3->battVolt, eq3->battPercent);
|
||||
pos += 3;
|
||||
break;
|
||||
case 0x2F: // Valve
|
||||
eq3->Changed |= (eq3->ValvePos != ServiceData[pos + 1]);
|
||||
eq3->ValvePos = ServiceData[pos + 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Valve: %u", addrStr(addr), eq3->ValvePos);
|
||||
pos += 2;
|
||||
if (pos > ServiceDataLength) break;
|
||||
eq3->Changed |= (eq3->ValvePos != ServiceData[pos - 1]);
|
||||
eq3->ValvePos = ServiceData[pos - 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Valve: %u", addrStr(addr), eq3->ValvePos);
|
||||
break;
|
||||
case 0x09: // Mode
|
||||
if (eq3->Mode != ServiceData[pos + 1]) {
|
||||
pos += 2;
|
||||
if (pos > ServiceDataLength) break;
|
||||
if (eq3->Mode != ServiceData[pos - 1]) {
|
||||
eq3->Changed = true;
|
||||
eq3->Mode = ServiceData[pos + 1];
|
||||
eq3->Mode = ServiceData[pos - 1];
|
||||
// Force poll if mode changed to HOLIDAY to get holiday end
|
||||
if (eq3->Mode == 2) EQ3Send(eq3->addr, TRV_POLL, nullptr, nullptr, 1);
|
||||
}
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Mode: %u", addrStr(addr), eq3->Mode);
|
||||
pos += 2;
|
||||
break;
|
||||
case 0x15: // Battery
|
||||
eq3->Changed |= (eq3->Battery != ServiceData[pos + 1]);
|
||||
eq3->Battery = ServiceData[pos + 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Battery: %u", addrStr(addr), eq3->Battery);
|
||||
pos += 2;
|
||||
if (pos > ServiceDataLength) break;
|
||||
eq3->Changed |= (eq3->Battery != ServiceData[pos - 1]);
|
||||
eq3->Battery = ServiceData[pos - 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Battery: %u", addrStr(addr), eq3->Battery);
|
||||
break;
|
||||
case 0x0F: // Boost
|
||||
eq3->Changed |= (eq3->Boost != ServiceData[pos + 1]);
|
||||
eq3->Boost = ServiceData[pos + 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Boost: %u", addrStr(addr), eq3->Boost);
|
||||
pos += 2;
|
||||
if (pos > ServiceDataLength) break;
|
||||
eq3->Changed |= (eq3->Boost != ServiceData[pos - 1]);
|
||||
eq3->Boost = ServiceData[pos - 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Boost: %u", addrStr(addr), eq3->Boost);
|
||||
break;
|
||||
case 0x2D: // Window
|
||||
eq3->Changed |= (eq3->Window != ServiceData[pos + 1]);
|
||||
eq3->Window = ServiceData[pos + 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Window: %u", addrStr(addr), eq3->Window);
|
||||
pos += 2;
|
||||
if (pos > ServiceDataLength) break;
|
||||
eq3->Changed |= (eq3->Window != ServiceData[pos - 1]);
|
||||
eq3->Window = ServiceData[pos - 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Window: %u", addrStr(addr), eq3->Window);
|
||||
break;
|
||||
case 0x1F: // Lock !! inverted value !!
|
||||
eq3->Changed |= (eq3->Lock != !ServiceData[pos + 1]);
|
||||
eq3->Lock = !ServiceData[pos + 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Lock: %u", addrStr(addr), eq3->Lock);
|
||||
pos += 2;
|
||||
if (pos > ServiceDataLength) break;
|
||||
eq3->Changed |= (eq3->Lock != !ServiceData[pos - 1]);
|
||||
eq3->Lock = !ServiceData[pos - 1];
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Lock: %u", addrStr(addr), eq3->Lock);
|
||||
break;
|
||||
case 0x19: // Connectivity
|
||||
pos += 2;
|
||||
if (pos > ServiceDataLength) break;
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_DEBUG], "EQ3: %s: Rec ADV Connected: %u", addrStr(addr), ServiceData[pos - 1]);
|
||||
break;
|
||||
default:
|
||||
AddLog(BLE_ESP32::BLELogLevel[LOG_LEVEL_INFO], "EQ3: %s: Rec ADV %u", addrStr(addr), ServiceData[pos]);
|
||||
AddLog(LOG_LEVEL_INFO, "EQ3: %s: Rec unhandled ADV %02X", addrStr(addr), ServiceData[pos]);
|
||||
pos ++;
|
||||
break;
|
||||
}
|
||||
@@ -876,7 +885,7 @@ int TaskEQ3advertismentCallback(BLE_ESP32::ble_advertisment_t* pStruct)
|
||||
// Identify device by device name; active scan needed
|
||||
if (!found) {
|
||||
for (const char* eq3Name : EQ3Names) {
|
||||
if (sname == eq3Name) {
|
||||
if (sname.starts_with(eq3Name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -1012,7 +1021,7 @@ int EQ3SendResult(char* requested, const char* result) {
|
||||
}
|
||||
|
||||
#ifdef USE_WEBSERVER
|
||||
constexpr const char HTTP_EQ3_STATUS1[] = "<tr><th colspan=2 nowrap><span title='eQ-3 TRV\n0x%6_H'>%s</span><span style='float:right'>";
|
||||
constexpr const char HTTP_EQ3_STATUS1[] = "<tr><th colspan=2 nowrap><span title='eQ-3 TRV%s\n0x%6_H'>%s</span><span style='float:right'>";
|
||||
constexpr const char HTTP_EQ3_STATUS2[] = "<span title='%s'>%s</span>";
|
||||
constexpr const char HTTP_EQ3_TEMPERATURE[] = "{s}┆ " D_THERMOSTAT_SET_POINT "{m}%*_f " D_UNIT_DEGREE "%c{e}";
|
||||
constexpr const char HTTP_EQ3_VALVE_POS[] = "{s}┆ " D_THERMOSTAT_VALVE_POSITION "{m}%d " D_UNIT_PERCENT "{e}";
|
||||
@@ -1037,12 +1046,17 @@ void EQ3Show(void)
|
||||
label = tlabel;
|
||||
}
|
||||
|
||||
char Firmware[16] = "";
|
||||
if (device.Firmware) {
|
||||
snprintf(Firmware, sizeof(Firmware), " - V%u.%02u", device.Firmware / 100, device.Firmware % 100);
|
||||
}
|
||||
|
||||
uint8_t rssi_as_quality = WifiGetRssiAsQuality(device.RSSI);
|
||||
uint8_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4);
|
||||
char rssi[16];
|
||||
snprintf(rssi, sizeof(rssi), "%d%% (%d dBm)", rssi_as_quality, device.RSSI);
|
||||
|
||||
WSContentSend_P(HTTP_EQ3_STATUS1, device.addr, label);
|
||||
WSContentSend_P(HTTP_EQ3_STATUS1, Firmware, device.addr, label);
|
||||
if (device.cryptState) WSContentSend_P(HTTP_EQ3_STATUS2, D_DECRYPTION " " D_FAILED, "<del>🔑</del>");
|
||||
bool showData = (!EQ3Period || device.BTHomeAdvert || device.lastStatusTime + (EQ3Period * 10) > UtcTime());
|
||||
if (showData) {
|
||||
@@ -1084,8 +1098,11 @@ void EQ3publishUpdate(void) {
|
||||
|
||||
void EQ3publishMain(eq3_device_t* eq3) {
|
||||
ResponseAppend_P("\"MAC\":\"%s\"", addrStr(eq3->addr));
|
||||
const char* alias = BLE_ESP32::getAlias(eq3->addr);
|
||||
if (alias && *alias) ResponseAppend_P(",\"Alias\":\"%s\"", alias);
|
||||
ResponseAppend_P(",\"tas\":\"%s\"", NetworkHostname());
|
||||
ResponseAppend_P(",\"RSSI\":%d", eq3->RSSI);
|
||||
if (eq3->Firmware) ResponseAppend_P(",\"Firmware\":\"%u.%02u\"", eq3->Firmware / 100, eq3->Firmware % 100);
|
||||
ResponseAppend_P(",\"stattime\":%u", eq3->BTHomeAdvert ? UtcTime() : eq3->lastStatusTime);
|
||||
ResponseAppend_P(",\"temp\":%1_f", &eq3->TargetTemp);
|
||||
ResponseAppend_P(",\"posn\":%u", eq3->ValvePos);
|
||||
@@ -1142,7 +1159,14 @@ int EQ3Send(const uint8_t* addr, uint8_t CmdIdx, const char* param1, const char*
|
||||
break;
|
||||
}
|
||||
|
||||
case TRV_INFO: {
|
||||
d[0] = 0x00;
|
||||
dlen = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case TRV_POLL:
|
||||
EQ3Send(addr, TRV_INFO, nullptr, nullptr, useAlias); // Fallthrough is wanted
|
||||
case TRV_STATE:
|
||||
case TRV_SETTIME: {
|
||||
if (!*param1) {
|
||||
@@ -1516,6 +1540,13 @@ void CmndTrvOnlyAliased(void) {
|
||||
ResponseCmndNumber(EQ3OnlyAliased);
|
||||
}
|
||||
|
||||
void CmndTrvAliasAsTopic(void) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
EQ3AliasAsTopic = XdrvMailbox.payload;
|
||||
}
|
||||
ResponseCmndNumber(EQ3AliasAsTopic);
|
||||
}
|
||||
|
||||
void CmndTrvMinRSSI(void) {
|
||||
if (XdrvMailbox.data_len) {
|
||||
trvMinRSSI = tmax(tmin(XdrvMailbox.payload, 0), -99);
|
||||
|
||||
Reference in new issue
Block a user