2021-10-05 03:51:53 +02:00
|
|
|
from typing import List
|
2021-08-26 18:49:18 +02:00
|
|
|
from MAXCube import MAXCube
|
|
|
|
from MAXPacket import MAXPacket, MAXPacketFactory, MAXPairPingPacket, MAXPairPongPacket, MAXAckPacket, \
|
2021-10-05 03:51:53 +02:00
|
|
|
MAXSetGroupIdPacket, MAXPushButtonPacket, MAXCubeAckPacket, MAXSetTempPacket, \
|
|
|
|
MAXRadiatorControlMode, MAXAddLinkPartnerPacket
|
|
|
|
from MAXDevice import MAXDevice, MAXPushButton, MAXThermostat
|
2021-08-26 18:49:18 +02:00
|
|
|
from enum import Enum
|
|
|
|
|
|
|
|
|
|
|
|
class HandshakeState(Enum):
|
|
|
|
PING_RECEIVED = 1
|
|
|
|
PONG_SENT = 2
|
|
|
|
PONG_ACK = 3
|
|
|
|
GROUP_ID_SENT = 4
|
|
|
|
GROUP_ID_ACK = 5
|
2021-10-05 03:51:53 +02:00
|
|
|
CONFIG_TEMP_SENT = 6
|
|
|
|
CONFIG_TEMP_ACK = 7
|
|
|
|
ADD_LINK_PARTNER_SENT = 8
|
|
|
|
ADD_LINK_PARTNER_ACK = 9
|
2021-08-26 18:49:18 +02:00
|
|
|
|
|
|
|
|
|
|
|
class Handshake:
|
|
|
|
def __init__(self, partner_addr, dev_type):
|
|
|
|
self.partner_addr = partner_addr
|
|
|
|
self.dev_type = dev_type
|
|
|
|
self.state: HandshakeState = HandshakeState.PING_RECEIVED
|
|
|
|
|
|
|
|
|
|
|
|
class MAXPacketHandler:
|
2021-10-05 03:51:53 +02:00
|
|
|
def __init__(self, cube, devices: MAXCube):
|
2021-08-26 18:49:18 +02:00
|
|
|
self.cube = cube
|
|
|
|
self.quit_flag = False
|
|
|
|
self.handshakes = []
|
2021-10-05 03:51:53 +02:00
|
|
|
self.devices: List[MAXDevice] = devices
|
2021-08-26 18:49:18 +02:00
|
|
|
|
|
|
|
def handle_msg(self, pkt: MAXPacket):
|
|
|
|
print(pkt.to_string())
|
|
|
|
if pkt.dest_address == self.cube.addr or pkt.dest_address == "000000":
|
|
|
|
if isinstance(pkt, MAXPairPingPacket):
|
|
|
|
handshake = Handshake(pkt.sender_address, pkt.device_type)
|
|
|
|
self.handshakes.append(handshake)
|
|
|
|
pong = MAXPairPongPacket(message_counter="00", message_flag="00", sender_address=self.cube.addr,
|
|
|
|
dest_address=pkt.sender_address, group_id="00")
|
|
|
|
pong_str = pong.serialize()
|
2021-10-05 03:51:53 +02:00
|
|
|
print(pong.to_string())
|
2021-08-26 18:49:18 +02:00
|
|
|
self.cube.request(pong_str)
|
|
|
|
handshake.state = HandshakeState.PONG_SENT
|
|
|
|
elif isinstance(pkt, MAXAckPacket):
|
|
|
|
cur_handshake: Handshake = None
|
|
|
|
for handshake in self.handshakes:
|
|
|
|
if handshake.partner_addr == pkt.sender_address:
|
|
|
|
cur_handshake = handshake
|
|
|
|
break
|
|
|
|
if cur_handshake is not None:
|
|
|
|
if cur_handshake.state == HandshakeState.PONG_SENT:
|
|
|
|
cur_handshake.state = HandshakeState.PONG_ACK
|
2021-10-05 03:51:53 +02:00
|
|
|
#print(pkt.to_string())
|
2021-08-26 18:49:18 +02:00
|
|
|
if cur_handshake.dev_type == "05":
|
|
|
|
# Handshake is finished
|
|
|
|
print("Paired device with addr={} and type={}".format(cur_handshake.partner_addr,
|
|
|
|
cur_handshake.dev_type))
|
2021-10-05 03:51:53 +02:00
|
|
|
found = False
|
|
|
|
for dev in self.devices:
|
|
|
|
if dev.address == cur_handshake.partner_addr:
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
if not found:
|
|
|
|
new_dev = MAXPushButton("PushButton_{}".format(cur_handshake.partner_addr),
|
|
|
|
cur_handshake.partner_addr)
|
|
|
|
self.devices.append(new_dev)
|
2021-08-26 18:49:18 +02:00
|
|
|
self.handshakes.remove(cur_handshake)
|
2021-10-05 03:51:53 +02:00
|
|
|
|
2021-08-26 18:49:18 +02:00
|
|
|
else:
|
|
|
|
set_group_id = MAXSetGroupIdPacket(message_counter="00", message_flag="00", sender_address=self.cube.addr,
|
|
|
|
dest_address=pkt.sender_address, group_id="00")
|
|
|
|
set_group_id_str = set_group_id.serialize()
|
2021-10-05 03:51:53 +02:00
|
|
|
print(set_group_id.to_string())
|
2021-08-26 18:49:18 +02:00
|
|
|
self.cube.request(set_group_id_str)
|
|
|
|
cur_handshake.state = HandshakeState.GROUP_ID_SENT
|
2021-10-05 03:51:53 +02:00
|
|
|
return
|
2021-08-26 18:49:18 +02:00
|
|
|
if cur_handshake.state == HandshakeState.GROUP_ID_SENT:
|
|
|
|
cur_handshake.state = HandshakeState.GROUP_ID_ACK
|
2021-10-05 03:51:53 +02:00
|
|
|
|
|
|
|
set_temp = MAXSetTempPacket(message_counter="00", message_flag="00", sender_address=self.cube.addr,
|
|
|
|
dest_address=pkt.sender_address, group_id="00", temp=21.5,
|
|
|
|
mode=MAXRadiatorControlMode.MANUAL)
|
|
|
|
set_temp_str = set_temp.serialize()
|
|
|
|
print(set_temp.to_string())
|
|
|
|
self.cube.request(set_temp_str)
|
|
|
|
|
|
|
|
cur_handshake.state = HandshakeState.CONFIG_TEMP_SENT
|
|
|
|
return
|
|
|
|
if cur_handshake.state == HandshakeState.CONFIG_TEMP_SENT:
|
|
|
|
cur_handshake.state = HandshakeState.CONFIG_TEMP_ACK
|
|
|
|
|
|
|
|
add_link = MAXAddLinkPartnerPacket(message_counter="00", message_flag="00", sender_address=self.cube.addr,
|
|
|
|
dest_address=pkt.sender_address, group_id="00", partner_addr=self.cube.addr, partner_type=0)
|
|
|
|
add_link_str = add_link.serialize()
|
|
|
|
print(add_link.to_string())
|
|
|
|
self.cube.request(add_link_str)
|
|
|
|
cur_handshake.state = HandshakeState.ADD_LINK_PARTNER_SENT
|
|
|
|
return
|
|
|
|
if cur_handshake.state == HandshakeState.ADD_LINK_PARTNER_SENT:
|
|
|
|
cur_handshake.state = HandshakeState.ADD_LINK_PARTNER_ACK
|
|
|
|
found = False
|
|
|
|
for dev in self.devices:
|
|
|
|
if dev.address == cur_handshake.partner_addr:
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
if not found:
|
|
|
|
new_dev = MAXThermostat("Thermostat_{}".format(cur_handshake.partner_addr),
|
|
|
|
cur_handshake.partner_addr)
|
|
|
|
self.devices.append(new_dev)
|
|
|
|
print("Paired device with addr={} and type={}".format(cur_handshake.partner_addr,
|
|
|
|
cur_handshake.dev_type))
|
|
|
|
self.handshakes.remove(cur_handshake)
|
|
|
|
return
|
2021-09-06 01:30:04 +02:00
|
|
|
elif isinstance(pkt, MAXPushButtonPacket):
|
|
|
|
dev = None
|
|
|
|
for known_dev in self.devices:
|
|
|
|
if known_dev.address == pkt.sender_address:
|
|
|
|
dev = known_dev
|
|
|
|
break
|
2021-10-05 03:51:53 +02:00
|
|
|
if dev is not None:
|
|
|
|
dev.state = pkt.button_state
|
|
|
|
print("Button {} state={}".format(dev.address, dev.state))
|
|
|
|
if not pkt.retransmit:
|
|
|
|
act_pkt = MAXCubeAckPacket(pkt.counter, "00", self.cube.addr,
|
|
|
|
pkt.sender_address, pkt.group_id, True)
|
|
|
|
act_str = act_pkt.serialize()
|
|
|
|
#print(act_str)
|
|
|
|
#self.cube.request(act_str)
|
|
|
|
#ToDo: Does not work properly
|
2021-08-26 18:49:18 +02:00
|
|
|
else:
|
|
|
|
print("Paket is not ours!")
|