(Late) initial commit, finalized controler for communication between TSE box serial interface and MQTT
This commit is contained in:
commit
7227decc36
5 changed files with 116 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.idea/
|
||||
__pycache__/
|
2
relay_board/relay_board_controler.py
Normal file
2
relay_board/relay_board_controler.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
import gpiozero as GPIO
|
||||
|
18
serialTests.py
Normal file
18
serialTests.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
import unittest
|
||||
|
||||
from tse_serial.tse_serial_interpreter import *
|
||||
|
||||
|
||||
class TestStringMethods(unittest.TestCase):
|
||||
|
||||
def test_response_parser(self):
|
||||
self.assertEquals(resp_to_relay_state("T5A_ON"), RelayState(relay_id=5, state=True))
|
||||
self.assertEquals(resp_to_relay_state("T3B_OFF"), RelayState(relay_id=11, state=False))
|
||||
self.assertEquals(resp_to_relay_state("re_2A=OFF"), RelayState(relay_id=2, state=False))
|
||||
self.assertEquals(resp_to_relay_state("re_1B=OFF"), RelayState(relay_id=9, state=False))
|
||||
|
||||
def test_command_parser(self):
|
||||
self.assertEquals(relay_state_to_cmd(RelayState(3, False)), "r39")
|
||||
self.assertEquals(relay_state_to_cmd(RelayState(5, True)), "r58")
|
||||
self.assertEquals(relay_state_to_cmd(RelayState(9, True)), "r16")
|
||||
self.assertEquals(relay_state_to_cmd(RelayState(11, False)), "r37")
|
59
tse_serial/tse_serial_controler.py
Normal file
59
tse_serial/tse_serial_controler.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
import asyncio
|
||||
import serial
|
||||
import aioserial
|
||||
import aiomqtt
|
||||
from tse_serial_interpreter import *
|
||||
|
||||
aser: aioserial.AioSerial = aioserial.AioSerial(
|
||||
port='/dev/cu.usbserial-14240',
|
||||
baudrate=1200,
|
||||
parity=serial.PARITY_NONE,
|
||||
bytesize=serial.EIGHTBITS,
|
||||
stopbits=serial.STOPBITS_ONE
|
||||
)
|
||||
# TODO adjust serial on actual TSE interface
|
||||
|
||||
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)
|
||||
publishTopic = f"p1/tseRelays/{relState.relay_id}/status"
|
||||
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/tseRelays/+/command'):
|
||||
msgTopic = mesg.topic.value
|
||||
cmnd = mesg.payload.decode()
|
||||
print("Received: [" + msgTopic + "] payload: [" + cmnd + "]")
|
||||
relay = int(mesg.topic.value.split("/")[-2])
|
||||
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 = "ON" if relState.state else "OFF"
|
||||
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())
|
35
tse_serial/tse_serial_interpreter.py
Normal file
35
tse_serial/tse_serial_interpreter.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class RelayState:
|
||||
relay_id: int
|
||||
state: bool
|
||||
|
||||
|
||||
def resp_to_relay_state(cmd: str) -> RelayState:
|
||||
state = True if cmd.find("ON") > -1 else False
|
||||
#state = False if cmd.find("OFF") > -1 and state == None else None
|
||||
|
||||
r_state = RelayState(0, state)
|
||||
id = 0
|
||||
|
||||
if cmd.startswith("T"):
|
||||
id = int(cmd[1]) + (8 if cmd[2] == "B" else 0)
|
||||
elif cmd.startswith("re_"):
|
||||
id = int(cmd[3]) + (8 if cmd[4] == "B" else 0)
|
||||
|
||||
r_state = RelayState(id, state)
|
||||
return r_state
|
||||
|
||||
|
||||
def relay_state_to_cmd(r_state: RelayState) -> str:
|
||||
#r[NUM][CMD]
|
||||
cmd = 8 if r_state.state else 9
|
||||
id = r_state.relay_id
|
||||
# banka B
|
||||
if id > 8:
|
||||
cmd -= 2
|
||||
id -= 8
|
||||
return f"r{id}{cmd}"
|
||||
#return "r" + str(id) + str(cmd)
|
Loading…
Reference in a new issue