import asyncio import socket import aiomqtt import telnetlib3 import toml from socket import gethostname import sys mainBarcoIP = '192.168.192.12' sideBarcoIP = '192.168.192.13' # TODO all the checks and stuff # TODO MAKE THIS CONFIGURALBE cmdMap = { 'power': 'POWR', 'shutter': 'PMUT', 'freeze': 'FRZE' } reverseCmdMap = {v: k for k, v in cmdMap.items()} def parse_barco_response(raw: str): raw = raw[1:-1] # strip square brackets #print(raw) if raw.startswith("ERR"): return None # TODO parse type error - "disabled control" is special case which shouldnt normally happen cmd, status = raw.split("!", maxsplit=2) #print(cmd + " " + status) cmd = reverseCmdMap[cmd] status = '1' if status == '01' else '0' return cmd, status async def barco_telnet_command(client, writer, select: str): onSub = f"p01/projectors/{select}/#" #print('TEST', onSub) onMatch = f"p01/projectors/{select}/command/+" await client.subscribe(onSub) #async with client.messages as msgs: async for mesg in client.messages: # print(mesg.topic.value) # print(mesg.payload.decode()) # print('on', select) if mesg.topic.matches(onMatch): # print("test") cmd = mesg.topic.value.split("/")[-1] #val = '1' if mesg.payload.decode() == 'ON' else '0' val = '1' if mesg.payload.decode() == '1' else '0' # refactor to direct 0 and 1 barcoCmd = f"[{cmdMap[cmd]}{val}]" print("Received: [" + mesg.topic.value + "] payload: [" + mesg.payload.decode() + "]") print("Sending command to Barco: " + barcoCmd) writer.write(barcoCmd) async def barco_telnet_read_status(client, reader, select: str): while True: output = await reader.readuntil(b']') raw_response: str = output.decode().strip() # strip not necessary? needed for local netcat testing though print("Received: " + raw_response + " from Barco (" + select + ')') parsed = parse_barco_response(raw_response) if parsed == None: continue #TODO alert for errors print(f"Updating topic [{parsed[0]}] with value [{parsed[1]}]") await client.publish(f"p01/projectors/{select}/status/{parsed[0]}", payload=parsed[1]) async def barco_telnet_query_status(writer, select: str): while True: for val in cmdMap.values(): print(f"Querying Barco {select} with: [{val}?]") writer.write(f"[{val}?]" + '\r\n') # TODO test if funny CRLF necessary (it probably gets ignored) await asyncio.sleep(0.2) # sleep between writes necessary, otherwise it gets confused. # simultaneous commands from control could break this? TODO fix later await asyncio.sleep(30) # TODO find appropriate period # async def shell(reader, writer): # async with aiomqtt.Client('localhost', 1883) as client: # task_status_query = asyncio.create_task(barco_telnet_query_status(writer)) # task_status_reader = asyncio.create_task(barco_telnet_read_status(client, reader)) # task_control = asyncio.create_task(barco_telnet_command(client, writer)) # await asyncio.gather(task_status_query, task_status_reader, task_control) async def main(mqttIP=localhost, barcoIP=localhost, mqttPort=1883, telnetPort=3023): conf = toml.load('config.toml') barco # mainBarcoIP = conf[gethostname()]['projektor_glavni'] # sideBarcoIP = conf[gethostname()]['projektor_stranski'] mainReader, mainWriter = await telnetlib3.open_connection(barcoIP, telnetPort) #sideReader, sideWriter = await telnetlib3.open_connection('localhost', 3024) async with aiomqtt.Client(mqttIP, mqttPort) as client: task_status_query_main = asyncio.create_task(barco_telnet_query_status(mainWriter, 'glavni')) task_status_reader_main = asyncio.create_task(barco_telnet_read_status(client, mainReader, 'glavni')) task_control_main = asyncio.create_task(barco_telnet_command(client, mainWriter, 'glavni')) #task_status_query_side = asyncio.create_task(barco_telnet_query_status(sideWriter, 'stranski')) #task_status_reader_side = asyncio.create_task(barco_telnet_read_status(client, sideReader, 'stranski')) #task_control_side = asyncio.create_task(barco_telnet_command(client, sideWriter, 'stranski')) await asyncio.gather(task_status_query_main, task_status_reader_main, task_control_main) #task_status_query_side, task_status_reader_side, task_control_side) ### fuj to, ne tk delat # if __name__ == '__main__': # loop = asyncio.get_event_loop() # coro = telnetlib3.open_connection(mainBarcoIP, 3023, shell=shell) # coro = telnetlib3.open_connection(mainBarcoIP, 3023, shell=shell) # # coro = telnetlib3.open_connection('localhost', 1234, shell=shell) # reader, writer = loop.run_until_complete(coro) # loop.run_until_complete(writer.protocol.waiter_closed) #mqttIP = sys.argv[1] #barcoIP = sys.argv[2] asyncio.run(main())