Skip to content

Instantly share code, notes, and snippets.

@welshdave
Last active March 1, 2023 13:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save welshdave/bec82b4ef4a2795b173a576dffb363d8 to your computer and use it in GitHub Desktop.
Save welshdave/bec82b4ef4a2795b173a576dffb363d8 to your computer and use it in GitHub Desktop.
Read/write charge time from FoxESS Hybrid Inverter
/*
This connects to the inverter using https://github.com/3cky/mbusd, a Raspberry Pi & a cheap RS-485 usb adaptor
but it should work if using any modbus TCP to RTU gateway.
Can easily be adapted to use a serial connection (change the client config).
Add to Cargo.toml:
[dependencies]
modbus = "1.0"
*/
use modbus::tcp;
use modbus::Client;
fn main() {
let config = tcp::Config::default();
let mut client = tcp::Transport::new_with_cfg("192.168.1.15", config).unwrap();
let address = 41001u16;
let count = 6u16;
client.set_uid(247);
let registers = client.read_holding_registers(address, count).unwrap();
println!("Current Values:");
display_configured_times(registers);
let start_time1 = "00:30";
let end_time1 = "04:30";
let start_time2 = "15:00";
let end_time2 = "16:00";
let new_values: Vec<u16> = vec![
1,
convert_from_time_string(start_time1),
convert_from_time_string(end_time1),
1,
convert_from_time_string(start_time2),
convert_from_time_string(end_time2),
];
println!("Setting new values...");
let _ = client
.write_multiple_registers(address, &new_values)
.unwrap();
let registers = client.read_holding_registers(address, count).unwrap();
display_configured_times(registers);
}
fn display_configured_times(registers: Vec<u16>) {
println!("Time period 1 enabled: {}", registers[0] != 0);
println!("Start time: {}", convert_to_time_string(registers[1]));
println!("End time: {}", convert_to_time_string(registers[2]));
println!("Time period 2 enabled: {}", registers[3] != 0);
println!("Start time: {}", convert_to_time_string(registers[4]));
println!("End time: {}", convert_to_time_string(registers[5]));
}
fn convert_to_time_string(encoded_time: u16) -> String {
let hour = |encoded_time| -> u16 { encoded_time / 256 };
let minute = |encoded_time| -> u16 { encoded_time % 256 };
format!("{:0>2}:{:0>2}", hour(&encoded_time), minute(&encoded_time))
}
fn convert_from_time_string(time: &str) -> u16 {
let split = time.split(":");
let values = split.collect::<Vec<&str>>();
let hours = values[0].parse::<u16>().unwrap() * 256;
let minutes = values[1].parse::<u16>().unwrap();
hours + minutes
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment