dvrip_rs/commands/
system_info.rs1use 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 async fn get_system_info(&mut self) -> Result<Value>;
12
13 async fn get_general_info(&mut self) -> Result<Value>;
15
16 async fn get_network_info(&mut self) -> Result<Value>;
18
19 async fn get_encode_capabilities(&mut self) -> Result<Value>;
21
22 async fn get_system_capabilities(&mut self) -> Result<Value>;
24
25 async fn get_camera_info(&mut self, default_config: bool) -> Result<Value>;
27
28 async fn get_encode_info(&mut self, default_config: bool) -> Result<Value>;
30
31 async fn get_time(&mut self) -> Result<DateTime<Local>>;
33
34 async fn set_time(&mut self, time: Option<DateTime<Local>>) -> Result<bool>;
36
37 async fn get_channel_titles(&mut self) -> Result<Vec<String>>;
39
40 async fn set_channel_titles(&mut self, titles: Vec<String>) -> Result<bool>;
42
43 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}