Narete stvari da delajo
This commit is contained in:
parent
64a10b0512
commit
29b2beca5a
45 changed files with 809 additions and 1600 deletions
|
@ -1,30 +1,23 @@
|
|||
#import gpiozero.pins.mock
|
||||
#from gpiozero import *
|
||||
#from grove.factory import Factory
|
||||
#from grove.grove_relay import GroveRelay
|
||||
MOCK = False
|
||||
import aiomqtt
|
||||
import asyncio
|
||||
#from i2cpy import I2C
|
||||
from smbus2 import SMBus
|
||||
import toml
|
||||
#import i2cpy
|
||||
#i2cset -y 1 0x11 0x11 0x42
|
||||
#set i2c address from 0x11 to 0x42
|
||||
import os
|
||||
|
||||
# ONLY FOR TESTING ON NON RPI
|
||||
#Device.pin_factory = gpiozero.pins.mock.MockFactory()
|
||||
|
||||
#relays = [LED(17), LED(27), LED(22), LED(23), LED(5), LED(6), LED(24), LED(25)]
|
||||
main_I2C_addr = 0 #default
|
||||
side_I2C_addr = 0 #TODO get actual projector motor things from config (dont hardcode main/side)
|
||||
room = ""
|
||||
use_offset = False
|
||||
room: str
|
||||
use_offset = False
|
||||
|
||||
""" 0 1 2 3 """
|
||||
relayMasks = [0b0001, 0b0010, 0b0100, 0b1000] #probably ne rabim
|
||||
|
||||
bus = SMBus(1)
|
||||
|
||||
i2c_map = {
|
||||
'main': -1,
|
||||
'side': -1,
|
||||
}
|
||||
|
||||
relMapping = {
|
||||
'service_down': 0,
|
||||
'service_up': 1,
|
||||
|
@ -38,36 +31,26 @@ currentState = {
|
|||
}
|
||||
|
||||
async def msgRelayBoard(projSelect, command, state: bool):
|
||||
#i2cAddr = relayBoardMain if projSelect == 'glavni' else relayBoardSide
|
||||
#TODO this is not optimal, check for more crap
|
||||
|
||||
# register 0x10 za releje
|
||||
|
||||
I2CAddr = 0 #glavni
|
||||
match projSelect:
|
||||
case 'main':
|
||||
I2CAddr = main_I2C_addr
|
||||
case 'side':
|
||||
I2CAddr = side_I2C_addr
|
||||
#return #TODO TEMPORARY, REMOVE LATER#
|
||||
case default:
|
||||
return #ignore if unknown position
|
||||
# Select the correct relay board
|
||||
i2c_addr = i2c_map[projSelect]
|
||||
|
||||
# Get the relay position for the given command
|
||||
maskShift = relMapping[command]
|
||||
# Set the corresponding bit
|
||||
mask = (1 << maskShift)
|
||||
if state:
|
||||
currentState[projSelect] = currentState[projSelect] | mask
|
||||
else:
|
||||
currentState[projSelect] = currentState[projSelect] & ~mask
|
||||
|
||||
bus.write_byte_data(I2CAddr, 0x10, currentState[projSelect])
|
||||
print("Command sent")
|
||||
#print('testirovano jako')
|
||||
|
||||
# Write it to the I2C bus (0x10 is the register for relay states)
|
||||
bus.write_byte_data(i2c_addr, 0x10, currentState[projSelect])
|
||||
print(projSelect, "{:04b}".format(currentState[projSelect]))
|
||||
|
||||
|
||||
"""
|
||||
SrvDwn SrvUp OpDwn OpUp
|
||||
MAIN: 0x42 0001 0010 0100 1000
|
||||
MAIN: 0x42 0001 0010 0100 1000
|
||||
SIDE: 0x43 0001 0010 0100 1000
|
||||
"""
|
||||
|
||||
|
@ -81,45 +64,84 @@ SIDE: 4 5 6 7
|
|||
#dej like bolš to podukumentiraj or smth
|
||||
|
||||
async def task_command2relays(controlClient: aiomqtt.Client):
|
||||
global room
|
||||
#relayCtrl = lambda cmd, relay: relays[relay].on() if cmd == 1 else relays[relay].off()
|
||||
#relayCtrl = lambda cmd, relay: [relays[r].on() if cmd == 1 and r == relay else relays[r].off for r in range(len(relays))]
|
||||
|
||||
relayCtrl = lambda x, y: print(x, y)
|
||||
"""Read commands from MQTT and send them to the relays"""
|
||||
|
||||
await controlClient.subscribe(f"{room}/projectors/+/lift/#")
|
||||
msgs = controlClient.messages
|
||||
async for mesg in msgs:
|
||||
mesg: aiomqtt.Message
|
||||
if mesg.topic.matches(f'{room}/projectors/+/lift/move/+'):
|
||||
msgTopicArr = mesg.topic.value.split('/')
|
||||
state = mesg.payload.decode()
|
||||
print("Received: " + str(msgTopicArr) + " payload: [" + state + "]")
|
||||
#testCase = (msgTopicArr[2], msgTopicArr[4])
|
||||
projSel = msgTopicArr[2] #TODO projselect odzadaj indexed (just works tm)
|
||||
if projSel != 'main' and projSel != 'side':
|
||||
continue #TODO error hnadling?
|
||||
command = msgTopicArr[5] #TODO same
|
||||
await msgRelayBoard(projSel, command, state == '1')
|
||||
await controlClient.publish(f'{room}/projectors/{projSel}/lift/status', payload="", qos=1, retain=True)
|
||||
|
||||
async for mesg in controlClient.messages:
|
||||
msgTopicArr = mesg.topic.value.split('/')
|
||||
value = mesg.payload.decode()
|
||||
|
||||
if mesg.topic.matches(f'{room}/projectors/+/lift/manual/+'):
|
||||
command = msgTopicArr[-1]
|
||||
projSel = msgTopicArr[-4]
|
||||
|
||||
if projSel not in ("main", "side") or command not in relMapping.keys() or value not in ("0", "1"):
|
||||
print("Invalid manual command:", projSel, command, value)
|
||||
continue
|
||||
|
||||
await msgRelayBoard(projSel, command, value == '1')
|
||||
|
||||
# Service move
|
||||
if "service" in command:
|
||||
# Manual control makes the position unknown, so we clear it
|
||||
if value == "1":
|
||||
status = "MOVING"
|
||||
else:
|
||||
status = "STOPPED"
|
||||
await controlClient.publish(f'{room}/projectors/{projSel}/lift/status', payload=status, qos=1, retain=True)
|
||||
# Normal move
|
||||
else:
|
||||
# HACK: if the press is too short it doesn't register, so we sleep for a bit
|
||||
if value == "1":
|
||||
await asyncio.sleep(.2)
|
||||
|
||||
#print("Pushing \'off\' to other relays to prevent conflicts")
|
||||
await asyncio.sleep(0.01)
|
||||
|
||||
elif mesg.topic.matches(f'{room}/projectors/+/lift/goto'):
|
||||
projSel = msgTopicArr[-3]
|
||||
|
||||
if projSel not in ("main", "side") or value not in ("UP", "DOWN"):
|
||||
print("Invalid goto command:", projSel, value)
|
||||
continue
|
||||
|
||||
# Clear manual control
|
||||
await msgRelayBoard(projSel, "service_down", False)
|
||||
await msgRelayBoard(projSel, "service_up", False)
|
||||
|
||||
if value == "UP":
|
||||
other = "down"
|
||||
elif value == "DOWN":
|
||||
other = "up"
|
||||
await msgRelayBoard(projSel, other, False)
|
||||
|
||||
# Click the buttom for a bit and release it, then publish that the lift has moved
|
||||
await msgRelayBoard(projSel, value.lower(), True)
|
||||
await asyncio.sleep(1)
|
||||
await msgRelayBoard(projSel, value.lower(), False)
|
||||
|
||||
await controlClient.publish(f'{room}/projectors/{projSel}/lift/status', payload=value, qos=1, retain=True)
|
||||
|
||||
await asyncio.sleep(0.01)
|
||||
|
||||
|
||||
|
||||
async def main():
|
||||
global main_I2C_addr, side_I2C_addr, room
|
||||
conf = toml.load('./malinaConfig.toml')
|
||||
projMotors = conf.get("projector_motors")
|
||||
mainMotor = projMotors.get("main")
|
||||
sideMotor = projMotors.get("side")
|
||||
main_I2C_addr = mainMotor['i2c_address']
|
||||
side_I2C_addr = sideMotor['i2c_address'] #TODO spremen v dict
|
||||
global i2c_map, room
|
||||
|
||||
room = conf["global"]["room"]
|
||||
config_file = os.getenv('MM_CONFIG_PATH', './malinaConfig.toml')
|
||||
conf = toml.load(config_file)
|
||||
room = conf['global']['room']
|
||||
mqttHost = conf['global']['mqttHost']
|
||||
mqttPort = conf['global']['mqttPort']
|
||||
|
||||
async with aiomqtt.Client('localhost', 1883) as client:
|
||||
projMotors = conf["projector_motors"]
|
||||
i2c_map['main'] = projMotors["main"]['i2c_address']
|
||||
i2c_map['side'] = projMotors["side"]['i2c_address']
|
||||
|
||||
async with aiomqtt.Client(mqttHost, mqttPort) as client:
|
||||
task_control = asyncio.create_task(task_command2relays(client))
|
||||
await asyncio.gather(task_control)
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
asyncio.run(main())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue