コード例 #1
0
    def __init__(self, host, port, timeout, stnaddr=1):
        """
        host (string) = IP address of server.
        port (integer) = Port for server.
        timeout (float) = Time out in seconds.
        stnaddr (integer) = The desired SBus station address.
        """
        self._host = host
        self._port = port
        self._timeout = timeout
        self._stnaddr = stnaddr
        self._msgsequence = 1

        # Define the boolean values for 0 and 1.
        self._bitoff = ModbusDataStrLib.boollist2bin(
            [False, False, False, False, False, False, False, False])
        self._biton = ModbusDataStrLib.boollist2bin(
            [True, False, False, False, False, False, False, False])

        # Initialise the client connection.
        try:
            self._msg = SBusSimpleClient.SBusSimpleClient(
                self._host, self._port, self._timeout)
        except:
            self._msg = None
            print((_ErrorMsgs['connnecterror']))
            # Raise the exception again so the next layer can deal with it.
            raise
コード例 #2
0
    def _handle(self):
        ReceivedData = self.rfile.read()

        if ReceivedData:

            # Decode message.
            try:
                (TelegramAttr, MsgSequence, StnAddr, CmdCode, DataAddr,
                 DataCount, MsgData,
                 MsgResult) = SBServerMsg.SBRequest(ReceivedData)
            # We can't decode this message at all, so just drop the request and stop here.
            # Can't decode the message, because the length is invalid.
            except SBusMsg.MessageLengthError:
                print('Server %d - Invalid message length. %s' %
                      (CmdOpts.GetPort(), time.ctime()))
                MsgResult = False
                MsgSequence = 0
            # Message had a CRC error.
            except SBusMsg.CRCError:
                print('Server %d - Bad CRC. %s' %
                      (CmdOpts.GetPort(), time.ctime()))
                MsgResult = False
                MsgSequence = 0
            # All other errors.
            except:
                print('Server %d - Request could not be decoded. %s' %
                      (CmdOpts.GetPort(), time.ctime()))
                MsgResult = False
                MsgSequence = 0

            ReplyData = ''

            # Handle the command, but only if know the parameters are valid.
            if (MsgResult):
                # Decode messages. If we get an error in reading/writing memory or
                # in constructing messages, we will consider this to be an SBus error.
                try:
                    # Read Flags.
                    if CmdCode == 2:
                        MemData = MemMap.GetFlags(DataAddr, DataCount)
                        MsgData = ModbusDataStrLib.boollist2bin(MemData)
                        ReplyData = SBServerMsg.SBResponse(
                            MsgSequence, CmdCode, 0, MsgData)

                    # Read Inputs
                    elif CmdCode == 3:
                        MemData = MemMap.GetInputs(DataAddr, DataCount)
                        MsgData = ModbusDataStrLib.boollist2bin(MemData)
                        ReplyData = SBServerMsg.SBResponse(
                            MsgSequence, CmdCode, 0, MsgData)

                    # Read Outputs
                    elif CmdCode == 5:
                        MemData = MemMap.GetOutputs(DataAddr, DataCount)
                        MsgData = ModbusDataStrLib.boollist2bin(MemData)
                        ReplyData = SBServerMsg.SBResponse(
                            MsgSequence, CmdCode, 0, MsgData)

                    # Read Registers
                    elif CmdCode == 6:
                        MemData = MemMap.GetRegisters(DataAddr, DataCount)
                        MsgData = SBusMsg.signedint32list2bin(MemData)
                        ReplyData = SBServerMsg.SBResponse(
                            MsgSequence, CmdCode, 0, MsgData)

                    # Write flags
                    elif CmdCode == 11:
                        MemData = ModbusDataStrLib.bin2boollist(MsgData)
                        MemMap.SetFlags(DataAddr, DataCount, MemData)
                        ReplyData = SBServerMsg.SBResponse(
                            MsgSequence, CmdCode, 0, '')

                    # Write outputs
                    elif CmdCode == 13:
                        MemData = ModbusDataStrLib.bin2boollist(MsgData)
                        MemMap.SetOutputs(DataAddr, DataCount, MemData)
                        ReplyData = SBServerMsg.SBResponse(
                            MsgSequence, CmdCode, 0, '')

                    # Write Registers
                    elif CmdCode == 14:
                        MemData = SBusMsg.signedbin2int32list(MsgData)
                        MemMap.SetRegisters(DataAddr, DataCount, MemData)
                        ReplyData = SBServerMsg.SBResponse(
                            MsgSequence, CmdCode, 0, '')

                    # We don't understand this command code.
                    else:
                        print('Server %d - Unsupported command code' %
                              CmdOpts.GetPort())
                        ReplyData = SBServerMsg.SBErrorResponse(MsgSequence)

                # We don't understand this message.
                except:
                    ReplyData = SBServerMsg.SBErrorResponse(MsgSequence)

            # The message was bad, so we return a NAK response.
            else:
                ReplyData = SBServerMsg.SBErrorResponse(MsgSequence)

            # Send the reply.
            try:
                self.wfile.write(ReplyData)
            except:
                # If we have an error here, there's not much we can do about it.
                print('Server %d - Could not reply to request. %s' %
                      (CmdOpts.GetPort(), time.ctime()))
コード例 #3
0
    def Request(self, cmdcode, dataaddr, data=None):
        """Read data from an address.
        Parameters: cmdcode (integer) = SBus command code.
            dataaddr (integer) = SBus address.
            data (integer) = Data to be written (optional).
        Returns: (tuple) = If OK, returns True plus the received data.
            If error, returns False plus an error message.
        """

        # Increment the transaction id.
        self._IncMsgSeq()

        # Only request one at a time.
        datacount = 1
        sendata = None

        # Only the following command codes are supported.
        if (cmdcode not in [2, 3, 5, 6, 11, 13, 14]):
            return False, _ErrorMsgs['badcmdcode']

        # Check if the SBus address is legal. This does not guaranty though
        # that it will be supported in the field device.
        if (dataaddr < 0) or (dataaddr > 65535):
            return False, _ErrorMsgs['invalidaddress']

        # If we are writing data, make sure it is valid.
        if cmdcode in [11, 13, 14]:
            try:
                dataint = int(data)
            except:
                return False, _ErrorMsgs['dataerr']

        # For writing data, convert the data to a binary string,
        # and check if it is within range for that function.
        if (cmdcode in (11, 13)):
            if (dataint == 0):
                sendata = self._bitoff
            elif (dataint == 1):
                sendata = self._biton
            else:
                return False, _ErrorMsgs['dataerr']
        elif (cmdcode == 14):
            if ((dataint >= -2147483648) and (dataint <= 2147483647)):
                sendata = SBusMsg.signedint32list2bin([data])
            else:
                return False, _ErrorMsgs['dataerr']

        # Send the request.
        try:
            self._msg.SendRequest(self._msgsequence, self._stnaddr, cmdcode,
                                  datacount, dataaddr, sendata)
        # Something was wrong with the parameters we gave it to send.
        # This should have been caught earlier.
        except SBusMsg.ParamError:
            return False, _ErrorMsgs['invalidparam']
        # Some other error occured while sending.
        except:
            return False, _ErrorMsgs['connnecterror']

        # Receive the response.
        try:
            telegramattr, recv_msgsequence, recv_msgdata = self._msg.ReceiveResponse(
            )
        # The message length did not match any valid message type.
        except SBusMsg.MessageLengthError:
            return False, _ErrorMsgs['responselength']
        # The message CRC was bad.
        except SBusMsg.CRCError:
            return False, _ErrorMsgs['crcerr']
        # Some other error occured while receiving.
        except:
            return False, _ErrorMsgs['connnecterror']

        # Look at the telegrapm attribute to see what sort of response
        # it was, and compare that to the command code.

        # If it was a 1, we expect some data from a read operation.
        if (telegramattr == 1):
            # Decode the data by command code.
            if (cmdcode in (2, 3, 5)):
                rdata = int(ModbusDataStrLib.bin2boollist(recv_msgdata)[0])
            elif (cmdcode == 6):
                rdata = SBusMsg.signedbin2int32list(recv_msgdata)[0]
        # This was an ack from a write operation, or it was a NAK.
        elif (telegramattr == 2):
            acknak = ModbusDataStrLib.signedbin2intlist(recv_msgdata)[0]
            # This is an ACK from a write operation
            if (acknak == 0) and (cmdcode in (11, 13, 14)):
                return True, ''
            else:
                return False, _ErrorMsgs['deviceerror']
        # We have an invalid telegram.
        else:
            return False, _ErrorMsgs['badmessage']

        return True, rdata
コード例 #4
0
    def handle_read(self):

        try:
            ReceivedData = self.recv(8192)
        except:
            ReceivedData = None

        if ReceivedData:

            if ShutDownCommand and (ReceivedData == ShutDownCommand):
                print('Shutdown command received by server %d. %s' %
                      (CmdOpts.GetPort(), time.ctime()))
                self.close()
                raise asyncore.ExitNow

            # Decode message. 'RequestData' may mean either number of coils or sent data, depending
            # upon the function code being received. For functions 15 and 16, it is a tuple containing
            # data and quantity.
            try:
                TransID, UnitID, FunctionCode, Start, RequestData, ExceptionCode = \
                 MBServerMSg.MBRequest(ReceivedData)
            except:
                FunctionCode = 0
                TransID = 0
                UnitID = 0
                Start = 0

            ReplyData = ''
            # Decode messages. If we get an error in reading/writing memory or in constructing messages,
            # we will consider this to be a Modbus exception.
            try:
                if FunctionCode == 1:  # Read coils.	RequestData = quantity.
                    MsgData = MemMap.GetCoils(Start, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 2:  # Read discrete inputs.	RequestData = quantity.
                    MsgData = MemMap.GetDiscreteInputs(Start, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 3:  # Read holding registers. RequestData = quantity.
                    MsgData = MemMap.GetHoldingRegisters(Start, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 4:  # Read input registers.	RequestData = quantity.
                    MsgData = MemMap.GetInputRegisters(Start, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 5:  # Write single coil. RequestData contains data.
                    MemMap.SetCoils(Start, 1, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       RequestData)

                elif FunctionCode == 6:  # Write single holding register. RequestData contains data.
                    MemMap.SetHoldingRegisters(Start, 1, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       RequestData)

                elif FunctionCode == 15:  # Write multiple coils.	RequestData is a tuple.
                    MemMap.SetCoils(Start, RequestData[0], RequestData[1])
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID, FunctionCode, \
                     Start, ModbusDataStrLib.Int2BinStr(RequestData[0]))

                elif FunctionCode == 16:  # Write multiple holding registers. RequestData is a tuple.
                    MemMap.SetHoldingRegisters(Start, RequestData[0],
                                               RequestData[1])
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID, FunctionCode, \
                     Start, ModbusDataStrLib.Int2BinStr(RequestData[0]))

                elif FunctionCode > 127:  # Modbus exception.
                    ReplyData = MBServerMSg.MBErrorResponse(
                        TransID, UnitID, FunctionCode, ExceptionCode)
                else:
                    print('Server %d - Unsupported function call' %
                          CmdOpts.GetPort())
                    ReplyData = MBServerMSg.MBErrorResponse(
                        TransID, UnitID, FunctionCode + 128, 1)

            except:
                # Modbus exception 4. An error has occured in reading or writing a memory location.
                ReplyData = MBServerMSg.MBErrorResponse(
                    TransID, UnitID, FunctionCode + 128, 4)

            # Send the reply.
            try:
                self.send(ReplyData)
            except:
                # If we have an error here, there's not much we can do about it.
                print('Server %d - Could not reply to request.' %
                      CmdOpts.GetPort())

        else:
            self.close()
コード例 #5
0
	def handle(self):
		ReceivedData = self.rfile.read()

		if ReceivedData: 

			# Decode message. 
			try:
				(TelegramAttr, MsgSequence, StnAddr, CmdCode, DataAddr, 
					DataCount, MsgData, MsgResult) = SBServerMsg.SBRequest(ReceivedData)
			# We can't decode this message at all, so just drop the request and stop here.
			# Can't decode the message, because the length is invalid.
			except SBusMsg.MessageLengthError:
				print('Server %d - Invalid message length. %s' % (CmdOpts.GetPort(), time.ctime()))
				MsgResult = False
				MsgSequence = 0
			# Message had a CRC error.
			except SBusMsg.CRCError:
				print('Server %d - Bad CRC. %s' % (CmdOpts.GetPort(), time.ctime()))
				MsgResult = False
				MsgSequence = 0
			# All other errors.
			except:
				print('Server %d - Request could not be decoded. %s' % (CmdOpts.GetPort(), time.ctime()))
				MsgResult = False
				MsgSequence = 0

			ReplyData = ''

			# Handle the command, but only if know the parameters are valid.
			if (MsgResult):
				# Decode messages. If we get an error in reading/writing memory or 
				# in constructing messages, we will consider this to be an SBus error.
				try:
					# Read Flags.
					if CmdCode == 2:
						MemData = MemMap.GetFlags(DataAddr, DataCount)
						MsgData = ModbusDataStrLib.boollist2bin(MemData)
						ReplyData = SBServerMsg.SBResponse(MsgSequence, CmdCode, 0, MsgData)

					# Read Inputs
					elif CmdCode == 3:
						MemData = MemMap.GetInputs(DataAddr, DataCount)
						MsgData = ModbusDataStrLib.boollist2bin(MemData)
						ReplyData = SBServerMsg.SBResponse(MsgSequence, CmdCode, 0, MsgData)

					# Read Outputs
					elif CmdCode == 5:
						MemData = MemMap.GetOutputs(DataAddr, DataCount)
						MsgData = ModbusDataStrLib.boollist2bin(MemData)
						ReplyData = SBServerMsg.SBResponse(MsgSequence, CmdCode, 0, MsgData)

					# Read Registers
					elif CmdCode == 6:
						MemData = MemMap.GetRegisters(DataAddr, DataCount)
						MsgData = SBusMsg.signedint32list2bin(MemData)
						ReplyData = SBServerMsg.SBResponse(MsgSequence, CmdCode, 0, MsgData)

					# Write flags
					elif CmdCode == 11:
						MemData = ModbusDataStrLib.bin2boollist(MsgData)
						MemMap.SetFlags(DataAddr, DataCount, MemData)
						ReplyData = SBServerMsg.SBResponse(MsgSequence, CmdCode, 0, '')

					# Write outputs
					elif CmdCode == 13:
						MemData = ModbusDataStrLib.bin2boollist(MsgData)
						MemMap.SetOutputs(DataAddr, DataCount, MemData)
						ReplyData = SBServerMsg.SBResponse(MsgSequence, CmdCode, 0, '')

					# Write Registers
					elif CmdCode == 14:
						MemData = SBusMsg.signedbin2int32list(MsgData)
						MemMap.SetRegisters(DataAddr, DataCount, MemData)
						ReplyData = SBServerMsg.SBResponse(MsgSequence, CmdCode, 0, '')

					# We don't understand this command code.
					else:
						print('Server %d - Unsupported command code' % CmdOpts.GetPort())
						ReplyData = SBServerMsg.SBErrorResponse(MsgSequence)

				# We don't understand this message.
				except:
					ReplyData = SBServerMsg.SBErrorResponse(MsgSequence)

			# The message was bad, so we return a NAK response. 
			else:
				ReplyData = SBServerMsg.SBErrorResponse(MsgSequence)


			# Send the reply.
			try:
				self.wfile.write(ReplyData)
			except:
				# If we have an error here, there's not much we can do about it.
				print('Server %d - Could not reply to request. %s' % (CmdOpts.GetPort(), time.ctime()))
コード例 #6
0
ファイル: pollmb.py プロジェクト: GotAudio/MBLogic-pollmb
SendAddr = int(CharAddr)

# Preset the transaction ID.
SendTransID = 0

CharacterOutput = CmdOpts.GetCharacter()


# If this is a write function, convert the data to binary packed string format.
BinData = '\x00\x00'
try:
	if (SendFunction == 5):
		sendval = int(SendData)
		if sendval in (0, 1):
			BinData = ModbusDataStrLib.coilvalue(int(SendData))
		else:
			print('Invalid data for Modbus Function %d.' % SendFunction)
			sys.exit(4)
	elif (SendFunction == 15):
		BinData = ModbusDataStrLib.bininversor(SendData)
	elif SendFunction in  (6, 16, 66):
		BinData = ModbusDataStrLib.hex2bin(SendData)
	elif SendFunction == 65:
		BinData = '\x00\x00'
	else:
		BinData = '\x00\x00'
except:
	print('Invalid data for modbus function %d.' % SendFunction)
	sys.exit(4)