predavalnice-kontroler/tse_serial/tse_serial_controler.py

91 lines
No EOL
3.1 KiB
Python

import asyncio
import serial
import aioserial
import aiomqtt
from tse_serial_interpreter import *
room = 'p1' #TODO make be do get fronm file of configuration
aser: aioserial.AioSerial = aioserial.AioSerial(
port='/dev/cu.usbserial-14240', #TODO not hardcode it
baudrate=1200,
parity=serial.PARITY_NONE,
bytesize=serial.EIGHTBITS,
stopbits=serial.STOPBITS_ONE
)
# TODO adjust serial on actual TSE interface
mapping = {
"master": 1,
"audio": 2,
"projectors": 3,
"platno_glavni_dol": 5,
"platno_glavni_gor": 6,
"platno_stranski_dol": 7,
"platno_stranski_gor": 8,
"sencilo_dol": 9,
"sencilo_gor": 10
#ostalo reserved
}
reverse_lookup = {v: k for k, v in mapping.items()}
def parse_topic_from_mqtt(topic: str):
topicArr = topic.split()
async def task_status2mqtt(statusClient: aiomqtt.Client):
while True:
data = await aser.read_until_async()
data = data.decode(errors='ignore').strip()
print("TSE box sent: " + data)
relState = resp_to_relay_state(data)
command = reverse_lookup[relState.relay_id]
action = relState.state
#TODO havent figured out a clean way to
# get out the action from topic yet as they are
# not always on the same level
# probably just do it the most straight forward way
# with some more code
publishTopic = f"{room}/"
publishPayload = "ON" if relState.state else "OFF"
print("Publishing [" + publishPayload + "] to topic [" + publishTopic + "]")
await statusClient.publish(publishTopic, payload=publishPayload)
async def task_command2serial(controlClient: aiomqtt.Client):
await controlClient.subscribe("p1/tseRelays/#")
async with controlClient.messages as msgs:
async for mesg in msgs:
mesg: aiomqtt.Message
if mesg.topic.matches('p1/tse_box/+/ukaz'):
msgTopic = mesg.topic.value
cmnd = mesg.payload.decode()
print("Received: [" + msgTopic + "] payload: [" + cmnd + "]")
relay = int(mesg.topic.value.split("/")[-2]) #TODO different by case
cmnd = cmnd == "ON"
relState = RelayState(relay, cmnd)
setRelay = relay_state_to_cmd(relState)
print("Sending to TSE box: " + setRelay)
await aser.write_async(bytes(setRelay + '\r\n', "ascii"))
publishTopic = f"p1/tseRelays/{relState.relay_id}/status"
publishPayload = "1" if relState.state else "0"
print("Also publishing topic [" + publishTopic + "] with status [" + publishPayload + "]")
await controlClient.publish(publishTopic, payload=publishPayload)
await asyncio.sleep(0.01)
async def main():
async with aiomqtt.Client('localhost', 1883) as client:
task_status = asyncio.create_task(task_status2mqtt(client))
task_control = asyncio.create_task(task_command2serial(client))
await asyncio.gather(task_status, task_control)
if __name__ == '__main__':
asyncio.run(main())