Directly send wol packet instead of using the webhook
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
a0cefa8302
commit
aa8963bd4a
|
@ -30,8 +30,9 @@ steps:
|
|||
|
||||
- docker rm automation_rs || true
|
||||
|
||||
- docker create -e RUST_LOG=$RUST_LOG -e MQTT_PASSWORD=$MQTT_PASSWORD -e HUE_TOKEN=$HUE_TOKEN -e NTFY_TOPIC=$NTFY_TOPIC --name automation_rs automation_rs
|
||||
- docker network connect mqtt automation_rs
|
||||
# Networks need to be setup to to allow broadcasts: https://www.devwithimagination.com/2020/06/15/homebridge-docker-and-wake-on-lan/ https://github.com/dhutchison/container-images/blob/0c2d7d96bab751fb0a008cc91ba2990724bbd11f/homebridge/configure_docker_networks_for_wol.sh
|
||||
# Needs to be done for ALL networks, because we can't seem to control which interface gets used to send the broadcast
|
||||
- docker create -e RUST_LOG=$RUST_LOG -e MQTT_PASSWORD=$MQTT_PASSWORD -e HUE_TOKEN=$HUE_TOKEN -e NTFY_TOPIC=$NTFY_TOPIC --network mqtt --restart unless-stopped --name automation_rs automation_rs
|
||||
- docker network connect web automation_rs
|
||||
- docker start automation_rs
|
||||
|
||||
|
|
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -17,6 +17,12 @@ version = "1.0.68"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
||||
|
||||
[[package]]
|
||||
name = "async-recursion"
|
||||
version = "1.0.0"
|
||||
|
@ -72,6 +78,7 @@ dependencies = [
|
|||
"toml",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"wakey",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -375,6 +382,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.8"
|
||||
|
@ -1282,6 +1295,16 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "wakey"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dedab5a691c0d33bcfb5c1ed6bb17265e531ed3392282eed9b20063a0f23e9f5"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"hex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
|
|
|
@ -33,6 +33,7 @@ futures = "0.3.25"
|
|||
eui48 = { version = "1.1.0", default-features = false, features = ["disp_hexstring", "serde"] }
|
||||
thiserror = "1.0.38"
|
||||
anyhow = "1.0.68"
|
||||
wakey = "0.3.0"
|
||||
|
||||
[profile.release]
|
||||
lto=true
|
||||
|
|
|
@ -46,6 +46,7 @@ name = "Zeus"
|
|||
room = "Living Room"
|
||||
topic = "automation/appliance/living_room/zeus"
|
||||
mac_address = "30:9c:23:60:9c:13"
|
||||
broadcast_ip = "10.0.0.255"
|
||||
|
||||
[devices.living_audio]
|
||||
type = "AudioSetup"
|
||||
|
|
|
@ -165,6 +165,8 @@ pub enum Device {
|
|||
#[serde(flatten)]
|
||||
mqtt: MqttDeviceConfig,
|
||||
mac_address: MacAddress,
|
||||
#[serde(default = "default_broadcast_ip")]
|
||||
broadcast_ip: Ipv4Addr,
|
||||
},
|
||||
KasaOutlet {
|
||||
ip: Ipv4Addr,
|
||||
|
@ -182,6 +184,10 @@ pub enum Device {
|
|||
}
|
||||
}
|
||||
|
||||
fn default_broadcast_ip() -> Ipv4Addr {
|
||||
Ipv4Addr::new(255, 255, 255, 255)
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn parse_file(filename: &str) -> Result<Self, ConfigParseError> {
|
||||
debug!("Loading config: {filename}");
|
||||
|
@ -227,9 +233,9 @@ impl Device {
|
|||
IkeaOutlet::build(&identifier, info, mqtt, kettle, client).await
|
||||
.map(device_box)?
|
||||
},
|
||||
Device::WakeOnLAN { info, mqtt, mac_address } => {
|
||||
Device::WakeOnLAN { info, mqtt, mac_address, broadcast_ip } => {
|
||||
trace!(id = identifier, "WakeOnLan [{} in {:?}]", info.name, info.room);
|
||||
WakeOnLAN::build(&identifier, info, mqtt, mac_address, client).await
|
||||
WakeOnLAN::build(&identifier, info, mqtt, mac_address, broadcast_ip, client).await
|
||||
.map(device_box)?
|
||||
},
|
||||
Device::KasaOutlet { ip } => {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use std::net::Ipv4Addr;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use google_home::{GoogleHomeDevice, types::Type, device, traits::{self, Scene}, errors::ErrorCode};
|
||||
use tracing::{debug, error};
|
||||
use rumqttc::{AsyncClient, Publish, matches};
|
||||
use pollster::FutureExt as _;
|
||||
use eui48::MacAddress;
|
||||
|
||||
use crate::{config::{InfoConfig, MqttDeviceConfig}, mqtt::{OnMqtt, ActivateMessage}, error::DeviceError};
|
||||
|
@ -15,14 +16,15 @@ pub struct WakeOnLAN {
|
|||
info: InfoConfig,
|
||||
mqtt: MqttDeviceConfig,
|
||||
mac_address: MacAddress,
|
||||
broadcast_ip: Ipv4Addr,
|
||||
}
|
||||
|
||||
impl WakeOnLAN {
|
||||
pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, mac_address: MacAddress, client: AsyncClient) -> Result<Self, DeviceError> {
|
||||
pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, mac_address: MacAddress, broadcast_ip: Ipv4Addr, client: AsyncClient) -> Result<Self, DeviceError> {
|
||||
// @TODO Handle potential errors here
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await?;
|
||||
|
||||
Ok(Self { identifier: identifier.to_owned(), info, mqtt, mac_address })
|
||||
Ok(Self { identifier: identifier.to_owned(), info, mqtt, mac_address, broadcast_ip })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,26 +81,16 @@ impl GoogleHomeDevice for WakeOnLAN {
|
|||
impl traits::Scene for WakeOnLAN {
|
||||
fn set_active(&self, activate: bool) -> Result<(), ErrorCode> {
|
||||
if activate {
|
||||
// @TODO In the future send the wake on lan package directly, this is kind of annoying
|
||||
// if we are inside of docker, so for now just call a webhook that does it for us
|
||||
let mac_address = self.mac_address.clone();
|
||||
let id = self.identifier.clone();
|
||||
debug!(id = self.identifier, "Activating Computer: {} (Sending to {})", self.mac_address, self.broadcast_ip);
|
||||
let wol = wakey::WolPacket::from_bytes(&self.mac_address.to_array()).map_err(|err| {
|
||||
error!(id = self.identifier, "invalid mac address: {err}");
|
||||
google_home::errors::DeviceError::TransientError
|
||||
})?;
|
||||
|
||||
debug!(id, "Activating Computer: {}", mac_address);
|
||||
let res = match reqwest::get(format!("http://10.0.0.2:9000/start-pc?mac={mac_address}")).block_on() {
|
||||
Ok(res) => res,
|
||||
Err(err) => {
|
||||
error!(id, "Failed to call webhook: {err}");
|
||||
return Err(google_home::errors::DeviceError::TransientError.into());
|
||||
}
|
||||
};
|
||||
|
||||
let status = res.status();
|
||||
if !status.is_success() {
|
||||
error!(id, "Failed to call webhook: {}", status);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
wol.send_magic_to((Ipv4Addr::new(0, 0, 0, 0), 0), (self.broadcast_ip, 9)).map_err(|err| {
|
||||
error!(id = self.identifier, "Failed to activate computer: {err}");
|
||||
google_home::errors::DeviceError::TransientError.into()
|
||||
}).map(|_| debug!(id = self.identifier, "Success!"))
|
||||
} else {
|
||||
debug!(id = self.identifier, "Trying to deactive computer, this is not currently supported");
|
||||
// We do not support deactivating this scene
|
||||
|
|
Loading…
Reference in New Issue
Block a user