sunspec_models/models/
mod.rs

1use std::io::Write;
2use std::mem;
3use crate::types::*;
4
5pub mod model1;
6pub mod model2;
7pub mod model3;
8pub mod model4;
9pub mod model5;
10pub mod model6;
11pub mod model7;
12pub mod model8;
13pub mod model9;
14pub mod model10;
15pub mod model11;
16pub mod model12;
17pub mod model13;
18pub mod model14;
19pub mod model15;
20pub mod model16;
21pub mod model17;
22pub mod model18;
23pub mod model19;
24pub mod model101;
25pub mod model102;
26pub mod model103;
27pub mod model111;
28pub mod model112;
29pub mod model113;
30pub mod model120;
31pub mod model121;
32pub mod model122;
33pub mod model123;
34pub mod model124;
35pub mod model125;
36pub mod model126;
37pub mod model127;
38pub mod model128;
39pub mod model129;
40pub mod model130;
41pub mod model131;
42pub mod model132;
43pub mod model133;
44pub mod model134;
45pub mod model135;
46pub mod model136;
47pub mod model137;
48pub mod model138;
49pub mod model139;
50pub mod model140;
51pub mod model141;
52pub mod model142;
53pub mod model143;
54pub mod model144;
55pub mod model145;
56pub mod model160;
57pub mod model201;
58pub mod model202;
59pub mod model203;
60pub mod model204;
61pub mod model211;
62pub mod model212;
63pub mod model213;
64pub mod model214;
65pub mod model220;
66pub mod model302;
67pub mod model303;
68pub mod model304;
69pub mod model305;
70pub mod model306;
71pub mod model307;
72pub mod model308;
73pub mod model401;
74pub mod model402;
75pub mod model403;
76pub mod model404;
77pub mod model501;
78pub mod model502;
79pub mod model601;
80pub mod model701;
81pub mod model702;
82pub mod model703;
83pub mod model704;
84pub mod model705;
85pub mod model706;
86pub mod model707;
87pub mod model708;
88pub mod model709;
89pub mod model710;
90pub mod model711;
91pub mod model712;
92pub mod model801;
93pub mod model802;
94pub mod model803;
95pub mod model804;
96pub mod model805;
97pub mod model806;
98pub mod model807;
99pub mod model808;
100pub mod model809;
101pub mod model63001;
102pub mod model63002;
103pub mod model64001;
104pub mod model64020;
105pub mod model64061;
106pub mod model64069;
107pub mod model64101;
108pub mod model64110;
109pub mod model64111;
110pub mod model64112;
111pub mod models200;
112pub mod models700;
113
114
115pub const SUNSPEC_INIT_ADDR: u16 = 40000;
116
117#[derive(Debug, Clone, Copy)]
118pub struct SunspecID {
119    pub id: [u8; 4]
120}
121
122#[derive(Debug, Clone)]
123pub struct Model {
124    pub start_addr: u16,
125    pub end_addr: u16,
126    pub model_number: u16,
127    pub qtd: u16,
128    pub update: bool,
129    pub data: Vec<DataTypes>,
130}
131
132#[derive(Debug, Clone)]
133pub struct Models {
134    pub id: SunspecID,
135    pub models: Vec<Model>,
136}
137
138// Declare the struct
139pub trait SunspecModels {
140    // This new function acts as a constructor
141    fn new (model_number: u16) -> Self;
142    fn new_blocks (model_number: u16, number: u16) -> Self;
143    fn update_data(&mut self, point: &str, value: &DataTypes);
144    fn update_data_by_index(&mut self, index: usize, value: &DataTypes);
145    fn get_data(&self, point: &str) -> DataTypes;
146    fn get_data_index(&self, point: &str) -> Option<usize>;
147    fn get_string(&self, point: &str) -> Option<String>;
148    fn get_string_by_index(&self, idx: usize) -> Option<String>;
149    fn get_f32(&self, point: &str) -> Option<f32>;
150    fn get_f32_by_index(&self, idx: usize) -> Option<f32>;
151    fn get_u16(&self, point: &str) -> Option<u16>;
152    fn get_u16_by_index(&self, idx: usize) -> Option<u16>;
153    fn get_u32(&self, point: &str) -> Option<u32>;
154    fn get_u32_by_index(&self, idx: usize) -> Option<u32>;
155    fn get_u64(&self, point: &str) -> Option<u64>;
156    fn get_u64_by_index(&self, idx: usize) -> Option<u64>;
157    fn get_u128(&self, point: &str) -> Option<u128>;
158    fn get_u128_by_index(&self, idx: usize) -> Option<u128>;
159    fn get_i16(&self, point: &str) -> Option<i16>;
160    fn get_i16_by_index(&self, idx: usize) -> Option<i16>;
161    fn get_i32(&self, point: &str) -> Option<i32>;
162    fn get_i32_by_index(&self, idx: usize) -> Option<i32>;
163    fn get_i64(&self, point: &str) -> Option<i64>;
164    fn get_i64_by_index(&self, idx: usize) -> Option<i64>;
165    fn print(&self);
166}
167
168
169impl SunspecID {
170    fn new () -> SunspecID {
171        let mut ret = SunspecID {
172            id: [0; 4],
173        };
174        srt_to_vec_u8("SunS", &mut ret.id).unwrap();
175        ret
176    }
177}
178
179impl Models {
180    pub fn new () -> Models {
181        Models { id: SunspecID::new(), models: Vec::new() }
182    }
183
184    pub fn get_model_index(&self, model_number: u16) -> Option<usize> {
185        for (idx, model) in self.models.iter().enumerate() {
186            if model_number == model.model_number {
187                return Some(idx);
188            }
189        }
190        None
191    }
192
193    pub fn compute_addr (&mut self) {
194        let mut end_addr = 0;
195        for (idx, model) in self.models.iter_mut().enumerate() {
196            if idx == 0 {
197                model.start_addr = SUNSPEC_INIT_ADDR + 2;
198            }else{
199                model.start_addr = end_addr;
200            }
201            model.end_addr = model.start_addr + model.qtd + 2;
202            end_addr = model.end_addr;
203        }
204    }
205}
206
207fn model_end() -> Model {
208    Model {
209        start_addr: 0,
210        model_number: 0xFFFF,
211        qtd: 0,
212        end_addr: 0,
213        update: false,
214        data: Vec::new(),
215    }
216}
217
218impl SunspecModels for Model {
219    fn new (model_number: u16) -> Model {
220        match model_number {
221            1 => model1::model1(),
222            2 => model2::model2(),
223            3 => model3::model3(),
224            4 => model4::model4(),
225            5 => model5::model5(),
226            6 => model6::model6(),
227            7 => model7::model7(),
228            8 => model8::model8(),
229            9 => model9::model9(),
230            10 => model10::model10(),
231            11 => model11::model11(),
232            12 => model12::model12(),
233            13 => model13::model13(),
234            14 => model14::model14(),
235            15 => model15::model15(),
236            16 => model16::model16(),
237            17 => model17::model17(),
238            18 => model18::model18(),
239            19 => model19::model19(),
240            101 => model101::model101(),
241            102 => model102::model102(),
242            103 => model103::model103(),
243            111 => model111::model111(),
244            112 => model112::model112(),
245            113 => model113::model113(),
246            120 => model120::model120(),
247            121 => model121::model121(),
248            122 => model122::model122(),
249            123 => model123::model123(),
250            124 => model124::model124(),
251            125 => model125::model125(),
252            126 => model126::model126(),
253            127 => model127::model127(),
254            128 => model128::model128(),
255            129 => model129::model129(),
256            130 => model130::model130(),
257            131 => model131::model131(),
258            132 => model132::model132(),
259            133 => model133::model133(),
260            134 => model134::model134(),
261            135 => model135::model135(),
262            136 => model136::model136(),
263            137 => model137::model137(),
264            138 => model138::model138(),
265            139 => model139::model139(),
266            140 => model140::model140(),
267            141 => model141::model141(),
268            142 => model142::model142(),
269            143 => model143::model143(),
270            144 => model144::model144(),
271            145 => model145::model145(),
272            //160 => model160::model160(),
273            201 => model201::model201(),
274            202 => model202::model202(),
275            203 => model203::model203(),
276            204 => model204::model204(),
277            211 => model211::model211(),
278            212 => model212::model212(),
279            213 => model213::model213(),
280            214 => model214::model214(),
281            220 => model220::model220(),
282            302 => model302::model302(),
283            303 => model303::model303(),
284            304 => model304::model304(),
285            305 => model305::model305(),
286            306 => model306::model306(),
287            307 => model307::model307(),
288            308 => model308::model308(),
289            401 => model401::model401(),
290            402 => model402::model402(),
291            404 => model404::model404(),
292            501 => model501::model501(),
293            502 => model502::model502(),
294            601 => model601::model601(),
295            701 => model701::model701(),
296            702 => model702::model702(),
297            703 => model703::model703(),
298            704 => model704::model704(),
299            705 => model705::model705(),
300            706 => model706::model706(),
301            707 => model707::model707(),
302            708 => model708::model708(),
303            709 => model709::model709(),
304            710 => model710::model710(),
305            711 => model711::model711(),
306            712 => model712::model712(),
307            801 => model801::model801(),
308            802 => model802::model802(),
309            803 => model803::model803(),
310            804 => model804::model804(),
311            805 => model805::model805(),
312            806 => model806::model806(),
313            807 => model807::model807(),
314            808 => model808::model808(),
315            809 => model809::model809(),
316            63001 => model63001::model63001(),
317            63002 => model63002::model63002(),
318            64001 => model64001::model64001(),
319            64061 => model64061::model64061(),
320            64069 => model64069::model64069(),
321            64020 => model64020::model64020(),
322            64101 => model64101::model64101(),
323            64110 => model64110::model64110(),
324            64111 => model64111::model64111(),
325            64112 => model64112::model64112(),
326            _ => model_end(),
327        }
328    }
329
330    fn new_blocks (model_number: u16, number: u16) -> Self {
331        match model_number {
332            160 => model160::model160(number),
333            403 => model403::model403(number),
334            _ => model160::model160(number)
335        }
336    }
337
338    fn update_data(&mut self, point: &str, value: &DataTypes) {
339        for data_tmp in self.data.iter_mut() {
340            match data_tmp {
341                DataTypes::SunspecString(data) => {
342                    if data.name.contains(point) && (data.name.len() == point.len()){
343                        if let DataTypes::SunspecString(update_value) = value {
344                            data.value = update_value.value.clone();
345                        }
346                    }
347                },
348                DataTypes::SunspecF32(data) => {
349                    if data.name.contains(point) && (data.name.len() == point.len()){
350                        if let DataTypes::SunspecF32(update_value) = value {
351                            data.value = update_value.value;
352                        }
353                    }
354                },
355                DataTypes::SunspecU16(data) => {
356                    if data.name.contains(point) && (data.name.len() == point.len()){
357                        if let DataTypes::SunspecU16(update_value) = value {
358                            data.value = update_value.value;
359                        }
360                    }
361                },
362                DataTypes::SunspecU32(data) => {
363                    if data.name.contains(point) && (data.name.len() == point.len()){
364                        if let DataTypes::SunspecU32(update_value) = value {
365                            data.value = update_value.value;
366                        }
367                    }
368                },
369                DataTypes::SunspecU64(data) => {
370                    if data.name.contains(point) && (data.name.len() == point.len()){
371                        if let DataTypes::SunspecU64(update_value) = value {
372                            data.value = update_value.value;
373                        }
374                    }
375                },
376                DataTypes::SunspecU128(data) => {
377                    if data.name.contains(point) && (data.name.len() == point.len()){
378                        if let DataTypes::SunspecU128(update_value) = value {
379                            data.value = update_value.value;
380                        }
381                    }
382                },
383                DataTypes::SunspecI16(data) => {
384                    if data.name.contains(point) && (data.name.len() == point.len()){
385                        if let DataTypes::SunspecI16(update_value) = value {
386                            data.value = update_value.value;
387                        }
388                    }
389                },
390                DataTypes::SunspecI32(data) => {
391                    if data.name.contains(point) && (data.name.len() == point.len()){
392                        if let DataTypes::SunspecI32(update_value) = value {
393                            data.value = update_value.value;
394                        }
395                    }
396                },
397                DataTypes::SunspecI64(data) => {
398                    if data.name.contains(point) && (data.name.len() == point.len()){
399                        if let DataTypes::SunspecI64(update_value) = value {
400                            data.value = update_value.value;
401                        }
402                    }
403                },
404            }
405        }
406    }
407
408    fn update_data_by_index(&mut self, index: usize, value: &DataTypes) {
409        match &mut self.data[index] {
410            DataTypes::SunspecString(data) => {
411                if let DataTypes::SunspecString(update_value) = value {
412                    data.value = update_value.value.clone();
413                }
414            },
415            DataTypes::SunspecF32(data) => {
416                if let DataTypes::SunspecF32(update_value) = value {
417                    data.value = update_value.value;
418                }
419            },
420            DataTypes::SunspecU16(data) => {
421                if let DataTypes::SunspecU16(update_value) = value {
422                    data.value = update_value.value;
423                }
424            },
425            DataTypes::SunspecU32(data) => {
426                if let DataTypes::SunspecU32(update_value) = value {
427                    data.value = update_value.value;
428                }
429            },
430            DataTypes::SunspecU64(data) => {
431                if let DataTypes::SunspecU64(update_value) = value {
432                    data.value = update_value.value;
433                }
434            },
435            DataTypes::SunspecU128(data) => {
436                if let DataTypes::SunspecU128(update_value) = value {
437                    data.value = update_value.value;
438                }
439            },
440            DataTypes::SunspecI16(data) => {
441                if let DataTypes::SunspecI16(update_value) = value {
442                    data.value = update_value.value;
443                }
444            },
445            DataTypes::SunspecI32(data) => {
446                if let DataTypes::SunspecI32(update_value) = value {
447                    data.value = update_value.value;
448                }
449            },
450            DataTypes::SunspecI64(data) => {
451                if let DataTypes::SunspecI64(update_value) = value {
452                    data.value = update_value.value;
453                }
454            },
455        }
456    }
457
458    fn get_data(&self, point: &str) -> DataTypes {
459        for data_tmp in self.data.iter() {
460            match data_tmp {
461                DataTypes::SunspecString(data) => {
462                    if data.name.contains(point) && (data.name.len() == point.len()) {
463                        return data_tmp.clone();
464                    }
465                },
466                DataTypes::SunspecU16(data) => {
467                    if data.name.contains(point) && (data.name.len() == point.len()) {
468                        return data_tmp.clone();
469                    }
470                },
471                DataTypes::SunspecU32(data) => {
472                    if data.name.contains(point) && (data.name.len() == point.len()) {
473                        return data_tmp.clone();
474                    }
475                },
476                DataTypes::SunspecU64(data) => {
477                    if data.name.contains(point) && (data.name.len() == point.len()) {
478                        return data_tmp.clone();
479                    }
480                },
481                DataTypes::SunspecU128(data) => {
482                    if data.name.contains(point) && (data.name.len() == point.len()) {
483                        return data_tmp.clone();
484                    }
485                },
486                DataTypes::SunspecI16(data) => {
487                    if data.name.contains(point) && (data.name.len() == point.len()) {
488                        return data_tmp.clone();
489                    }
490                },
491                DataTypes::SunspecI32(data) => {
492                    if data.name.contains(point) && (data.name.len() == point.len()) {
493                        return data_tmp.clone();
494                    }
495                },
496                DataTypes::SunspecI64(data) => {
497                    if data.name.contains(point) && (data.name.len() == point.len()) {
498                        return data_tmp.clone();
499                    }
500                },
501                DataTypes::SunspecF32(data) => {
502                    if data.name.contains(point) && (data.name.len() == point.len()) {
503                        return data_tmp.clone();
504                    }
505                }
506            };
507        }
508        DataTypes::SunspecU16(Point { name: "", offset: 0, length: 1, write_access: false, value: 0 } )
509    }
510
511    fn get_data_index(&self, point: &str) -> Option<usize> {
512        for (idx, data_tmp) in self.data.iter().enumerate() {
513            match data_tmp {
514                DataTypes::SunspecString(data) => {
515                    if data.name.contains(point) && (data.name.len() == point.len()) {
516                        return Some(idx);
517                    }
518                },
519                DataTypes::SunspecU16(data) => {
520                    if data.name.contains(point) && (data.name.len() == point.len()) {
521                        return Some(idx);
522                    }
523                },
524                DataTypes::SunspecU32(data) => {
525                    if data.name.contains(point) && (data.name.len() == point.len()) {
526                        return Some(idx);
527                    }
528                },
529                DataTypes::SunspecU64(data) => {
530                    if data.name.contains(point) && (data.name.len() == point.len()) {
531                        return Some(idx);
532                    }
533                },
534                DataTypes::SunspecU128(data) => {
535                    if data.name.contains(point) && (data.name.len() == point.len()) {
536                        return Some(idx);
537                    }
538                },
539                DataTypes::SunspecI16(data) => {
540                    if data.name.contains(point) && (data.name.len() == point.len()) {
541                        return Some(idx);
542                    }
543                },
544                DataTypes::SunspecI32(data) => {
545                    if data.name.contains(point) && (data.name.len() == point.len()) {
546                        return Some(idx);
547                    }
548                },
549                DataTypes::SunspecI64(data) => {
550                    if data.name.contains(point) && (data.name.len() == point.len()) {
551                        return Some(idx);
552                    }
553                },
554                DataTypes::SunspecF32(data) => {
555                    if data.name.contains(point) && (data.name.len() == point.len()) {
556                        return Some(idx);
557                    }
558                }
559            };
560        }
561        None
562    }
563
564    fn get_f32(&self, point: &str) -> Option<f32> {
565        for data_tmp in self.data.iter() {
566            if let DataTypes::SunspecF32(data) = data_tmp {
567                if data.name.contains(point) && (data.name.len() == point.len()) {
568                    return Some(data.value);
569                }
570            }
571        }
572        None
573    }
574
575    fn get_f32_by_index(&self, idx: usize) -> Option<f32> {
576        match self.data[idx] {
577            DataTypes::SunspecF32(data) => {
578                Some(data.value)
579            },
580            _ => None
581        }
582    }
583
584    fn get_string(&self, point: &str) -> Option<String> {
585        for data_tmp in self.data.iter() {
586            if let DataTypes::SunspecString(data) = data_tmp {
587                if data.name.contains(point) && (data.name.len() == point.len()) {
588                    return Some(data.value.clone());
589                }
590            }
591        }
592        None
593    }
594
595    fn get_string_by_index(&self, idx: usize) -> Option<String> {
596        match &self.data[idx] {
597            DataTypes::SunspecString(data) => {
598                Some(data.value.clone())
599            },
600            _ => None
601        }
602    }
603
604    fn get_u16(&self, point: &str) -> Option<u16> {
605        for data_tmp in self.data.iter() {
606            if let DataTypes::SunspecU16(data) = data_tmp {
607                if data.name.contains(point) && (data.name.len() == point.len()) {
608                    return Some(data.value);
609                }
610            }
611        }
612        None
613    }
614
615    fn get_u16_by_index(&self, idx: usize) -> Option<u16> {
616        match self.data[idx] {
617            DataTypes::SunspecU16(data) => {
618                Some(data.value)
619            },
620            _ => None
621        }
622    }
623
624    fn get_u32(&self, point: &str) -> Option<u32> {
625        for data_tmp in self.data.iter() {
626            if let DataTypes::SunspecU32(data) = data_tmp {
627                if data.name.contains(point) && (data.name.len() == point.len()) {
628                    return Some(data.value);
629                }
630            }
631        }
632        None
633    }
634
635    fn get_u32_by_index(&self, idx: usize) -> Option<u32> {
636        match self.data[idx] {
637            DataTypes::SunspecU32(data) => {
638                Some(data.value)
639            },
640            _ => None
641        }
642    }
643
644    fn get_u64(&self, point: &str) -> Option<u64> {
645        for data_tmp in self.data.iter() {
646            if let DataTypes::SunspecU64(data) = data_tmp {
647                if data.name.contains(point) && (data.name.len() == point.len()) {
648                    return Some(data.value);
649                }
650            }
651        }
652        None
653    }
654
655    fn get_u64_by_index(&self, idx: usize) -> Option<u64> {
656        match self.data[idx] {
657            DataTypes::SunspecU64(data) => {
658                Some(data.value)
659            },
660            _ => None
661        }
662    }
663
664    fn get_u128(&self, point: &str) -> Option<u128> {
665        for data_tmp in self.data.iter() {
666            if let DataTypes::SunspecU128(data) = data_tmp {
667                if data.name.contains(point) && (data.name.len() == point.len()) {
668                    return Some(data.value);
669                }
670            }
671        }
672        None
673    }
674
675    fn get_u128_by_index(&self, idx: usize) -> Option<u128> {
676        match self.data[idx] {
677            DataTypes::SunspecU128(data) => {
678                Some(data.value)
679            },
680            _ => None
681        }
682    }
683
684    fn get_i16(&self, point: &str) -> Option<i16> {
685        for data_tmp in self.data.iter() {
686            if let DataTypes::SunspecI16(data) = data_tmp {
687                if data.name.contains(point) && (data.name.len() == point.len()) {
688                    return Some(data.value);
689                }
690            }
691        }
692        None
693    }
694
695    fn get_i16_by_index(&self, idx: usize) -> Option<i16> {
696        match self.data[idx] {
697            DataTypes::SunspecI16(data) => {
698                Some(data.value)
699            },
700            _ => None
701        }
702    }
703
704    fn get_i32(&self, point: &str) -> Option<i32> {
705        for data_tmp in self.data.iter() {
706            if let DataTypes::SunspecI32(data) = data_tmp {
707                if data.name.contains(point) && (data.name.len() == point.len()) {
708                    return Some(data.value);
709                }
710            }
711        }
712        None
713    }
714
715    fn get_i32_by_index(&self, idx: usize) -> Option<i32> {
716        match self.data[idx] {
717            DataTypes::SunspecI32(data) => {
718                Some(data.value)
719            },
720            _ => None
721        }
722    }
723
724    fn get_i64(&self, point: &str) -> Option<i64> {
725        for data_tmp in self.data.iter() {
726            if let DataTypes::SunspecI64(data) = data_tmp {
727                if data.name.contains(point) && (data.name.len() == point.len()) {
728                    return Some(data.value);
729                }
730            }
731        }
732        None
733    }
734
735    fn get_i64_by_index(&self, idx: usize) -> Option<i64> {
736        match self.data[idx] {
737            DataTypes::SunspecI64(data) => {
738                Some(data.value)
739            },
740            _ => None
741        }
742    }
743
744    fn print(&self) {
745        println!("Model {}:", self.model_number);
746        for data in self.data.iter() {
747            match data {
748                DataTypes::SunspecF32(data) => println!("{}: {}", data.name, data.value),
749                DataTypes::SunspecU16(data) => println!("{}: {}", data.name, data.value),
750                DataTypes::SunspecU32(data) => println!("{}: {}", data.name, data.value),
751                DataTypes::SunspecU64(data) => println!("{}: {}", data.name, data.value),
752                DataTypes::SunspecU128(data) => println!("{}: {}", data.name, data.value),
753                DataTypes::SunspecI16(data) => println!("{}: {}", data.name, data.value),
754                DataTypes::SunspecI32(data) => println!("{}: {}", data.name, data.value),
755                DataTypes::SunspecI64(data) => println!("{}: {}", data.name, data.value),
756                DataTypes::SunspecString(data) => println!("{}: {}", data.name, data.value.clone()),
757            }
758        }
759        println!(" ");
760    }
761}
762
763
764fn vec_u8_to_vec_u16(src: &[u8], dst: &mut [u16], mut idx: usize, size: usize) -> usize {
765    for i in (0..size).step_by(2) {
766        dst[idx] = (src[i] as u16) << 8;
767        dst[idx] += src[i+1] as u16;
768        idx += 1;
769    }
770    idx
771}
772
773pub fn srt_to_vec_u8(src: &str, mut dst: &mut [u8]) -> Result<usize, std::io::Error> {
774    dst.write(src.as_bytes())
775}
776
777impl From<SunspecID> for Vec<u16> {
778    fn from(from: SunspecID) -> Self {
779        let size = mem::size_of::<SunspecID>() / 2;
780        let mut registers: Vec<u16> = vec![0; size];
781        
782        vec_u8_to_vec_u16(&from.id, &mut registers, 0, from.id.len());
783        registers
784    }
785}
786
787impl From<Vec<u16>> for SunspecID {
788    fn from(from: Vec<u16>) -> Self {
789        let mut sunspec = SunspecID::new();
790        sunspec.id[0] = (from[0] >> 8) as u8;
791        sunspec.id[1] = (from[0] & 0xFF) as u8;
792        sunspec.id[2] = (from[1] >> 8) as u8;
793        sunspec.id[3] = (from[1] & 0xFF) as u8;
794        sunspec
795    }
796}
797
798impl From<Model> for Vec<u16> {
799    fn from(from: Model) -> Self {
800        let mut registers: Vec<u16> = vec![0; 2];
801        registers[0] = from.model_number;
802        registers[1] = from.qtd;
803
804        for data in from.data.iter() {
805            match data {
806                DataTypes::SunspecF32(data) => registers.extend(f32::encode(data.value)),
807                DataTypes::SunspecU16(data) => registers.extend(u16::encode(data.value)),
808                DataTypes::SunspecU32(data) => registers.extend(u32::encode(data.value)),
809                DataTypes::SunspecU64(data) => registers.extend(u64::encode(data.value)),
810                DataTypes::SunspecU128(data) => registers.extend(u128::encode(data.value)),
811                DataTypes::SunspecI16(data) => registers.extend(i16::encode(data.value)),
812                DataTypes::SunspecI32(data) => registers.extend(i32::encode(data.value)),
813                DataTypes::SunspecI64(data) => registers.extend(i64::encode(data.value)),
814                DataTypes::SunspecString(data) => registers.extend(Point::<String>::encode(data.clone())),
815            }
816        }
817        registers
818    }
819}
820
821impl From<(Vec<u16>, u16, u16, &Model)> for Model {
822    fn from(from: (Vec<u16>, u16, u16, &Model)) -> Self {
823        let mut model1 = from.3.clone();
824        let mut offset = from.1 - model1.start_addr;
825        let mut qtd = from.2;
826
827        let mut regs = from.0.clone();
828
829        while qtd > 0 {
830            for data in model1.data.iter_mut() {
831                match data {
832                    DataTypes::SunspecString(data) => {
833                        if (offset == data.offset) && (data.write_access) {
834                            data.value = Point::<String>::decode(regs.clone()).value;
835                            offset += data.length;
836                            qtd -= data.length;
837                            for _i in 0..data.length {
838                                regs.remove(0);
839                            }
840                        }
841                    },
842                    DataTypes::SunspecU16(data) => {
843                        if (offset == data.offset) && (data.write_access) {
844                            data.value = u16::decode(regs.clone());
845                            offset += data.length;
846                            qtd -= data.length;
847                            for _i in 0..data.length {
848                                regs.remove(0);
849                            }
850                        }
851                    },
852                    DataTypes::SunspecU32(data) => {
853                        if (offset == data.offset) && (data.write_access) {
854                            data.value = u32::decode(regs.clone());
855                            offset += data.length;
856                            qtd -= data.length;
857                            for _i in 0..data.length {
858                                regs.remove(0);
859                            }
860                        }
861                    },
862                    DataTypes::SunspecU64(data) => {
863                        if (offset == data.offset) && (data.write_access) {
864                            data.value = u64::decode(regs.clone());
865                            offset += data.length;
866                            qtd -= data.length;
867                            for _i in 0..data.length {
868                                regs.remove(0);
869                            }
870                        }
871                    },
872                    DataTypes::SunspecU128(data) => {
873                        if (offset == data.offset) && (data.write_access) {
874                            data.value = u128::decode(regs.clone());
875                            offset += data.length;
876                            qtd -= data.length;
877                            for _i in 0..data.length {
878                                regs.remove(0);
879                            }
880                        }
881                    },
882                    DataTypes::SunspecI16(data) => {
883                        if (offset == data.offset) && (data.write_access) {
884                            data.value = i16::decode(regs.clone());
885                            offset += data.length;
886                            qtd -= data.length;
887                            for _i in 0..data.length {
888                                regs.remove(0);
889                            }
890                        }
891                    },
892                    DataTypes::SunspecI32(data) => {
893                        if (offset == data.offset) && (data.write_access) {
894                            data.value = i32::decode(regs.clone());
895                            offset += data.length;
896                            qtd -= data.length;
897                            for _i in 0..data.length {
898                                regs.remove(0);
899                            }
900                        }
901                    },
902                    DataTypes::SunspecI64(data) => {
903                        if (offset == data.offset) && (data.write_access) {
904                            data.value = i64::decode(regs.clone());
905                            offset += data.length;
906                            qtd -= data.length;
907                            for _i in 0..data.length {
908                                regs.remove(0);
909                            }
910                        }
911                    },
912                    _ => {}
913                }
914                if qtd == 0 {
915                    break;
916                }
917            }
918        }
919        model1
920    }
921}