power: use a mutex to prevent concurrent device requests
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
724c29c4a7
commit
0917536ccc
|
@ -13,7 +13,7 @@ import socket
|
||||||
import gpiod
|
import gpiod
|
||||||
from tornado.ioloop import IOLoop
|
from tornado.ioloop import IOLoop
|
||||||
from tornado.iostream import IOStream
|
from tornado.iostream import IOStream
|
||||||
from tornado import gen
|
from tornado.locks import Lock
|
||||||
from tornado.httpclient import AsyncHTTPClient
|
from tornado.httpclient import AsyncHTTPClient
|
||||||
from tornado.escape import json_decode
|
from tornado.escape import json_decode
|
||||||
|
|
||||||
|
@ -238,6 +238,7 @@ class HTTPDevice(PowerDevice):
|
||||||
default_user=None, default_password=None):
|
default_user=None, default_password=None):
|
||||||
super().__init__(config)
|
super().__init__(config)
|
||||||
self.client = AsyncHTTPClient()
|
self.client = AsyncHTTPClient()
|
||||||
|
self.request_mutex = Lock()
|
||||||
self.addr = config.get("address")
|
self.addr = config.get("address")
|
||||||
self.port = config.getint("port", default_port)
|
self.port = config.getint("port", default_port)
|
||||||
self.user = config.get("user", default_user)
|
self.user = config.get("user", default_user)
|
||||||
|
@ -265,24 +266,26 @@ class HTTPDevice(PowerDevice):
|
||||||
"_send_status_request must be implemented by children")
|
"_send_status_request must be implemented by children")
|
||||||
|
|
||||||
async def refresh_status(self):
|
async def refresh_status(self):
|
||||||
try:
|
async with self.request_mutex:
|
||||||
state = await self._send_status_request()
|
try:
|
||||||
except Exception:
|
state = await self._send_status_request()
|
||||||
self.state = "error"
|
except Exception:
|
||||||
msg = f"Error Refeshing Device Status: {self.name}"
|
self.state = "error"
|
||||||
logging.exception(msg)
|
msg = f"Error Refeshing Device Status: {self.name}"
|
||||||
raise self.server.error(msg) from None
|
logging.exception(msg)
|
||||||
self.state = state
|
raise self.server.error(msg) from None
|
||||||
|
self.state = state
|
||||||
|
|
||||||
async def set_power(self, state):
|
async def set_power(self, state):
|
||||||
try:
|
async with self.request_mutex:
|
||||||
state = await self._send_power_request(state)
|
try:
|
||||||
except Exception:
|
state = await self._send_power_request(state)
|
||||||
self.state = "error"
|
except Exception:
|
||||||
msg = f"Error Setting Device Status: {self.name} to {state}"
|
self.state = "error"
|
||||||
logging.exception(msg)
|
msg = f"Error Setting Device Status: {self.name} to {state}"
|
||||||
raise self.server.error(msg) from None
|
logging.exception(msg)
|
||||||
self.state = state
|
raise self.server.error(msg) from None
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
|
||||||
class GpioChipFactory:
|
class GpioChipFactory:
|
||||||
|
@ -381,6 +384,7 @@ class TPLinkSmartPlug(PowerDevice):
|
||||||
START_KEY = 0xAB
|
START_KEY = 0xAB
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
super().__init__(config)
|
super().__init__(config)
|
||||||
|
self.request_mutex = Lock()
|
||||||
self.addr = config.get("address").split('/')
|
self.addr = config.get("address").split('/')
|
||||||
self.port = config.getint("port", 9999)
|
self.port = config.getint("port", 9999)
|
||||||
|
|
||||||
|
@ -448,33 +452,35 @@ class TPLinkSmartPlug(PowerDevice):
|
||||||
await self.refresh_status()
|
await self.refresh_status()
|
||||||
|
|
||||||
async def refresh_status(self):
|
async def refresh_status(self):
|
||||||
try:
|
async with self.request_mutex:
|
||||||
res = await self._send_tplink_command("info")
|
try:
|
||||||
if len(self.addr) == 2:
|
res = await self._send_tplink_command("info")
|
||||||
# TPLink device controls multiple devices
|
if len(self.addr) == 2:
|
||||||
children = res['system']['get_sysinfo']['children']
|
# TPLink device controls multiple devices
|
||||||
state = children[int(self.addr[1])]['state']
|
children = res['system']['get_sysinfo']['children']
|
||||||
else:
|
state = children[int(self.addr[1])]['state']
|
||||||
state = res['system']['get_sysinfo']['relay_state']
|
else:
|
||||||
except Exception:
|
state = res['system']['get_sysinfo']['relay_state']
|
||||||
self.state = "error"
|
except Exception:
|
||||||
msg = f"Error Refeshing Device Status: {self.name}"
|
self.state = "error"
|
||||||
logging.exception(msg)
|
msg = f"Error Refeshing Device Status: {self.name}"
|
||||||
raise self.server.error(msg) from None
|
logging.exception(msg)
|
||||||
self.state = "on" if state else "off"
|
raise self.server.error(msg) from None
|
||||||
|
self.state = "on" if state else "off"
|
||||||
|
|
||||||
async def set_power(self, state):
|
async def set_power(self, state):
|
||||||
try:
|
async with self.request_mutex:
|
||||||
res = await self._send_tplink_command(state)
|
try:
|
||||||
err = res['system']['set_relay_state']['err_code']
|
res = await self._send_tplink_command(state)
|
||||||
except Exception:
|
err = res['system']['set_relay_state']['err_code']
|
||||||
err = 1
|
except Exception:
|
||||||
logging.exception(f"Power Toggle Error: {self.name}")
|
err = 1
|
||||||
if err:
|
logging.exception(f"Power Toggle Error: {self.name}")
|
||||||
self.state = "error"
|
if err:
|
||||||
raise self.server.error(
|
self.state = "error"
|
||||||
f"Error Toggling Device Power: {self.name}")
|
raise self.server.error(
|
||||||
self.state = state
|
f"Error Toggling Device Power: {self.name}")
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
|
||||||
class Tasmota(HTTPDevice):
|
class Tasmota(HTTPDevice):
|
||||||
|
|
Loading…
Reference in New Issue