Rough writeup of necessary functionality for Barco control, main features work (polish with error handling pending)
This commit is contained in:
parent
7227decc36
commit
a2303045ee
1 changed files with 72 additions and 0 deletions
72
barco_telnet/barco_telnet_control.py
Normal file
72
barco_telnet/barco_telnet_control.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
import asyncio
|
||||
import aiomqtt
|
||||
import telnetlib3
|
||||
|
||||
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
|
||||
cmd, status = raw.split("!", maxsplit=2)
|
||||
#print(cmd + " " + status)
|
||||
cmd = reverseCmdMap[cmd]
|
||||
status = 'ON' if status == '01' else 'OFF'
|
||||
return cmd, status
|
||||
|
||||
|
||||
async def barco_telnet_command(client, writer):
|
||||
await client.subscribe("p1/projectors/main/#")
|
||||
async with client.messages() as msgs:
|
||||
async for mesg in msgs:
|
||||
if mesg.topic.matches('p1/projectors/main/command/+'):
|
||||
cmd = mesg.topic.value.split("/")[-1]
|
||||
val = '1' if mesg.payload.decode() == 'ON' else '0'
|
||||
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):
|
||||
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")
|
||||
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"p1/projectors/main/status/{parsed[0]}", payload=parsed[1])
|
||||
|
||||
|
||||
async def barco_telnet_query_status(writer):
|
||||
while True:
|
||||
for val in cmdMap.values():
|
||||
print(f"Querying Barco with: [{val}?]")
|
||||
writer.write(f"[{val}?]" + '\r\n') # TODO test if funny CRLF necessary (it probably gets ignored)
|
||||
await asyncio.sleep(1) # sleep between writes necessary, otherwise it gets confused.
|
||||
# simultaneous commands from control could break this? TODO fix later
|
||||
await asyncio.sleep(1000) # 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)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
loop = asyncio.get_event_loop()
|
||||
#coro = telnetlib3.open_connection('192.168.192.12', 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)
|
Loading…
Reference in a new issue