Skip to main content

dvrip_rs/commands/
system_info.rs

1use crate::constants::DATE_FORMAT;
2use crate::error::Result;
3use crate::{Authentication, dvrip::DVRIPCam};
4use async_trait::async_trait;
5use chrono::{DateTime, Local, NaiveDateTime};
6use serde_json::Value;
7
8#[async_trait]
9pub trait SystemInfo: Send + Sync {
10    /// Get general system information
11    async fn get_system_info(&mut self) -> Result<Value>;
12
13    /// Get general information
14    async fn get_general_info(&mut self) -> Result<Value>;
15
16    /// Get network information
17    async fn get_network_info(&mut self) -> Result<Value>;
18
19    /// Get encoding capabilities
20    async fn get_encode_capabilities(&mut self) -> Result<Value>;
21
22    /// Get system capabilities
23    async fn get_system_capabilities(&mut self) -> Result<Value>;
24
25    /// Get camera information
26    async fn get_camera_info(&mut self, default_config: bool) -> Result<Value>;
27
28    /// Get encoding information
29    async fn get_encode_info(&mut self, default_config: bool) -> Result<Value>;
30
31    /// Get current device time
32    async fn get_time(&mut self) -> Result<DateTime<Local>>;
33
34    /// Set device time
35    async fn set_time(&mut self, time: Option<DateTime<Local>>) -> Result<bool>;
36
37    /// Get channel titles
38    async fn get_channel_titles(&mut self) -> Result<Vec<String>>;
39
40    /// Set channel titles
41    async fn set_channel_titles(&mut self, titles: Vec<String>) -> Result<bool>;
42
43    /// Get channel statuses
44    async fn get_channel_statuses(&mut self) -> Result<Value>;
45}
46
47#[async_trait]
48impl SystemInfo for DVRIPCam {
49    async fn get_system_info(&mut self) -> Result<Value> {
50        self.get_command("SystemInfo", None).await
51    }
52
53    async fn get_general_info(&mut self) -> Result<Value> {
54        self.get_command("General", None).await
55    }
56
57    async fn get_network_info(&mut self) -> Result<Value> {
58        self.get_command("NetWork.NetCommon", None).await
59    }
60
61    async fn get_encode_capabilities(&mut self) -> Result<Value> {
62        self.get_command("EncodeCapability", None).await
63    }
64
65    async fn get_system_capabilities(&mut self) -> Result<Value> {
66        self.get_command("SystemFunction", None).await
67    }
68
69    async fn get_camera_info(&mut self, default_config: bool) -> Result<Value> {
70        let code = if default_config {
71            Some(1044)
72        } else {
73            Some(1042)
74        };
75        self.get_command("Camera", code).await
76    }
77
78    async fn get_encode_info(&mut self, default_config: bool) -> Result<Value> {
79        let code = if default_config {
80            Some(1044)
81        } else {
82            Some(1042)
83        };
84        self.get_command("Simplify.Encode", code).await
85    }
86
87    async fn get_time(&mut self) -> Result<DateTime<Local>> {
88        let time_str = self
89            .get_command("OPTimeQuery", None)
90            .await?
91            .as_str()
92            .ok_or_else(|| {
93                crate::error::DVRIPError::ProtocolError("Invalid time response".to_string())
94            })?
95            .to_string();
96
97        let naive = NaiveDateTime::parse_from_str(&time_str, DATE_FORMAT).map_err(|e| {
98            crate::error::DVRIPError::ProtocolError(format!("Error parsing date: {}", e))
99        })?;
100
101        Ok(DateTime::from_naive_utc_and_offset(
102            naive,
103            *Local::now().offset(),
104        ))
105    }
106
107    async fn set_time(&mut self, time: Option<DateTime<Local>>) -> Result<bool> {
108        let time_to_set = time.unwrap_or_else(Local::now);
109        let time_str = time_to_set.format(DATE_FORMAT).to_string();
110
111        let reply = self
112            .set_command("OPTimeSetting", serde_json::json!(time_str), None)
113            .await?;
114        if let Some(ret) = reply.get("Ret").and_then(|r| r.as_u64()) {
115            return Ok(crate::constants::OK_CODES.contains(&(ret as u32)));
116        }
117        Ok(false)
118    }
119
120    async fn get_channel_titles(&mut self) -> Result<Vec<String>> {
121        let data = self.get_command("ChannelTitle", Some(1048)).await?;
122        if let Some(titles) = data.as_array() {
123            return Ok(titles
124                .iter()
125                .filter_map(|v| v.as_str().map(|s| s.to_string()))
126                .collect());
127        }
128        Ok(vec![])
129    }
130
131    async fn set_channel_titles(&mut self, titles: Vec<String>) -> Result<bool> {
132        let session = self.session_id();
133        let data = serde_json::json!({
134            "ChannelTitle": titles,
135            "Name": "ChannelTitle",
136            "SessionID": format!("0x{:08X}", session),
137        });
138
139        let reply = self.set_command("ChannelTitle", data, None).await?;
140        if let Some(ret) = reply.get("Ret").and_then(|r| r.as_u64()) {
141            return Ok(crate::constants::OK_CODES.contains(&(ret as u32)));
142        }
143        Ok(false)
144    }
145
146    async fn get_channel_statuses(&mut self) -> Result<Value> {
147        self.get_command("NetWork.ChnStatus", None).await
148    }
149}