Skip to content

Commit

Permalink
feat: disconnect from HA in standby (#51)
Browse files Browse the repository at this point in the history
New option to disconnect from HA server when the device enters standby
and immediately reconnects when leaving standby (enabled by default).
This is controlled by the `enter_standby` and `exit_standby` events from
Remote Two.

Closes #50
  • Loading branch information
zehnm authored Feb 16, 2024
1 parent 390c3b2 commit 1a243a1
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

_Changes in the next release_

### Added
- Option to disconnect from HA when device enters standby ([#50](https://github.com/unfoldedcircle/integration-home-assistant/issues/50)).
### Changed
- Update Rust crates.

---
## v0.7.0 - 2024-02-05
### Added
Expand Down
1 change: 1 addition & 0 deletions configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ integration:
# heartbeat:
# interval_sec: 20
# timeout_sec: 40
# disconnect_in_standby: true
9 changes: 9 additions & 0 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ pub struct HomeAssistantSettings {
pub max_frame_size_kb: usize,
pub reconnect: ReconnectSettings,
pub heartbeat: HeartbeatSettings,
/// Disconnect WebSocket connection when remote enters standby.
/// Should be enabled if running on the device, disabled for an external integration.
// for data migration of existing configurations
#[serde(default = "default_disconnect_in_standby")]
pub disconnect_in_standby: bool,
}

impl Default for HomeAssistantSettings {
Expand All @@ -142,13 +147,17 @@ impl Default for HomeAssistantSettings {
max_frame_size_kb: 5120,
reconnect: Default::default(),
heartbeat: Default::default(),
disconnect_in_standby: default_disconnect_in_standby(),
}
}
}

fn default_request_timeout() -> u8 {
6
}
fn default_disconnect_in_standby() -> bool {
true
}

#[serde_as]
#[derive(Clone, serde::Deserialize, serde::Serialize)]
Expand Down
8 changes: 7 additions & 1 deletion src/controller/handler/r2_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,16 @@ impl Handler<R2EventMsg> for Controller {
}
R2Event::EnterStandby => {
session.standby = true;
if self.settings.hass.disconnect_in_standby {
ctx.notify(DisconnectMsg {});
}
}
R2Event::ExitStandby => {
session.standby = false;
// TODO send updates #5
if self.settings.hass.disconnect_in_standby {
ctx.notify(ConnectMsg::default());
self.send_device_state(&msg.ws_id);
}
}
R2Event::AbortDriverSetup => {
ctx.notify(AbortDriverSetup {
Expand Down
15 changes: 15 additions & 0 deletions src/controller/handler/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ impl Handler<SetDriverUserDataMsg> for Controller {
cfg.request_timeout = value;
}
}
if let Some(value) = parse_value(&values, "disconnect_in_standby") {
cfg.disconnect_in_standby = value;
}
if let Some(value) = parse_value(&values, "max_frame_size_kb") {
if value >= 1024 {
cfg.max_frame_size_kb = value;
Expand Down Expand Up @@ -239,6 +242,18 @@ impl Handler<RequestExpertOptionsMsg> for Controller {
}
}
},
{
"id": "disconnect_in_standby",
"label": {
"en": "Disconnect when entering standby",
"de": "Trennen der Verbindung im Standby-Modus"
},
"field": {
"checkbox": {
"value": self.settings.hass.disconnect_in_standby
}
}
},
{
"id": "max_frame_size_kb",
"label": {
Expand Down
1 change: 0 additions & 1 deletion src/controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ impl Controller {
if let Some(session) = self.sessions.get(ws_id) {
if session.standby {
debug!("Remote is in standby, not sending message: {:?}", message);
// TODO queue entity update events? #5
return;
}
if let Err(e) = session.recipient.try_send(SendWsMessage(message)) {
Expand Down
1 change: 0 additions & 1 deletion src/server/ws/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ impl Handler<SendWsMessage> for WsConn {
impl WsConn {
fn start_heartbeat(&self, ctx: &mut WebsocketContext<Self>) {
ctx.run_interval(self.heartbeat.interval, |act, ctx| {
// TODO check if we got standby event from remote: suspend until out of standby and then test connection #5
if Instant::now().duration_since(act.hb) > act.heartbeat.timeout {
info!("[{}] Closing connection due to failed heartbeat", act.id);
// remove WebSocket connection from our handler
Expand Down

0 comments on commit 1a243a1

Please sign in to comment.