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

Plusaddon/digital in #1396

Merged
merged 4 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ Reverting to stock firmware is also possible [see here](https://github.com/mongo

## Supported devices and features

### Gen 3 Devices

Currently not supported.

### Plus devices

Expand Down Expand Up @@ -72,7 +75,7 @@ Features that are not yet supported:
* Watch a 2 minute [video](https://www.youtube.com/watch?v=BZc-kp4dDRw).

* *New:* One link for all device types: `http://A.B.C.D/ota?url=http://shelly.rojer.cloud/update`
* **Note:** There is an issue upgrading Plus devices on latest stock firmwares; The problem is fixed with the latest beta available here: https://github.com/mongoose-os-apps/shelly-homekit/releases/tag/2.12.0-beta2 The update has to be done via Webinterface and the corresponding shelly-homekit-[your device].zip File **Note that this is a beta version**
* **Note:** There is an issue upgrading Plus devices on latest stock firmwares; The problem is fixed with the latest beta available here: https://github.com/mongoose-os-apps/shelly-homekit/releases/tag/2.12.0-beta4 The update has to be done via Webinterface and the corresponding shelly-homekit-[your device].zip File **Note that this is a beta version** On safari: save files with right click otherwise zip will be extracted on
*
<details>
<summary>If that doesn't work (did you remember to update the stock firmware first?), try link for a specific model</summary>
Expand Down Expand Up @@ -153,6 +156,7 @@ This firmware is free software and is distributed under [Apache 2.0 license](LIC
[+1]: https://www.shelly.cloud/en/products/shop/shelly-plus-1
[+1PM]: https://www.shelly.cloud/en/products/shop/shelly-plus-1-pm-2-pack/shelly-plus-1-pm
[+2PM]: https://www.shelly.cloud/en/products/shop/shelly-plus-2-pm
[+Plug S]: https://www.shelly.cloud/en/products/shop/shelly-plus-plug-s
[1L]: https://www.shelly.cloud/en/products/shop/shelly-1l
[Plug]: https://www.shelly.cloud/en/products/shop/1xplug
[PlugS]: https://www.shelly.cloud/en/products/shop/shelly-plug-s
Expand Down
7 changes: 5 additions & 2 deletions mos.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
author: Shelly-HomeKit contributors
description: A HomeKit firmware for Shelly switches
version: 2.12.0-beta3
version: 2.12.0-beta4

libs_version: latest
modules_version: latest
Expand Down Expand Up @@ -564,7 +564,7 @@ conds:
cdefs:
LED_GPIO: 2 # Blue, 0 red.
LED_ON: 0
BTN_GPIO: 13
BTN_GPIO: 9
BTN_DOWN: 0
PRODUCT_HW_REV: "1.0"
STOCK_FW_MODEL: SHPLG-S
Expand Down Expand Up @@ -772,6 +772,9 @@ conds:
- ["in2", "in", {title: "Input 2 settings"}]
- ["in2.ssw.name", "Shelly SSW2"]
- ["in2.sensor.name", "Shelly S2"]
- ["in3", "in", {title: "Input 3 settings"}]
- ["in3.ssw.name", "Shelly SSW3"]
- ["in3.sensor.name", "Shelly S3"]
- ["wc1", "wc", {title: "WC1 settings"}]
- ["wc1.name", "Window 1"]
- ["gdo1", "gdo", {title: "GDO1 settings"}]
Expand Down
66 changes: 10 additions & 56 deletions src/Shelly25/shelly_init_components.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,64 +27,18 @@ namespace shelly {
void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,
std::vector<std::unique_ptr<mgos::hap::Accessory>> *accs,
HAPAccessoryServerRef *svr) {
// Roller-shutter mode.
if (mgos_sys_config_get_shelly_mode() == 1) {
const int id = 1;
auto *wc_cfg = (struct mgos_config_wc *) mgos_sys_config_get_wc1();
auto im = static_cast<hap::WindowCovering::InMode>(wc_cfg->in_mode);
Input *in1 = FindInput(1), *in2 = FindInput(2);
std::unique_ptr<hap::WindowCovering> wc(
new hap::WindowCovering(id, in1, in2, FindOutput(1), FindOutput(2),
FindPM(1), FindPM(2), wc_cfg));
if (wc == nullptr || !wc->Init().ok()) {
return;
}
wc->set_primary(true);
switch (im) {
case hap::WindowCovering::InMode::kSeparateMomentary:
case hap::WindowCovering::InMode::kSeparateToggle: {
// Single accessory with a single primary service.
mgos::hap::Accessory *pri_acc = (*accs)[0].get();
pri_acc->SetCategory(kHAPAccessoryCategory_WindowCoverings);
pri_acc->AddService(wc.get());
break;
}
case hap::WindowCovering::InMode::kSingle:
case hap::WindowCovering::InMode::kDetached: {
std::unique_ptr<mgos::hap::Accessory> acc(
new mgos::hap::Accessory(SHELLY_HAP_AID_BASE_WINDOW_COVERING + id,
kHAPAccessoryCategory_BridgedAccessory,
wc_cfg->name, GetIdentifyCB(), svr));
acc->AddHAPService(&mgos_hap_accessory_information_service);
acc->AddService(wc.get());
accs->push_back(std::move(acc));
if (im == hap::WindowCovering::InMode::kDetached) {
hap::CreateHAPInput(1, mgos_sys_config_get_in1(), comps, accs, svr);
hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
} else if (wc_cfg->swap_inputs) {
hap::CreateHAPInput(1, mgos_sys_config_get_in1(), comps, accs, svr);
} else {
hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
}
break;
}
}
comps->emplace(comps->begin(), std::move(wc));
if (mgos_sys_config_get_shelly_mode() == (int) Mode::kRollerShutter) {
hap::CreateHAPWC(1, FindInput(1), FindInput(2), FindOutput(1),
FindOutput(2), FindPM(1), FindPM(2),
mgos_sys_config_get_wc1(), mgos_sys_config_get_in1(),
mgos_sys_config_get_in2(), comps, accs, svr);
return;
}
// Garage door opener mode.
if (mgos_sys_config_get_shelly_mode() == 2) {
auto *gdo_cfg = (struct mgos_config_gdo *) mgos_sys_config_get_gdo1();
std::unique_ptr<hap::GarageDoorOpener> gdo(new hap::GarageDoorOpener(
1, FindInput(1), FindInput(2), FindOutput(1), FindOutput(2), gdo_cfg));
if (gdo == nullptr || !gdo->Init().ok()) {
return;
}
gdo->set_primary(true);
mgos::hap::Accessory *pri_acc = (*accs)[0].get();
pri_acc->SetCategory(kHAPAccessoryCategory_GarageDoorOpeners);
pri_acc->AddService(gdo.get());
comps->emplace_back(std::move(gdo));

if (mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor) {
hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
FindOutput(2), mgos_sys_config_get_gdo1(), comps, accs,
svr, true /* single accessory */);
return;
}
// Use legacy layout if upgraded from an older version (pre-2.1).
Expand Down
18 changes: 9 additions & 9 deletions src/ShellyPlus1/shelly_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,13 @@ void CreatePeripherals(std::vector<std::unique_ptr<Input>> *inputs,
s_onewire.reset();
sensors = DiscoverDHTSensors(pin_in, pin_out);
}
if (sensors.empty()) {
// No sensors detected, we assume to use addon as input for switch or
// closed/open sensor
auto *in2 = new InputPin(2, pin_in, 0, MGOS_GPIO_PULL_NONE, false);
in2->Init();
inputs->emplace_back(in2);
}

auto *in2 = new InputPin(2, 19, 0, MGOS_GPIO_PULL_NONE, false);
in2->Init();
inputs->emplace_back(in2);

} else {
RestoreUART();
InitSysLED(LED_GPIO, LED_ON);
}
InitSysBtn(BTN_GPIO, BTN_DOWN);
Expand All @@ -69,7 +68,7 @@ void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,
bool gdo_mode = mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor;
bool ext_sensor_switch = (FindInput(2) != nullptr);
bool detatched_sensor =
(mgos_sys_config_get_sw1_in_mode() != (int) InMode::kDetached) &&
(mgos_sys_config_get_sw1_in_mode() == (int) InMode::kDetached) &&
!gdo_mode && ext_sensor_switch;
bool single_accessory = sensors.empty() && !detatched_sensor;
if (gdo_mode) {
Expand All @@ -83,7 +82,8 @@ void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,

if (!sensors.empty()) {
CreateHAPSensors(&sensors, comps, accs, svr);
} else if (detatched_sensor) {
}
if (ext_sensor_switch && !gdo_mode) {
hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/ShellyPlus1PM/shelly_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,13 @@ void CreatePeripherals(std::vector<std::unique_ptr<Input>> *inputs,
s_onewire.reset();
sensors = DiscoverDHTSensors(pin_in, pin_out);
}
if (sensors.empty()) {
// No sensors detected, we assume to use addon as input for switch or
// closed/open sensor
auto *in2 = new InputPin(2, pin_in, 0, MGOS_GPIO_PULL_NONE, false);
in2->Init();
inputs->emplace_back(in2);
}

auto *in2 = new InputPin(2, 19, 0, MGOS_GPIO_PULL_NONE, false);
in2->Init();
inputs->emplace_back(in2);

} else {
RestoreUART();
InitSysLED(LED_GPIO, LED_ON);
}
InitSysBtn(BTN_GPIO, BTN_DOWN);
Expand All @@ -131,7 +130,7 @@ void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,
bool gdo_mode = mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor;
bool ext_sensor_switch = (FindInput(2) != nullptr);
bool detatched_sensor =
(mgos_sys_config_get_sw1_in_mode() != (int) InMode::kDetached) &&
(mgos_sys_config_get_sw1_in_mode() == (int) InMode::kDetached) &&
!gdo_mode && ext_sensor_switch;
bool single_accessory = sensors.empty() && !detatched_sensor;
if (gdo_mode) {
Expand All @@ -145,7 +144,8 @@ void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,

if (!sensors.empty()) {
CreateHAPSensors(&sensors, comps, accs, svr);
} else if (detatched_sensor) {
}
if (ext_sensor_switch && !gdo_mode) {
hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
}
}
Expand Down
74 changes: 16 additions & 58 deletions src/ShellyPlus2PM/shelly_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,23 +213,20 @@ void CreatePeripherals(std::vector<std::unique_ptr<Input>> *inputs,
int pin_out = 0;
int pin_in = 1;

// TODO: this blocks UART as UART TX is GPIO1. Can we find out via
// ESP_UART_ENABLE (WHICH GPIO)?
if (DetectAddon(pin_in, pin_out)) {
s_onewire.reset(new Onewire(pin_in, pin_out));
sensors = s_onewire->DiscoverAll();
if (sensors.empty()) {
s_onewire.reset();
sensors = DiscoverDHTSensors(pin_in, pin_out);
}
if (sensors.empty()) {
// No sensors detected, we assume to use addon as input for switch or
// closed/open sensor
auto *in2 = new InputPin(2, pin_in, 0, MGOS_GPIO_PULL_NONE, false);
in2->Init();
inputs->emplace_back(in2);
}

auto *in_digital = new InputPin(3, 19, 0, MGOS_GPIO_PULL_NONE, false);
in_digital->Init();
inputs->emplace_back(in_digital);

} else {
RestoreUART();
InitSysLED(LED_GPIO, LED_ON);
}

Expand All @@ -239,59 +236,17 @@ void CreatePeripherals(std::vector<std::unique_ptr<Input>> *inputs,
void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,
std::vector<std::unique_ptr<mgos::hap::Accessory>> *accs,
HAPAccessoryServerRef *svr) {
bool single_accessory = sensors.empty();

// do not block uart when ESP_DBG_UART = 1
// this should be gpio19?
// mgos_gpio_setup_input(19, MGOS_GPIO_PULL_NONE); // pulldown?
// bool val = mgos_gpio_read(19);
// LOG(LL_INFO, ("gpio 19 is: %i", val ? 1 : 0));

if (mgos_sys_config_get_shelly_mode() == (int) Mode::kRollerShutter) {
const int id = 1;
auto *wc_cfg = (struct mgos_config_wc *) mgos_sys_config_get_wc1();
auto im = static_cast<hap::WindowCovering::InMode>(wc_cfg->in_mode);
Input *in1 = FindInput(1), *in2 = FindInput(2);
std::unique_ptr<hap::WindowCovering> wc(
new hap::WindowCovering(id, in1, in2, FindOutput(1), FindOutput(2),
FindPM(1), FindPM(2), wc_cfg));
if (wc == nullptr || !wc->Init().ok()) {
return;
}
wc->set_primary(true);
switch (im) {
case hap::WindowCovering::InMode::kSeparateMomentary:
case hap::WindowCovering::InMode::kSeparateToggle: {
// Single accessory with a single primary service.
mgos::hap::Accessory *pri_acc = (*accs)[0].get();
pri_acc->SetCategory(kHAPAccessoryCategory_WindowCoverings);
pri_acc->AddService(wc.get());
break;
}
case hap::WindowCovering::InMode::kSingle:
case hap::WindowCovering::InMode::kDetached: {
std::unique_ptr<mgos::hap::Accessory> acc(
new mgos::hap::Accessory(SHELLY_HAP_AID_BASE_WINDOW_COVERING + id,
kHAPAccessoryCategory_BridgedAccessory,
wc_cfg->name, GetIdentifyCB(), svr));
acc->AddHAPService(&mgos_hap_accessory_information_service);
acc->AddService(wc.get());
accs->push_back(std::move(acc));
if (im == hap::WindowCovering::InMode::kDetached) {
hap::CreateHAPInput(1, mgos_sys_config_get_in1(), comps, accs, svr);
hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
} else if (wc_cfg->swap_inputs) {
hap::CreateHAPInput(1, mgos_sys_config_get_in1(), comps, accs, svr);
} else {
hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
}
break;
}
}
comps->emplace(comps->begin(), std::move(wc));
hap::CreateHAPWC(1, FindInput(1), FindInput(2), FindOutput(1),
FindOutput(2), FindPM(1), FindPM(2),
mgos_sys_config_get_wc1(), mgos_sys_config_get_in1(),
mgos_sys_config_get_in2(), comps, accs, svr);
return;
}

bool additional_input_digital = (FindInput(3) != nullptr);
bool single_accessory = sensors.empty() and !additional_input_digital;

if (mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor) {
hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
FindOutput(2), mgos_sys_config_get_gdo1(), comps, accs,
Expand All @@ -306,6 +261,9 @@ void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,
if (!sensors.empty()) {
CreateHAPSensors(&sensors, comps, accs, svr);
}
if (additional_input_digital) {
hap::CreateHAPInput(3, mgos_sys_config_get_in3(), comps, accs, svr);
}
}

} // namespace shelly
1 change: 1 addition & 0 deletions src/ShellyPlusI4/shelly_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ void CreatePeripherals(std::vector<std::unique_ptr<Input>> *inputs,
sensors = DiscoverDHTSensors(pin_in, pin_out);
}
} else {
RestoreUART();
InitSysLED(LED_GPIO, LED_ON);
}
InitSysBtn(BTN_GPIO, BTN_DOWN);
Expand Down
51 changes: 51 additions & 0 deletions src/shelly_hap_window_covering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include "mgos.hpp"
#include "mgos_system.hpp"

#include "shelly_hap_input.hpp"
#include "shelly_main.hpp"

namespace shelly {
namespace hap {

Expand Down Expand Up @@ -730,5 +733,53 @@ void WindowCovering::HandleInputSingle(const char *src) {
}
}

void CreateHAPWC(int id, Input *in1, Input *in2, Output *out1, Output *out2,
PowerMeter *pm1, PowerMeter *pm2,
const struct mgos_config_wc *wc_cfg,
const struct mgos_config_in *in1_cfg,
const struct mgos_config_in *in2_cfg,
std::vector<std::unique_ptr<Component>> *comps,
std::vector<std::unique_ptr<mgos::hap::Accessory>> *accs,
HAPAccessoryServerRef *svr) {
auto im = static_cast<hap::WindowCovering::InMode>(wc_cfg->in_mode);
std::unique_ptr<hap::WindowCovering> wc(new hap::WindowCovering(
id, in1, in2, out1, out2, pm1, pm2, (struct mgos_config_wc *) wc_cfg));
if (wc == nullptr || !wc->Init().ok()) {
return;
}
wc->set_primary(true);
switch (im) {
case hap::WindowCovering::InMode::kSeparateMomentary:
case hap::WindowCovering::InMode::kSeparateToggle: {
// Single accessory with a single primary service.
mgos::hap::Accessory *pri_acc = (*accs)[0].get();
pri_acc->SetCategory(kHAPAccessoryCategory_WindowCoverings);
pri_acc->AddService(wc.get());
break;
}
case hap::WindowCovering::InMode::kSingle:
case hap::WindowCovering::InMode::kDetached: {
// non primary
std::unique_ptr<mgos::hap::Accessory> acc(
new mgos::hap::Accessory(SHELLY_HAP_AID_BASE_WINDOW_COVERING + id,
kHAPAccessoryCategory_BridgedAccessory,
wc_cfg->name, GetIdentifyCB(), svr));
acc->AddHAPService(&mgos_hap_accessory_information_service);
acc->AddService(wc.get());
accs->push_back(std::move(acc));
if (im == hap::WindowCovering::InMode::kDetached) {
hap::CreateHAPInput(1, in1_cfg, comps, accs, svr);
hap::CreateHAPInput(2, in2_cfg, comps, accs, svr);
} else if (wc_cfg->swap_inputs) {
hap::CreateHAPInput(1, in1_cfg, comps, accs, svr);
} else {
hap::CreateHAPInput(2, in2_cfg, comps, accs, svr);
}
break;
}
}
comps->emplace(comps->begin(), std::move(wc));
}

} // namespace hap
} // namespace shelly
Loading