2020-09-14 10:37:51 +02:00
|
|
|
use slog::Logger;
|
2020-09-15 11:38:15 +02:00
|
|
|
|
2020-09-15 14:31:10 +02:00
|
|
|
use crate::config::Settings;
|
2020-09-15 11:38:15 +02:00
|
|
|
use crate::registries::{Registries, Actuator, ActBox};
|
|
|
|
use crate::error::Result;
|
|
|
|
|
|
|
|
use std::pin::Pin;
|
|
|
|
use futures::prelude::*;
|
|
|
|
use futures::ready;
|
|
|
|
use futures::task::{Poll, Context};
|
2020-09-14 10:37:51 +02:00
|
|
|
|
2020-09-15 11:38:15 +02:00
|
|
|
use paho_mqtt as mqtt;
|
2020-09-14 10:37:51 +02:00
|
|
|
|
2020-09-15 11:38:15 +02:00
|
|
|
// TODO: Late config parsing. Right now the config is validated at the very startup in its
|
|
|
|
// entirety. This works reasonably enough for this static modules here but if we do dynamic loading
|
|
|
|
// via dlopen(), lua API, python API etc it will not.
|
2020-09-15 14:31:10 +02:00
|
|
|
pub async fn run(log: Logger, config: Settings, registries: Registries) {
|
2020-09-17 14:32:53 +02:00
|
|
|
let shelly = Shelly::new(config).await;
|
2020-09-15 11:38:15 +02:00
|
|
|
|
2020-09-17 14:32:53 +02:00
|
|
|
let r = registries.actuators.register("shelly".to_string(), shelly).await;
|
2020-09-14 10:37:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// An actuator for all Shellies connected listening on one MQTT broker
|
|
|
|
///
|
|
|
|
/// This actuator can power toggle an arbitrariy named shelly on the broker it is connected to. If
|
|
|
|
/// you need to toggle shellies on multiple brokers you need multiple instanced of this actuator.
|
2020-09-17 14:32:53 +02:00
|
|
|
#[derive(Clone)]
|
2020-09-14 10:37:51 +02:00
|
|
|
struct Shelly {
|
2020-09-15 11:38:15 +02:00
|
|
|
client: mqtt::AsyncClient,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Shelly {
|
2020-09-17 14:34:57 +02:00
|
|
|
// Can't use Error, it's not Send. fabinfra/fabaccess/bffh#7
|
2020-09-17 14:32:53 +02:00
|
|
|
pub async fn new(config: Settings) -> ActBox {
|
|
|
|
let client = mqtt::AsyncClient::new(config.shelly.unwrap().mqtt_url).unwrap();
|
2020-09-15 11:38:15 +02:00
|
|
|
|
2020-09-17 14:32:53 +02:00
|
|
|
client.connect(mqtt::ConnectOptions::new()).await.unwrap();
|
2020-09-15 11:38:15 +02:00
|
|
|
|
2020-09-17 14:32:53 +02:00
|
|
|
Box::new(Shelly { client })
|
2020-09-15 11:38:15 +02:00
|
|
|
}
|
2020-09-14 10:37:51 +02:00
|
|
|
}
|
|
|
|
|
2020-09-15 11:38:15 +02:00
|
|
|
|
|
|
|
#[async_trait]
|
2020-09-14 10:37:51 +02:00
|
|
|
impl Actuator for Shelly {
|
2020-09-15 11:38:15 +02:00
|
|
|
async fn power_on(&mut self, name: String) {
|
2020-09-15 14:31:10 +02:00
|
|
|
let topic = format!("shellies/{}/relay/0/command", name);
|
|
|
|
let msg = mqtt::Message::new(topic, "on", 0);
|
2020-09-15 11:38:15 +02:00
|
|
|
self.client.publish(msg).map(|_| ()).await
|
|
|
|
}
|
2020-09-14 10:37:51 +02:00
|
|
|
|
2020-09-15 11:38:15 +02:00
|
|
|
async fn power_off(&mut self, name: String) {
|
2020-09-15 14:31:10 +02:00
|
|
|
let topic = format!("shellies/{}/relay/0/command", name);
|
|
|
|
let msg = mqtt::Message::new(topic, "off", 0);
|
2020-09-15 11:38:15 +02:00
|
|
|
self.client.publish(msg).map(|_| ()).await
|
|
|
|
}
|
2020-09-14 10:37:51 +02:00
|
|
|
}
|