feat(valve): Implement obstacle detection with configurable thresholds
Introduces separate configurable current thresholds for obstacle detection during valve opening and closing movements. - Added state to . - Added and to . - Modified to implement obstacle detection in , setting on high current, and to load/save these new thresholds via settings. - Added new setter/getter functions for obstacle thresholds to and . - Updated with new shell commands (, ) and updated to display these settings. - Updated to document the new registers and error states. - Updated to include new register definitions, menu options, and display of obstacle current thresholds.
This commit is contained in:
@@ -27,6 +27,8 @@ REG_HOLDING_MAX_OPENING_TIME_S = 0x0001
|
||||
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_OBSTACLE_CURRENT_THRESHOLD_OPEN_MA = 0x0005
|
||||
REG_HOLDING_OBSTACLE_CURRENT_THRESHOLD_CLOSE_MA = 0x0006
|
||||
REG_HOLDING_DIGITAL_OUTPUTS_STATE = 0x0010
|
||||
REG_HOLDING_WATCHDOG_TIMEOUT_S = 0x00F0
|
||||
REG_HOLDING_DEVICE_RESET = 0x00F1
|
||||
@@ -90,7 +92,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_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)
|
||||
hr_valve = client.read_holding_registers(REG_HOLDING_MAX_OPENING_TIME_S, count=4, slave=slave_id)
|
||||
hr_valve = client.read_holding_registers(REG_HOLDING_MAX_OPENING_TIME_S, count=6, 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)
|
||||
|
||||
@@ -99,7 +101,7 @@ def poll_status(slave_id, interval):
|
||||
raise ModbusException(str(res))
|
||||
|
||||
valve_state_raw = ir_valve.registers[0]
|
||||
movement_map = {0: "Idle", 1: "Opening", 2: "Closing", 3: "Error"}
|
||||
movement_map = {0: "Idle", 1: "Opening", 2: "Closing", 3: "Error", 4: "Obstacle"}
|
||||
state_map = {0: "Closed", 1: "Open"}
|
||||
new_data["movement"] = movement_map.get(valve_state_raw >> 8, 'Unknown')
|
||||
new_data["state"] = state_map.get(valve_state_raw & 0xFF, 'Unknown')
|
||||
@@ -109,6 +111,8 @@ def poll_status(slave_id, interval):
|
||||
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["obs_curr_open"] = f"{hr_valve.registers[4]}mA"
|
||||
new_data["obs_curr_close"] = f"{hr_valve.registers[5]}mA"
|
||||
new_data["digital_inputs"] = f"0x{ir_dig.registers[0]:04X}"
|
||||
new_data["button_events"] = f"0x{ir_dig.registers[1]:04X}"
|
||||
new_data["digital_outputs"] = f"0x{hr_dig.registers[0]:04X}"
|
||||
@@ -234,7 +238,7 @@ def main_menu(stdscr, slave_id):
|
||||
stdscr.bkgd(' ', curses.color_pair(1))
|
||||
|
||||
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"]
|
||||
settings_menu = ["Set Max Open Time", "Set Max Close Time", "Set End Current Open", "Set End Current Close", "Set Obstacle Current Open", "Set Obstacle Current Close", "Set Watchdog", "Back"]
|
||||
current_menu = menu
|
||||
current_row_idx = 0
|
||||
message, message_time = "", 0
|
||||
@@ -285,6 +289,10 @@ def main_menu(stdscr, slave_id):
|
||||
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 Obstacle Current Open":
|
||||
input_mode, input_prompt, input_target_reg = True, "Enter Obstacle Current Threshold Open (mA): ", REG_HOLDING_OBSTACLE_CURRENT_THRESHOLD_OPEN_MA
|
||||
elif selected_option == "Set Obstacle Current Close":
|
||||
input_mode, input_prompt, input_target_reg = True, "Enter Obstacle Current Threshold Close (mA): ", REG_HOLDING_OBSTACLE_CURRENT_THRESHOLD_CLOSE_MA
|
||||
elif selected_option == "Set Watchdog":
|
||||
input_mode, input_prompt, input_target_reg = True, "Enter Watchdog Timeout (s): ", REG_HOLDING_WATCHDOG_TIMEOUT_S
|
||||
elif selected_option == "Reset Node":
|
||||
@@ -324,6 +332,8 @@ def main_menu(stdscr, slave_id):
|
||||
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(6, col3, "Obs Curr Open:", bold); stdscr.addstr(6, col3 + 16, str(current_data.get('obs_curr_open', 'N/A')), normal)
|
||||
stdscr.addstr(7, col3, "Obs Curr Close:", bold); stdscr.addstr(7, col3 + 16, str(current_data.get('obs_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(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)
|
||||
|
||||
Reference in New Issue
Block a user