From 74b0192b63ec8524d60997ade6f2f0e44b2f5fc0 Mon Sep 17 00:00:00 2001 From: Markus Kirberg Date: Thu, 17 Mar 2022 21:18:44 +0100 Subject: [PATCH] Shelly1/PM: Support Addon as Switch (Input) with autodetect wip more elaborate addon detection --- mos.yml | 15 ++++++++++--- src/Shelly1/shelly_init.cpp | 42 +++++++++++++++++++++++------------ src/Shelly1PM/shelly_init.cpp | 28 +++++++++++++++++------ src/ShellyU/shelly_init.cpp | 32 +++++++++++++++++--------- src/shelly_main.cpp | 15 +++++++++++++ src/shelly_main.hpp | 1 + 6 files changed, 98 insertions(+), 35 deletions(-) diff --git a/mos.yml b/mos.yml index b81aeafc..2842c8e6 100644 --- a/mos.yml +++ b/mos.yml @@ -231,9 +231,12 @@ conds: - ["in1", "in", {title: "Input 1 settings"}] - ["in1.ssw.name", "Shelly SSW1"] - ["in1.sensor.name", "Shelly S1"] + - ["in2", "in", {title: "Input 2 settings"}] + - ["in2.ssw.name", "Shelly SSW2"] + - ["in2.sensor.name", "Shelly S2"] - ["gdo1", "gdo", {title: "GDO1 settings"}] - ["gdo1.name", "Garage Door"] - - ["gdo1.open_sensor_mode", -1] + - ["gdo1.open_sensor_mode", 2] # Only for backward compatibility (config <= v3). - ["ssw1", "ssw", {title: "SSW1 settings"}] - ["ssw1.name", "Input"] @@ -315,9 +318,12 @@ conds: - ["in1", "in", {title: "Input 1 settings"}] - ["in1.ssw.name", "Shelly SSW1"] - ["in1.sensor.name", "Shelly S1"] + - ["in2", "in", {title: "Input 2 settings"}] + - ["in2.ssw.name", "Shelly SSW2"] + - ["in2.sensor.name", "Shelly S2"] - ["gdo1", "gdo", {title: "GDO1 settings"}] - ["gdo1.name", "Garage Door"] - - ["gdo1.open_sensor_mode", -1] + - ["gdo1.open_sensor_mode", 2] - ["bl0937.power_coeff", "f", 0, {title: "BL0937 counts -> watts conversion coefficient"}] - ["bl0937.power_coeff", 1.79942025] # (16 + 1010 + 1935) / (8.53 + 561 + 1076) # Only for backward compatibility (config <= v3). @@ -592,7 +598,7 @@ conds: - ["in1.sensor.name", "Shelly S1"] - ["gdo1", "gdo", {title: "GDO1 settings"}] - ["gdo1.name", "Garage Door"] - - ["gdo1.open_sensor_mode", -1] + - ["gdo1.open_sensor_mode", 2] # Only for backward compatibility (config <= v3). - ["ssw1", "ssw", {title: "SSW1 settings"}] - ["ssw1.name", "Input"] @@ -839,6 +845,9 @@ conds: - ["in1", "in", {title: "Input 1 settings"}] - ["in1.ssw.name", "ShellyU SSW1"] - ["in1.sensor.name", "ShellyU S1"] + - ["in2", "in", {title: "Input 2 settings"}] + - ["in2.ssw.name", "ShellyU SSW2"] + - ["in2.sensor.name", "ShellyU S2"] - when: build_vars.MODEL == "ShellyUDuo" apply: diff --git a/src/Shelly1/shelly_init.cpp b/src/Shelly1/shelly_init.cpp index e37e2328..0d6b93f2 100644 --- a/src/Shelly1/shelly_init.cpp +++ b/src/Shelly1/shelly_init.cpp @@ -18,6 +18,7 @@ #include "mgos_hap.h" #include "shelly_hap_garage_door_opener.hpp" +#include "shelly_hap_input.hpp" #include "shelly_hap_temperature_sensor.hpp" #include "shelly_input_pin.hpp" #include "shelly_main.hpp" @@ -34,26 +35,34 @@ void CreatePeripherals(std::vector> *inputs, std::vector> *pms UNUSED_ARG, std::unique_ptr *sys_temp UNUSED_ARG) { outputs->emplace_back(new OutputPin(1, 4, 1)); - auto *in = new InputPin(1, 5, 1, MGOS_GPIO_PULL_NONE, true); - in->AddHandler(std::bind(&HandleInputResetSequence, in, 4, _1, _2)); - in->Init(); - inputs->emplace_back(in); - - s_onewire.reset(new Onewire(3, 0)); - if (s_onewire->DiscoverAll().empty()) { - s_onewire.reset(); + auto *in1 = new InputPin(1, 5, 1, MGOS_GPIO_PULL_NONE, true); + in1->AddHandler(std::bind(&HandleInputResetSequence, in1, 4, _1, _2)); + in1->Init(); + inputs->emplace_back(in1); + + bool addon_detected = DetectAddon(3, 0); + + if (addon_detected) { + s_onewire.reset(new Onewire(3, 0)); + if (s_onewire->DiscoverAll().empty()) { + s_onewire.reset(); + + // No sensor detected, we assume we have a switch attached + auto *in2 = new InputPin(2, 3, 0, MGOS_GPIO_PULL_NONE, false); + in2->Init(); + inputs->emplace_back(in2); + } } } void CreateComponents(std::vector> *comps, std::vector> *accs, HAPAccessoryServerRef *svr) { - // Garage door opener mode. - if (mgos_sys_config_get_shelly_mode() == 2) { + if (mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor) { auto *gdo_cfg = (struct mgos_config_gdo *) mgos_sys_config_get_gdo1(); - std::unique_ptr gdo( - new hap::GarageDoorOpener(1, FindInput(1), nullptr /* in_open */, - FindOutput(1), FindOutput(1), gdo_cfg)); + + std::unique_ptr gdo(new hap::GarageDoorOpener( + 1, FindInput(1), FindInput(2), FindOutput(1), FindOutput(1), gdo_cfg)); if (gdo == nullptr) return; auto st = gdo->Init(); if (!st.ok()) { @@ -74,9 +83,12 @@ void CreateComponents(std::vector> *comps, sensors = s_onewire->DiscoverAll(); } + bool ext_sensor_switch = (FindInput(2) != nullptr); + // Single switch with non-detached input and no sensors = only one accessory. bool to_pri_acc = (sensors.empty() && (mgos_sys_config_get_sw1_in_mode() != - (int) InMode::kDetached)); + (int) InMode::kDetached)) && + !ext_sensor_switch; CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(), comps, accs, svr, to_pri_acc); @@ -92,6 +104,8 @@ void CreateComponents(std::vector> *comps, CreateHAPTemperatureSensor(i + 1, std::move(sensors[i]), ts_cfg, comps, accs, svr); } + } else if (ext_sensor_switch) { + hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr); } } diff --git a/src/Shelly1PM/shelly_init.cpp b/src/Shelly1PM/shelly_init.cpp index 898abe12..3a64ab4d 100644 --- a/src/Shelly1PM/shelly_init.cpp +++ b/src/Shelly1PM/shelly_init.cpp @@ -16,6 +16,7 @@ */ #include "shelly_hap_garage_door_opener.hpp" +#include "shelly_hap_input.hpp" #include "shelly_input_pin.hpp" #include "shelly_main.hpp" #include "shelly_pm_bl0937.hpp" @@ -51,10 +52,19 @@ void CreatePeripherals(std::vector> *inputs, } sys_temp->reset(new TempSensorSDNT1608X103F3950(0, 3.3f, 33000.0f)); - s_onewire.reset(new Onewire(3, 0)); - if (s_onewire->DiscoverAll().empty()) { + bool addon_detected = DetectAddon(3, 0); + + if (addon_detected) { + s_onewire.reset(new Onewire(3, 0)); + if (s_onewire->DiscoverAll().empty()) { + s_onewire.reset(); + + auto *in2 = new InputPin(2, 3, 0, MGOS_GPIO_PULL_NONE, false); + in2->Init(); + inputs->emplace_back(in2); + } + } else { // Sys LED shares the same pin. - s_onewire.reset(); InitSysLED(LED_GPIO, LED_ON); } InitSysBtn(BTN_GPIO, BTN_DOWN); @@ -66,9 +76,8 @@ void CreateComponents(std::vector> *comps, if (mgos_sys_config_get_shelly_mode() == 2) { // Garage door opener mode. auto *gdo_cfg = (struct mgos_config_gdo *) mgos_sys_config_get_gdo1(); - std::unique_ptr gdo( - new hap::GarageDoorOpener(1, FindInput(1), nullptr /* in_open */, - FindOutput(1), FindOutput(1), gdo_cfg)); + std::unique_ptr gdo(new hap::GarageDoorOpener( + 1, FindInput(1), FindInput(2), FindOutput(1), FindOutput(1), gdo_cfg)); if (gdo == nullptr) return; auto st = gdo->Init(); if (!st.ok()) { @@ -89,9 +98,12 @@ void CreateComponents(std::vector> *comps, sensors = s_onewire->DiscoverAll(); } + bool ext_sensor_switch = (FindInput(2) != nullptr); + // Single switch with non-detached input and no sensors = only one accessory. bool to_pri_acc = (sensors.empty() && (mgos_sys_config_get_sw1_in_mode() != - (int) InMode::kDetached)); + (int) InMode::kDetached)) && + !ext_sensor_switch; CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(), comps, accs, svr, to_pri_acc); @@ -107,6 +119,8 @@ void CreateComponents(std::vector> *comps, CreateHAPTemperatureSensor(i + 1, std::move(sensors[i]), ts_cfg, comps, accs, svr); } + } else if (ext_sensor_switch) { + hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr); } } diff --git a/src/ShellyU/shelly_init.cpp b/src/ShellyU/shelly_init.cpp index a6f34229..b67fa0f7 100644 --- a/src/ShellyU/shelly_init.cpp +++ b/src/ShellyU/shelly_init.cpp @@ -21,6 +21,7 @@ #include "mgos_rpc.h" #include "mgos_sys_config.h" +#include "shelly_hap_input.hpp" #include "shelly_hap_temperature_sensor.hpp" #include "shelly_input_pin.hpp" #include "shelly_main.hpp" @@ -33,9 +34,13 @@ void CreatePeripherals(std::vector> *inputs, std::vector> *outputs, std::vector> *pms, std::unique_ptr *sys_temp) { - Input *in = new InputPin(1, 12, 1, MGOS_GPIO_PULL_NONE, true); - in->Init(); - inputs->emplace_back(in); + auto *in1 = new InputPin(1, 12, 1, MGOS_GPIO_PULL_NONE, true); + in1->Init(); + inputs->emplace_back(in1); + + auto *in2 = new InputPin(2, 3, 0, MGOS_GPIO_PULL_NONE, false); + in2->Init(); + inputs->emplace_back(in2); outputs->emplace_back(new OutputPin(1, 34, 1)); @@ -53,15 +58,20 @@ void CreateComponents(std::vector> *comps, comps, accs, svr, false /* to_pri_acc */, nullptr /* led_out */); - // Sensors - for (int i = 0; i < 2; i++) { - std::unique_ptr temp(new MockTempSensor(25.125 + i)); - auto *ts_cfg = (i == 0) - ? (struct mgos_config_ts *) mgos_sys_config_get_ts1() - : (struct mgos_config_ts *) mgos_sys_config_get_ts2(); + bool ext_switch_detected = false; // can be set for testing purposes + + if (ext_switch_detected) { + hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr); + } else { + for (int i = 0; i < 2; i++) { + std::unique_ptr temp(new MockTempSensor(25.125 + i)); + auto *ts_cfg = (i == 0) + ? (struct mgos_config_ts *) mgos_sys_config_get_ts1() + : (struct mgos_config_ts *) mgos_sys_config_get_ts2(); - CreateHAPTemperatureSensor(i + 1, std::move(temp), ts_cfg, comps, accs, - svr); + CreateHAPTemperatureSensor(i + 1, std::move(temp), ts_cfg, comps, accs, + svr); + } } } diff --git a/src/shelly_main.cpp b/src/shelly_main.cpp index 4250cb22..f406a7aa 100644 --- a/src/shelly_main.cpp +++ b/src/shelly_main.cpp @@ -119,6 +119,21 @@ static std::vector s_hap_accs; static std::unique_ptr s_sys_temp_sensor; std::vector> g_comps; +bool DetectAddon(int pin_in, int pin_out) { + // case 1: input with pull up + mgos_gpio_setup_input(pin_in, MGOS_GPIO_PULL_UP); + // check if pulled by something external, not check output to input yet + bool active = mgos_gpio_read(pin_in); + if (!active) { + // something is pulling us low, we might have an addon with switchss + return true; + } + + // Try to pull low via addon + mgos_gpio_setup_output(pin_out, 0 /* LOW */); + mgos_gpio_setup_input(pin_in, MGOS_GPIO_PULL_NONE); + return !mgos_gpio_read(pin_in); +} template T *FindById(const std::vector> &vv, int id) { for (auto &v : vv) { diff --git a/src/shelly_main.hpp b/src/shelly_main.hpp index e07fb2f4..f2b8c771 100644 --- a/src/shelly_main.hpp +++ b/src/shelly_main.hpp @@ -40,6 +40,7 @@ namespace shelly { extern std::vector> g_comps; +bool DetectAddon(int pin_in, int pin_out); Input *FindInput(int id); Output *FindOutput(int id); PowerMeter *FindPM(int id);