open_protocol/messages/
job.rs

1use chrono::{DateTime, Local};
2use open_protocol_codec::{decode, encode};
3use open_protocol_codec_proc_macro::{OpenProtocolDecode, OpenProtocolEncode, OpenProtocolMessage};
4
5#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
6#[open_protocol_message(MID = 0030, revision = 1)]
7pub struct MID0030rev1 {
8    // No data field for this MID
9}
10
11#[derive(
12    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
13)]
14#[open_protocol_message(MID = 0031, revision = 1)]
15pub struct MID0031rev1 {
16    /// Number of jobs available on the controller
17    #[open_protocol_field(length = 2)]
18    pub number_of_jobs: u8,
19
20    /// List of Job IDs, each ID is 2 ASCII characters long
21    #[open_protocol_field(list, amount = "number_of_jobs", length = 2)]
22    pub job_ids: Vec<u8>,
23}
24
25#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
26#[open_protocol_message(MID = 0031, revision = 2)]
27pub struct MID0031rev2 {
28    /// Number of jobs available on the controller
29    #[open_protocol_field(length = 4)]
30    pub number_of_jobs: u16,
31
32    /// List of Job IDs, each ID is 4 ASCII characters long
33    #[open_protocol_field(list, amount = "number_of_jobs", length = 4)]
34    pub job_ids: Vec<u16>,
35}
36
37#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
38#[open_protocol_message(MID = 0032, revision = 1)]
39pub struct MID0032rev1 {
40    /// The ID of the requested job, 2 ASCII characters long
41    #[open_protocol_field(length = 2)]
42    pub job_id: u8,
43}
44
45#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
46#[open_protocol_message(MID = 0032, revision = 2)]
47pub struct MID0032rev2 {
48    /// The ID of the requested job, 4 ASCII characters long
49    #[open_protocol_field(length = 4)]
50    pub job_id: u16,
51}
52
53#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
54#[open_protocol_message(MID = 0033, revision = 1)]
55pub struct MID0033rev1 {
56    /// The ID of the job
57    #[open_protocol_field(number = 1, length = 2)]
58    pub job_id: u8,
59
60    /// The name of the job, maximum 25 characters
61    #[open_protocol_field(number = 2, length = 25)]
62    pub job_name: String,
63
64    /// Indicates the order type: 0=free, 1=forced, 2=free and forced
65    #[open_protocol_field(number = 3, length = 1)]
66    pub forced_order: u8,
67
68    /// Maximum time allowed for the first tightening in the job, in seconds
69    #[open_protocol_field(number = 4, length = 4)]
70    pub max_time_first_tightening: u16,
71
72    /// Maximum time allowed to complete the job, in seconds
73    #[open_protocol_field(number = 5, length = 5)]
74    pub max_time_to_complete_job: u32,
75
76    /// Job batch mode: 0=Only OK tightenings counted, 1=Both OK and NOK tightenings counted
77    #[open_protocol_field(number = 6, length = 1)]
78    pub job_batch_mode: u8,
79
80    /// Indicates if the tool should be locked when the job is done: 0=No, 1=Yes
81    #[open_protocol_field(number = 7, length = 1)]
82    pub lock_at_job_done: u8,
83
84    /// Indicates if line control is used: 0=No, 1=Yes
85    #[open_protocol_field(number = 8, length = 1)]
86    pub use_line_control: u8,
87
88    /// Indicates if the job is repeatable: 0=No, 1=Yes
89    #[open_protocol_field(number = 9, length = 1)]
90    pub repeat_job: u8,
91
92    /// Tool loosening mode: 0=Enable, 1=Disable, 2=Enable only on NOK tightenings
93    #[open_protocol_field(number = 10, length = 1)]
94    pub tool_loosening: u8,
95
96    /// Reserved for future use
97    #[open_protocol_field(number = 11, length = 1)]
98    pub reserved: u8,
99
100    /// Number of parameter sets included in the job
101    #[open_protocol_field(number = 12, length = 2)]
102    pub number_of_parameter_sets: u8,
103
104    /// List of parameter sets in the job
105    #[open_protocol_field(list, amount = "number_of_parameter_sets", length = 12)]
106    pub job_list: Vec<JobParameterRev1>,
107}
108
109#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
110#[open_protocol_message(MID = 0034, revision = 1)]
111pub struct MID0034rev1 {
112    // No data field for this MID
113}
114
115#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
116#[open_protocol_message(MID = 0035, revision = 1)]
117pub struct MID0035rev1 {
118    /// ID of the job being executed
119    #[open_protocol_field(number = 1, length = 2)]
120    pub job_id: u8,
121
122    /// Status of the job: 0=Not completed, 1=OK, 2=NOK
123    #[open_protocol_field(number = 2, length = 1)]
124    pub job_status: u8,
125
126    /// Batch mode of the job
127    #[open_protocol_field(number = 3, length = 1)]
128    pub job_batch_mode: u8,
129
130    /// Total number of tightenings required in the job
131    #[open_protocol_field(number = 4, length = 4)]
132    pub job_batch_size: u16,
133
134    /// Current count of completed tightenings in the job
135    #[open_protocol_field(number = 5, length = 4)]
136    pub job_batch_counter: u16,
137
138    /// Timestamp of the job information
139    #[open_protocol_field(number = 6, length = 19)]
140    pub timestamp: DateTime<Local>,
141}
142
143#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
144#[open_protocol_message(MID = 0036, revision = 1)]
145pub struct MID0036rev1 {
146    // No data field for this MID
147}
148
149#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
150#[open_protocol_message(MID = 0037, revision = 1)]
151pub struct MID0037rev1 {
152    // No data field for this MID
153}
154
155#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
156#[open_protocol_message(MID = 0038, revision = 1)]
157pub struct MID0038rev1 {
158    /// ID of the job to be selected, 2 ASCII characters
159    #[open_protocol_field(number = 1, length = 2)]
160    pub job_id: u8,
161}
162
163#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
164#[open_protocol_message(MID = 0038, revision = 2)]
165pub struct MID0038rev2 {
166    /// ID of the job to be selected, 4 ASCII characters
167    #[open_protocol_field(number = 1, length = 4)]
168    pub job_id: u16,
169}
170
171#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
172#[open_protocol_message(MID = 0039, revision = 1)]
173pub struct MID0039rev1 {
174    /// ID of the job to be restarted, 2 ASCII characters
175    #[open_protocol_field(number = 1, length = 2)]
176    pub job_id: u8,
177}
178
179#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
180#[open_protocol_message(MID = 0039, revision = 2)]
181pub struct MID0039rev2 {
182    /// ID of the job to be restarted, 4 ASCII characters
183    #[open_protocol_field(number = 1, length = 4)]
184    pub job_id: u16,
185}
186
187#[derive(Debug, Default, Eq, PartialEq)]
188pub struct JobParameterRev1 {
189    /// ID of the channel associated with this parameter set
190    pub channel_id: u8,
191
192    /// ID of the program or parameter set
193    pub program_id: u16,
194
195    /// Indicates if auto-select is enabled: 0=No, 1=Yes
196    pub auto_select: bool,
197
198    /// Batch size for this parameter set
199    pub batch_size: u8,
200}
201
202impl decode::Decode for JobParameterRev1 {
203    fn decode(decoder: &mut decode::Decoder) -> decode::Result<Self> {
204        let channel_id: u8 = decoder.read_sized_field(2)?;
205        decoder.expect_char(':')?;
206        let program_id: u16 = decoder.read_sized_field(3)?;
207        decoder.expect_char(':')?;
208        let auto_select: bool = decoder.read_sized_field(1)?;
209        decoder.expect_char(':')?;
210        let batch_size: u8 = decoder.read_sized_field(2)?;
211        decoder.expect_char(';')?;
212
213        Ok(Self {
214            channel_id,
215            program_id,
216            auto_select,
217            batch_size,
218        })
219    }
220}
221
222impl encode::Encode for JobParameterRev1 {
223    fn encode(&self, encoder: &mut encode::Encoder) -> encode::Result<()> {
224        self.channel_id.encode_sized(encoder, 2)?;
225        ':'.encode(encoder)?;
226        self.program_id.encode_sized(encoder, 3)?;
227        ':'.encode(encoder)?;
228        self.auto_select.encode_sized(encoder, 1)?;
229        ':'.encode(encoder)?;
230        self.batch_size.encode_sized(encoder, 2)?;
231        ';'.encode(encoder)?;
232        Ok(())
233    }
234}
235
236#[cfg(test)]
237mod tests {
238    use super::*;
239    use chrono::TimeZone;
240    use open_protocol_codec::{decode, encode, message::Message};
241
242    #[test]
243    fn test_mid0030rev1() {
244        assert_eq!(MID0030rev1::mid(), 30);
245        assert_eq!(MID0030rev1::revision(), 1);
246        assert_eq!(MID0030rev1 {}.to_mid(), 30);
247        assert_eq!(MID0030rev1 {}.to_revision(), 1);
248    }
249
250    #[test]
251    fn test_mid0031rev1() {
252        let message = MID0031rev1 {
253            number_of_jobs: 2,
254            job_ids: vec![3, 4],
255        };
256
257        assert_eq!(message.to_mid(), MID0031rev1::mid());
258        assert_eq!(message.to_mid(), 31);
259        assert_eq!(message.to_revision(), MID0031rev1::revision());
260        assert_eq!(message.to_revision(), 1);
261    }
262
263    #[test]
264    fn test_mid0035rev1_encode() {
265        let message = MID0035rev1 {
266            job_id: 1,
267            job_status: 0,
268            job_batch_mode: 0,
269            job_batch_size: 8,
270            job_batch_counter: 3,
271            timestamp: Local.with_ymd_and_hms(2001, 12, 1, 20, 12, 45).unwrap(),
272        };
273
274        let encoded = encode::encode(&message);
275
276        assert_eq!(
277            encoded,
278            Ok("0101020030040008050003062001-12-01:20:12:45".to_string())
279        );
280    }
281
282    #[test]
283    fn test_mid0035rev1_decode() {
284        let str = "0101020030040008050003062001-12-01:20:12:45";
285        let decoded = decode::decode::<MID0035rev1>(str.as_bytes());
286        let obj = MID0035rev1 {
287            job_id: 1,
288            job_status: 0,
289            job_batch_mode: 0,
290            job_batch_size: 8,
291            job_batch_counter: 3,
292            timestamp: Local.with_ymd_and_hms(2001, 12, 1, 20, 12, 45).unwrap(),
293        };
294
295        assert_eq!(decoded, Ok(obj));
296    }
297}