1use super::types::{AlarmSeverity, DropPolicy, TargetType};
2use crate::{AccessMode, DataType, NGValue, PointValue, Transform};
3use bytes::Bytes;
4use chrono::{DateTime, Duration, Utc};
5use sea_orm::FromJsonQueryResult;
6use serde::{Deserialize, Serialize};
7use std::{collections::HashMap, fmt::Debug, sync::Arc};
8use uuid::Uuid;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct Command {
13 pub command_id: String,
15 pub key: String,
17 pub target_type: TargetType,
19 pub device_id: Option<i32>,
21 pub device_name: Option<String>,
23 pub params: Option<serde_json::Value>,
25 #[serde(skip_serializing_if = "Option::is_none")]
27 pub timeout_ms: Option<u64>,
28 pub timestamp: DateTime<Utc>,
30}
31
32impl Command {
33 pub fn new(
35 command_id: String,
36 key: String,
37 target_type: TargetType,
38 device_id: i32,
39 device_name: String,
40 params: serde_json::Value,
41 ) -> Self {
42 Self {
43 command_id,
44 key,
45 target_type,
46 device_id: Some(device_id),
47 device_name: Some(device_name),
48 params: Some(params),
49 timeout_ms: None,
50 timestamp: Utc::now(),
51 }
52 }
53
54 pub fn with_timeout(mut self, timeout_ms: u64) -> Self {
56 self.timeout_ms = Some(timeout_ms);
57 self
58 }
59
60 #[inline]
61 pub fn is_expired(&self) -> bool {
63 if let Some(expires_at) = self.timeout_ms {
64 Utc::now() > self.timestamp + Duration::milliseconds(expires_at as i64)
65 } else {
66 false
67 }
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct WritePoint {
79 pub request_id: String,
81 pub point_id: i32,
83 pub value: NGValue,
85 pub timestamp: DateTime<Utc>,
87 #[serde(skip_serializing_if = "Option::is_none")]
89 pub timeout_ms: Option<u64>,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct WritePointResponse {
95 pub request_id: String,
97 pub point_id: i32,
99 pub device_id: i32,
101 #[serde(with = "arc_str_serde")]
108 pub device_name: Arc<str>,
109 #[serde(with = "arc_str_serde")]
115 pub point_key: Arc<str>,
116 pub status: WritePointStatus,
118 #[serde(skip_serializing_if = "Option::is_none")]
120 pub error: Option<WritePointError>,
121 #[serde(skip_serializing_if = "Option::is_none")]
123 pub applied_value: Option<NGValue>,
124 pub completed_at: DateTime<Utc>,
126}
127
128impl WritePointResponse {
129 #[inline]
130 pub fn success(
131 request_id: String,
132 point_id: i32,
133 device_id: i32,
134 device_name: Arc<str>,
135 point_key: Arc<str>,
136 applied_value: Option<NGValue>,
137 completed_at: DateTime<Utc>,
138 ) -> Self {
139 Self {
140 request_id,
141 point_id,
142 device_id,
143 device_name,
144 point_key,
145 status: WritePointStatus::Success,
146 error: None,
147 applied_value,
148 completed_at,
149 }
150 }
151
152 #[inline]
153 pub fn failed(
154 request_id: String,
155 point_id: i32,
156 device_id: i32,
157 device_name: Arc<str>,
158 point_key: Arc<str>,
159 error: WritePointError,
160 completed_at: DateTime<Utc>,
161 ) -> Self {
162 Self {
163 request_id,
164 point_id,
165 device_id,
166 device_name,
167 point_key,
168 status: WritePointStatus::Failed,
169 error: Some(error),
170 applied_value: None,
171 completed_at,
172 }
173 }
174}
175
176#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
177pub enum WritePointStatus {
178 Success,
179 Failed,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct WritePointError {
184 pub kind: WritePointErrorKind,
185 pub message: String,
186}
187
188impl WritePointError {
189 #[inline]
194 pub fn new(kind: WritePointErrorKind, message: impl Into<String>) -> Self {
195 Self {
196 kind,
197 message: message.into(),
198 }
199 }
200}
201
202#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
203pub enum WritePointErrorKind {
204 NotFound,
206 NotWriteable,
207 TypeMismatch,
208 OutOfRange,
209 NotConnected,
210 QueueTimeout,
212 DriverError,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
218pub struct DeviceConnectedData {
219 pub device_id: i32,
221 pub device_name: String,
223 pub device_type: String,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize)]
229pub struct DeviceDisconnectedData {
230 pub device_id: i32,
232 pub device_name: String,
234 pub device_type: String,
236}
237
238#[derive(Debug, Clone, Serialize, Deserialize)]
240pub struct TelemetryData {
241 pub device_id: i32,
243 pub device_name: String,
245 pub timestamp: DateTime<Utc>,
247 pub values: Vec<PointValue>,
251 #[serde(default)]
253 pub metadata: HashMap<String, serde_json::Value>,
254}
255
256impl TelemetryData {
257 pub fn new(device_id: i32, device_name: impl Into<String>, values: Vec<PointValue>) -> Self {
259 Self {
260 device_id,
261 device_name: device_name.into(),
262 timestamp: Utc::now(),
263 values,
264 metadata: HashMap::new(),
265 }
266 }
267
268 pub fn with_metadata(mut self, metadata: HashMap<String, serde_json::Value>) -> Self {
270 self.metadata = metadata;
271 self
272 }
273
274 pub fn to_json_bytes(&self) -> Result<Bytes, serde_json::Error> {
276 let json = serde_json::to_vec(self)?;
277 Ok(Bytes::from(json))
278 }
279}
280
281#[derive(Debug, Clone, Serialize, Deserialize)]
283pub struct AttributeData {
284 pub device_id: i32,
286 pub device_name: String,
288 pub timestamp: DateTime<Utc>,
290 #[serde(default)]
292 pub client_attributes: Vec<PointValue>,
293 #[serde(default)]
295 pub shared_attributes: Vec<PointValue>,
296 #[serde(default)]
298 pub server_attributes: Vec<PointValue>,
299}
300
301impl AttributeData {
302 pub fn new_client_attributes(
304 device_id: i32,
305 device_name: impl Into<String>,
306 attributes: Vec<PointValue>,
307 ) -> Self {
308 Self {
309 device_id,
310 device_name: device_name.into(),
311 timestamp: Utc::now(),
312 client_attributes: attributes,
313 shared_attributes: Vec::new(),
314 server_attributes: Vec::new(),
315 }
316 }
317
318 pub fn new_shared_attributes(
320 device_id: i32,
321 device_name: impl Into<String>,
322 attributes: Vec<PointValue>,
323 ) -> Self {
324 Self {
325 device_id,
326 device_name: device_name.into(),
327 timestamp: Utc::now(),
328 client_attributes: Vec::new(),
329 shared_attributes: attributes,
330 server_attributes: Vec::new(),
331 }
332 }
333
334 pub fn to_json_bytes(&self) -> Result<Bytes, serde_json::Error> {
336 let json = serde_json::to_vec(self)?;
337 Ok(Bytes::from(json))
338 }
339}
340
341#[derive(Debug, Clone, Serialize, Deserialize)]
343pub struct RpcRequest {
344 pub target_type: TargetType,
346 pub request_id: Uuid,
348 pub device_id: i32,
350 pub device_name: String,
352 pub method: String,
354 pub params: Option<serde_json::Value>,
356}
357
358#[derive(Debug, Clone, Serialize, Deserialize)]
360pub struct ServerRpcResponse {
361 pub request_id: String,
364 pub target_type: TargetType,
366 #[serde(skip_serializing_if = "Option::is_none")]
368 pub result: Option<serde_json::Value>,
369 #[serde(skip_serializing_if = "Option::is_none")]
371 pub error: Option<String>,
372 pub timestamp: DateTime<Utc>,
374}
375
376#[derive(Debug, Clone, Serialize, Deserialize)]
378pub struct ClientRpcResponse {
379 pub device_id: i32,
381 #[serde(skip_serializing_if = "Option::is_none")]
383 pub device_name: Option<String>,
384 pub request_id: String,
387 pub target_type: TargetType,
389 #[serde(skip_serializing_if = "Option::is_none")]
391 pub result: Option<serde_json::Value>,
392 #[serde(skip_serializing_if = "Option::is_none")]
394 pub error: Option<String>,
395 pub timestamp: DateTime<Utc>,
397}
398
399impl ClientRpcResponse {
400 pub fn success(
402 request_id: String,
403 target_type: TargetType,
404 device_id: i32,
405 device_name: Option<String>,
406 result: serde_json::Value,
407 ) -> Self {
408 Self {
409 request_id,
410 target_type,
411 device_id,
412 device_name,
413 result: Some(result),
414 error: None,
415 timestamp: Utc::now(),
416 }
417 }
418
419 pub fn error(
421 request_id: String,
422 target_type: TargetType,
423 device_id: i32,
424 device_name: Option<String>,
425 error: String,
426 ) -> Self {
427 Self {
428 request_id,
429 target_type,
430 device_id,
431 device_name,
432 result: None,
433 error: Some(error),
434 timestamp: Utc::now(),
435 }
436 }
437
438 pub fn is_success(&self) -> bool {
439 self.error.is_none()
440 }
441
442 pub fn to_json_bytes(&self) -> Result<Bytes, serde_json::Error> {
444 let json = serde_json::to_vec(self)?;
445 Ok(Bytes::from(json))
446 }
447}
448
449#[derive(Debug, Clone, Serialize, Deserialize)]
451pub struct AlarmData {
452 pub device_id: i32,
454 pub device_name: String,
456 pub alarm_type: String,
458 pub severity: AlarmSeverity,
460 pub message: String,
462 pub details: HashMap<String, serde_json::Value>,
464 pub timestamp: DateTime<Utc>,
466 pub cleared: bool,
468}
469
470impl AlarmData {
471 pub fn new(
473 device_id: i32,
474 device_name: String,
475 alarm_type: String,
476 severity: AlarmSeverity,
477 message: String,
478 ) -> Self {
479 Self {
480 device_id,
481 device_name,
482 alarm_type,
483 severity,
484 message,
485 details: HashMap::new(),
486 timestamp: Utc::now(),
487 cleared: false,
488 }
489 }
490
491 pub fn clear(mut self) -> Self {
493 self.cleared = true;
494 self
495 }
496
497 pub fn with_details(mut self, details: HashMap<String, serde_json::Value>) -> Self {
499 self.details = details;
500 self
501 }
502}
503
504#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)]
505#[serde(rename_all = "camelCase")]
506pub struct QueuePolicy {
507 #[serde(default = "QueuePolicy::default_capacity")]
508 pub capacity: u32,
509 #[serde(default = "QueuePolicy::default_drop_policy")]
510 pub drop_policy: DropPolicy,
511 #[serde(default = "QueuePolicy::default_block_duration_ms")]
512 pub block_duration: u64,
513 #[serde(default = "QueuePolicy::default_buffer_enabled")]
515 pub buffer_enabled: bool,
516 #[serde(default = "QueuePolicy::default_buffer_capacity")]
518 pub buffer_capacity: u32,
519 #[serde(default = "QueuePolicy::default_buffer_expire_ms")]
521 pub buffer_expire_ms: u64,
522}
523
524impl QueuePolicy {
525 fn default_capacity() -> u32 {
526 1000
527 }
528
529 fn default_drop_policy() -> DropPolicy {
530 DropPolicy::Discard
531 }
532
533 fn default_block_duration_ms() -> u64 {
534 1000
535 }
536
537 fn default_buffer_enabled() -> bool {
538 true
539 }
540
541 fn default_buffer_capacity() -> u32 {
542 1000
543 }
544
545 fn default_buffer_expire_ms() -> u64 {
546 300_000 }
548}
549
550impl sea_orm::IntoActiveValue<QueuePolicy> for QueuePolicy {
551 fn into_active_value(self) -> sea_orm::ActiveValue<QueuePolicy> {
552 sea_orm::ActiveValue::Set(self)
553 }
554}
555
556mod arc_str_serde {
561 use serde::{Deserialize, Deserializer, Serializer};
562 use std::sync::Arc;
563
564 pub fn serialize<S>(v: &Arc<str>, serializer: S) -> Result<S::Ok, S::Error>
565 where
566 S: Serializer,
567 {
568 serializer.serialize_str(v.as_ref())
569 }
570
571 pub fn deserialize<'de, D>(deserializer: D) -> Result<Arc<str>, D::Error>
572 where
573 D: Deserializer<'de>,
574 {
575 let s = String::deserialize(deserializer)?;
576 Ok(Arc::<str>::from(s))
577 }
578
579 pub mod option {
580 use super::*;
581 use serde::Deserialize;
582
583 pub fn serialize<S>(v: &Option<Arc<str>>, serializer: S) -> Result<S::Ok, S::Error>
584 where
585 S: Serializer,
586 {
587 match v {
588 Some(s) => serializer.serialize_some(s.as_ref()),
589 None => serializer.serialize_none(),
590 }
591 }
592
593 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Arc<str>>, D::Error>
594 where
595 D: Deserializer<'de>,
596 {
597 let opt = Option::<String>::deserialize(deserializer)?;
598 Ok(opt.map(Arc::<str>::from))
599 }
600 }
601}
602
603#[derive(Clone, Debug, Serialize, Deserialize)]
612pub struct PointMeta {
613 pub point_id: i32,
615 pub channel_id: i32,
617 #[serde(with = "arc_str_serde")]
619 pub channel_name: Arc<str>,
620 pub device_id: i32,
622 #[serde(with = "arc_str_serde")]
624 pub device_name: Arc<str>,
625 #[serde(with = "arc_str_serde")]
627 pub point_name: Arc<str>,
628 #[serde(with = "arc_str_serde")]
630 pub point_key: Arc<str>,
631 pub data_type: DataType,
633 pub access_mode: AccessMode,
635 #[serde(default, with = "arc_str_serde::option")]
637 pub unit: Option<Arc<str>>,
638 pub min_value: Option<f64>,
640 pub max_value: Option<f64>,
642 #[serde(default)]
646 pub transform: Transform,
647 #[serde(default, with = "arc_str_serde::option")]
649 pub description: Option<Arc<str>>,
650}
651
652impl PointMeta {
653 #[inline]
657 pub fn wire_data_type(&self) -> DataType {
658 self.data_type
659 }
660
661 #[inline]
666 pub fn logical_data_type(&self) -> DataType {
667 self.transform.resolve_logical_datatype(self.data_type)
668 }
669
670 #[inline]
671 pub fn readable(&self) -> bool {
672 matches!(self.access_mode, AccessMode::Read | AccessMode::ReadWrite)
673 }
674
675 #[inline]
676 pub fn writable(&self) -> bool {
677 matches!(self.access_mode, AccessMode::Write | AccessMode::ReadWrite)
678 }
679}