1
0
Fork 0

Fix utf8 register parsing

main
Bo Jeanes 2022-09-29 18:19:06 +10:00
parent 20438cd765
commit 4d43f8ef66
3 changed files with 173 additions and 10 deletions

View File

@ -86,7 +86,9 @@ If the connection is successful, you will see the following message like the fol
#### Full connection examples #### Full connection examples
All fields accepted (optional fields show defaults) Check the `examples/` directory for some examples and please feel free to share your own examples, noting the appropriate vendor/device info.
The following JSON is all supported connection configuration fields, where the optional fields show the default values in use.
```jsonc ```jsonc
{ {

View File

@ -9,14 +9,20 @@
"type": "u32", "type": "u32",
"name": "dc_power", "name": "dc_power",
"swap_words": true, "swap_words": true,
"period": "1s" "period": "500ms"
}, },
{ {
"address": 13034, "address": 13034,
"type": "u32", "type": "u32",
"name": "active_power", "name": "active_power",
"swap_words": true, "swap_words": true,
"period": "1s" "period": "500ms"
},
{
"address": 4990,
"name": "serial_number",
"type": "string",
"length": 10
}, },
{ {
"address": 5008, "address": 5008,
@ -25,24 +31,45 @@
"period": "1m", "period": "1m",
"scale": -1 "scale": -1
}, },
{
"address": 5001,
"type": "u16",
"name": "nominal_output_power",
"period": "1m",
"scale": 2
},
{ {
"address": 13008, "address": 13008,
"type": "s32", "type": "s32",
"name": "load_power", "name": "load_power",
"swap_words": true, "swap_words": true,
"period": "1s" "period": "500ms"
}, },
{ {
"address": 13010, "address": 13010,
"type": "s32", "type": "s32",
"name": "export_power", "name": "export_power",
"swap_words": true, "swap_words": true,
"period": "1s" "period": "500ms"
},
{
"address": 13020,
"name": "battery_voltage",
"period": "3s",
"type": "u16",
"scale": -1
}, },
{ {
"address": 13022, "address": 13022,
"name": "battery_power", "name": "battery_power",
"period": "1s" "period": "500ms"
},
{
"address": 13021,
"name": "battery_current",
"period": "500ms",
"type": "s16",
"scale": -1
}, },
{ {
"address": 13023, "address": 13023,
@ -85,12 +112,12 @@
"scale": -1 "scale": -1
}, },
{ {
"address": 5012, "address": 5013,
"name": "mppt2_voltage", "name": "mppt2_voltage",
"scale": -1 "scale": -1
}, },
{ {
"address": 5013, "address": 5014,
"name": "mppt2_current", "name": "mppt2_current",
"scale": -1 "scale": -1
}, },
@ -118,6 +145,116 @@
"address": 33148, "address": 33148,
"name": "forced_battery_power", "name": "forced_battery_power",
"scale": 1 "scale": 1
},
{
"address": 13002,
"type": "u16",
"name": "daily_pv_generation",
"scale": -1
},
{
"address": 13003,
"type": "u32",
"swap_words": true,
"name": "total_pv_generation",
"scale": -1
},
{
"address": 13005,
"type": "u16",
"name": "daily_export_energy",
"scale": -1
},
{
"address": 13006,
"type": "u32",
"swap_words": true,
"name": "total_export_energy",
"scale": -1
},
{
"address": 13012,
"type": "u16",
"name": "daily_battery_charge_energy",
"scale": -1
},
{
"address": 13013,
"type": "u32",
"swap_words": true,
"name": "total_battery_charge_energy",
"scale": -1
},
{
"address": 13026,
"type": "u16",
"name": "daily_battery_discharge_energy",
"scale": -1
},
{
"address": 13027,
"type": "u32",
"swap_words": true,
"name": "total_battery_discharge_energy",
"scale": -1
},
{
"address": 13017,
"type": "u16",
"name": "daily_direct_energy_consumption",
"scale": -1
},
{
"address": 13018,
"type": "u32",
"swap_words": true,
"name": "total_direct_energy_consumption",
"scale": -1
},
{
"address": 5003,
"type": "u16",
"name": "daily_output_energy",
"scale": -1
},
{
"address": 5004,
"type": "u32",
"swap_words": true,
"name": "total_output_energy",
"scale": -1
},
{
"address": 13029,
"type": "u16",
"name": "daily_self_consumption_rate",
"scale": -1
},
{
"address": 13036,
"type": "u16",
"name": "daily_import_energy",
"scale": -1
},
{
"address": 13037,
"type": "u32",
"swap_words": true,
"name": "total_import_energy",
"scale": -1
},
{
"address": 13040,
"type": "u16",
"name": "daily_charge_energy",
"scale": -1
},
{
"address": 13041,
"type": "u32",
"swap_words": true,
"name": "total_charge_energy",
"scale": -1
} }
] ]
} }

View File

@ -466,7 +466,7 @@ impl RegisterValueType {
} }
} }
T::String(RegisterString { .. }) => { T::String(RegisterString { .. }) => {
json!(String::from_utf16_lossy(words)) json!(String::from_utf8_lossy(&bytes).trim_end_matches(char::from(0)))
} }
T::Array(RegisterArray { .. }) => todo!(), T::Array(RegisterArray { .. }) => todo!(),
} }
@ -511,7 +511,7 @@ impl Register {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
#[test] #[test]
fn test_parse_1() { fn test_parse_numeric() {
use serde_json::json; use serde_json::json;
let reg = Register { let reg = Register {
@ -534,3 +534,27 @@ fn test_parse_1() {
assert_eq!(reg.parse_words(&[843, 0]), json!(843)); assert_eq!(reg.parse_words(&[843, 0]), json!(843));
} }
#[test]
fn test_parse_string() {
use serde_json::json;
let reg = Register {
register_type: RegisterType::Input,
address: 42,
name: None,
interval: Default::default(),
parse: RegisterParse {
swap_bytes: Swap(false),
swap_words: Swap(false),
value_type: RegisterValueType::String(RegisterString { length: 10 }),
},
};
assert_eq!(
reg.parse_words(&[
0x6865, 0x6c6c, 0x6f20, 0x776f, 0x726c, 0x6400, 0x0000, 0x0000, 0x0000, 0x0000,
]),
json!("hello world")
);
}