Пример #1
0
    def do_command(self, cmd, fields=None, timeout=2, extended_crc=False):
        # type: (MasterCommandSpec, Optional[Dict[str,Any]], Union[T_co, int], bool) -> Union[T_co, Dict[str, Any]]
        """
        Send a command over the serial port and block until an answer is received.
        If the master does not respond within the timeout period, a CommunicationTimedOutException
        is raised

        :param cmd: specification of the command to execute
        :param fields: an instance of one of the available fields
        :param timeout: maximum allowed time before a CommunicationTimedOutException is raised
        :param extended_crc: indicates whether to include the action in the CRC
        :returns: dict containing the output fields of the command
        """
        if self.__maintenance_mode:
            raise InMaintenanceModeException()

        if fields is None:
            fields = dict()

        cid = self.__get_cid()
        consumer = Consumer(cmd, cid)
        inp = cmd.create_input(cid, fields, extended_crc)

        with self.__command_lock:
            self.__command_total_histogram.update({str(cmd.action): 1})
            self.__consumers.append(consumer)
            self.__write_to_serial(inp)
            try:
                result = consumer.get(timeout).fields
                if cmd.output_has_crc() and not MasterCommunicator.__check_crc(
                        cmd, result, extended_crc):
                    raise CrcCheckFailedException()
                else:
                    self.__last_success = time.time()
                    self.__communication_stats['calls_succeeded'].append(
                        time.time())
                    self.__communication_stats[
                        'calls_succeeded'] = self.__communication_stats[
                            'calls_succeeded'][-50:]
                    self.__command_success_histogram.update(
                        {str(cmd.action): 1})
                    return result
            except CommunicationTimedOutException:
                if cmd.action != bytearray(b'FV'):
                    # The FV instruction is a direct call to the Slave module. Older versions did not implement this
                    # call, so this call can timeout while it's expected. We don't take those into account.
                    self.__communication_stats['calls_timedout'].append(
                        time.time())
                    self.__communication_stats[
                        'calls_timedout'] = self.__communication_stats[
                            'calls_timedout'][-50:]
                self.__command_timeout_histogram.update({str(cmd.action): 1})
                raise
Пример #2
0
    def start_maintenance_mode(self):
        """ Start maintenance mode.

        :raises: :class`InMaintenanceModeException` if master is in maintenance mode.
        """
        if self.__maintenance_mode:
            raise InMaintenanceModeException()

        while True:
            try:
                self.__maintenance_queue.get(block=False)
            except Empty:
                break

        self.__maintenance_mode = True
        self.send_maintenance_data(master_api.to_cli_mode().create_input(0))
Пример #3
0
    def send_passthrough_data(self, data):
        """ Send raw data on the serial port.

        :param data: string of bytes with raw command for the master.
        :raises: :class`InMaintenanceModeException` if master is in maintenance mode.
        """
        if self.__maintenance_mode:
            raise InMaintenanceModeException()

        if not self.__passthrough_mode:
            self.__command_lock.acquire()
            self.__passthrough_done.clear()
            self.__passthrough_mode = True
            passthrough_thread = BaseThread(name='passthroughwait', target=self.__passthrough_wait)
            passthrough_thread.daemon = True
            passthrough_thread.start()

        self.__write_to_serial(data)
Пример #4
0
 def update_mode_start(self):
     # type: () -> None
     if self.__maintenance_mode:
         raise InMaintenanceModeException()
     self.__update_mode = True