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
138pub trait SunspecModels {
140 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 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}