esphome_native_api/
esphomeserver.rs1#![allow(dead_code)]
2
3use log::debug;
4use log::error;
5use noise_protocol::CipherState;
6use noise_protocol::HandshakeState;
7use noise_rust_crypto::ChaCha20Poly1305;
8use noise_rust_crypto::Sha256;
9use noise_rust_crypto::X25519;
10use std::collections::HashMap;
11use std::str;
12use std::sync::Arc;
13use std::sync::atomic::AtomicBool;
14use tokio::net::TcpStream;
15use tokio::sync::Mutex;
16use tokio::sync::broadcast;
17use tokio::sync::mpsc;
18use typed_builder::TypedBuilder;
19
20use crate::esphomeapi::EspHomeApi;
21use crate::parser::ProtoMessage;
22use crate::proto::ListEntitiesDoneResponse;
23
24#[derive(TypedBuilder)]
25pub struct EspHomeServer {
26 #[builder(default=HashMap::new(), setter(skip))]
28 pub(crate) components_by_key: HashMap<u32, Entity>,
29 #[builder(default=HashMap::new(), setter(skip))]
30 pub(crate) components_key_id: HashMap<String, u32>,
31 #[builder(default = 0, setter(skip))]
32 pub(crate) current_key: u32,
33
34 #[builder(via_mutators, default=Arc::new(AtomicBool::new(false)))]
35 pub(crate) encrypted_api: Arc<AtomicBool>,
36
37 #[builder(via_mutators)]
38 pub(crate) noise_psk: Vec<u8>,
39
40 #[builder(default=Arc::new(Mutex::new(None)), setter(skip))]
41 pub(crate) handshake_state:
42 Arc<Mutex<Option<HandshakeState<X25519, ChaCha20Poly1305, Sha256>>>>,
43 #[builder(default=Arc::new(Mutex::new(None)), setter(skip))]
44 pub(crate) encrypt_cypher: Arc<Mutex<Option<CipherState<ChaCha20Poly1305>>>>,
45 #[builder(default=Arc::new(Mutex::new(None)), setter(skip))]
46 pub(crate) decrypt_cypher: Arc<Mutex<Option<CipherState<ChaCha20Poly1305>>>>,
47
48 name: String,
49
50 #[builder(default = None, setter(strip_option))]
51 #[deprecated(note = "https://esphome.io/components/api.html#configuration-variables")]
52 password: Option<String>,
53 #[builder(default = None, setter(strip_option))]
54 encryption_key: Option<String>,
55
56 #[builder(default = 1)]
57 api_version_major: u32,
58 #[builder(default = 10)]
59 api_version_minor: u32,
60 #[builder(default="Rust: esphome-native-api".to_string())]
61 server_info: String,
62
63 #[builder(default = None, setter(strip_option))]
64 friendly_name: Option<String>,
65
66 #[builder(default = None, setter(strip_option))]
67 mac: Option<String>,
68
69 #[builder(default = None, setter(strip_option))]
70 model: Option<String>,
71
72 #[builder(default = None, setter(strip_option))]
73 manufacturer: Option<String>,
74 #[builder(default = None, setter(strip_option))]
75 suggested_area: Option<String>,
76 #[builder(default = None, setter(strip_option))]
77 bluetooth_mac_address: Option<String>,
78}
79
80impl EspHomeServer {
84 pub async fn start(
85 &mut self,
86 tcp_stream: TcpStream,
87 ) -> Result<
88 (
89 mpsc::Sender<ProtoMessage>,
90 broadcast::Receiver<ProtoMessage>,
91 ),
92 Box<dyn std::error::Error>,
93 > {
94 let mut server = EspHomeApi::builder()
95 .api_version_major(self.api_version_major)
96 .api_version_minor(self.api_version_minor)
97 .server_info(self.server_info.clone())
99 .name(self.name.clone())
100 .build();
107 let (messages_tx, mut messages_rx) = server.start(tcp_stream).await?;
108 let (outgoing_messages_tx, outgoing_messages_rx) = broadcast::channel::<ProtoMessage>(16);
109 let api_components_clone = self.components_by_key.clone();
110 tokio::spawn(async move {
113 loop {
114 messages_rx.recv().await.map_or_else(
115 |e| {
116 error!("Error receiving message: {:?}", e);
117 },
119 |message| {
120 debug!("Received message: {:?}", message);
122
123 match message {
124 ProtoMessage::ListEntitiesRequest(list_entities_request) => {
125 debug!("ListEntitiesRequest: {:?}", list_entities_request);
126
127 for _sensor in api_components_clone.values() {
128 }
131 outgoing_messages_tx
132 .send(ProtoMessage::ListEntitiesDoneResponse(
133 ListEntitiesDoneResponse {},
134 ))
135 .unwrap();
136 }
137 other_message => {
138 if let Err(e) = outgoing_messages_tx.send(other_message) {
140 error!("Error sending message to outgoing channel: {:?}", e);
141 }
142 }
143 }
144 },
145 );
146 }
147 });
148
149 Ok((messages_tx.clone(), outgoing_messages_rx))
150 }
151
152 pub fn add_entity(&mut self, entity_id: &str, entity: Entity) {
153 self.components_key_id
154 .insert(entity_id.to_string(), self.current_key);
155 self.components_by_key.insert(self.current_key, entity);
156
157 self.current_key += 1;
158 }
159}
160
161#[derive(Clone, Debug)]
162pub enum Entity {
163 BinarySensor(BinarySensor),
164}
165
166#[derive(Clone, Debug)]
167pub struct BinarySensor {
168 pub object_id: String,
169}