Пример #1
0
    def __init__(self):
        super(Actuasim, self).__init__()
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
        file_handler = RotatingFileHandler('actuasim.log', 'a', 10000000, 1)
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)
        self.logger.info('=======================================')
        self.logger.info('           ACTUASIM START')
        self.logger.info('=======================================')
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.resize(1700, 900)
        self.classrooms = []
        self.tabs = QTabWidget()
        self.setCentralWidget(self.tabs)
        self.file_menu = self.ui.menubar.addMenu("&File")
        self.save_action = QAction("&Save", self, triggered=self.save)
        self.file_menu.addAction(self.save_action)
        self.load_action = QAction("&Load", self, triggered=self.load)
        self.file_menu.addAction(self.load_action)
        self.command_handler = CommandHandler(self)

        # endpoints, status, id
        self.control_endpoint = ('0.0.0.0', 0)
        self.data_endpoint = ('0.0.0.0', 0)
        self.status = 0
        self.channel_id = random.randint(0, 255)  # TODO: handle multiple channel

        # server
        self.knxserver = Knxserver()
        self.knxserver.trigger.connect(self.frame_received)
        self.knxserver.start()
    def __init__(self):
        super(Actuasim, self).__init__()
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            '%(asctime)s :: %(levelname)s :: %(message)s')
        file_handler = RotatingFileHandler('actuasim.log', 'a', 10000000, 1)
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)
        self.logger.info('=======================================')
        self.logger.info('           ACTUASIM START')
        self.logger.info('=======================================')
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.resize(1700, 900)
        self.classrooms = []
        self.tabs = QTabWidget()
        self.setCentralWidget(self.tabs)
        self.file_menu = self.ui.menubar.addMenu("&File")
        self.save_action = QAction("&Save", self, triggered=self.save)
        self.file_menu.addAction(self.save_action)
        self.load_action = QAction("&Load", self, triggered=self.load)
        self.file_menu.addAction(self.load_action)
        self.command_handler = CommandHandler(self)

        # endpoints, status, id
        self.control_endpoint = ('0.0.0.0', 0)
        self.data_endpoint = ('0.0.0.0', 0)
        self.status = 0
        self.channel_id = random.randint(0,
                                         255)  # TODO: handle multiple channel
        self.tunnel_req_data_response = None  # Store the tunneling request that contains the response for a read

        # server
        self.knxserver = Knxserver()
        self.knxserver.trigger.connect(self.frame_received)
        self.knxserver.start()
Пример #3
0
class Actuasim(QMainWindow):

    save_filename = 'saved_rooms.json'

    def __init__(self):
        super(Actuasim, self).__init__()
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
        file_handler = RotatingFileHandler('actuasim.log', 'a', 10000000, 1)
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)
        self.logger.info('=======================================')
        self.logger.info('           ACTUASIM START')
        self.logger.info('=======================================')
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.resize(1700, 900)
        self.classrooms = []
        self.tabs = QTabWidget()
        self.setCentralWidget(self.tabs)
        self.file_menu = self.ui.menubar.addMenu("&File")
        self.save_action = QAction("&Save", self, triggered=self.save)
        self.file_menu.addAction(self.save_action)
        self.load_action = QAction("&Load", self, triggered=self.load)
        self.file_menu.addAction(self.load_action)
        self.command_handler = CommandHandler(self)

        # endpoints, status, id
        self.control_endpoint = ('0.0.0.0', 0)
        self.data_endpoint = ('0.0.0.0', 0)
        self.status = 0
        self.channel_id = random.randint(0, 255)  # TODO: handle multiple channel

        # server
        self.knxserver = Knxserver()
        self.knxserver.trigger.connect(self.frame_received)
        self.knxserver.start()

    def load_rooms(self, json_data=None):
        self._clean_rooms()
        if json_data is not None:
            data = json.loads(json_data, object_pairs_hook=OrderedDict)
            for key, val in data.items():
                room = Room.from_dict(title=key, room_dict=val)
                self.classrooms.append(room)
                self.tabs.addTab(room, key)

    def save(self):
        classrooms = OrderedDict()
        for i in range(self.tabs.count()):
            room = self.tabs.widget(i)
            classrooms[room.title] = room.get_room_dict()
        json_data = json.dumps(classrooms, indent=4)
        with open(Actuasim.save_filename, 'w') as f:
            f.write(json_data)

    def load(self):
        if os.path.isfile(Actuasim.save_filename):
            with open(Actuasim.save_filename, 'r') as f:
                json_data = f.read()
            self.load_rooms(json_data)
            return True
        else:
            m = "{0} not found".format(Actuasim.save_filename)
            print(m)
            logging.error(m)
            return False

    def load_room_template(self):
        template = """
                    {
                        "room 1": {
                            "blinds": [
                                {
                                    "value": 48,
                                    "address": "4.11.1@1/4/1"
                                },
                                {
                                    "value": 100,
                                    "address": "4.11.2@1/4/2"
                                }
                            ],
                            "valves": [
                                {
                                    "value": 48,
                                    "address": "4.0.1@0/4/1"
                                },
                                {
                                    "value": 100,
                                    "address": "4.1.1@0/4/2"
                                }
                            ]
                        },
                        "room 2": {
                            "blinds": [
                                {
                                    "value": 33,
                                    "address": "4.11.2@1/4/1"
                                },
                                {
                                    "value": 33,
                                    "address": "4.11.2@1/4/2"
                                }
                            ],
                            "valves": [
                                {
                                    "value": 33,
                                    "address": "4.0.2@0/4/10"
                                },
                                {
                                    "value": 33,
                                    "address": "4.1.2@0/4/11"
                                }
                            ]
                        }
                    }
                """
        self.load_rooms(template)

    def frame_received(self, frame):
        self.logger.info('Frame received:' + str([hex(h) for h in frame]))
        decoded_frame = knxnet.decode_frame(frame)
        if decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.CONNECTION_REQUEST:
            self.logger.info('= Connection request:\n' + str(decoded_frame))
            conn_resp = knxnet.create_frame(knxnet.ServiceTypeDescriptor.CONNECTION_RESPONSE,
                                            self.channel_id,
                                            self.status,
                                            self.data_endpoint)
            self.knxserver.send(conn_resp.frame)
            self.logger.info('Frame sent:' + repr(conn_resp))
            self.logger.info('= Connection response:\n' + str(conn_resp))
        elif decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.CONNECTION_STATE_REQUEST:
            self.logger.info('= Connection state request:\n' + str(decoded_frame))
            conn_state_resp = knxnet.create_frame(knxnet.ServiceTypeDescriptor.CONNECTION_STATE_RESPONSE,
                                                  self.channel_id,
                                                  self.status)
            self.knxserver.send(conn_state_resp.frame)
            self.logger.info('Frame sent:' + repr(conn_state_resp))
            self.logger.info('= Connection state response:\n' + str(conn_state_resp))
        elif decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.DISCONNECT_REQUEST:
            self.logger.info('= Disconnect request:\n' + str(decoded_frame))
            disconnect_resp = knxnet.create_frame(knxnet.ServiceTypeDescriptor.DISCONNECT_RESPONSE,
                                                  self.channel_id,
                                                  self.status)
            self.knxserver.send(disconnect_resp.frame)
            self.logger.info('Frame sent:' + repr(disconnect_resp))
            self.logger.info('= Disconnect response:\n' + str(disconnect_resp))
        elif decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.TUNNELLING_REQUEST:
            self.logger.info('= Tunnelling request:\n' + str(decoded_frame))
            self.command_handler.handle_tunnelling_request(decoded_frame)
            tunnel_ack = knxnet.create_frame(knxnet.ServiceTypeDescriptor.TUNNELLING_ACK,
                                             self.channel_id,
                                             self.status)
            self.knxserver.send(tunnel_ack.frame)
            self.logger.info('Frame sent:' + repr(tunnel_ack))
            self.logger.info('= Tunnelling ack:\n' + str(tunnel_ack))
        else:
            self.logger.info('The frame is not supported')

    def closeEvent(self, QCloseEvent):
        self.knxserver.close_server()
        self.save()
        self.logger.info('=======================================')
        self.logger.info('    *****   ACTUASIM STOP   *****')
        self.logger.info('=======================================')

    def _clean_rooms(self):
        for i in range(len(self.tabs)):
            self.tabs.removeTab(0)
        for room in self.classrooms:
            room.deleteLater()
        self.classrooms = []
class Actuasim(QMainWindow):

    save_filename = 'saved_rooms.json'

    def __init__(self):
        super(Actuasim, self).__init__()
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            '%(asctime)s :: %(levelname)s :: %(message)s')
        file_handler = RotatingFileHandler('actuasim.log', 'a', 10000000, 1)
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)
        self.logger.info('=======================================')
        self.logger.info('           ACTUASIM START')
        self.logger.info('=======================================')
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.resize(1700, 900)
        self.classrooms = []
        self.tabs = QTabWidget()
        self.setCentralWidget(self.tabs)
        self.file_menu = self.ui.menubar.addMenu("&File")
        self.save_action = QAction("&Save", self, triggered=self.save)
        self.file_menu.addAction(self.save_action)
        self.load_action = QAction("&Load", self, triggered=self.load)
        self.file_menu.addAction(self.load_action)
        self.command_handler = CommandHandler(self)

        # endpoints, status, id
        self.control_endpoint = ('0.0.0.0', 0)
        self.data_endpoint = ('0.0.0.0', 0)
        self.status = 0
        self.channel_id = random.randint(0,
                                         255)  # TODO: handle multiple channel
        self.tunnel_req_data_response = None  # Store the tunneling request that contains the response for a read

        # server
        self.knxserver = Knxserver()
        self.knxserver.trigger.connect(self.frame_received)
        self.knxserver.start()

    def load_rooms(self, json_data=None):
        self._clean_rooms()
        if json_data is not None:
            data = json.loads(json_data, object_pairs_hook=OrderedDict)
            for key, val in data.items():
                room = Room.from_dict(title=key, room_dict=val)
                self.classrooms.append(room)
                self.tabs.addTab(room, key)

    def save(self):
        classrooms = OrderedDict()
        for i in range(self.tabs.count()):
            room = self.tabs.widget(i)
            classrooms[room.title] = room.get_room_dict()
        json_data = json.dumps(classrooms, indent=4)
        with open(Actuasim.save_filename, 'w') as f:
            f.write(json_data)

    def load(self):
        if os.path.isfile(Actuasim.save_filename):
            with open(Actuasim.save_filename, 'r') as f:
                json_data = f.read()
            self.load_rooms(json_data)
            return True
        else:
            m = "{0} not found".format(Actuasim.save_filename)
            print(m)
            logging.error(m)
            return False

    def load_room_template(self):
        template = """
                    {
                        "room 1": {
                            "blinds": [
                                {
                                    "value": 19,
                                    "address": "1.0.0@1/4/1"
                                },
                                {
                                    "value": 19,
                                    "address": "1.0.1@1/4/2"
                                }
                            ],
                            "valves": [
                                {
                                    "value": 19,
                                    "address": "1.0.2@0/4/1"
                                },
                                {
                                    "value": 19,
                                    "address": "1.0.3@0/4/2"
                                }
                            ]
                        },
                        "room 2": {
                            "blinds": [
                                {
                                    "value": 19,
                                    "address": "2.0.0@1/4/10"
                                },
                                {
                                    "value": 19,
                                    "address": "2.0.1@1/4/11"
                                }
                            ],
                            "valves": [
                                {
                                    "value": 19,
                                    "address": "2.0.2@0/4/10"
                                },
                                {
                                    "value": 19,
                                    "address": "2.0.3@0/4/11"
                                }
                            ]
                        }
                    }
                """
        self.load_rooms(template)

    def frame_received(self, frame):
        self.logger.info('Frame received:' + str([hex(h) for h in frame[0]]))
        decoded_frame = knxnet.decode_frame(frame[0])
        if decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.CONNECTION_REQUEST:
            self.logger.info('= Connection request:\n' + str(decoded_frame))
            conn_resp = knxnet.create_frame(
                knxnet.ServiceTypeDescriptor.CONNECTION_RESPONSE,
                self.channel_id, self.status, self.data_endpoint)
            self.knxserver.send(conn_resp.frame)
            self.logger.info('Frame sent:' + repr(conn_resp))
            self.logger.info('= Connection response:\n' + str(conn_resp))
        elif decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.CONNECTION_STATE_REQUEST:
            self.logger.info('= Connection state request:\n' +
                             str(decoded_frame))
            conn_state_resp = knxnet.create_frame(
                knxnet.ServiceTypeDescriptor.CONNECTION_STATE_RESPONSE,
                self.channel_id, self.status)
            self.knxserver.send(conn_state_resp.frame)
            self.logger.info('Frame sent:' + repr(conn_state_resp))
            self.logger.info('= Connection state response:\n' +
                             str(conn_state_resp))
        elif decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.DISCONNECT_REQUEST:
            self.logger.info('= Disconnect request:\n' + str(decoded_frame))
            disconnect_resp = knxnet.create_frame(
                knxnet.ServiceTypeDescriptor.DISCONNECT_RESPONSE,
                self.channel_id, self.status)
            self.knxserver.send(disconnect_resp.frame)
            self.logger.info('Frame sent:' + repr(disconnect_resp))
            self.logger.info('= Disconnect response:\n' + str(disconnect_resp))
        elif decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.TUNNELLING_REQUEST:
            self.logger.info('= Tunnelling request:\n' + str(decoded_frame))
            self.tunnel_req_data_response = self.command_handler.handle_tunnelling_request(
                decoded_frame)
            tunnel_ack = knxnet.create_frame(
                knxnet.ServiceTypeDescriptor.TUNNELLING_ACK, self.channel_id,
                self.status, decoded_frame.sequence_counter)
            self.knxserver.send(tunnel_ack.frame)
            self.logger.info('Frame sent:' + repr(tunnel_ack))
            self.logger.info('= Tunnelling ack:\n' + str(tunnel_ack))

            # after sending our tunnelling ack
            # we must send a tunnelling request to confirm the data
            data_service = 0x2e
            sequence_counter = 0
            tunnel_req_confirm = knxnet.create_frame(
                knxnet.ServiceTypeDescriptor.TUNNELLING_REQUEST,
                decoded_frame.dest_addr_group, decoded_frame.channel_id,
                decoded_frame.data, decoded_frame.data_size,
                decoded_frame.apci, data_service, sequence_counter)
            self.knxserver.send(tunnel_req_confirm.frame)
            self.logger.info('Frame sent:' + repr(tunnel_req_confirm))
            self.logger.info('= Tunnelling ack:\n' + str(tunnel_req_confirm))

        elif decoded_frame.header.service_type_descriptor == knxnet.ServiceTypeDescriptor.TUNNELLING_ACK:
            self.logger.info('= Tunnelling ack:\n' + str(decoded_frame))
            # Do we have a response to send?
            if self.tunnel_req_data_response:
                self.knxserver.send(self.tunnel_req_data_response.frame)
                self.logger.info('Frame sent:' +
                                 repr(self.tunnel_req_data_response))
                self.logger.info('= Tunnelling request:\n' +
                                 str(self.tunnel_req_data_response))
                self.tunnel_req_data_response = None

        else:
            self.logger.info('The frame is not supported')

    def closeEvent(self, QCloseEvent):
        self.knxserver.close_server()
        self.save()
        self.logger.info('=======================================')
        self.logger.info('    *****   ACTUASIM STOP   *****')
        self.logger.info('=======================================')

    def _clean_rooms(self):
        for i in range(len(self.tabs)):
            self.tabs.removeTab(0)
        for room in self.classrooms:
            room.deleteLater()
        self.classrooms = []