solis_models/models/
mod.rs

1use crate::types::*;
2
3pub mod model1;
4pub mod model2;
5pub mod model4;
6pub mod model5;
7pub mod model6_4x;
8pub mod model7_4x;
9pub mod model8_4x;
10pub mod model9_4x;
11pub mod model10_4x;
12pub mod model11_4x;
13
14#[derive(Debug, Clone)]
15pub struct SolModel {
16    pub start_addr: u16,
17    pub end_addr: u16,
18    pub reg_types: u16,
19    pub model_number: u16,
20    pub qtd: u16,
21    pub data: Vec<SDataTypes>,
22}
23
24#[derive(Debug, Clone)]
25pub struct SolModels {
26    pub models: Vec<SolModel>,
27}
28
29// Declare the struct
30pub trait SolisModels {
31    // This new function acts as a constructor
32    fn new (model_number: u16) -> Self;
33    fn update_data(&mut self, point: &str, value: &SDataTypes);
34    fn update_data_by_index(&mut self, index: usize, value: &SDataTypes);
35    fn get_data(&self, point: &str) -> SDataTypes;
36    fn get_data_index(&self, point: &str) -> Option<usize>;
37    fn get_u16(&self, point: &str) -> Option<u16>;
38    fn get_u16_by_index(&self, idx: usize) -> Option<u16>;
39    fn get_u32(&self, point: &str) -> Option<u32>;
40    fn get_u32_by_index(&self, idx: usize) -> Option<u32>;
41    fn get_i16(&self, point: &str) -> Option<i16>;
42    fn get_i16_by_index(&self, idx: usize) -> Option<i16>;
43    fn get_i32(&self, point: &str) -> Option<i32>;
44    fn get_i32_by_index(&self, idx: usize) -> Option<i32>;
45    fn get_string(&self, point: &str) -> Option<String>;
46    fn get_string_by_index(&self, idx: usize) -> Option<String>;
47    fn print(&self);
48}
49
50impl Default for SolModels {
51    fn default() -> Self {
52        Self::new()
53    }
54}
55
56impl SolModels {
57    pub fn new () -> SolModels {
58        SolModels { models: Vec::new() }
59    }
60
61    pub fn get_model_index(&self, model_number: u16) -> Option<usize> {
62        for (idx, model) in self.models.iter().enumerate() {
63            if model_number == model.model_number {
64                return Some(idx);
65            }
66        }
67        None
68    }
69}
70
71impl SolisModels for SolModel {
72    fn new (model_number: u16) -> SolModel {
73        match model_number {
74            1 => model1::model(),
75            2 => model2::model(),
76            4 => model4::model(),
77            5 => model5::model(),
78            6 => model6_4x::model(),
79            7 => model7_4x::model(),
80            8 => model8_4x::model(),
81            9 => model9_4x::model(),
82            10 => model10_4x::model(),
83            11 => model11_4x::model(),
84            _ => model1::model(),
85        }
86    }
87
88    fn update_data(&mut self, point: &str, value: &SDataTypes) {
89        for data_tmp in self.data.iter_mut() {
90            match data_tmp {
91                SDataTypes::SolisU16(data) => {
92                    if data.name.contains(point) && (data.name.len() == point.len()){
93                        if let SDataTypes::SolisU16(update_value) = value {
94                            data.value = update_value.value;
95                        }
96                    }
97                },
98                SDataTypes::SolisU32(data) => {
99                    if data.name.contains(point) && (data.name.len() == point.len()){
100                        if let SDataTypes::SolisU32(update_value) = value {
101                            data.value = update_value.value;
102                        }
103                    }
104                },
105                SDataTypes::SolisI16(data) => {
106                    if data.name.contains(point) && (data.name.len() == point.len()){
107                        if let SDataTypes::SolisI16(update_value) = value {
108                            data.value = update_value.value;
109                        }
110                    }
111                },
112                SDataTypes::SolisI32(data) => {
113                    if data.name.contains(point) && (data.name.len() == point.len()){
114                        if let SDataTypes::SolisI32(update_value) = value {
115                            data.value = update_value.value;
116                        }
117                    }
118                },
119                SDataTypes::SolisString(data) => {
120                    if data.name.contains(point) && (data.name.len() == point.len()){
121                        if let SDataTypes::SolisString(update_value) = value {
122                            data.value = update_value.value.clone();
123                        }
124                    }
125                }
126            }
127        }
128    }
129
130    fn update_data_by_index(&mut self, index: usize, value: &SDataTypes) {
131        match &mut self.data[index] {
132            SDataTypes::SolisU16(data) => {
133                if let SDataTypes::SolisU16(update_value) = value {
134                    data.value = update_value.value;
135                }
136            },
137            SDataTypes::SolisU32(data) => {
138                if let SDataTypes::SolisU32(update_value) = value {
139                    data.value = update_value.value;
140                }
141            },
142            SDataTypes::SolisI16(data) => {
143                if let SDataTypes::SolisI16(update_value) = value {
144                    data.value = update_value.value;
145                }
146            },
147            SDataTypes::SolisI32(data) => {
148                if let SDataTypes::SolisI32(update_value) = value {
149                    data.value = update_value.value;
150                }
151            },
152            SDataTypes::SolisString(data) => {
153                if let SDataTypes::SolisString(update_value) = value {
154                    data.value = update_value.value.clone();
155                }
156            }
157        }
158    }
159
160    fn get_data(&self, point: &str) -> SDataTypes {
161        for data_tmp in self.data.iter() {
162            match data_tmp {
163                SDataTypes::SolisU16(data) => {
164                    if data.name.contains(point) && (data.name.len() == point.len()) {
165                        return data_tmp.clone();
166                    }
167                },
168                SDataTypes::SolisU32(data) => {
169                    if data.name.contains(point) && (data.name.len() == point.len()) {
170                        return data_tmp.clone();
171                    }
172                },
173                SDataTypes::SolisI16(data) => {
174                    if data.name.contains(point) && (data.name.len() == point.len()) {
175                        return data_tmp.clone();
176                    }
177                },
178                SDataTypes::SolisI32(data) => {
179                    if data.name.contains(point) && (data.name.len() == point.len()) {
180                        return data_tmp.clone();
181                    }
182                },
183                SDataTypes::SolisString(data) => {
184                    if data.name.contains(point) && (data.name.len() == point.len()) {
185                        return data_tmp.clone();
186                    }
187                }
188            };
189        }
190        SDataTypes::SolisU16(Point { name: "", offset: 0, length: 1, write_access: false, value: 0 } )
191    }
192
193    fn get_data_index(&self, point: &str) -> Option<usize> {
194        for (idx, data_tmp) in self.data.iter().enumerate() {
195            match data_tmp {
196                SDataTypes::SolisU16(data) => {
197                    if data.name.contains(point) && (data.name.len() == point.len()) {
198                        return Some(idx);
199                    }
200                },
201                SDataTypes::SolisU32(data) => {
202                    if data.name.contains(point) && (data.name.len() == point.len()) {
203                        return Some(idx);
204                    }
205                },
206                SDataTypes::SolisI16(data) => {
207                    if data.name.contains(point) && (data.name.len() == point.len()) {
208                        return Some(idx);
209                    }
210                },
211                SDataTypes::SolisI32(data) => {
212                    if data.name.contains(point) && (data.name.len() == point.len()) {
213                        return Some(idx);
214                    }
215                },
216                SDataTypes::SolisString(data) => {
217                    if data.name.contains(point) && (data.name.len() == point.len()) {
218                        return Some(idx);
219                    }
220                }
221            };
222        }
223        None
224    }
225    
226    fn get_u16(&self, point: &str) -> Option<u16> {
227        for data_tmp in self.data.iter() {
228            if let SDataTypes::SolisU16(data) = data_tmp {
229                if data.name.contains(point) && (data.name.len() == point.len()) {
230                    return Some(data.value);
231                }
232            }
233        }
234        None
235    }
236
237    fn get_u16_by_index(&self, idx: usize) -> Option<u16> {
238        match self.data[idx] {
239            SDataTypes::SolisU16(data) => {
240                Some(data.value)
241            },
242            _ => None
243        }
244    }
245
246    fn get_u32(&self, point: &str) -> Option<u32> {
247        for data_tmp in self.data.iter() {
248            if let SDataTypes::SolisU32(data) = data_tmp {
249                if data.name.contains(point) && (data.name.len() == point.len()) {
250                    return Some(data.value);
251                }
252            }
253        }
254        None
255    }
256
257    fn get_u32_by_index(&self, idx: usize) -> Option<u32> {
258        match self.data[idx] {
259            SDataTypes::SolisU32(data) => {
260                Some(data.value)
261            },
262            _ => None
263        }
264    }
265
266    fn get_i16(&self, point: &str) -> Option<i16> {
267        for data_tmp in self.data.iter() {
268            if let SDataTypes::SolisI16(data) = data_tmp {
269                if data.name.contains(point) && (data.name.len() == point.len()) {
270                    return Some(data.value);
271                }
272            }
273        }
274        None
275    }
276
277    fn get_i16_by_index(&self, idx: usize) -> Option<i16> {
278        match self.data[idx] {
279            SDataTypes::SolisI16(data) => {
280                Some(data.value)
281            },
282            _ => None
283        }
284    }
285
286    fn get_i32(&self, point: &str) -> Option<i32> {
287        for data_tmp in self.data.iter() {
288            if let SDataTypes::SolisI32(data) = data_tmp {
289                if data.name.contains(point) && (data.name.len() == point.len()) {
290                    return Some(data.value);
291                }
292            }
293        }
294        None
295    }
296
297    fn get_i32_by_index(&self, idx: usize) -> Option<i32> {
298        match self.data[idx] {
299            SDataTypes::SolisI32(data) => {
300                Some(data.value)
301            },
302            _ => None
303        }
304    }
305
306    fn get_string(&self, point: &str) -> Option<String> {
307        for data_tmp in self.data.iter() {
308            if let SDataTypes::SolisString(data) = data_tmp {
309                if data.name.contains(point) && (data.name.len() == point.len()) {
310                    return Some(data.value.clone());
311                }
312            }
313        }
314        None
315    }
316
317    fn get_string_by_index(&self, idx: usize) -> Option<String> {
318        match &self.data[idx] {
319            SDataTypes::SolisString(data) => {
320                Some(data.value.clone())
321            },
322            _ => None
323        }
324    }
325
326    fn print(&self) {
327        println!("Model {}:", self.model_number);
328        for data in self.data.iter() {
329            match data {
330                SDataTypes::SolisI16(data) => println!("{}: {}", data.name, data.value),
331                SDataTypes::SolisI32(data) => println!("{}: {}", data.name, data.value),
332                SDataTypes::SolisU16(data) => println!("{}: {}", data.name, data.value),
333                SDataTypes::SolisU32(data) => println!("{}: {}", data.name, data.value),
334                SDataTypes::SolisString(data) => println!("{}: {}", data.name, data.value.clone()),
335            }
336        }
337        println!(" ");
338    }
339}
340
341impl From<SolModel> for Vec<u16> {
342    fn from(from: SolModel) -> Self {
343        let mut registers: Vec<u16> = Vec::new();
344
345        for data in from.data.iter() {
346            match data {
347                SDataTypes::SolisU16(data) => registers.extend(u16::encode(data.value)),
348                SDataTypes::SolisU32(data) => registers.extend(u32::encode(data.value)),
349                SDataTypes::SolisI16(data) => registers.extend(i16::encode(data.value)),
350                SDataTypes::SolisI32(data) => registers.extend(i32::encode(data.value)),
351                SDataTypes::SolisString(data) => registers.extend(Point::<String>::encode(data.clone())),
352            }
353        }
354        registers
355    }
356}
357
358impl From<(Vec<u16>, u16, u16, &SolModel)> for SolModel {
359    fn from(from: (Vec<u16>, u16, u16, &SolModel)) -> Self {
360        let mut model1 = from.3.clone();
361        let mut offset = from.1;
362        let mut qtd = from.2;
363
364        while qtd > 0 {
365            for data in model1.data.iter_mut() {
366                match data {
367                    SDataTypes::SolisU16(data) => {
368                        if offset == data.offset {
369                            let slice = from.0[data.offset as usize..(data.offset + data.length) as usize].to_vec();
370                            data.value = u16::decode(slice);
371                            offset += data.length;
372                            qtd -= data.length;
373                        }
374                    },
375                    SDataTypes::SolisU32(data) => {
376                        if offset == data.offset {
377                            let slice = from.0[data.offset as usize..(data.offset + data.length) as usize].to_vec();
378                            data.value = u32::decode(slice);
379                            offset += data.length;
380                            qtd -= data.length;
381                        }
382                    },
383                    SDataTypes::SolisI16(data) => {
384                        if offset == data.offset {
385                            let slice = from.0[data.offset as usize..(data.offset + data.length) as usize].to_vec();
386                            data.value = i16::decode(slice);
387                            offset += data.length;
388                            qtd -= data.length;
389                        }
390                    },
391                    SDataTypes::SolisI32(data) => {
392                        if offset == data.offset {
393                            let slice = from.0[data.offset as usize..(data.offset + data.length) as usize].to_vec();
394                            data.value = i32::decode(slice);
395                            offset += data.length;
396                            qtd -= data.length;
397                        }
398                    },
399                    SDataTypes::SolisString(data) => {
400                        if offset == data.offset {
401                            let slice = from.0[data.offset as usize..(data.offset + data.length) as usize].to_vec();
402                            let hex_string = format!("{:4X}", slice[0]);
403                            data.value = hex_string.chars().rev().collect();
404                            offset += data.length;
405                            qtd -= data.length;
406                        }
407                    },
408                }
409            }
410        }
411        model1
412    }
413}