mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 09:10:30 +08:00
fixes
This commit is contained in:
parent
31fdcd2f3c
commit
a6385cd20e
@ -52,8 +52,9 @@ class UserGpioApi:
|
||||
async def __switch_handler(self, request: Request) -> Response:
|
||||
channel = valid_ugpio_channel(request.query.get("channel"))
|
||||
state = valid_bool(request.query.get("state"))
|
||||
done = await self.__user_gpio.switch(channel, state)
|
||||
return make_json_response({"done": done})
|
||||
wait = valid_bool(request.query.get("wait", "0"))
|
||||
await self.__user_gpio.switch(channel, state, wait)
|
||||
return make_json_response()
|
||||
|
||||
@exposed_http("POST", "/gpio/pulse")
|
||||
async def __pulse_handler(self, request: Request) -> Response:
|
||||
|
||||
@ -26,7 +26,9 @@ import operator
|
||||
from typing import List
|
||||
from typing import Dict
|
||||
from typing import AsyncGenerator
|
||||
from typing import Callable
|
||||
from typing import Optional
|
||||
from typing import Any
|
||||
|
||||
from ...logging import get_logger
|
||||
|
||||
@ -120,9 +122,14 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
||||
|
||||
self.__switch: bool = config.switch
|
||||
|
||||
self.__pulse_delay: float = config.pulse.delay
|
||||
self.__min_pulse_delay: float = config.pulse.min_delay
|
||||
self.__max_pulse_delay: float = config.pulse.max_delay
|
||||
self.__pulse_delay = 0.0
|
||||
self.__min_pulse_delay = 0.0
|
||||
self.__max_pulse_delay = 0.0
|
||||
if config.pulse.delay:
|
||||
assert config.pulse.max_delay > 0
|
||||
self.__pulse_delay = min(max(config.pulse.delay, config.pulse.min_delay), config.pulse.max_delay)
|
||||
self.__min_pulse_delay = config.pulse.min_delay
|
||||
self.__max_pulse_delay = config.pulse.max_delay
|
||||
|
||||
self.__busy_delay: float = config.busy_delay
|
||||
|
||||
@ -135,9 +142,9 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
||||
return {
|
||||
"switch": self.__switch,
|
||||
"pulse": {
|
||||
"delay": min(max(self.__pulse_delay, self.__min_pulse_delay), self.__max_pulse_delay),
|
||||
"min_delay": (self.__min_pulse_delay if self.__pulse_delay else 0),
|
||||
"max_delay": (self.__max_pulse_delay if self.__pulse_delay else 0),
|
||||
"delay": self.__pulse_delay,
|
||||
"min_delay": self.__min_pulse_delay,
|
||||
"max_delay": self.__max_pulse_delay,
|
||||
},
|
||||
"hw": {
|
||||
"driver": self.__driver.get_instance_id(),
|
||||
@ -159,39 +166,44 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
||||
"busy": busy,
|
||||
}
|
||||
|
||||
async def switch(self, state: bool) -> bool:
|
||||
async def switch(self, state: bool, wait: bool) -> None:
|
||||
if not self.__switch:
|
||||
raise GpioSwitchNotSupported()
|
||||
async with self.__region:
|
||||
if state != self.__read():
|
||||
self.__write(state)
|
||||
get_logger(0).info("Switched %s to state=%d", self, state)
|
||||
await asyncio.sleep(self.__busy_delay)
|
||||
return True
|
||||
await asyncio.sleep(self.__busy_delay)
|
||||
return False
|
||||
await self.__run_action(wait, "switch", self.__inner_switch, state)
|
||||
|
||||
@aiotools.atomic
|
||||
async def pulse(self, delay: float, wait: bool) -> None:
|
||||
if not self.__pulse_delay:
|
||||
raise GpioPulseNotSupported()
|
||||
delay = min(max((delay or self.__pulse_delay), self.__min_pulse_delay), self.__max_pulse_delay)
|
||||
await self.__run_action(wait, "pulse", self.__inner_pulse, delay)
|
||||
|
||||
# =====
|
||||
|
||||
@aiotools.atomic
|
||||
async def __run_action(self, wait: bool, name: str, method: Callable, *args: Any) -> None:
|
||||
if wait:
|
||||
async with self.__region:
|
||||
await self.__inner_pulse(delay)
|
||||
await method(*args)
|
||||
else:
|
||||
await aiotools.run_region_task(
|
||||
f"Can't perform pulse of {self} or operation was not completed",
|
||||
self.__region, self.__inner_pulse_tasked, delay,
|
||||
f"Can't perform {name} of {self} or operation was not completed",
|
||||
self.__region, self.__action_task_wrapper, name, method, *args,
|
||||
)
|
||||
|
||||
@aiotools.atomic
|
||||
async def __inner_pulse_tasked(self, delay: float) -> None:
|
||||
async def __action_task_wrapper(self, name: str, method: Callable, *args: Any) -> None:
|
||||
try:
|
||||
await self.__inner_pulse(delay)
|
||||
return (await method(*args))
|
||||
except GpioDriverOfflineError:
|
||||
get_logger(0).error("Can't perform pulse of %s or operation was not completed"
|
||||
" because the driver is offline", self)
|
||||
get_logger(0).error("Can't perform %s of %s or operation was not completed: driver offline", name, self)
|
||||
|
||||
@aiotools.atomic
|
||||
async def __inner_switch(self, state: bool) -> None:
|
||||
if state != self.__read():
|
||||
self.__write(state)
|
||||
get_logger(0).info("Switched %s to state=%d", self, state)
|
||||
await asyncio.sleep(self.__busy_delay)
|
||||
|
||||
@aiotools.atomic
|
||||
async def __inner_pulse(self, delay: float) -> None:
|
||||
@ -203,6 +215,8 @@ class _GpioOutput: # pylint: disable=too-many-instance-attributes
|
||||
await asyncio.sleep(self.__busy_delay)
|
||||
get_logger(0).info("Pulsed %s with delay=%.2f", self, delay)
|
||||
|
||||
# =====
|
||||
|
||||
def __read(self) -> bool:
|
||||
return (self.__driver.read(self.__pin) ^ self.__inverted)
|
||||
|
||||
@ -228,7 +242,7 @@ class UserGpio:
|
||||
notifier=self.__notifier,
|
||||
**drv_config._unpack(ignore=["instance_name", "notifier", "type"]),
|
||||
)
|
||||
for (driver, drv_config) in config.drivers.items()
|
||||
for (driver, drv_config) in sorted(config.drivers.items(), key=operator.itemgetter(0))
|
||||
}
|
||||
|
||||
self.__inputs: Dict[str, _GpioInput] = {}
|
||||
@ -284,11 +298,11 @@ class UserGpio:
|
||||
except Exception:
|
||||
get_logger().exception("Can't cleanup driver %s", driver)
|
||||
|
||||
async def switch(self, channel: str, state: bool) -> bool:
|
||||
async def switch(self, channel: str, state: bool, wait: bool) -> None:
|
||||
gout = self.__outputs.get(channel)
|
||||
if gout is None:
|
||||
raise GpioChannelNotFoundError()
|
||||
return (await gout.switch(state))
|
||||
await gout.switch(state, wait)
|
||||
|
||||
async def pulse(self, channel: str, delay: float, wait: bool) -> None:
|
||||
gout = self.__outputs.get(channel)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user