Signed-off-by: Frank Villaro-Dixon <frank@villaro-dixon.eu>
This commit is contained in:
Frank Villaro-Dixon 2024-03-04 20:24:00 +01:00
parent 4f5ea343f3
commit 12efb33cf2
5 changed files with 100 additions and 88 deletions

View file

@ -18,6 +18,6 @@ fn main() {
let tp = a.get_tank_parameters().unwrap();
println!("Tank: {:?}", tp);
//let hp = a.get_heating_parameters().unwrap();
//println!("Heating: {:?}", hp);
let hp = a.get_heating_parameters().unwrap();
println!("Heating: {:?}", hp);
}

19
src/errors.rs Normal file
View file

@ -0,0 +1,19 @@
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DAError {
#[error("Communication error")]
CommunicationError,
#[error("Conversion error")]
ConversionError,
#[error("Set value error")]
SetValueError(String),
#[error("No such field")]
NoSuchFieldError,
#[error("Value conversion error")]
ValueConversionError,
#[error("Url Parse error")]
UrlParseError,
#[error("WebSocket Error")]
WebSocketError,
}

View file

@ -1,99 +1,21 @@
use std::{error::Error, fmt::Debug, net::TcpStream};
use thiserror::Error;
use std::{fmt::Debug, net::TcpStream};
use uuid::Uuid;
use serde_json::{json, Value};
use tungstenite::{connect, stream, Message, WebSocket};
use url::Url;
#[derive(Error, Debug)]
pub enum DAError {
#[error("Communication error")]
CommunicationError,
#[error("Conversion error")]
ConversionError,
#[error("Set value error")]
SetValueError(String),
#[error("No such field")]
NoSuchFieldError,
#[error("Value conversion error")]
ValueConversionError,
#[error("Url Parse error")]
UrlParseError,
#[error("WebSocket Error")]
WebSocketError,
}
mod errors;
mod params;
mod traits;
use crate::errors::DAError;
use crate::params::HeatingParameters;
use crate::params::TankParameters;
pub struct DaikinAlthermaClient {
ws_client: WebSocket<stream::MaybeTlsStream<TcpStream>>,
}
//
#[derive(Debug)]
pub struct TankParameters {
/// The current temperature of the water tank, in °C
pub temperature: f64,
/// The setpoint (wanted) temperature of the water tank, in °C
pub setpoint_temperature: f64,
/// Is the tank heating enabled
pub enabled: bool,
/// Is it on powerful (quick heating) mode
pub powerful: bool,
}
#[derive(Debug)]
pub struct HeatingParameters {
/// The current indoor temperature, in °C
pub indoor_temperature: f64,
/// The current outdoor temperature, in °C
pub outdoor_temperature: f64,
/// The current indoor setpoint (target) temperature, in °C
pub indoor_setpoint_temperature: f64,
/// The leaving water temperature, in °C
pub leaving_water_temperature: f64,
/// Is the heating enabled
pub enabled: bool,
/// Is the heating on holiday (disabled)
pub on_holiday: bool,
// Is it on powerful (quick heating) mode
//mode: ,
}
trait FromJsonValue<T>: Sized {
fn from_json_value(value: &Value) -> Result<T, DAError>;
}
// Implement the trait for i64
impl FromJsonValue<i64> for i64 {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
value.as_i64().ok_or(DAError::ValueConversionError)
}
}
// Implement the trait for f64
impl FromJsonValue<f64> for f64 {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
value.as_f64().ok_or(DAError::ValueConversionError)
}
}
// Implement the trait for String
impl FromJsonValue<String> for String {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
let v = value.as_str().ok_or(DAError::ValueConversionError)?;
Ok(v.to_string())
}
}
// Implement the trait for bool
impl FromJsonValue<bool> for bool {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
value.as_bool().ok_or(DAError::ValueConversionError)
}
}
impl DaikinAlthermaClient {
/// Creates a new client to a Daikin Altherma LAN adapter.
pub fn new(adapter_hostname: String) -> Result<Self, DAError> {
@ -228,7 +150,10 @@ impl DaikinAlthermaClient {
self.set_value_hp("1/Operation/Power", Some(payload), "/")
}
fn request_value_hp_dft<T: FromJsonValue<T>>(&mut self, item: &str) -> Result<T, DAError> {
fn request_value_hp_dft<T: traits::FromJsonValue<T>>(
&mut self,
item: &str,
) -> Result<T, DAError> {
let hp_item = format!("MNAE/{item}");
let json_val = self.request_value(hp_item.as_str(), None, "/m2m:rsp/pc/m2m:cin/con")?;
T::from_json_value(&json_val)

33
src/params.rs Normal file
View file

@ -0,0 +1,33 @@
use std::fmt::Debug;
#[derive(Debug)]
pub struct TankParameters {
/// The current temperature of the water tank, in °C
pub temperature: f64,
/// The setpoint (wanted) temperature of the water tank, in °C
pub setpoint_temperature: f64,
/// Is the tank heating enabled
pub enabled: bool,
/// Is it on powerful (quick heating) mode
pub powerful: bool,
}
#[derive(Debug)]
pub struct HeatingParameters {
/// The current indoor temperature, in °C
pub indoor_temperature: f64,
/// The current outdoor temperature, in °C
pub outdoor_temperature: f64,
/// The current indoor setpoint (target) temperature, in °C
pub indoor_setpoint_temperature: f64,
/// The leaving water temperature, in °C
pub leaving_water_temperature: f64,
/// Is the heating enabled
pub enabled: bool,
/// Is the heating on holiday (disabled)
pub on_holiday: bool,
// Is it on powerful (quick heating) mode
//mode: ,
}

35
src/traits.rs Normal file
View file

@ -0,0 +1,35 @@
use crate::errors::DAError;
use serde_json::Value;
pub trait FromJsonValue<T>: Sized {
fn from_json_value(value: &Value) -> Result<T, DAError>;
}
// Implement the trait for i64
impl FromJsonValue<i64> for i64 {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
value.as_i64().ok_or(DAError::ValueConversionError)
}
}
// Implement the trait for f64
impl FromJsonValue<f64> for f64 {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
value.as_f64().ok_or(DAError::ValueConversionError)
}
}
// Implement the trait for String
impl FromJsonValue<String> for String {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
let v = value.as_str().ok_or(DAError::ValueConversionError)?;
Ok(v.to_string())
}
}
// Implement the trait for bool
impl FromJsonValue<bool> for bool {
fn from_json_value(value: &Value) -> Result<Self, DAError> {
value.as_bool().ok_or(DAError::ValueConversionError)
}
}