def _SetHoldingRegistersOverlay(self, addr, qty, data): """Same as SetHoldingRegisters, except for register overlay option. The coils appear to be packed into holding registers 0 to 4095. """ if (addr > 4095): self._SetHoldingRegisters(addr, qty, data) else: binstr = ModbusDataStrLib.swapbytes(data) self._Coils[addr * 16 : (addr + qty) * 16] = ModbusDataStrLib.bin2boollist(binstr)[:qty * 16]
def _GetHoldingRegistersOverlay(self, addr, qty): """Same as GetHoldingRegisters, except for register overlay option. The coils appear to be packed into holding registers 0 to 4095. """ if (addr > 4095): return self._GetHoldingRegisters(addr, qty) else: binstr = ModbusDataStrLib.boollist2bin(self._Coils[addr * 16 : (addr + qty) * 16]) return ModbusDataStrLib.swapbytes(binstr)
def _GetInputRegistersOverlay(self, addr, qty): """Same as GetInputRegisters, except for register overlay option. The discrete inputs appear to be packed into input registers 0 to 4095. """ if (addr > 4095): return self._GetInputRegisters(addr, qty) else: binstr = ModbusDataStrLib.boollist2bin(self._DiscInputs[addr * 16 : (addr + qty) * 16]) return ModbusDataStrLib.swapbytes(binstr)
def _SetInputRegistersOverlay(self, addr, qty, data): """Same as SetInputRegisters, except for register overlay option. The discrete inputs appear to be packed into input registers 0 to 4095. """ if (addr > 4095): self._SetInputRegisters(addr, qty, data) else: binstr = ModbusDataStrLib.swapbytes(data) self._DiscInputs[addr * 16 : (addr + qty) * 16] = ModbusDataStrLib.bin2boollist(binstr)[:qty * 16]
def _GetInputRegistersOverlay(self, addr, qty): """Same as GetInputRegisters, except for register overlay option. The discrete inputs appear to be packed into input registers 0 to 4095. """ if (addr > 4095): return self._GetInputRegisters(addr, qty) else: binstr = ModbusDataStrLib.boollist2bin( self._DiscInputs[addr * 16:(addr + qty) * 16]) return ModbusDataStrLib.swapbytes(binstr)
def _SetHoldingRegistersOverlay(self, addr, qty, data): """Same as SetHoldingRegisters, except for register overlay option. The coils appear to be packed into holding registers 0 to 4095. """ if (addr > 4095): self._SetHoldingRegisters(addr, qty, data) else: binstr = ModbusDataStrLib.swapbytes(data) self._Coils[addr * 16:(addr + qty) * 16] = ModbusDataStrLib.bin2boollist(binstr)[:qty * 16]
def _GetHoldingRegistersOverlay(self, addr, qty): """Same as GetHoldingRegisters, except for register overlay option. The coils appear to be packed into holding registers 0 to 4095. """ if (addr > 4095): return self._GetHoldingRegisters(addr, qty) else: binstr = ModbusDataStrLib.boollist2bin( self._Coils[addr * 16:(addr + qty) * 16]) return ModbusDataStrLib.swapbytes(binstr)
def _SetInputRegistersOverlay(self, addr, qty, data): """Same as SetInputRegisters, except for register overlay option. The discrete inputs appear to be packed into input registers 0 to 4095. """ if (addr > 4095): self._SetInputRegisters(addr, qty, data) else: binstr = ModbusDataStrLib.swapbytes(data) self._DiscInputs[addr * 16:(addr + qty) * 16] = ModbusDataStrLib.bin2boollist(binstr)[:qty * 16]
def SetCoils(self, addr, qty, data): """Store the data in a packed binary string to the coils. addr (integer) - Coil address. qty (integer) - Number of coils to set. data (packed binary string) - Data. """ self._Coils[addr : addr + qty] = ModbusDataStrLib.bin2boollist(data)[:qty]
def _SetInputRegisters(self, addr, qty, data): """Store the data in a packed binary string to the input registers. addr (integer) - Input register address. qty (integer) - Number of input registers to set. data (packed binary string) - Data. """ self._InputRegs[addr : addr + qty] = ModbusDataStrLib.signedbin2intlist(data)[:qty]
def _GetInputRegisters(self, addr, qty): """Return qty input register values as a packed binary string. addr (integer) - Input register address. qty (integer) - Number of input registers desired. Returns a packed binary string. """ return ModbusDataStrLib.signedintlist2bin(self._InputRegs[addr : addr + qty])
def SetDiscreteInputs(self, addr, qty, data): """"Store the data in a packed binary string to the discrete inputs. addr (integer) - Discrete input address. qty (integer) - Number of discrete inputs to set. data (packed binary string) - Data. """ self._DiscInputs[addr : addr + qty] = ModbusDataStrLib.bin2boollist(data)[:qty]
def _SetInputRegisters(self, addr, qty, data): """Store the data in a packed binary string to the input registers. addr (integer) - Input register address. qty (integer) - Number of input registers to set. data (packed binary string) - Data. """ self._InputRegs[addr:addr + qty] = ModbusDataStrLib.signedbin2intlist(data)[:qty]
def _GetInputRegisters(self, addr, qty): """Return qty input register values as a packed binary string. addr (integer) - Input register address. qty (integer) - Number of input registers desired. Returns a packed binary string. """ return ModbusDataStrLib.signedintlist2bin(self._InputRegs[addr:addr + qty])
def SetDiscreteInputs(self, addr, qty, data): """"Store the data in a packed binary string to the discrete inputs. addr (integer) - Discrete input address. qty (integer) - Number of discrete inputs to set. data (packed binary string) - Data. """ self._DiscInputs[addr:addr + qty] = ModbusDataStrLib.bin2boollist(data)[:qty]
def SetCoils(self, addr, qty, data): """Store the data in a packed binary string to the coils. addr (integer) - Coil address. qty (integer) - Number of coils to set. data (packed binary string) - Data. """ self._Coils[addr:addr + qty] = ModbusDataStrLib.bin2boollist(data)[:qty]
def GetCoils(self, addr, qty): """Return qty coil values as a packed binary string. If qty is not a multiple of 8, the remainder of the string will be padded with zeros. addr (integer) - Coil address. qty (integer) - Number of coils desired. Returns a packed binary string. """ return ModbusDataStrLib.boollist2bin(self._Coils[addr:addr + qty])
def GetDiscreteInputs(self, addr, qty): """Return qty discrete input values as a packed binary string. If qty is not a multiple of 8, the remainder of the string will be padded with zeros. addr (integer) - Discrete input address. qty (integer) - Number of discrete inputs desired. Returns a packed binary string. """ return ModbusDataStrLib.boollist2bin(self._DiscInputs[addr:addr + qty])
def GetCoils(self, addr, qty): """Return qty coil values as a packed binary string. If qty is not a multiple of 8, the remainder of the string will be padded with zeros. addr (integer) - Coil address. qty (integer) - Number of coils desired. Returns a packed binary string. """ return ModbusDataStrLib.boollist2bin(self._Coils[addr : addr + qty])
def GetDiscreteInputs(self, addr, qty): """Return qty discrete input values as a packed binary string. If qty is not a multiple of 8, the remainder of the string will be padded with zeros. addr (integer) - Discrete input address. qty (integer) - Number of discrete inputs desired. Returns a packed binary string. """ return ModbusDataStrLib.boollist2bin(self._DiscInputs[addr : addr + qty])
def MBPostRequest(self, Func, Addr, Qty, TID, UID, Message): # Check the parameters which represent the URL string. FunctionCode, Address, Quantity, TransID, UnitID = self._ValidateURLParams(Func, Addr, Qty, TID, UID) # Check if the values could be read without error. if ((FunctionCode == None) or (Address == None) or (Quantity == None) or (TransID == None) or (UnitID == None)): # Set some initial default values for these. TransID = -1 UnitID = -1 FunctionCode = 0 Address = 0 data = '0000' exceptioncode = 0 return TransID, UnitID, FunctionCode, Address, data, exceptioncode # Try to parse the XML message to get just the data portion of the message. XMLParser = RestXMLParser() if XMLParser.ParseRequest(Message): MsgData = XMLParser.GetMsgData() else: MsgData = '' # At this point, the parameters have all be checked to see if they can be used. # Now validate the data according to the requirements of each function. if (FunctionCode == 5): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Check if request data is valid. if MsgData not in ('0000', 'ff00', 'fF00', 'Ff00', 'FF00'): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, MsgData, exceptioncode elif (FunctionCode == 6): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Check if message length is OK. if (len(MsgData) != 4): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. else: # Try to convert to binary string. If no good, then # the string is not valid hexadecimal data. try: temp = ModbusDataStrLib.hex2bin(MsgData) except: FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, MsgData, exceptioncode elif (FunctionCode == 15): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Qty of outputs is out of range. elif ((Quantity < 1) or (Quantity > self._protocollimits[FunctionCode])): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty for coils exceeds the amount of data sent. elif (Quantity > len(MsgData)): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty for coils is less than the amount of data sent. elif (Quantity < (len(MsgData) - 8)): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty for coils exceeds amount of data sent. # Try to convert to binary string. If no good, then # the string is not valid hexadecimal data. # Length must also be a multiple of 8. else: try: temp = ModbusDataStrLib.bininversor(MsgData) except: FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, (Quantity, MsgData), exceptioncode elif (FunctionCode == 16): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Qty of registers is out of range. elif ((Quantity < 1) or (Quantity > self._protocollimits[FunctionCode])): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty does not match the amount of data sent. elif ((Quantity * 4) != len(MsgData)): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Check if message length is OK. Length must be a multiple of 4. elif ((len(MsgData) % 4) != 0): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. else: # Try to convert to binary string. If no good, then # the string is not valid hexadecimal data. try: temp = ModbusDataStrLib.hex2bin(MsgData) except: FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, (Quantity, MsgData), exceptioncode # Function code is not supported. else: # This error code needs special treatment in case of bad function # codes that are very large. FunctionCode = (FunctionCode & 0xff) | 0x80 # Create error code. exceptioncode = 1 # Exception code. return TransID, UnitID, FunctionCode, 0, '0000', exceptioncode
def MBPostRequest(self, Func, Addr, Qty, TID, UID, Message): # Check the parameters which represent the URL string. FunctionCode, Address, Quantity, TransID, UnitID = self._ValidateURLParams( Func, Addr, Qty, TID, UID) # Check if the values could be read without error. if ((FunctionCode == None) or (Address == None) or (Quantity == None) or (TransID == None) or (UnitID == None)): # Set some initial default values for these. TransID = -1 UnitID = -1 FunctionCode = 0 Address = 0 data = '0000' exceptioncode = 0 return TransID, UnitID, FunctionCode, Address, data, exceptioncode # Try to parse the XML message to get just the data portion of the message. XMLParser = RestXMLParser() if XMLParser.ParseRequest(Message): MsgData = XMLParser.GetMsgData() else: MsgData = '' # At this point, the parameters have all be checked to see if they can be used. # Now validate the data according to the requirements of each function. if (FunctionCode == 5): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Check if request data is valid. if MsgData not in ('0000', 'ff00', 'fF00', 'Ff00', 'FF00'): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, MsgData, exceptioncode elif (FunctionCode == 6): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Check if message length is OK. if (len(MsgData) != 4): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. else: # Try to convert to binary string. If no good, then # the string is not valid hexadecimal data. try: temp = ModbusDataStrLib.hex2bin(MsgData) except: FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, MsgData, exceptioncode elif (FunctionCode == 15): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Qty of outputs is out of range. elif ((Quantity < 1) or (Quantity > self._protocollimits[FunctionCode])): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty for coils exceeds the amount of data sent. elif (Quantity > len(MsgData)): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty for coils is less than the amount of data sent. elif (Quantity < (len(MsgData) - 8)): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty for coils exceeds amount of data sent. # Try to convert to binary string. If no good, then # the string is not valid hexadecimal data. # Length must also be a multiple of 8. else: try: temp = ModbusDataStrLib.bininversor(MsgData) except: FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, ( Quantity, MsgData), exceptioncode elif (FunctionCode == 16): exceptioncode = 0 # Default exception code. # Check for address limits. if not self._AddrLimitsOK(Address, Quantity, FunctionCode): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 2 # Exception code. # Qty of registers is out of range. elif ((Quantity < 1) or (Quantity > self._protocollimits[FunctionCode])): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Qty does not match the amount of data sent. elif ((Quantity * 4) != len(MsgData)): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. # Check if message length is OK. Length must be a multiple of 4. elif ((len(MsgData) % 4) != 0): FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. else: # Try to convert to binary string. If no good, then # the string is not valid hexadecimal data. try: temp = ModbusDataStrLib.hex2bin(MsgData) except: FunctionCode = FunctionCode + 128 # Create error code. exceptioncode = 3 # Exception code. return TransID, UnitID, FunctionCode, Address, ( Quantity, MsgData), exceptioncode # Function code is not supported. else: # This error code needs special treatment in case of bad function # codes that are very large. FunctionCode = (FunctionCode & 0xff) | 0x80 # Create error code. exceptioncode = 1 # Exception code. return TransID, UnitID, FunctionCode, 0, '0000', exceptioncode