Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New DEEPSLEEP topic for HA + Battery Level % support #19134

Merged
merged 12 commits into from
Jul 20, 2023
4 changes: 2 additions & 2 deletions tasmota/include/tasmota_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,8 @@ typedef struct {
uint16_t artnet_universe; // 734
uint16_t modbus_sbaudrate; // 736
uint16_t shutter_motorstop; // 738

uint8_t free_73A[3]; // 73A
uint8_t battery_level_percent; // 73A
uint8_t free_73B[2]; // 73B

uint8_t novasds_startingoffset; // 73D
uint8_t web_color[18][3]; // 73E
Expand Down
1 change: 1 addition & 0 deletions tasmota/tasmota_support/settings.ino
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ void SettingsDefaultSet2(void) {
if (Settings->sleep < 50) {
Settings->sleep = 50; // Default to 50 for sleep, for now
}
Settings->battery_level_percent = 101;

// Module
flag.interlock |= APP_INTERLOCK_MODE;
Expand Down
10 changes: 10 additions & 0 deletions tasmota/tasmota_support/support_command.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix
D_CMND_DEVICENAME "|" D_CMND_FN "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|"
D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|"
D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM"|" D_CMND_GLOBAL_PRESS "|" D_CMND_SWITCHTEXT "|" D_CMND_WIFISCAN "|" D_CMND_WIFITEST "|"
D_CMND_ZIGBEE_BATTPERCENT "|"
#ifdef USE_I2C
D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|"
#endif
Expand Down Expand Up @@ -73,6 +74,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = {
&CmndDevicename, &CmndFriendlyname, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd,
&CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode,
&CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndGlobalPress, &CmndSwitchText, &CmndWifiScan, &CmndWifiTest,
&CmndBatteryPercent,
#ifdef USE_I2C
&CmndI2cScan, &CmndI2cDriver,
#endif
Expand Down Expand Up @@ -245,6 +247,14 @@ void CmndWifiTest(void)
#endif //USE_WEBSERVER
}

void CmndBatteryPercent(void) {
if (XdrvMailbox.payload > 101) XdrvMailbox.payload = 100;
if (XdrvMailbox.payload >= 0) {
Settings->battery_level_percent = XdrvMailbox.payload;
}
ResponseCmndNumber(Settings->battery_level_percent);
}

#endif // not defined FIRMWARE_MINIMAL_ONLY

void ResponseCmndNumber(int value) {
Expand Down
7 changes: 7 additions & 0 deletions tasmota/tasmota_support/support_tasmota.ino
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,13 @@ void MqttShowState(void)
ResponseAppendTime();
ResponseAppend_P(PSTR(",\"" D_JSON_UPTIME "\":\"%s\",\"UptimeSec\":%u"), GetUptime().c_str(), UpTime());


// Battery Level expliciet for deepsleep devices
if (Settings->battery_level_percent != 101) {
ResponseAppend_P(PSTR(",\"" D_CMND_ZIGBEE_BATTPERCENT "\":%d"), Settings->battery_level_percent);
}


#ifdef ESP8266
#ifdef USE_ADC_VCC
dtostrfd((double)ESP.getVcc()/1000, 3, stemp1);
Expand Down
7 changes: 6 additions & 1 deletion tasmota/tasmota_xdrv_driver/xdrv_12_discovery.ino
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ void TasDiscoverMessage(void) {
"\"117\":%d},"
"\"lk\":%d," // Light CTRGB linked
"\"lt_st\":%d," // Light SubType
"\"bat\":%d," // Battery operates yes/no
"\"dslp\":%d," // Deepsleep configured yes/no
"\"sho\":["), // Shutter Options (start)
Settings->flag.mqtt_response,
Settings->flag.button_swap,
Expand All @@ -198,7 +200,10 @@ void TasDiscoverMessage(void) {
Settings->flag5.mqtt_switches,
Settings->flag5.fade_fixed_duration,
light_controller_isCTRGBLinked,
light_subtype);
light_subtype,
Settings->battery_level_percent==101?0:1,
Settings->deepsleep==0?0:1
);

for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) {
#ifdef USE_SHUTTER
Expand Down
31 changes: 16 additions & 15 deletions tasmota/tasmota_xdrv_driver/xdrv_29_deepsleep.ino
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
xdrv_29_deepsleep.ino - DeepSleep support for Tasmota

Copyright (C) 2022 Stefan Bode
Copyright (C) 2023 Stefan Bode

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -89,8 +89,9 @@ void DeepSleepReInit(void)
RtcSettings.ultradeepsleep = 0;
}

void DeepSleepPrepare(void)
void DeepSleepStart(void)
{
char stopic[TOPSZ];
// Deepsleep_slip is ideally 10.000 == 100%
// Typically the device has up to 4% slip. Anything else is a wrong setting in the deepsleep_slip
// Therefore all values >110% or <90% will be resetted to 100% to avoid crazy sleep times.
Expand Down Expand Up @@ -133,16 +134,17 @@ void DeepSleepPrepare(void)
// uint32_t deepsleep_sleeptime = DEEPSLEEP_MAX_CYCLE < (RtcSettings.nextwakeup - LocalTime()) ? (uint32_t)DEEPSLEEP_MAX_CYCLE : RtcSettings.nextwakeup - LocalTime();
deepsleep_sleeptime = tmin((uint32_t)DEEPSLEEP_MAX_CYCLE ,RtcSettings.nextwakeup - LocalTime());

// stat/tasmota/DEEPSLEEP = {"DeepSleep":{"Time":"2019-11-12T21:33:45","Epoch":1573590825}}
Response_P(PSTR("{\"" D_PRFX_DEEPSLEEP "\":{\"" D_JSON_TIME "\":\"%s\",\"Epoch\":%d}}"), (char*)dt.c_str(), RtcSettings.nextwakeup);
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_DEEPSLEEP));
// Sending Deepsleep parameters to automation for react
Response_P(PSTR("{\"" D_PRFX_DEEPSLEEP "\":{\"" D_JSON_TIME "\":\"%s\",\"" D_PRFX_DEEPSLEEP "\":%d,\"Wakeup\":%d}}"), (char*)dt.c_str(), LocalTime(), RtcSettings.nextwakeup);
MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_PRFX_DEEPSLEEP), true);

// Response_P(S_LWT_OFFLINE);
// MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
}
// Change LWT Topic to Sleep to ensure automation see different state
//GetTopic_P(stopic, TELE, TasmotaGlobal.mqtt_topic, S_LWT);
//Response_P(PSTR(D_PRFX_DEEPSLEEP));
//MqttPublish(stopic, true);

void DeepSleepStart(void)
{
//MqttClient.disconnect(true);
//EspClient.stop();
WifiShutdown();
RtcSettings.ultradeepsleep = RtcSettings.nextwakeup - LocalTime();
RtcSettingsSave();
Expand All @@ -155,8 +157,10 @@ void DeepSleepStart(void)
esp_deep_sleep_start();
#endif // ESP32
yield();

}


void DeepSleepEverySecond(void)
{
//AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("Wifi Info: up %d, wifidown %d, wifistatus %d, flag %d"),TasmotaGlobal.uptime, TasmotaGlobal.global_state.wifi_down, Wifi.status , deepsleep_flag);
Expand All @@ -168,12 +172,8 @@ void DeepSleepEverySecond(void)
if (!deepsleep_flag) { return; }

if (DeepSleepEnabled()) {
if (DEEPSLEEP_START_COUNTDOWN == deepsleep_flag) { // Allow 4 seconds to update web console before deepsleep
if (DEEPSLEEP_START_COUNTDOWN == deepsleep_flag) {
SettingsSaveAll();
DeepSleepPrepare();
}
deepsleep_flag--;
if (deepsleep_flag <= 0) {
DeepSleepStart();
}
} else {
Expand All @@ -197,6 +197,7 @@ void CmndDeepsleepTime(void)
Settings->tele_period = TELE_PERIOD; // Need teleperiod to go back to sleep
}
}
TasDiscovery();
}
ResponseCmndNumber(Settings->deepsleep);
}
Expand Down