def add_block(self, block_name, block_type, starting_address, size): """Add a new block identified by its name""" with self._data_lock: # thread-safe if size <= 0: raise InvalidArgumentError("size must be a positive number") if starting_address < 0: raise InvalidArgumentError( "starting address must be zero or positive number") if block_name in self._blocks: raise DuplicatedKeyError("Block %s already exists. " % block_name) if block_type not in self._memory: raise InvalidModbusBlockError("Invalid block type %d" % block_type) # check that the new block doesn't overlap an existing block # it means that only 1 block per type must correspond to a given address # for example: it must not have 2 holding registers at address 100 index = 0 for i in xrange(len(self._memory[block_type])): block = self._memory[block_type][i] if block.is_in(starting_address, size): raise OverlapModbusBlockError, "Overlap block at %d size %d" % ( block.starting_address, block.size) if block.starting_address > starting_address: index = i break # if the block is ok: register it self._blocks[block_name] = (block_type, starting_address) # add it in the 'per type' shortcut self._memory[block_type].insert( index, ModbusBlockDatabusMediator(block_name, starting_address))
def build_request(self, pdu, slave): """Add the Modbus RTU part to the request""" self._request_address = slave if (self._request_address < 0) or (self._request_address > 255): raise InvalidArgumentError("Invalid address {0}".format(self._request_address)) data = struct.pack(">B", self._request_address) + pdu crc = struct.pack(">H", utils.calculate_crc(data)) return data + crc
def build_request(self, pdu, slave): """Add the Modbus TCP part to the request""" if (slave < 0) or (slave > 255): raise InvalidArgumentError("{0} Invalid value for slave id".format(slave)) self._request_mbap.length = len(pdu) + 1 self._request_mbap.transaction_id = self._get_transaction_id() self._request_mbap.unit_id = slave mbap = self._request_mbap.pack() return mbap + pdu