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

Detached with relay control #1011

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions fs_src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,13 @@ <h1 id="head">Switch</h1>
<option id="in_mode_6" value="6">Activation (both inputs)</option>
</select>
</div>
<div class="form-control" id="homekit_button_container" style="display: none">
<label for="homekit_button">Homekit Button</label>
<label class="switch">
<input type="checkbox" id="homekit_button">
<span class="slider round"></span>
</label>
</div>
<div class="form-control" id="in_inverted_container" style="display: none">
<label for="in_inverted">Inverted Input:</label>
<label class="switch">
Expand Down
6 changes: 6 additions & 0 deletions fs_src/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ function swSetConfig(c) {
svc_type: parseInt(el(c, "svc_type").value),
initial_state: parseInt(el(c, "initial").value),
auto_off: autoOff,
homekit_button: el(c, "homekit_button").checked,
in_inverted: el(c, "in_inverted").checked,
out_inverted: el(c, "out_inverted").checked,
};
Expand Down Expand Up @@ -697,6 +698,10 @@ function updateComponent(cd) {
selectIfNotModified(el(c, "initial"), cd.initial);
if (cd.in_mode >= 0) {
selectIfNotModified(el(c, "in_mode"), cd.in_mode);
if (cd.in_mode == 0) {
checkIfNotModified(el(c, "homekit_button"), cd.homekit_button);
el(c, "homekit_button_container").style.display = "block";
}
if (cd.in_mode != 3) {
checkIfNotModified(el(c, "in_inverted"), cd.in_inverted);
el(c, "in_inverted_container").style.display = "block";
Expand All @@ -707,6 +712,7 @@ function updateComponent(cd) {
}
} else {
el(c, "in_mode_container").style.display = "none";
el(c, "homekit_button_container").style.display = "none";
el(c, "in_inverted_container").style.display = "none";
if (el(c, "initial_3")) el(c, "initial_3").remove();
}
Expand Down
3 changes: 2 additions & 1 deletion 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.11.0
version: 2.11.0-homekitButton

libs_version: latest
modules_version: latest
Expand Down Expand Up @@ -49,6 +49,7 @@ config_schema:
- ["sw.enable", "b", true, {title: "Enable this switch in the accessory"}]
- ["sw.out_inverted", "b", false, {title: "Invert output, set to true for normally open output"}]
- ["sw.in_mode", "i", 1, {title: "-1 - Absent, 0 - Momentary, 1 - Toggle, 2 - Edge, 3 - Detached"}]
- ["sw.homekit_button", "b", false, {title: "Advanced: Homekit Button"}]
- ["sw.in_inverted", "b", false, {title: "Invert input, set to true for normally closed input"}]
- ["sw.state", "b", false, {title: "State of the switch"}]
- ["sw.svc_type", "i", 0, {title: "HAP service type, -1 = disable, 0 = switch, 1 = outlet, 2 = lock, 3 = valve"}]
Expand Down
3 changes: 2 additions & 1 deletion src/Shelly1PM/shelly_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,

// 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) && (mgos_sys_config_get_sw1_in_mode() ==
(int) InMode::kMomentary && mgos_sys_config_get_sw1_homekit_button() != true));
CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
comps, accs, svr, to_pri_acc);

Expand Down
2 changes: 1 addition & 1 deletion src/ShellyRGBW2/shelly_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void CreateComponents(std::vector<std::unique_ptr<Component>> *comps,
}
comps->push_back(std::move(hap_light));

if (lb_cfg->in_mode == (int) InMode::kDetached && first_detatched_input) {
if ( lb_cfg->in_mode == (int) InMode::kDetached && first_detatched_input) {
hap::CreateHAPInput(1, mgos_sys_config_get_in1(), comps, accs, svr);
first_detatched_input = false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/shelly_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void CreateHAPSwitch(int id, const struct mgos_config_sw *sw_cfg,
acc->AddService(sw2);
accs->push_back(std::move(acc));
}
if (sw_cfg->in_mode == (int) InMode::kDetached) {
if (sw_cfg->in_mode == (int) InMode::kDetached || (sw_cfg->in_mode == (int) InMode::kMomentary && sw_cfg->homekit_button)) {
hap::CreateHAPInput(id, in_cfg, comps, accs, svr);
}
}
Expand Down
24 changes: 18 additions & 6 deletions src/shelly_switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,18 @@ StatusOr<std::string> ShellySwitch::GetInfo() const {
int in_st = -1;
if (!ins_.empty()) in_st = GetInputState();
const_cast<ShellySwitch *>(this)->SaveState();
return mgos::SPrintf("st:%d in_st:%d inm:%d ininv:%d", out_->GetState(),
in_st, cfg_->in_mode, cfg_->in_inverted);
return mgos::SPrintf("st:%d in_st:%d inm:%d hkbtn:%d ininv:%d", out_->GetState(),
in_st, cfg_->in_mode, cfg_->homekit_button, cfg_->in_inverted);
}

StatusOr<std::string> ShellySwitch::GetInfoJSON() const {
const bool hdim = (SHELLY_HAVE_DUAL_INPUT_MODES ? true : false);
std::string res = mgos::JSONPrintStringf(
"{id: %d, type: %d, name: %Q, svc_type: %d, valve_type: %d, in_mode: %d, "
"{id: %d, type: %d, name: %Q, svc_type: %d, valve_type: %d, in_mode: %d, homekit_button: %B, "
"in_inverted: %B, initial: %d, state: %B, auto_off: %B, "
"auto_off_delay: %.3f, state_led_en: %d, out_inverted: %B, hdim: %B",
id(), type(), (cfg_->name ? cfg_->name : ""), cfg_->svc_type,
cfg_->valve_type, cfg_->in_mode, cfg_->in_inverted, cfg_->initial_state,
cfg_->valve_type, cfg_->in_mode, cfg_->homekit_button, cfg_->in_inverted, cfg_->initial_state,
out_->GetState(), cfg_->auto_off, cfg_->auto_off_delay,
cfg_->state_led_en, cfg_->out_inverted, hdim);
if (out_pm_ != nullptr) {
Expand All @@ -105,14 +105,15 @@ Status ShellySwitch::SetConfig(const std::string &config_json,
bool *restart_required) {
struct mgos_config_sw cfg = *cfg_;
int8_t in_inverted = -1;
int8_t homekit_button = -1;
cfg.name = nullptr;
cfg.in_mode = -2;
json_scanf(
config_json.c_str(), config_json.size(),
"{name: %Q, svc_type: %d, valve_type: %d, in_mode: %d, in_inverted: %B, "
"{name: %Q, svc_type: %d, valve_type: %d, in_mode: %d, homekit_button: %B, in_inverted: %B, "
"initial_state: %d, "
"auto_off: %B, auto_off_delay: %lf, state_led_en: %d, out_inverted: %B}",
&cfg.name, &cfg.svc_type, &cfg.valve_type, &cfg.in_mode, &in_inverted,
&cfg.name, &cfg.svc_type, &cfg.valve_type, &cfg.in_mode, &homekit_button, &in_inverted,
&cfg.initial_state, &cfg.auto_off, &cfg.auto_off_delay, &cfg.state_led_en,
&cfg.out_inverted);
mgos::ScopedCPtr name_owner((void *) cfg.name);
Expand Down Expand Up @@ -174,6 +175,10 @@ Status ShellySwitch::SetConfig(const std::string &config_json,
}
cfg_->in_mode = cfg.in_mode;
}
if (homekit_button != -1 && cfg_->homekit_button != homekit_button) {
cfg_->homekit_button = homekit_button;
*restart_required = true;
}
if (in_inverted != -1 && cfg_->in_inverted != in_inverted) {
cfg_->in_inverted = in_inverted;
*restart_required = true;
Expand Down Expand Up @@ -318,6 +323,9 @@ void ShellySwitch::InputEventHandler(Input::Event ev, bool state) {
case Input::Event::kChange: {
switch (static_cast<InMode>(cfg_->in_mode)) {
case InMode::kMomentary:
if (cfg_->homekit_button) {
break;
}
if (state) { // Only on 0 -> 1 transitions.
SetOutputState(!out_->GetState(), "ext_mom");
}
Expand Down Expand Up @@ -357,6 +365,10 @@ void ShellySwitch::InputEventHandler(Input::Event ev, bool state) {
}
break;
case Input::Event::kSingle:
if (in_mode == InMode::kMomentary && cfg_->homekit_button) {
SetOutputState(!out_->GetState(), "ext_mom");
}
break;
case Input::Event::kDouble:
case Input::Event::kReset:
case Input::Event::kMax:
Expand Down
2 changes: 1 addition & 1 deletion tools/flash-shelly.py
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ def check_fw(self, device, version):
device_version = self.parse_version(device.info.get('version', '0.0.0'))
if device.fw_type == "homekit" and float(f"{device_version[0]}.{device_version[1]}") < version:
logger.error(f"{WHITE}Host: {NC}{device.host}")
logger.error(f"Version {device.info.get('version')} is to old for this script,")
logger.error(f"Version {device.info.get('version')} is too old for this script,")
logger.error("please update via the device webUI.")
logger.error("")
return False
Expand Down