|
- from typing import List
- from MAXCube import MAXCube
- from MAXPacket import MAXPacket, MAXPacketFactory, MAXPairPingPacket, MAXPairPongPacket, MAXAckPacket, \
- MAXSetGroupIdPacket, MAXPushButtonPacket, MAXCubeAckPacket, MAXSetTempPacket, \
- MAXRadiatorControlMode, MAXAddLinkPartnerPacket
- from MAXDevice import MAXDevice, MAXPushButton, MAXThermostat
- from enum import Enum
-
-
- class HandshakeState(Enum):
- PING_RECEIVED = 1
- PONG_SENT = 2
- PONG_ACK = 3
- GROUP_ID_SENT = 4
- GROUP_ID_ACK = 5
- CONFIG_TEMP_SENT = 6
- CONFIG_TEMP_ACK = 7
- ADD_LINK_PARTNER_SENT = 8
- ADD_LINK_PARTNER_ACK = 9
-
-
- 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:
- def __init__(self, cube, devices: MAXCube):
- self.cube = cube
- self.quit_flag = False
- self.handshakes = []
- self.devices: List[MAXDevice] = devices
-
- 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()
- print(pong.to_string())
- 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
- #print(pkt.to_string())
- 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))
- 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)
- self.handshakes.remove(cur_handshake)
-
- 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()
- print(set_group_id.to_string())
- self.cube.request(set_group_id_str)
- cur_handshake.state = HandshakeState.GROUP_ID_SENT
- return
- if cur_handshake.state == HandshakeState.GROUP_ID_SENT:
- cur_handshake.state = HandshakeState.GROUP_ID_ACK
-
- 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
- elif isinstance(pkt, MAXPushButtonPacket):
- dev = None
- for known_dev in self.devices:
- if known_dev.address == pkt.sender_address:
- dev = known_dev
- break
- 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
- else:
- print("Paket is not ours!")
|