plc_comm_hostlink/
model.rs1use std::sync::Arc;
2use std::time::SystemTime;
3use time::{Month, OffsetDateTime};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum HostLinkTransportMode {
7 Tcp,
8 Udp,
9}
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum KvPlcMode {
13 Program = 0,
14 Run = 1,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum HostLinkTraceDirection {
19 Send,
20 Receive,
21}
22
23#[derive(Debug, Clone)]
24pub struct HostLinkTraceFrame {
25 pub direction: HostLinkTraceDirection,
26 pub data: Vec<u8>,
27 pub timestamp: SystemTime,
28}
29
30pub type TraceHook = Arc<dyn Fn(HostLinkTraceFrame) + Send + Sync>;
31
32#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct KvModelInfo {
34 pub code: String,
35 pub model: String,
36}
37
38#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct HostLinkClock {
40 pub year: u8,
41 pub month: u8,
42 pub day: u8,
43 pub hour: u8,
44 pub minute: u8,
45 pub second: u8,
46 pub week: u8,
47}
48
49impl HostLinkClock {
50 pub fn now_local() -> Self {
51 let now = OffsetDateTime::now_local().unwrap_or_else(|_| OffsetDateTime::now_utc());
52 Self::from_offset_datetime(now)
53 }
54
55 fn from_offset_datetime(now: OffsetDateTime) -> Self {
56 let week = now.weekday().number_days_from_sunday();
57 Self {
58 year: (now.year() % 100) as u8,
59 month: month_to_number(now.month()),
60 day: now.day(),
61 hour: now.hour(),
62 minute: now.minute(),
63 second: now.second(),
64 week,
65 }
66 }
67}
68
69fn month_to_number(month: Month) -> u8 {
70 match month {
71 Month::January => 1,
72 Month::February => 2,
73 Month::March => 3,
74 Month::April => 4,
75 Month::May => 5,
76 Month::June => 6,
77 Month::July => 7,
78 Month::August => 8,
79 Month::September => 9,
80 Month::October => 10,
81 Month::November => 11,
82 Month::December => 12,
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::HostLinkClock;
89 use time::{Date, Month, Time};
90
91 fn clock_for(year: i32, month: Month, day: u8) -> HostLinkClock {
92 let date = Date::from_calendar_date(year, month, day).unwrap();
93 let time = Time::from_hms(1, 2, 3).unwrap();
94 HostLinkClock::from_offset_datetime(date.with_time(time).assume_utc())
95 }
96
97 #[test]
98 fn clock_uses_sunday_based_weekday() {
99 assert_eq!(clock_for(2026, Month::March, 15).week, 0);
100 assert_eq!(clock_for(2026, Month::March, 16).week, 1);
101 assert_eq!(clock_for(2026, Month::March, 21).week, 6);
102 }
103}
104
105#[derive(Debug, Clone)]
106pub struct HostLinkConnectionOptions {
107 pub host: String,
108 pub port: u16,
109 pub timeout: std::time::Duration,
110 pub transport: HostLinkTransportMode,
111 pub append_lf_on_send: bool,
112}
113
114impl HostLinkConnectionOptions {
115 pub fn new(host: impl Into<String>) -> Self {
116 Self {
117 host: host.into(),
118 port: 8501,
119 timeout: std::time::Duration::from_secs(3),
120 transport: HostLinkTransportMode::Tcp,
121 append_lf_on_send: false,
122 }
123 }
124}