Better idle handling

This commit is contained in:
Lynn Ochs 2022-11-07 06:29:51 +01:00
parent 4ea571dc20
commit 11c900c2e5

View File

@ -87,12 +87,9 @@ class Control(util.Loggable):
def _run_control(self):
# Last known state
st = state.IDLE
# Current action
action = state.IDLE
# Not controlling the lock
controlling = False
cmd = {
None: lambda: None,
state.IDLE: lambda: None,
state.ERROR: lambda: None,
state.RESTART: self._comms.cmd_restart,
state.OPEN: self._comms.cmd_open,
state.OPEN_THEN_CLOSE: self._comms.cmd_open,
@ -102,6 +99,8 @@ class Control(util.Loggable):
with self._control_update:
last_target = state.IDLE
last_state = None
action = None
# When starting, reset the MCU once
self.target(state.CLOSE)
# Starting time of the current action
@ -118,40 +117,38 @@ class Control(util.Loggable):
# Update was that the target has changed
if self.target() != last_target:
self._logger().debug(f"Target update: {state_names[self.target()]}")
self._logger().debug(f"{cmd[self.target()]}, {cmd[last_target]}")
if cmd.get(action, None) != cmd[self.target()]:
action = cmd.get(self.target(), None)
last_action = cmd.get(last_target, None)
if action != None and last_action != action:
# We need to send a different command for this
self._logger().debug(f"Calling {cmd[self.target()]}")
cmd[self.target()]()
else:
self._logger().debug(f"Calling {action}")
action()
elif action == last_action:
self._logger().debug(f"Same command as {state_names[last_target]}")
# Update last known target and starting time
last_target = self.target()
start_time = datetime.now()
# Update current target
target = last_target
if self.state() != st:
if self.state() != last_state:
# State from position handling differs from last known state
self._logger().debug(f"State update, target is {state_names[target]}")
st = self.state()
self._logger().debug(f"State update, target is {state_names[self.target()]}")
last_state = self.state()
self._logger().info("Reached state "
f"{state_names.get(st, st)}")
if action == state.IDLE:
if action == None and self.state() != state.ERROR:
self._logger().info("Probably somebody using the key")
self.target(st)
target = last_target = st
elif st == target:
self.target(last_state)
last_target = last_state
elif last_state == last_target:
# Reached target
timeouts = 0
if target == state.CLOSE \
if last_target == state.CLOSE \
and self.position() > constants.CLOSED_WANT:
self._logger().info(
f"Position is {self.position()}, "
"closing some more")
self._comms.cmd_close()
action = state.IDLE
controlling = False
elif self.state() == state.ERROR:
# Position too high, restart
self._comm.cmd_restart()
@ -159,25 +156,22 @@ class Control(util.Loggable):
else:
if timeouts < 3:
timeouts += 1
if action == target:
if self.target() == last_target:
# Initially, switch to the other one
# and execute that
action = {
last_target = {
state.CLOSE: state.OPEN_THEN_CLOSE,
state.OPEN: state.CLOSE_THEN_OPEN
}.get(target, state.RESTART)
cmd[action]()
}.get(last_target, state.RESTART)
cmd[last_target]()
else:
# Then go back
action = target
cmd[action]()
last_target = self.target()
cmd[last_target]()
else:
# Tried too often, restart
self.target(state.RESTART)
if action == state.IDLE:
continue
def start(self):
with self._mutex:
if not self._started: