rework of tse controler to work with new mqtt structure, probably not working 100% yet
This commit is contained in:
parent
e595fb97ce
commit
1984db16bf
3 changed files with 143 additions and 36 deletions
|
@ -32,3 +32,7 @@
|
||||||
- `/projectors` - Projectors and lifts
|
- `/projectors` - Projectors and lifts
|
||||||
- `status` - current power status (`0` or `1`)
|
- `status` - current power status (`0` or `1`)
|
||||||
- `set` - set the power status (`0` or `1`)
|
- `set` - set the power status (`0` or `1`)
|
||||||
|
|
||||||
|
- `/firanki/`
|
||||||
|
- `status` - `STATIONARY`, `MOVING_UP`, `MOVING_DOWN`
|
||||||
|
- `command` - `NONE`, `MOVE_UP`, `MOVE_DOWN`
|
4
tse_serial/requirements.txt
Normal file
4
tse_serial/requirements.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import asyncio
|
||||||
|
import serial
|
||||||
|
import aioserial
|
||||||
|
import aiomqtt
|
|
@ -3,6 +3,7 @@ import serial
|
||||||
import aioserial
|
import aioserial
|
||||||
import aiomqtt
|
import aiomqtt
|
||||||
from tse_serial_interpreter import *
|
from tse_serial_interpreter import *
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
room = 'p1' #TODO make be do get fronm file of configuration
|
room = 'p1' #TODO make be do get fronm file of configuration
|
||||||
|
|
||||||
|
@ -15,22 +16,33 @@ aser: aioserial.AioSerial = aioserial.AioSerial(
|
||||||
)
|
)
|
||||||
# TODO adjust serial on actual TSE interface
|
# TODO adjust serial on actual TSE interface
|
||||||
|
|
||||||
mapping = {
|
#TODO get this from file da ni hardcoded
|
||||||
|
|
||||||
|
mapping_toggles = {
|
||||||
"master": 1,
|
"master": 1,
|
||||||
"audio": 2,
|
"audio": 2,
|
||||||
"projectors": 3,
|
"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()}
|
platno_mapping = {
|
||||||
|
"glavni": {
|
||||||
|
"dol": 5,
|
||||||
|
"gor": 6
|
||||||
|
},
|
||||||
|
"stranski": {
|
||||||
|
"dol": 7,
|
||||||
|
"gor": 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shades_mapping = {
|
||||||
|
"dol": 9,
|
||||||
|
"gor": 10
|
||||||
|
}
|
||||||
|
|
||||||
|
#reverse_lookup = {v: k for k, v in mapping.items()} #fujto
|
||||||
|
# TODO simple reverse lookup za ko kripa pove kaj
|
||||||
|
|
||||||
|
|
||||||
def parse_topic_from_mqtt(topic: str):
|
def parse_topic_from_mqtt(topic: str):
|
||||||
topicArr = topic.split()
|
topicArr = topic.split()
|
||||||
|
@ -42,43 +54,130 @@ async def task_status2mqtt(statusClient: aiomqtt.Client):
|
||||||
data = await aser.read_until_async()
|
data = await aser.read_until_async()
|
||||||
data = data.decode(errors='ignore').strip()
|
data = data.decode(errors='ignore').strip()
|
||||||
print("TSE box sent: " + data)
|
print("TSE box sent: " + data)
|
||||||
relState = resp_to_relay_state(data)
|
#relState = resp_to_relay_state(data)
|
||||||
command = reverse_lookup[relState.relay_id]
|
#command = reverse_lookup[relState.relay_id]
|
||||||
action = relState.state
|
#action = relState.state
|
||||||
#TODO havent figured out a clean way to
|
#TODO havent figured out a clean way to
|
||||||
# get out the action from topic yet as they are
|
# get out the action from topic yet as they are
|
||||||
# not always on the same level
|
# not always on the same level
|
||||||
|
# REWORK
|
||||||
# probably just do it the most straight forward way
|
# probably just do it the most straight forward way
|
||||||
# with some more code
|
# with some more code
|
||||||
publishTopic = f"{room}/"
|
#publishTopic = f"{room}/"
|
||||||
publishPayload = "ON" if relState.state else "OFF"
|
#publishPayload = "ON" if relState.state else "OFF"
|
||||||
print("Publishing [" + publishPayload + "] to topic [" + publishTopic + "]")
|
#print("Publishing [" + publishPayload + "] to topic [" + publishTopic + "]")
|
||||||
await statusClient.publish(publishTopic, payload=publishPayload)
|
#await statusClient.publish(publishTopic, payload=publishPayload)
|
||||||
|
await asyncio.sleep(0.01)
|
||||||
|
|
||||||
|
|
||||||
|
async def executeAndPublish(topicVal, mqttClient, pubTopic, pubPayload, relStat):
|
||||||
|
setRelayCmd = relay_state_to_cmd(relStat)
|
||||||
|
print("Received: [" + topicVal + "] payload: [" + pubPayload + "]")
|
||||||
|
print("Sending to TSE box: " + setRelayCmd)
|
||||||
|
print(f"Also publishing topic [{pubTopic}] with status [{pubPayload}]")
|
||||||
|
#await aser.write_async(bytes(setRelayCmd + '\r\n', "ascii"))
|
||||||
|
await mqttClient.publish(pubTopic, payload=pubPayload)
|
||||||
|
|
||||||
|
|
||||||
|
async def handleTsePower(tval, client, sysSelect, cmd):
|
||||||
|
rel = RelayState(mapping_toggles[sysSelect], cmd == '1')
|
||||||
|
await executeAndPublish(tval, client, f'{room}/power/{sysSelect}/status', cmd, rel)
|
||||||
|
|
||||||
|
async def handleTseSencilo(tval, client, cmd):
|
||||||
|
#relName = tval.split('/')[3]
|
||||||
|
topicPub = f'{room}/firanki/status'
|
||||||
|
if cmd == "MOVE_UP":
|
||||||
|
rel = RelayState(shades_mapping['gor'], True)
|
||||||
|
await executeAndPublish(tval, client, topicPub, "MOVING_UP", rel)
|
||||||
|
elif cmd == "MOVE_DOWN":
|
||||||
|
rel = RelayState(shades_mapping['dol'], True)
|
||||||
|
await executeAndPublish(tval, client, topicPub, "MOVING_DOWN", rel)
|
||||||
|
else:
|
||||||
|
await executeAndPublish(tval, client, topicPub, "STATIONARY", RelayState(shades_mapping['gor'], False))
|
||||||
|
await executeAndPublish(tval, client, topicPub, "STATIONARY", RelayState(shades_mapping['dol'], False))
|
||||||
|
|
||||||
|
|
||||||
|
platnoBckgdMoving = False # mucho importante variable prav zares dedoles
|
||||||
|
|
||||||
|
async def platnoTimeout(topicVal, mqttClient, pubTopic, pubPayload, relStat):
|
||||||
|
global platnoBckgdMoving
|
||||||
|
await asyncio.sleep(3) #TODO time actual delay
|
||||||
|
relStat.state = False
|
||||||
|
executeAndPublish(topicVal, mqttClient, pubTopic, pubPayload, relStat)
|
||||||
|
platnoBckgdMoving = False
|
||||||
|
|
||||||
|
async def handleTsePlatno(tval, client, proj, cmdType, cmd):
|
||||||
|
global platnoBckgdMoving
|
||||||
|
topicSplit = tval.split('/')
|
||||||
|
# {room} {projectors} {[select]} {platno} {move/goto}
|
||||||
|
projector = topicSplit[2]
|
||||||
|
command = topicSplit[4]
|
||||||
|
pubTop = f'{room}/projectors/{projector}/status'
|
||||||
|
|
||||||
|
if platnoBckgdMoving:
|
||||||
|
if cmd == 'STOP':
|
||||||
|
pubPld = 'UNKNOWN'
|
||||||
|
rel1 = RelayState(platno_mapping[projector]['gor'], False)
|
||||||
|
rel2 = RelayState(platno_mapping[projector]['dol'], False)
|
||||||
|
executeAndPublish(tval,client,pubTop, pubPld, rel1)
|
||||||
|
executeAndPublish(tval,client,pubTop, pubPld, rel2)
|
||||||
|
else:
|
||||||
|
return # ignore any other move commands while moving
|
||||||
|
|
||||||
|
#movement cmds
|
||||||
|
if cmdType == 'move':
|
||||||
|
rel: RelayState
|
||||||
|
if cmd == 'UP':
|
||||||
|
rel = RelayState(platno_mapping[proj]['gor'], True)
|
||||||
|
elif cmd == 'DOWN':
|
||||||
|
rel = RelayState(platno_mapping[proj]['dol'], True)
|
||||||
|
else:
|
||||||
|
return # in case of invalid input skip
|
||||||
|
platnoBckgdState = True
|
||||||
|
pubPld = 'MOVING'
|
||||||
|
executeAndPublish(tval, client, pubTop, pubPld, rel)
|
||||||
|
|
||||||
|
elif cmdType == 'goto':
|
||||||
|
rel: RelayState
|
||||||
|
if cmd == 'UP':
|
||||||
|
rel = RelayState(platno_mapping[proj]['gor'], True)
|
||||||
|
elif cmd == 'DOWN':
|
||||||
|
rel = RelayState(platno_mapping[proj]['dol'], True)
|
||||||
|
else:
|
||||||
|
return # in case of invalid input skip
|
||||||
|
platnoBckgdState = True
|
||||||
|
pubPld = 'MOVING'
|
||||||
|
executeAndPublish(tval, client, pubTop, pubPld, rel)
|
||||||
|
asyncio.create_task(platnoTimeout(tval, client, pubTop, pubPld, rel))
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
async def task_command2serial(controlClient: aiomqtt.Client):
|
async def task_command2serial(controlClient: aiomqtt.Client):
|
||||||
await controlClient.subscribe("p1/tseRelays/#")
|
await controlClient.subscribe(f"{room}/#")
|
||||||
async with controlClient.messages as msgs:
|
async with controlClient.messages as msgs:
|
||||||
async for mesg in msgs:
|
async for mesg in msgs:
|
||||||
mesg: aiomqtt.Message
|
mesg: aiomqtt.Message
|
||||||
if mesg.topic.matches('p1/tse_box/+/ukaz'):
|
topicVal = mesg.topic.value
|
||||||
msgTopic = mesg.topic.value
|
msgTopic = mesg.topic.value.split('/')
|
||||||
cmnd = mesg.payload.decode()
|
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"
|
if mesg.topic.matches(f'{room}/projectors/+/platno/#'):
|
||||||
publishPayload = "1" if relState.state else "0"
|
proj = msgTopic[2] # glavni / stranski
|
||||||
print("Also publishing topic [" + publishTopic + "] with status [" + publishPayload + "]")
|
cmdType = msgTopic[4] # move / goto
|
||||||
await controlClient.publish(publishTopic, payload=publishPayload)
|
await handleTsePlatno(topicVal, controlClient, proj, cmdType, cmnd)
|
||||||
|
|
||||||
await asyncio.sleep(0.01)
|
elif mesg.topic.matches(f'{room}/power/#'):
|
||||||
|
systype = msgTopic[2]
|
||||||
|
await handleTsePower(topicVal, controlClient, systype, cmnd)
|
||||||
|
|
||||||
|
elif mesg.topic.matches(f'{room}/firanki/command/#'):
|
||||||
|
await handleTseSencilo(topicVal, controlClient, cmnd)
|
||||||
|
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
# code after if block doesnt execute in this case
|
||||||
|
|
||||||
|
await asyncio.sleep(0.01)
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
|
Loading…
Reference in a new issue