driver: Add lock for tcp writer & reader stream

This commit is contained in:
linuswck 2024-04-02 13:19:40 +08:00
parent 6d107d55cf
commit 09863353cd
1 changed files with 54 additions and 26 deletions

View File

@ -87,10 +87,11 @@ Filter_Config = {
}
class Device:
def __init__(self, send_cmd_handler, send_raw_cmd_handler, read_response):
def __init__(self, send_cmd_handler, send_raw_cmd_handler, read_response, cmd_lock):
self._send_cmd = send_cmd_handler
self._send_raw_cmd = send_raw_cmd_handler
self._read_response = read_response
self._cmd_lock = cmd_lock
async def set_ip_settings(self, addr=[192, 168, 1, 128], port=1337, prefix_len=24, gateway=[192, 168, 1, 1]):
"""
@ -154,11 +155,17 @@ class Device:
}
}
"""
response = await self._send_cmd(TARGET_DEVICE, "GetStatusReport")
if response["msg_type"] != "Acknowledge":
return response
return await self._read_response()
retry = 0
while(retry < 3):
response = await self._send_cmd(TARGET_DEVICE, "GetStatusReport")
if response["msg_type"] != "Acknowledge":
return response
status_report = await self._read_response()
if "ts" in status_report:
return status_report
else:
retry += 1
return None
async def get_settings_summary(self):
"""
@ -263,8 +270,9 @@ class Device:
return await self._send_cmd(TARGET_DEVICE, "HardReset")
class Laser:
def __init__(self, send_cmd_handler):
def __init__(self, send_cmd_handler, cmd_lock):
self._send_cmd = send_cmd_handler
self._cmd_lock = cmd_lock
async def set_power_on(self, on):
"""
@ -313,10 +321,12 @@ class Laser:
- responsitivity: A/W
- dark current: A
"""
response = await self._send_cmd(TARGET_LD, "SetPdResponsitivity", responsitivity)
if response["msg_type"] != "Acknowledge":
return response
return await self._send_cmd(TARGET_LD, "SetPdDarkCurrent", dark_current)
async with self._cmd_lock:
response = await self._send_cmd(TARGET_LD, "SetPdResponsitivity", responsitivity, lock=False)
print(response)
if response["msg_type"] != "Acknowledge":
return response
return await self._send_cmd(TARGET_LD, "SetPdDarkCurrent", dark_current, lock=False)
async def set_ld_pwr_limit(self, pwr_limit):
"""
@ -334,10 +344,10 @@ class Laser:
return await self._send_cmd(TARGET_LD, "ClearAlarm")
class Thermostat:
def __init__(self, send_cmd_handler, send_raw_cmd_handler):
def __init__(self, send_cmd_handler, send_raw_cmd_handler, cmd_lock):
self._send_cmd = send_cmd_handler
self._send_raw_cmd = send_raw_cmd_handler
self._cmd_lock = cmd_lock
async def set_power_on(self, on):
"""
Power up or power down thermostat
@ -522,9 +532,9 @@ class Kirdy:
self._cmd_lock = asyncio.Lock()
self._report_mode_on = False
self.timeout = None
self.device = Device(self._send_cmd_handler, self._send_raw_cmd_handler, self._read_response)
self.laser = Laser(self._send_cmd_handler)
self.thermostat = Thermostat(self._send_cmd_handler, self._send_raw_cmd_handler)
self.device = Device(self._send_cmd_handler, self._send_raw_cmd_handler, self._read_response, self._cmd_lock)
self.laser = Laser(self._send_cmd_handler, self._cmd_lock)
self.thermostat = Thermostat(self._send_cmd_handler, self._send_raw_cmd_handler, self._cmd_lock)
self._cmd_list = {
TARGET_DEVICE: {
@ -646,21 +656,37 @@ class Kirdy:
pass
return { "msg_type": "Internal No json object found in response" }
async def _send_raw_cmd_handler(self, cmd, lock=True):
if lock:
async with self._cmd_lock:
return await asyncio.shield(self._send_raw_cmd(cmd))
else:
return await asyncio.shield(self._send_raw_cmd(cmd))
# If the cmd involves a cmd specific data type,
# checking is done separately within the functions being called
async def _send_raw_cmd_handler(self, cmd):
async def _send_raw_cmd(self, cmd):
retry = 0
while retry < 10:
self._writer.write(bytes(json.dumps(cmd), "UTF-8"))
await self._writer.drain()
response = await self._read_response()
if response["msg_type"] == "Acknowledge":
return response
retry += 1
await asyncio.sleep(0.1)
try:
if response["msg_type"] == "Acknowledge":
return response
except:
retry += 1
await asyncio.sleep(0.1)
raise NoAckRecv
async def _send_cmd_handler(self, target, cmd, data=None):
async def _send_cmd_handler(self, target, cmd, data=None, lock=True):
if lock:
async with self._cmd_lock:
return await asyncio.shield(self._send_cmd(target, cmd, data))
else:
return await asyncio.shield(self._send_cmd(target, cmd, data))
async def _send_cmd(self, target, cmd, data):
cmd_dict = {}
if not(target in self._cmd_list.keys()) or not(cmd in self._cmd_list[target].keys()):
@ -688,10 +714,12 @@ class Kirdy:
self._writer.write(bytes(json.dumps(cmd_dict), "UTF-8"))
await self._writer.drain()
response = await self._read_response()
if response["msg_type"] == "Acknowledge":
return response
retry += 1
await asyncio.sleep(0.1)
try:
if response["msg_type"] == "Acknowledge":
return response
except:
retry += 1
await asyncio.sleep(0.1)
raise NoAckRecv
async def report_mode(self, report_interval = 0.0, buffer_size = 16384):