Skip to content

Commit f2ead0d

Browse files
committed
Reboot the device if there is no wifi connection for 5 minutes
As a workaround for WiFi issues. Make sure that reboot only happens when there's nothing else going on and that the output state is preserved. #310
1 parent 91aaf90 commit f2ead0d

File tree

5 files changed

+66
-19
lines changed

5 files changed

+66
-19
lines changed

mos.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ conds:
382382
- ["wifi.ap.gw", ""]
383383
- ["wifi.ap.dhcp_start", "192.168.33.2"]
384384
- ["wifi.ap.dhcp_end", "192.168.33.100"]
385+
- ["wifi.sta_connect_timeout", 15]
386+
# This is a mitigation for devices dropping of wifi and never coming back.
387+
# While this is being investigated, the workaround is to reboot if not connected for 5 minutes when supposed to be.
388+
- ["shelly.wifi_connect_reboot_timeout", "i", 300, {title: "If not connected for this long when supposed to be, reboot"}]
385389
libs:
386390
- origin: https://github.com/mongoose-os-libs/adc
387391
- origin: https://github.com/mongoose-os-libs/wifi

src/Shelly1L/shelly_init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void CreatePeripherals(std::vector<std::unique_ptr<Input>> *inputs,
3636
auto *in2 = new NoisyInputPin(2, 14, 1, MGOS_GPIO_PULL_NONE, false);
3737
in2->Init();
3838
inputs->emplace_back(in2);
39-
#if 0 // 1L uses BL0937 in current-only mode. This is not yet supported.
39+
#if 0 // 1L uses BL0937 in current-only mode. This is not yet supported.
4040
std::unique_ptr<PowerMeter> pm(new BL0937PowerMeter(1, -1, 4, -1));
4141
if (pm->Init().ok()) {
4242
pms->emplace_back(std::move(pm));

src/shelly_main.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@
2525
#include "mgos_http_server.h"
2626
#include "mgos_ota.h"
2727
#include "mgos_rpc.h"
28+
#ifdef MGOS_HAVE_WIFI
29+
#include "mgos_wifi.h"
30+
#endif
2831

2932
#include "mongoose.h"
3033

3134
#if CS_PLATFORM == CS_P_ESP8266
3235
#include "esp_coredump.h"
3336
#include "esp_rboot.h"
37+
extern "C" {
38+
#include "user_interface.h"
39+
}
3440
#endif
3541

3642
#include "HAP.h"
@@ -543,6 +549,26 @@ static void StatusTimerCB(void *arg) {
543549
(sys_temp.ok() ? sys_temp.ValueOrDie() : 0), status.c_str()));
544550
s_cnt = 0;
545551
}
552+
#ifdef MGOS_HAVE_WIFI
553+
if (mgos_sys_config_get_wifi_sta_enable() &&
554+
mgos_sys_config_get_shelly_wifi_connect_reboot_timeout() > 0) {
555+
static int64_t s_last_connected = 0;
556+
int64_t now = mgos_uptime_micros();
557+
struct mgos_net_ip_info ip_info;
558+
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_STA,
559+
&ip_info)) {
560+
s_last_connected = now;
561+
} else if (AllComponentsIdle()) { // Only reboot if all components are
562+
// idle.
563+
int64_t timeout_micros =
564+
mgos_sys_config_get_shelly_wifi_connect_reboot_timeout() * 1000000;
565+
if (now - s_last_connected > timeout_micros) {
566+
LOG(LL_ERROR, ("Not connected for too long, rebooting"));
567+
mgos_system_restart_after(500);
568+
}
569+
}
570+
}
571+
#endif // MGOS_HAVE_WIFI
546572
(void) arg;
547573
}
548574

@@ -791,6 +817,15 @@ bool WipeDevice() {
791817
return wiped;
792818
}
793819

820+
bool IsSoftReboot() {
821+
#if CS_PLATFORM == CS_P_ESP8266
822+
const struct rst_info *ri = system_get_rst_info();
823+
return (ri->reason == REASON_SOFT_RESTART);
824+
#else
825+
return false;
826+
#endif
827+
}
828+
794829
void InitApp() {
795830
if (s_failsafe_mode) {
796831
if (WipeDevice()) {

src/shelly_main.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ void RestartService();
5252

5353
bool WipeDevice();
5454

55+
bool IsSoftReboot();
56+
5557
StatusOr<int> GetSystemTemperature();
5658

5759
#define SHELLY_SERVICE_FLAG_UPDATE (1 << 0)

src/shelly_switch.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "mgos_hap_accessory.hpp"
2222
#include "mgos_hap_chars.hpp"
2323

24+
#include "shelly_main.hpp"
25+
2426
namespace shelly {
2527

2628
ShellySwitch::ShellySwitch(int id, Input *in, Output *out, PowerMeter *out_pm,
@@ -163,24 +165,28 @@ Status ShellySwitch::Init() {
163165
std::bind(&ShellySwitch::InputEventHandler, this, _1, _2));
164166
in_->SetInvert(cfg_->in_inverted);
165167
}
166-
switch (static_cast<InitialState>(cfg_->initial_state)) {
167-
case InitialState::kOff:
168-
SetOutputState(false, "init");
169-
break;
170-
case InitialState::kOn:
171-
SetOutputState(true, "init");
172-
break;
173-
case InitialState::kLast:
174-
SetOutputState(cfg_->state, "init");
175-
break;
176-
case InitialState::kInput:
177-
if (in_ != nullptr &&
178-
cfg_->in_mode == static_cast<int>(InMode::kToggle)) {
179-
SetOutputState(in_->GetState(), "init");
180-
}
181-
break;
182-
case InitialState::kMax:
183-
break;
168+
bool should_restore = (cfg_->initial_state == (int) InitialState::kLast);
169+
if (IsSoftReboot()) should_restore = true;
170+
if (should_restore) {
171+
SetOutputState(cfg_->state, "init");
172+
} else {
173+
switch (static_cast<InitialState>(cfg_->initial_state)) {
174+
case InitialState::kOff:
175+
SetOutputState(false, "init");
176+
break;
177+
case InitialState::kOn:
178+
SetOutputState(true, "init");
179+
break;
180+
case InitialState::kInput:
181+
if (in_ != nullptr &&
182+
cfg_->in_mode == static_cast<int>(InMode::kToggle)) {
183+
SetOutputState(in_->GetState(), "init");
184+
}
185+
break;
186+
case InitialState::kLast:
187+
case InitialState::kMax:
188+
break;
189+
}
184190
}
185191
LOG(LL_INFO, ("Exporting '%s': type %d, state: %d", cfg_->name,
186192
cfg_->svc_type, out_->GetState()));

0 commit comments

Comments
 (0)