feat(valve): Make end-position current thresholds configurable
Introduces separate Modbus holding registers for configurable end-position current thresholds for both opening and closing valve movements. - Added REG_HOLDING_VALVE_END_CURRENT_THRESHOLD_OPEN_MA and REG_HOLDING_VALVE_END_CURRENT_THRESHOLD_CLOSE_MA to modbus_server.h. - Modified valve.c to use these new thresholds and save/load them via settings. - Added new setter functions to valve.h. - Created new shell_valve library with commands to set/get these thresholds. - Updated modbus_tool.py to include new menu options for setting thresholds. - Updated docs/modbus-registers.de.md to document the new registers. This enhances the flexibility and calibration of the valve control system.
This commit is contained in:
parent
bd8a7a766c
commit
92bb171e85
|
|
@ -49,6 +49,8 @@ Alle Register sind in einer einzigen, durchgehenden Liste pro Register-Typ (`Inp
|
||||||
| **0x0000** | `VALVE_COMMAND` | Ventil | `1`=Öffnen, `2`=Schliessen, `0`=Bewegung stoppen. |
|
| **0x0000** | `VALVE_COMMAND` | Ventil | `1`=Öffnen, `2`=Schliessen, `0`=Bewegung stoppen. |
|
||||||
| **0x0001** | `MAX_OPENING_TIME_S` | Ventil | Sicherheits-Timeout in Sekunden für den Öffnen-Vorgang. |
|
| **0x0001** | `MAX_OPENING_TIME_S` | Ventil | Sicherheits-Timeout in Sekunden für den Öffnen-Vorgang. |
|
||||||
| **0x0002** | `MAX_CLOSING_TIME_S` | Ventil | Sicherheits-Timeout in Sekunden für den Schliessen-Vorgang. |
|
| **0x0002** | `MAX_CLOSING_TIME_S` | Ventil | Sicherheits-Timeout in Sekunden für den Schliessen-Vorgang. |
|
||||||
|
| **0x0003** | `END_CURRENT_THRESHOLD_OPEN_MA` | Ventil | Minimaler Stromschwellenwert in mA zur Endlagenerkennung beim Öffnen. |
|
||||||
|
| **0x0004** | `END_CURRENT_THRESHOLD_CLOSE_MA` | Ventil | Minimaler Stromschwellenwert in mA zur Endlagenerkennung beim Schliessen. |
|
||||||
| **0x0010** | `DIGITAL_OUTPUTS_STATE` | Ausgänge | Bitmaske zum Lesen und Schreiben der Ausgänge. Bit 0: Ausgang 1, Bit 1: Ausgang 2. `1`=AN, `0`=AUS. |
|
| **0x0010** | `DIGITAL_OUTPUTS_STATE` | Ausgänge | Bitmaske zum Lesen und Schreiben der Ausgänge. Bit 0: Ausgang 1, Bit 1: Ausgang 2. `1`=AN, `0`=AUS. |
|
||||||
| **0x00F0** | `WATCHDOG_TIMEOUT_S` | System | Timeout des Fail-Safe-Watchdogs in Sekunden. `0`=Deaktiviert. |
|
| **0x00F0** | `WATCHDOG_TIMEOUT_S` | System | Timeout des Fail-Safe-Watchdogs in Sekunden. `0`=Deaktiviert. |
|
||||||
| **0x00F1** | `DEVICE_RESET` | System | Schreibt `1` um das Gerät neu zu starten. |
|
| **0x00F1** | `DEVICE_RESET` | System | Schreibt `1` um das Gerät neu zu starten. |
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
rsource "lib/Kconfig"
|
rsource "lib/Kconfig"
|
||||||
|
rsource "lib/shell_valve/Kconfig"
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,10 @@ enum {
|
||||||
* @brief Safety timeout in seconds for the closing process.
|
* @brief Safety timeout in seconds for the closing process.
|
||||||
*/
|
*/
|
||||||
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002,
|
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002,
|
||||||
|
/**
|
||||||
|
* @brief Minimum current threshold in mA for end-position detection.
|
||||||
|
*/
|
||||||
|
REG_HOLDING_VALVE_END_CURRENT_THRESHOLD_MA = 0x0003,
|
||||||
/**
|
/**
|
||||||
* @brief Bitmask for reading and writing digital outputs. Bit 0: Output 1,
|
* @brief Bitmask for reading and writing digital outputs. Bit 0: Output 1,
|
||||||
* Bit 1: Output 2. 1=ON, 0=OFF.
|
* Bit 1: Output 2. 1=ON, 0=OFF.
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,20 @@ void valve_set_max_open_time(uint16_t seconds);
|
||||||
*/
|
*/
|
||||||
void valve_set_max_close_time(uint16_t seconds);
|
void valve_set_max_close_time(uint16_t seconds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the current threshold for end-position detection during opening.
|
||||||
|
*
|
||||||
|
* @param current_ma The current threshold in milliamps.
|
||||||
|
*/
|
||||||
|
void valve_set_end_current_threshold_open(uint16_t current_ma);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the current threshold for end-position detection during closing.
|
||||||
|
*
|
||||||
|
* @param current_ma The current threshold in milliamps.
|
||||||
|
*/
|
||||||
|
void valve_set_end_current_threshold_close(uint16_t current_ma);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the configured maximum opening time.
|
* @brief Gets the configured maximum opening time.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@ add_subdirectory_ifdef(CONFIG_LIB_FWU fwu)
|
||||||
add_subdirectory_ifdef(CONFIG_LIB_MODBUS_SERVER modbus_server)
|
add_subdirectory_ifdef(CONFIG_LIB_MODBUS_SERVER modbus_server)
|
||||||
add_subdirectory_ifdef(CONFIG_LIB_VALVE valve)
|
add_subdirectory_ifdef(CONFIG_LIB_VALVE valve)
|
||||||
add_subdirectory_ifdef(CONFIG_SHELL_SYSTEM shell_system)
|
add_subdirectory_ifdef(CONFIG_SHELL_SYSTEM shell_system)
|
||||||
add_subdirectory_ifdef(CONFIG_SHELL_MODBUS shell_modbus)
|
add_subdirectory_ifdef(CONFIG_SHELL_MODBUS shell_modbus)
|
||||||
|
add_subdirectory_ifdef(CONFIG_SHELL_VALVE shell_valve)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
zephyr_library()
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
config SHELL_VALVE
|
||||||
|
bool "Shell Valve commands"
|
||||||
|
default y
|
||||||
|
depends on SHELL
|
||||||
|
help
|
||||||
|
Enable the shell commands for valve control.
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/shell/shell.h>
|
||||||
|
#include <lib/valve.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static int cmd_valve_set_max_open_time(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
shell_print(sh, "Usage: valve set_max_open_time <seconds>");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t seconds = (uint16_t)atoi(argv[1]);
|
||||||
|
valve_set_max_open_time(seconds);
|
||||||
|
shell_print(sh, "Max open time set to %u seconds.", seconds);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_valve_get_max_open_time(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
uint16_t seconds = valve_get_max_open_time();
|
||||||
|
shell_print(sh, "Max open time: %u seconds.", seconds);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_valve_set_max_close_time(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
shell_print(sh, "Usage: valve set_max_close_time <seconds>");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t seconds = (uint16_t)atoi(argv[1]);
|
||||||
|
valve_set_max_close_time(seconds);
|
||||||
|
shell_print(sh, "Max close time set to %u seconds.", seconds);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_valve_get_max_close_time(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
uint16_t seconds = valve_get_max_close_time();
|
||||||
|
shell_print(sh, "Max close time: %u seconds.", seconds);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_valve_set_end_current_threshold_open(
|
||||||
|
const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
shell_print(sh, "Usage: valve set_end_current_threshold_open <milliamps>");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t current_ma = (uint16_t)atoi(argv[1]);
|
||||||
|
valve_set_end_current_threshold_open(current_ma);
|
||||||
|
shell_print(sh, "End current threshold (open) set to %u mA.", current_ma);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_valve_get_end_current_threshold_open(
|
||||||
|
const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
uint16_t current_ma = valve_get_end_current_threshold_open();
|
||||||
|
shell_print(sh, "End current threshold (open): %u mA.", current_ma);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_valve_set_end_current_threshold_close(
|
||||||
|
const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
shell_print(sh, "Usage: valve set_end_current_threshold_close <milliamps>");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t current_ma = (uint16_t)atoi(argv[1]);
|
||||||
|
valve_set_end_current_threshold_close(current_ma);
|
||||||
|
shell_print(sh, "End current threshold (close) set to %u mA.", current_ma);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_valve_get_end_current_threshold_close(
|
||||||
|
const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
uint16_t current_ma = valve_get_end_current_threshold_close();
|
||||||
|
shell_print(sh, "End current threshold (close): %u mA.", current_ma);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_valve_settings,
|
||||||
|
SHELL_CMD(set_max_open_time, NULL, "Set max open time (seconds)", cmd_valve_set_max_open_time),
|
||||||
|
SHELL_CMD(get_max_open_time, NULL, "Get max open time (seconds)", cmd_valve_get_max_open_time),
|
||||||
|
SHELL_CMD(
|
||||||
|
set_max_close_time, NULL, "Set max close time (seconds)", cmd_valve_set_max_close_time),
|
||||||
|
SHELL_CMD(
|
||||||
|
get_max_close_time, NULL, "Get max close time (seconds)", cmd_valve_get_max_close_time),
|
||||||
|
SHELL_CMD(set_end_current_threshold_open,
|
||||||
|
NULL,
|
||||||
|
"Set end current threshold for opening (mA)",
|
||||||
|
cmd_valve_set_end_current_threshold_open),
|
||||||
|
SHELL_CMD(get_end_current_threshold_open,
|
||||||
|
NULL,
|
||||||
|
"Get end current threshold for opening (mA)",
|
||||||
|
cmd_valve_get_end_current_threshold_open),
|
||||||
|
SHELL_CMD(set_end_current_threshold_close,
|
||||||
|
NULL,
|
||||||
|
"Set end current threshold for closing (mA)",
|
||||||
|
cmd_valve_set_end_current_threshold_close),
|
||||||
|
SHELL_CMD(get_end_current_threshold_close,
|
||||||
|
NULL,
|
||||||
|
"Get end current threshold for closing (mA)",
|
||||||
|
cmd_valve_get_end_current_threshold_close),
|
||||||
|
SHELL_SUBCMD_SET_END);
|
||||||
|
|
||||||
|
SHELL_CMD_REGISTER(valve, &sub_valve_settings, "Valve commands", NULL);
|
||||||
|
|
@ -27,6 +27,8 @@ static enum valve_state current_state = VALVE_STATE_OPEN;
|
||||||
static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE;
|
static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE;
|
||||||
static uint16_t max_opening_time_s = 10;
|
static uint16_t max_opening_time_s = 10;
|
||||||
static uint16_t max_closing_time_s = 10;
|
static uint16_t max_closing_time_s = 10;
|
||||||
|
static uint16_t end_current_threshold_open_ma = 10; // Default value for open
|
||||||
|
static uint16_t end_current_threshold_close_ma = 10; // Default value for close
|
||||||
static struct k_work_delayable valve_work; // Work item for scheduling valve movement timeouts
|
static struct k_work_delayable valve_work; // Work item for scheduling valve movement timeouts
|
||||||
static struct k_timer movement_timer;
|
static struct k_timer movement_timer;
|
||||||
|
|
||||||
|
|
@ -45,14 +47,14 @@ static void valve_work_handler(struct k_work *work)
|
||||||
|
|
||||||
if (current_movement == VALVE_MOVEMENT_OPENING) {
|
if (current_movement == VALVE_MOVEMENT_OPENING) {
|
||||||
vnd7050aj_read_load_current(vnd7050aj_dev, VALVE_CHANNEL_OPEN, ¤t_ma);
|
vnd7050aj_read_load_current(vnd7050aj_dev, VALVE_CHANNEL_OPEN, ¤t_ma);
|
||||||
if (current_ma > 10) {
|
if (current_ma > end_current_threshold_open_ma) {
|
||||||
k_work_schedule(&valve_work, VALVE_ENDPOSITION_CHECK_INTERVAL);
|
k_work_schedule(&valve_work, VALVE_ENDPOSITION_CHECK_INTERVAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_INF("Valve finished opening");
|
LOG_INF("Valve finished opening");
|
||||||
} else if (current_movement == VALVE_MOVEMENT_CLOSING) {
|
} else if (current_movement == VALVE_MOVEMENT_CLOSING) {
|
||||||
vnd7050aj_read_load_current(vnd7050aj_dev, VALVE_CHANNEL_CLOSE, ¤t_ma);
|
vnd7050aj_read_load_current(vnd7050aj_dev, VALVE_CHANNEL_CLOSE, ¤t_ma);
|
||||||
if (current_ma > 10) {
|
if (current_ma > end_current_threshold_close_ma) {
|
||||||
k_work_schedule(&valve_work, VALVE_ENDPOSITION_CHECK_INTERVAL);
|
k_work_schedule(&valve_work, VALVE_ENDPOSITION_CHECK_INTERVAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -96,10 +98,19 @@ int valve_init(void)
|
||||||
|
|
||||||
settings_load_one("valve/max_open_time", &max_opening_time_s, sizeof(max_opening_time_s));
|
settings_load_one("valve/max_open_time", &max_opening_time_s, sizeof(max_opening_time_s));
|
||||||
settings_load_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
|
settings_load_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
|
||||||
|
settings_load_one("valve/end_current_threshold_open",
|
||||||
|
&end_current_threshold_open_ma,
|
||||||
|
sizeof(end_current_threshold_open_ma));
|
||||||
|
settings_load_one("valve/end_current_threshold_close",
|
||||||
|
&end_current_threshold_close_ma,
|
||||||
|
sizeof(end_current_threshold_close_ma));
|
||||||
|
|
||||||
LOG_INF("Valve initialized: max_open=%us, max_close=%us",
|
LOG_INF("Valve initialized: max_open=%us, max_close=%us, end_curr_open=%umA, "
|
||||||
|
"end_curr_close=%umA",
|
||||||
max_opening_time_s,
|
max_opening_time_s,
|
||||||
max_closing_time_s);
|
max_closing_time_s,
|
||||||
|
end_current_threshold_open_ma,
|
||||||
|
end_current_threshold_close_ma);
|
||||||
valve_close();
|
valve_close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -158,6 +169,23 @@ void valve_set_max_close_time(uint16_t seconds)
|
||||||
max_closing_time_s = seconds;
|
max_closing_time_s = seconds;
|
||||||
settings_save_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
|
settings_save_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void valve_set_end_current_threshold_open(uint16_t current_ma)
|
||||||
|
{
|
||||||
|
end_current_threshold_open_ma = current_ma;
|
||||||
|
settings_save_one("valve/end_current_threshold_open",
|
||||||
|
&end_current_threshold_open_ma,
|
||||||
|
sizeof(end_current_threshold_open_ma));
|
||||||
|
}
|
||||||
|
|
||||||
|
void valve_set_end_current_threshold_close(uint16_t current_ma)
|
||||||
|
{
|
||||||
|
end_current_threshold_close_ma = current_ma;
|
||||||
|
settings_save_one("valve/end_current_threshold_close",
|
||||||
|
&end_current_threshold_close_ma,
|
||||||
|
sizeof(end_current_threshold_close_ma));
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t valve_get_max_open_time(void)
|
uint16_t valve_get_max_open_time(void)
|
||||||
{
|
{
|
||||||
return max_opening_time_s;
|
return max_opening_time_s;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ REG_INPUT_FWU_LAST_CHUNK_CRC = 0x0100
|
||||||
REG_HOLDING_VALVE_COMMAND = 0x0000
|
REG_HOLDING_VALVE_COMMAND = 0x0000
|
||||||
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001
|
REG_HOLDING_MAX_OPENING_TIME_S = 0x0001
|
||||||
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002
|
REG_HOLDING_MAX_CLOSING_TIME_S = 0x0002
|
||||||
|
REG_HOLDING_END_CURRENT_THRESHOLD_OPEN_MA = 0x0003
|
||||||
|
REG_HOLDING_END_CURRENT_THRESHOLD_CLOSE_MA = 0x0004
|
||||||
REG_HOLDING_DIGITAL_OUTPUTS_STATE = 0x0010
|
REG_HOLDING_DIGITAL_OUTPUTS_STATE = 0x0010
|
||||||
REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0
|
REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0
|
||||||
REG_HOLDING_DEVICE_RESET = 0x00F1
|
REG_HOLDING_DEVICE_RESET = 0x00F1
|
||||||
|
|
@ -88,7 +90,7 @@ def poll_status(slave_id, interval):
|
||||||
ir_current = client.read_input_registers(REG_INPUT_MOTOR_OPEN_CURRENT_MA, count=2, slave=slave_id)
|
ir_current = client.read_input_registers(REG_INPUT_MOTOR_OPEN_CURRENT_MA, count=2, slave=slave_id)
|
||||||
ir_dig = client.read_input_registers(REG_INPUT_DIGITAL_INPUTS_STATE, count=2, slave=slave_id)
|
ir_dig = client.read_input_registers(REG_INPUT_DIGITAL_INPUTS_STATE, count=2, slave=slave_id)
|
||||||
ir_sys = client.read_input_registers(REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR, count=6, slave=slave_id)
|
ir_sys = client.read_input_registers(REG_INPUT_FIRMWARE_VERSION_MAJOR_MINOR, count=6, slave=slave_id)
|
||||||
hr_valve = client.read_holding_registers(REG_HOLDING_MAX_OPENING_TIME_S, count=2, slave=slave_id)
|
hr_valve = client.read_holding_registers(REG_HOLDING_MAX_OPENING_TIME_S, count=4, slave=slave_id)
|
||||||
hr_dig = client.read_holding_registers(REG_HOLDING_DIGITAL_OUTPUTS_STATE, count=1, slave=slave_id)
|
hr_dig = client.read_holding_registers(REG_HOLDING_DIGITAL_OUTPUTS_STATE, count=1, slave=slave_id)
|
||||||
hr_sys = client.read_holding_registers(REG_HOLDING_WATCHDOG_TIMEOUT_S, count=1, slave=slave_id)
|
hr_sys = client.read_holding_registers(REG_HOLDING_WATCHDOG_TIMEOUT_S, count=1, slave=slave_id)
|
||||||
|
|
||||||
|
|
@ -105,6 +107,8 @@ def poll_status(slave_id, interval):
|
||||||
new_data["motor_current_close"] = f"{ir_current.registers[1]} mA"
|
new_data["motor_current_close"] = f"{ir_current.registers[1]} mA"
|
||||||
new_data["open_time"] = f"{hr_valve.registers[0]}s"
|
new_data["open_time"] = f"{hr_valve.registers[0]}s"
|
||||||
new_data["close_time"] = f"{hr_valve.registers[1]}s"
|
new_data["close_time"] = f"{hr_valve.registers[1]}s"
|
||||||
|
new_data["end_curr_open"] = f"{hr_valve.registers[2]}mA"
|
||||||
|
new_data["end_curr_close"] = f"{hr_valve.registers[3]}mA"
|
||||||
new_data["digital_inputs"] = f"0x{ir_dig.registers[0]:04X}"
|
new_data["digital_inputs"] = f"0x{ir_dig.registers[0]:04X}"
|
||||||
new_data["button_events"] = f"0x{ir_dig.registers[1]:04X}"
|
new_data["button_events"] = f"0x{ir_dig.registers[1]:04X}"
|
||||||
new_data["digital_outputs"] = f"0x{hr_dig.registers[0]:04X}"
|
new_data["digital_outputs"] = f"0x{hr_dig.registers[0]:04X}"
|
||||||
|
|
@ -229,7 +233,9 @@ def main_menu(stdscr, slave_id):
|
||||||
curses.start_color(); curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE); curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_WHITE); curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLUE)
|
curses.start_color(); curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE); curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_WHITE); curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLUE)
|
||||||
stdscr.bkgd(' ', curses.color_pair(1))
|
stdscr.bkgd(' ', curses.color_pair(1))
|
||||||
|
|
||||||
menu = ["Open Valve", "Close Valve", "Stop Valve", "Toggle Output 1", "Toggle Output 2", "Set Max Open Time", "Set Max Close Time", "Set Watchdog", "Reset Node", "Firmware Update", "Exit"]
|
menu = ["Open Valve", "Close Valve", "Stop Valve", "Toggle Output 1", "Toggle Output 2", "Settings", "Reset Node", "Firmware Update", "Exit"]
|
||||||
|
settings_menu = ["Set Max Open Time", "Set Max Close Time", "Set End Current Open", "Set End Current Close", "Set Watchdog", "Back"]
|
||||||
|
current_menu = menu
|
||||||
current_row_idx = 0
|
current_row_idx = 0
|
||||||
message, message_time = "", 0
|
message, message_time = "", 0
|
||||||
input_mode, input_prompt, input_str, input_target_reg = False, "", "", 0
|
input_mode, input_prompt, input_str, input_target_reg = False, "", "", 0
|
||||||
|
|
@ -253,12 +259,14 @@ def main_menu(stdscr, slave_id):
|
||||||
elif key == curses.KEY_BACKSPACE or key == 127: input_str = input_str[:-1]
|
elif key == curses.KEY_BACKSPACE or key == 127: input_str = input_str[:-1]
|
||||||
elif key != -1 and chr(key).isprintable(): input_str += chr(key)
|
elif key != -1 and chr(key).isprintable(): input_str += chr(key)
|
||||||
else:
|
else:
|
||||||
if key == curses.KEY_UP: current_row_idx = (current_row_idx - 1) % len(menu)
|
if key == curses.KEY_UP: current_row_idx = (current_row_idx - 1) % len(current_menu)
|
||||||
elif key == curses.KEY_DOWN: current_row_idx = (current_row_idx + 1) % len(menu)
|
elif key == curses.KEY_DOWN: current_row_idx = (current_row_idx + 1) % len(current_menu)
|
||||||
elif key == curses.KEY_ENTER or key in [10, 13]:
|
elif key == curses.KEY_ENTER or key in [10, 13]:
|
||||||
selected_option = menu[current_row_idx]
|
selected_option = current_menu[current_row_idx]
|
||||||
message_time = time.time()
|
message_time = time.time()
|
||||||
if selected_option == "Exit": stop_event.set(); continue
|
if selected_option == "Exit": stop_event.set(); continue
|
||||||
|
elif selected_option == "Back": current_menu = menu; current_row_idx = 0; continue
|
||||||
|
elif selected_option == "Settings": current_menu = settings_menu; current_row_idx = 0; continue
|
||||||
elif selected_option == "Open Valve": client.write_register(REG_HOLDING_VALVE_COMMAND, 1, slave=slave_id); message = "-> Sent OPEN command"
|
elif selected_option == "Open Valve": client.write_register(REG_HOLDING_VALVE_COMMAND, 1, slave=slave_id); message = "-> Sent OPEN command"
|
||||||
elif selected_option == "Close Valve": client.write_register(REG_HOLDING_VALVE_COMMAND, 2, slave=slave_id); message = "-> Sent CLOSE command"
|
elif selected_option == "Close Valve": client.write_register(REG_HOLDING_VALVE_COMMAND, 2, slave=slave_id); message = "-> Sent CLOSE command"
|
||||||
elif selected_option == "Stop Valve": client.write_register(REG_HOLDING_VALVE_COMMAND, 0, slave=slave_id); message = "-> Sent STOP command"
|
elif selected_option == "Stop Valve": client.write_register(REG_HOLDING_VALVE_COMMAND, 0, slave=slave_id); message = "-> Sent STOP command"
|
||||||
|
|
@ -273,6 +281,10 @@ def main_menu(stdscr, slave_id):
|
||||||
input_mode, input_prompt, input_target_reg = True, "Enter Max Open Time (s): ", REG_HOLDING_MAX_OPENING_TIME_S
|
input_mode, input_prompt, input_target_reg = True, "Enter Max Open Time (s): ", REG_HOLDING_MAX_OPENING_TIME_S
|
||||||
elif selected_option == "Set Max Close Time":
|
elif selected_option == "Set Max Close Time":
|
||||||
input_mode, input_prompt, input_target_reg = True, "Enter Max Close Time (s): ", REG_HOLDING_MAX_CLOSING_TIME_S
|
input_mode, input_prompt, input_target_reg = True, "Enter Max Close Time (s): ", REG_HOLDING_MAX_CLOSING_TIME_S
|
||||||
|
elif selected_option == "Set End Current Open":
|
||||||
|
input_mode, input_prompt, input_target_reg = True, "Enter End Current Threshold Open (mA): ", REG_HOLDING_END_CURRENT_THRESHOLD_OPEN_MA
|
||||||
|
elif selected_option == "Set End Current Close":
|
||||||
|
input_mode, input_prompt, input_target_reg = True, "Enter End Current Threshold Close (mA): ", REG_HOLDING_END_CURRENT_THRESHOLD_CLOSE_MA
|
||||||
elif selected_option == "Set Watchdog":
|
elif selected_option == "Set Watchdog":
|
||||||
input_mode, input_prompt, input_target_reg = True, "Enter Watchdog Timeout (s): ", REG_HOLDING_WATCHDOG_TIMEOUT_S
|
input_mode, input_prompt, input_target_reg = True, "Enter Watchdog Timeout (s): ", REG_HOLDING_WATCHDOG_TIMEOUT_S
|
||||||
elif selected_option == "Reset Node":
|
elif selected_option == "Reset Node":
|
||||||
|
|
@ -310,13 +322,15 @@ def main_menu(stdscr, slave_id):
|
||||||
stdscr.addstr(1, col3, "Max Open Time:", bold); stdscr.addstr(1, col3 + 16, str(current_data.get('open_time', 'N/A')), normal)
|
stdscr.addstr(1, col3, "Max Open Time:", bold); stdscr.addstr(1, col3 + 16, str(current_data.get('open_time', 'N/A')), normal)
|
||||||
stdscr.addstr(2, col3, "Max Close Time:", bold); stdscr.addstr(2, col3 + 16, str(current_data.get('close_time', 'N/A')), normal)
|
stdscr.addstr(2, col3, "Max Close Time:", bold); stdscr.addstr(2, col3 + 16, str(current_data.get('close_time', 'N/A')), normal)
|
||||||
stdscr.addstr(3, col3, "Watchdog:", bold); stdscr.addstr(3, col3 + 16, str(current_data.get('watchdog', 'N/A')), normal)
|
stdscr.addstr(3, col3, "Watchdog:", bold); stdscr.addstr(3, col3 + 16, str(current_data.get('watchdog', 'N/A')), normal)
|
||||||
|
stdscr.addstr(4, col3, "End Curr Open:", bold); stdscr.addstr(4, col3 + 16, str(current_data.get('end_curr_open', 'N/A')), normal)
|
||||||
|
stdscr.addstr(5, col3, "End Curr Close:", bold); stdscr.addstr(5, col3 + 16, str(current_data.get('end_curr_close', 'N/A')), normal)
|
||||||
stdscr.addstr(1, col4, "Firmware:", bold); stdscr.addstr(1, col4 + 14, str(current_data.get('firmware', 'N/A')), normal)
|
stdscr.addstr(1, col4, "Firmware:", bold); stdscr.addstr(1, col4 + 14, str(current_data.get('firmware', 'N/A')), normal)
|
||||||
stdscr.addstr(2, col4, "Uptime:", bold); stdscr.addstr(2, col4 + 14, str(current_data.get('uptime', 'N/A')), normal)
|
stdscr.addstr(2, col4, "Uptime:", bold); stdscr.addstr(2, col4 + 14, str(current_data.get('uptime', 'N/A')), normal)
|
||||||
stdscr.addstr(3, col4, "Dev. Status:", bold); stdscr.addstr(3, col4 + 14, str(current_data.get('device_status', 'N/A')), normal)
|
stdscr.addstr(3, col4, "Dev. Status:", bold); stdscr.addstr(3, col4 + 14, str(current_data.get('device_status', 'N/A')), normal)
|
||||||
stdscr.addstr(4, col4, "Supply V:", bold); stdscr.addstr(4, col4 + 14, str(current_data.get('supply_voltage', 'N/A')), normal)
|
stdscr.addstr(4, col4, "Supply V:", bold); stdscr.addstr(4, col4 + 14, str(current_data.get('supply_voltage', 'N/A')), normal)
|
||||||
stdscr.addstr(6, 0, "─" * (w - 1), normal)
|
stdscr.addstr(6, 0, "─" * (w - 1), normal)
|
||||||
for idx, row in enumerate(menu):
|
for idx, row in enumerate(current_menu):
|
||||||
draw_button(stdscr, h // 2 - len(menu) + (idx * 2), w // 2 - len(row) // 2, row, idx == current_row_idx)
|
draw_button(stdscr, h // 2 - len(current_menu) + (idx * 2), w // 2 - len(row) // 2, row, idx == current_row_idx)
|
||||||
if time.time() - message_time < 2.0: stdscr.addstr(h - 2, 0, message.ljust(w - 1), curses.color_pair(1) | curses.A_BOLD)
|
if time.time() - message_time < 2.0: stdscr.addstr(h - 2, 0, message.ljust(w - 1), curses.color_pair(1) | curses.A_BOLD)
|
||||||
if input_mode:
|
if input_mode:
|
||||||
curses.curs_set(1); stdscr.addstr(h - 2, 0, (input_prompt + input_str).ljust(w-1), curses.color_pair(2)); stdscr.move(h - 2, len(input_prompt) + len(input_str))
|
curses.curs_set(1); stdscr.addstr(h - 2, 0, (input_prompt + input_str).ljust(w-1), curses.color_pair(2)); stdscr.move(h - 2, len(input_prompt) + len(input_str))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue