def change(): #Current address 01 is changed to 09 #01 10 00 00 00 01 02 00 09 66 56 builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) #builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x10) #builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x01) #builder.add_8bit_uint(0x02) #builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x09) #builder.add_8bit_uint(0x01) # Unit ID #builder.add_8bit_uint(0x10) # function ID #builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x00) # coil ID #builder.add_8bit_uint(0x00) # data, here: on #builder.add_8bit_uint(0x01) #builder.add_8bit_uint(0x02) #builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x09) builder.add_8bit_uint(0x01) # Unit ID builder.add_8bit_uint(0x10) # function ID builder.add_8bit_uint(0x00) builder.add_8bit_uint(0x00) # coil ID builder.add_8bit_uint(0x00) # data builder.add_8bit_uint(0x01) builder.add_8bit_uint(0x02) builder.add_8bit_uint(0x00) builder.add_8bit_uint(0x09) builder.build() utils.appendCrc(builder) print('TMP:', builder) #print(computeCRC(str(builder).encode())) #crc = computeCRC(ut.make_byte_string(builder.to_string())) #print(crc) #hexStr = '%04x' % crc #hex1 = int(hexStr[0] + hexStr[1], 16) #hex2 = int(hexStr[2] + hexStr[3], 16) ##print(hex(hex2)) ##builder.add_8bit_uint(0x66) ##builder.add_8bit_uint(0x56) #builder.add_8bit_uint(hex1) #builder.add_8bit_uint(hex2) return builder.build()
def testPayloadBuilderReset(self): ''' Test basic bit message encoding/decoding ''' builder = BinaryPayloadBuilder() builder.add_8bit_uint(0x12) builder.add_8bit_uint(0x34) builder.add_8bit_uint(0x56) builder.add_8bit_uint(0x78) self.assertEqual('\x12\x34\x56\x78', str(builder)) self.assertEqual(['\x12\x34', '\x56\x78'], builder.build()) builder.reset() self.assertEqual('', str(builder)) self.assertEqual([], builder.build())
def testPayloadBuilderReset(self): """ Test basic bit message encoding/decoding """ builder = BinaryPayloadBuilder() builder.add_8bit_uint(0x12) builder.add_8bit_uint(0x34) builder.add_8bit_uint(0x56) builder.add_8bit_uint(0x78) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([b'\x12\x34', b'\x56\x78'], builder.build()) builder.reset() self.assertEqual(b'', builder.to_string()) self.assertEqual([], builder.build())
def testPayloadBuilderReset(self): """ Test basic bit message encoding/decoding """ builder = BinaryPayloadBuilder() builder.add_8bit_uint(0x12) builder.add_8bit_uint(0x34) builder.add_8bit_uint(0x56) builder.add_8bit_uint(0x78) self.assertEqual("\x12\x34\x56\x78", str(builder)) self.assertEqual(["\x12\x34", "\x56\x78"], builder.build()) builder.reset() self.assertEqual("", str(builder)) self.assertEqual([], builder.build())
def encode_field(self, value, mb_type='unit16'): builder = BinaryPayloadBuilder(endian=self.endian) if mb_type == 'bit' or mb_type == 'bits': builder.add_bits(value) elif mb_type == 'uint8': builder.add_8bit_uint(value) elif mb_type == 'uint16': builder.add_16bit_uint(value) elif mb_type == 'uint32': builder.add_32bit_uint(value) elif mb_type == 'uint64': builder.add_64bit_uint(value) elif mb_type == 'int8': builder.add_8bit_int(value) elif mb_type == 'int16': builder.add_16bit_int(value) elif mb_type == 'int32': builder.add_32bit_int(value) elif mb_type == 'int64': builder.add_64bit_int(value) elif mb_type == 'float32': builder.add_32bit_float(value) elif mb_type == 'float64': builder.add_64bit_float(value) elif mb_type == 'string' or mb_type == 'str': builder.add_string(value) else: log.warn('Not supported DataType: "%s"' % mb_type) return builder.build()
def write_registers(self, key): point = self.point_dict.get(key[2:]) if point: value = conpot_core.get_databus().get_value(key) if not point.encoding == 'none': endian = Endian.Auto if point.endian == 'Little': endian = Endian.Little elif point.endian == 'Big': endian = Endian.Big builder = BinaryPayloadBuilder(endian=endian) builder_map = {'bits': builder.add_bits, '8unit': builder.add_8bit_uint, '16unit': builder.add_16bit_uint, '32unit': builder.add_32bit_uint, '64unit': builder.add_64bit_uint, '8int': builder.add_8bit_int, '16int': builder.add_16bit_int, '32int': builder.add_32bit_int, '64int': builder.add_64bit_int, '32float': builder.add_32bit_float, '64float': builder.add_64bit_float, 'string': builder.add_string} builder_map[point.encoding](value) payload = [unpack(endian + 'H', x)[0] for x in builder.build()] with lock: return self.modbus_client.write_registers(point.address, payload, unit=point.slave_id) else: with lock: return self.modbus_client.write_registers(point.address, [value], unit=point.slave_id)
async def _write_register_value( self, key: str, value: Union[str, float, int]) -> WriteMultipleRegistersResponse: """Write a single value to the holding registers. Currently registers are written one at a time to avoid issues with discontinuous modbus addresses. """ start_address = self.tags[key]['address']['start'] - 400001 builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) data_type = self.tags[key]['type'] if data_type == 'float': builder.add_32bit_float(value) elif data_type == 'str': chars = self.tags[key]['length'] if len(value) > chars: raise ValueError(f'{value} is too long for {key}. ' f'Max: {chars} chars') builder.add_string(value.ljust(chars)) elif data_type == 'int16': builder.add_16bit_int(value) elif data_type == 'int32': builder.add_32bit_int(value) else: raise ValueError("Missing data type.") resp = await self.write_registers(start_address, builder.build(), skip_encode=True) return resp[0]
def write_modbus(solve_coo): if solve_coo is None: return False ra = solve_coo.ra.deg if ra > 180: ra -= 360 ra = ra * np.pi/180. dec = solve_coo.dec.deg * np.pi/180. val_dict = { 24592: ra, 24590: dec, 24594: time.time() - 1544000000. } for address, value in val_dict.items(): builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) print(address, value) builder.add_32bit_float(value) payload = builder.build() registers = builder.to_registers() rr = modbus_client.write_registers(address, registers, unit=modbus_UNIT) time.sleep(0.1) if rr.isError(): return False return True
def write_registers(self, key): point = self.point_dict.get(key[2:]) if point: value = conpot_core.get_databus().get_value(key) if not point.encoding == 'none': endian = Endian.Auto if point.endian == 'Little': endian = Endian.Little elif point.endian == 'Big': endian = Endian.Big builder = BinaryPayloadBuilder(endian=endian) builder_map = { 'bits': builder.add_bits, '8unit': builder.add_8bit_uint, '16unit': builder.add_16bit_uint, '32unit': builder.add_32bit_uint, '64unit': builder.add_64bit_uint, '8int': builder.add_8bit_int, '16int': builder.add_16bit_int, '32int': builder.add_32bit_int, '64int': builder.add_64bit_int, '32float': builder.add_32bit_float, '64float': builder.add_64bit_float, 'string': builder.add_string } builder_map[point.encoding](value) payload = [unpack(endian + 'H', x)[0] for x in builder.build()] with lock: return self.modbus_client.write_registers( point.address, payload, unit=point.slave_id) else: with lock: return self.modbus_client.write_registers( point.address, [value], unit=point.slave_id)
def write(self, displayName, address, value, dtype=None, bits=None): if dtype: builder = BinaryPayloadBuilder(wordorder=Endian.Big) # This code trick generates and calls methods of PayloadBuilder, # like `builder.add_16bit_int(r['value']) # where 16 = r[bits], int = r['typename'] if dtype == 'string': method_name = "add_string" else: method_name = "add_{0}bit_{1}".format(bits, dtype) getattr(builder, method_name)(value) payload = builder.build() logging.debug("Packed value '{0}' with method {1} into {2}".format( value, method_name, payload)) registers = builder.to_registers() self.mb_client.write_registers(address, registers, unit=1) # self.mb_client.write_registers(address, payload, skip_encode=True, unit=UNIT) else: logging.debug("Wrote value '{0}' to 16bit register as {1}".format(value, int(value))) self.mb_client.write_register(address, int(value), unit=UNIT)
def setAngle(self, angle): # Set up aim to angle and set up angle if self.mode != self.MODE_ANGLE: self.mode = self.MODE_ANGLE builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) builder.add_32bit_int(int(angle)) payload = builder.build() self.client.write_registers(4, payload, skip_encode=True, unit=self.id)
def sendFloat(self, value, address): """Send a 32 bit value to the first modbus unit. Parameters: value and address where the value will be stored in. Return: Result if it was successful or not.""" builder = BinaryPayloadBuilder(byteorder=Endian.Big) builder.add_32bit_float(value) payload = builder.build() result = self.modbusClient.write_single_register(address, payload) return result
def modbusWrite(self, address, value): toChange = self._IEEE754reverse(value) toSend = self._changingTheOrder(toChange) builder = BinaryPayloadBuilder(endian=Endian.Little) # That is because of difficulies with the PLC builder.add_32bit_uint((toSend)) payload = builder.build() #result = client.write_registers(address, payload, skip_encode=True) result = self.client.write_registers(address, payload, skip_encode=True)
def send(self, hex_list): builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) for hex_val in hex_list: builder.add_8bit_uint(hex_val) Modules.Utils.append_crc(builder) print('sending: ', builder.to_string()) payload = builder.build() for char in payload: self.client.send(char)
def loadsensorconfig(self, filename): d = np.load(filename) builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) for i in d: builder.add_16bit_int(i) p = builder.build() for i, j in zip(p, range(len(d))): self.client.write_register(30 + j, i, skip_encode=True, unit=self.id)
def writeValue(self, varname, value): if CONST_MAP_VARIABLES_TO_ID[varname]["write"] != True: self.logger.error( "Helios: Variable {0} may not be written!".format(varname)) return False success = False self._lock.acquire() try: # if we have got to write a single bit, we need the current (byte) value to # reproduce the other bits... # if CONST_MAP_VARIABLES_TO_ID[varname]["type"] == "bit": # currentval = None # # Send poll request # # Read response # # CONST_MAP_VARIABLES_TO_ID[varname]["variable"] # value = value # if currentval == None: # self.logger.error("Helios: Sending value to ventilation system failed. Can not read current variable value '{0}'." # .format(varname)) # return False # rawvalue = self._convertFromValue(varname, value, currentval) # else: # #rawvalue = self._convertFromValue(varname, value, None) rawvalue = str(value) # send the new value if rawvalue is not None: # Writing value builder = BinaryPayloadBuilder() builder.add_string( CONST_MAP_VARIABLES_TO_ID[varname]["variable"] + '=' + rawvalue + '\0') payload = builder.build() self._port.write_registers(FIRST_REGISTER_ADDR, payload, skip_encode=True, unit=SLAVE_ID) success = True else: self.logger.error( "Helios: Sending value to ventilation system failed. Can not convert value '{0}' for variable '{1}'." .format(value, varname)) success = False except Exception as e: self.logger.error( "Helios: Exception in writeValue() occurred: {0}".format(e)) finally: self._lock.release() return success
async def set_setpoint(self, zone: int, setpoint: float): """Set the temperature setpoint for a zone. For more information on a 'Zone', refer to Watlow manuals. """ if not self.setpoint_range[0] <= setpoint <= self.setpoint_range[1]: raise ValueError(f"Setpoint ({setpoint}) in not in the valid range from" f" {self.setpoint_range[0]} to {self.setpoint_range[1]}") address = (zone - 1) * self.modbus_offset + self.setpoint_address builder = BinaryPayloadBuilder(byteorder=Endian.Big) builder.add_32bit_float(setpoint) await self.client.protocol.write_registers(address, builder.build(), skip_encode=True)
def int_to_register(self, address, value): try: # Create a builder builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) # Add num to builder builder.add_16bit_int(value) payload = builder.to_registers() payload = builder.build() registers = builder.to_registers() # Write value self.client.write_registers(address, registers, unit=1) except Exception as ex: print(ex)
def write_multiple_registers(self, command): parser = argument_parser() command = 'write_multiple_registers ' + command spec = parser.parse_args(command.split()) builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) for func, value in spec.values: getattr(builder, func)(value) payload = builder.build() response = _ModbusClient.write_registers( self, spec.address, payload, skip_encode=True, unit=spec.unit_id) return response
def on(): builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) builder.add_8bit_uint(UNIT_ID) # Unit ID builder.add_8bit_uint(0x05) # function ID builder.add_8bit_uint(0x00) builder.add_8bit_uint(0x01) # coil ID builder.add_8bit_uint(0x01) # data, here: on builder.add_8bit_uint(0x00) #builder.add_8bit_uint(0x9d) # here checksum #builder.add_8bit_uint(0x9a) # here checksum utils.appendCrc(builder) return builder.build()
def readValue(self, varname): if CONST_MAP_VARIABLES_TO_ID[varname]["read"] != True: self.logger.error("Variable {0} may not be read!".format(varname)) return False value = None self._lock.acquire() try: self.logger.debug("Helios: Reading value: {0}".format(varname)) # Send poll request builder = BinaryPayloadBuilder() builder.add_string(CONST_MAP_VARIABLES_TO_ID[varname]["variable"] + '\0') payload = builder.build() self._port.write_registers(FIRST_REGISTER_ADDR, payload, skip_encode=True, unit=SLAVE_ID) # Read response rtr = CONST_MAP_VARIABLES_TO_ID[varname]["count"] + 3 if rtr < 8: rtr = 8 result = self._port.read_holding_registers(FIRST_REGISTER_ADDR, rtr, unit=SLAVE_ID) output = BinaryPayloadDecoder.fromRegisters( result.registers).decode_string(rtr) output = re.sub(u'([\x00])', "", output.decode('utf-8')) reg, value = output.split('=') if value is not None: raw_value = value value = self._convertFromRawValue(varname, value) self.logger.debug( "Value for {0} ({1}) received: {2} --> converted = {3}". format(varname, CONST_MAP_VARIABLES_TO_ID[varname]["variable"], raw_value, value)) else: # logging in debug only, so we stop spamming log file (noise on the bus seems to be normal) self.logger.debug( "Helios: No valid value for '{0}' from ventilation system received." .format(varname)) except Exception as e: self.logger.error( "Helios: Exception in readValue() occurred: {0}".format(e)) finally: self._lock.release() return value
def Write_Multiple(Client, Start_Tag_Number, New_Value_List): ''' Inputs: __ Client: See client __ Start_Tag_Number: This is the starting tag value, this will increment by two for each of the items in the New_Values_List __ New_Values_List: This is a list of new values that you want to write, this is typically the same number repeated once for each time that you want to write to each magnet. This is done this way so that you can write different values to each magnet if you want to. (Typically by a scaled amount if you are doing that.) - Must have an established Client before running this function. - Outputs: __ Writes to a number of user defined magnets, may, in the future, allow one value to be written to a specified number of magnets. - Method: - Set up the Client - Define the start tag value, 22201 for dipole 1 for example - For each dipole you want to step, you define the new value you want written to it. - Example (Writing to 8 Dipoles starting with DP1) List = [0.100,0.100,0.100,0.100,0.100,0.100,0.100,0.100] DP1_Tag = 22201 Client = M.Make_Client('192.168.1.2') M.Write_Multiple(Client, DP1_Tag, List) - Result: All of the Dipoles (Assuming there are 8 will be written to 0.100) ''' Tag_Number = int(Start_Tag_Number) - 1 Builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) for value in New_Value_List: Builder.add_32bit_float(value) Payload = Builder.to_registers() Payload = Builder.build() Client.write_registers(Tag_Number, Payload, skip_encode=True, unit=1) return
def WriteR32(self,myadr_dec,value): myreadregister= self.client.read_holding_registers(myadr_dec,2,unit=71) myreadregister = BinaryPayloadDecoder.fromRegisters(myreadregister.registers, byteorder=Endian.Big, wordorder=Endian.Little) myreadregister =round(myreadregister.decode_32bit_float(),2) print ("I read the value before setting it - value was ", myreadregister) mybuilder = BinaryPayloadBuilder(byteorder=Endian.Big,wordorder=Endian.Little) mybuilder.add_32bit_float(value) mypayload = mybuilder.build() mywriteregister=self.client.write_registers(myadr_dec,mypayload,skip_encode=True, unit=71) """ print ("From subroutine WriteS16 - In theory .... - I should get the value back that we pushed ", value ,"----", myreadregister) print("Register I wrote",mywriteregister) """ return(mywriteregister)
def push_buffer(self, buff): builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) [builder.add_8bit_uint(i) for i in buff] builder.add_16bit_uint(self.calc_crc(buff)) payload = builder.build() rq = self.client.write_registers(self.MB_STREAM_REG, payload, skip_encode=True, unit=self.id) #logging.info(f"Push {binascii.hexlify(buff)}") # logging.info(rq.isError()) if not rq.isError(): return True else: logging.warning(f"Can't write stream data") return False
def change_station_id(modbusid, serialport, id_setting, current_baudrate): instrument = ModbusSerialClient(method='rtu', port=serialport, baudrate=current_baudrate) builder = BinaryPayloadBuilder(byteorder=Endian.Big) builder.add_16bit_int(id_setting) payload = builder.build() pld = payload[0][1] | (payload[0][0] << 8) instrument.connect() instrument.write_register(1000, pld, unit=modbusid, timeout=.1) instrument.close()
def write_small_buff(self, buff): if len(buff) == self.mb_transfer_size: self.reset_state() # reset error state builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) [builder.add_16bit_uint(i) for i in buff] builder.add_16bit_uint(self.calc_crc(buff)) payload = builder.build() #print(payload) self.client.write_registers(self.MB_START_STREAM, payload, skip_encode=True, unit=self.id) if self.update_state() == 0: #check errors self.client.write_register(self.MB_ACTION_REG, self.MB_ACTION_WRITE, unit=self.id) if self.update_state() == 0: return True return False
def write_register(self,register_name,value, unit=None): """ :param register_name: register key from holding register dictionary generated by yaml config :param value: value to write to register :returns: -- Nothing """ # TODO add the ability to discern which settings will be appropriate for # the device that is being written to if (unit is None): unit = self.UNIT_ID ''' builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER, wordorder=self.WORD_ORDER_DICT[unit]) ''' builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER_DICT[unit], wordorder=self.WORD_ORDER_DICT[unit]) # This will change depending on the device that is being connected # potentially so it has to be correleated to the device ID if (self.holding_register_dict[register_name][1] == '8int'): builder.add_8bit_int(value) elif (self.holding_register_dict[register_name][1] == '8uint'): builder.add_8bit_uint(value) elif (self.holding_register_dict[register_name][1] == '16int'): builder.add_16bit_int(value) elif (self.holding_register_dict[register_name][1] == '16uint'): builder.add_16bit_uint(value) elif (self.holding_register_dict[register_name][1] == '32int'): builder.add_32bit_int(value) elif (self.holding_register_dict[register_name][1] == '32uint'): builder.add_32bit_uint(value) elif (self.holding_register_dict[register_name][1] == '32float'): builder.add_32bit_float(value) elif (self.holding_register_dict[register_name][1] == '64int'): builder.add_64bit_int(value) elif (self.holding_register_dict[register_name][1] == '64uint'): builder.add_64bit_uint(value) elif (self.holding_register_dict[register_name][1] == '64float'): builder.add_64bit_float(value) else: print("Bad type") exit() payload = builder.build() self.client.write_registers(self.holding_register_dict[register_name][0], payload, skip_encode=True, unit = self.UNIT_ID)
def set_address_value(address, value): """ Sets value to address :param address : address number in integer :param client : client object """ # Handle exception builder = BinaryPayloadBuilder(byteorder=Endian.Little, wordorder=Endian.Little) builder.add_32bit_float(value) payload = builder.build() result = client.write_registers(address=address, values=payload, skip_encode=True, unit=1)
def Write(Client, Tag_Number, New_Value, Bool=False): ''' -Future: input a safety method to make sure we aren't drastically changing values Inputs: Client, see "Client" Above __ Tag_Number: which modbus to read, convention is this: input the modbus start tag number. Must have a modbus tag. __ New_Value: New value which you want the modbus to output to -Must have established client before attempting to write to the client -Outputs: The value of that Moodbus tag Method: - Build a payload to send to register - Add float value to that payload - Build payload path (path to register) - Build the payload - Write the new value -Required imports from pymodbus.client.sync import ModbusTcpClient from pymodbus.payload import BinaryPayloadDecoder from pymodbus.constants import Endian -example: Client = Make_Client('192.168.1.2') Dipole_1_Current = Write(Client,22201,0.450) ''' Tag_Number = int(Tag_Number) - 1 if Bool == False: Builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) Builder.add_32bit_float(New_Value) Payload = Builder.to_registers() Payload = Builder.build() Client.write_registers(Tag_Number, Payload, skip_encode=True, unit=1) if Bool == True: Client.write_coils(Tag_Number, [New_Value], skip_encode=False, unit=1) return
def write_register(self, address, value, eval_mode, byteorder, wordorder): builder = BinaryPayloadBuilder(byteorder=byteorder, wordorder=wordorder) if not eval_mode.startswith('string'): if eval_mode == 'floating point: ieee754': cast_method = float else: cast_method = int value = cast_method(value) getattr(builder, self.get_builder_method(eval_mode, 1))(value) payload = builder.build() LOG.debug(payload) with self.__device_lock: response = self.client.write_register(address, payload[0], skip_encode=True, unit=self.slave_id) return response
def makeMotionParameter(): builder = BinaryPayloadBuilder(byteorder=Endian.Big) builder.add_32bit_int(method) # 方式(基準アドレス+0,1) builder.add_32bit_int(position) # 位置(基準アドレス+2, 3) builder.add_32bit_int(speed) # 速度(基準アドレス+4, 5) builder.add_32bit_int(changeSpeed) # 起動・変速(基準アドレス+6, 7) builder.add_32bit_int(stop) # 停止(基準アドレス+8, 9) builder.add_32bit_int(motionSupply) # 運転電流(基準アドレス+10 11) builder.add_32bit_int(motionFinishDelay) # 運転終了遅延(基準アドレス+12, 13) builder.add_32bit_int(merge) # 結合(基準アドレス+14, 15) builder.add_32bit_int(mergeTo) # 結合先(基準アドレス+16, 17) builder.add_32bit_int(offsetArea) # オフセット(エリア)(基準アドレス+18, 19) builder.add_32bit_int(widthArea) # 幅(エリア)(基準アドレス+20, 21) builder.add_32bit_int(countLoop) # カウント(loop) (基準アドレス+22, 23) builder.add_32bit_int(postionOffset) # 位置オフセット(基準アドレス+24, 25) builder.add_32bit_int(finishLoop) # 終了(loop)(基準アドレス+26, 27) builder.add_32bit_int(weakEvent) # 弱イ.ベント(基準アドレス+28, 29) builder.add_32bit_int(strongEvent) # 強イベント(基準ドレス+30, 31) return builder.build()
def setUp(self): ''' Initializes the test environment and builds request/result encoding pairs ''' self.value = 0xabcd self.values = [0xa, 0xb, 0xc] builder = BinaryPayloadBuilder(endian=Endian.Big) builder.add_16bit_uint(0x1234) self.payload = builder.build() self.write = { WriteSingleRegisterRequest(1, self.value) : b'\x00\x01\xab\xcd', WriteSingleRegisterResponse(1, self.value) : b'\x00\x01\xab\xcd', WriteMultipleRegistersRequest(1, self.values) : b'\x00\x01\x00\x03\x06\x00\n\x00\x0b\x00\x0c', WriteMultipleRegistersResponse(1, 5) : b'\x00\x01\x00\x05', WriteSingleRegisterRequest(1, self.payload[0], skip_encode=True): b'\x00\x01\x12\x34', WriteMultipleRegistersRequest(1, self.payload, skip_encode=True): b'\x00\x01\x00\x01\x02\x12\x34', }
def setUp(self): ''' Initializes the test environment and builds request/result encoding pairs ''' self.value = 0xabcd self.values = [0xa, 0xb, 0xc] builder = BinaryPayloadBuilder(byteorder=Endian.Big) builder.add_16bit_uint(0x1234) self.payload = builder.build() self.write = { WriteSingleRegisterRequest(1, self.value) : b'\x00\x01\xab\xcd', WriteSingleRegisterResponse(1, self.value) : b'\x00\x01\xab\xcd', WriteMultipleRegistersRequest(1, self.values) : b'\x00\x01\x00\x03\x06\x00\n\x00\x0b\x00\x0c', WriteMultipleRegistersResponse(1, 5) : b'\x00\x01\x00\x05', WriteSingleRegisterRequest(1, self.payload[0], skip_encode=True): b'\x00\x01\x12\x34', WriteMultipleRegistersRequest(1, self.payload, skip_encode=True): b'\x00\x01\x00\x01\x02\x12\x34', }
def change_tracker_setpoint(modbusid, serialport, setpoint): instrument = ModbusSerialClient(method='rtu', port=serialport, baudrate=9600) builder = BinaryPayloadBuilder(endian=Endian.Big) builder.add_16bit_int(setpoint) payload = builder.build() #print(payload) #print(payload[0][0]) #print(payload[0][1]) pld = payload[0][1] | (payload[0][0] << 8) instrument.connect() instrument.write_register(3, pld, unit=modbusid, timeout=.1) instrument.close()
# Here we demonstrate packing a random payload layout, unpacked it looks # like the following: # # - a 8 byte string 'abcdefgh' # - a 32 bit float 22.34 # - a 16 bit unsigned int 0x1234 # - an 8 bit int 0x12 # - an 8 bit bitstring [0,1,0,1,1,0,1,0] # ---------------------------------------------------------------------------# builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_string("abcdefgh") builder.add_32bit_float(22.34) builder.add_16bit_uint(0x1234) builder.add_8bit_int(0x12) builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0]) payload = builder.build() address = 0x01 result = client.write_registers(address, payload, skip_encode=True) # ---------------------------------------------------------------------------# # If you need to decode a collection of registers in a weird layout, the # payload decoder can help you as well. # # Here we demonstrate decoding a random register layout, unpacked it looks # like the following: # # - a 8 byte string 'abcdefgh' # - a 32 bit float 22.34 # - a 16 bit unsigned int 0x1234 # - an 8 bit int 0x12 # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
def run_binary_payload_ex(): # ----------------------------------------------------------------------- # # We are going to use a simple client to send our requests # ----------------------------------------------------------------------- # client = ModbusClient('127.0.0.1', port=5440) client.connect() # ----------------------------------------------------------------------- # # If you need to build a complex message to send, you can use the payload # builder to simplify the packing logic. # # Here we demonstrate packing a random payload layout, unpacked it looks # like the following: # # - a 8 byte string 'abcdefgh' # - a 32 bit float 22.34 # - a 16 bit unsigned int 0x1234 # - another 16 bit unsigned int 0x5678 # - an 8 bit int 0x12 # - an 8 bit bitstring [0,1,0,1,1,0,1,0] # - an 32 bit uint 0x12345678 # - an 32 bit signed int -0x1234 # - an 64 bit signed int 0x12345678 # The packing can also be applied to the word (wordorder) and bytes in each # word (byteorder) # The wordorder is applicable only for 32 and 64 bit values # Lets say we need to write a value 0x12345678 to a 32 bit register # The following combinations could be used to write the register # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # # Word Order - Big Byte Order - Big # word1 =0x1234 word2 = 0x5678 # Word Order - Big Byte Order - Little # word1 =0x3412 word2 = 0x7856 # Word Order - Little Byte Order - Big # word1 = 0x5678 word2 = 0x1234 # Word Order - Little Byte Order - Little # word1 =0x7856 word2 = 0x3412 # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # # ----------------------------------------------------------------------- # builder = BinaryPayloadBuilder(byteorder=Endian.Little, wordorder=Endian.Big) builder.add_string('abcdefgh') builder.add_32bit_float(22.34) builder.add_16bit_uint(0x1234) builder.add_16bit_uint(0x5678) builder.add_8bit_int(0x12) builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0]) builder.add_32bit_uint(0x12345678) builder.add_32bit_int(-0x1234) builder.add_64bit_int(0x1234567890ABCDEF) payload = builder.build() address = 0 client.write_registers(address, payload, skip_encode=True, unit=1) # ----------------------------------------------------------------------- # # If you need to decode a collection of registers in a weird layout, the # payload decoder can help you as well. # # Here we demonstrate decoding a random register layout, unpacked it looks # like the following: # # - a 8 byte string 'abcdefgh' # - a 32 bit float 22.34 # - a 16 bit unsigned int 0x1234 # - another 16 bit unsigned int which we will ignore # - an 8 bit int 0x12 # - an 8 bit bitstring [0,1,0,1,1,0,1,0] # ----------------------------------------------------------------------- # address = 0x00 count = len(payload) result = client.read_holding_registers(address, count, unit=1) print("-" * 60) print("Registers") print("-" * 60) print(result.registers) print("\n") decoder = BinaryPayloadDecoder.fromRegisters(result.registers, byteorder=Endian.Little, wordorder=Endian.Big) decoded = { 'string': decoder.decode_string(8), 'float': decoder.decode_32bit_float(), '16uint': decoder.decode_16bit_uint(), 'ignored': decoder.skip_bytes(2), '8int': decoder.decode_8bit_int(), 'bits': decoder.decode_bits(), "32uints": decoder.decode_32bit_uint(), "32ints": decoder.decode_32bit_int(), "64ints": decoder.decode_64bit_int(), } print("-" * 60) print("Decoded Data") print("-" * 60) for name, value in iteritems(decoded): print("%s\t" % name, hex(value) if isinstance(value, int) else value) # ----------------------------------------------------------------------- # # close the client # ----------------------------------------------------------------------- # client.close()
endian=client.read_holding_registers(49991,4,unit=1) #endian.registers[0] = byteswap(endian.registers[0]) #endian.registers[1] = byteswap(endian.registers[1]) #endian.registers[2] = byteswap(endian.registers[2]) #endian.registers[3] = byteswap(endian.registers[3]) decoder=BinaryPayloadDecoder.fromRegisters(endian.registers,endian=Endian.Big) decoded={ 'val':hex(decoder.decode_32bit_uint()), 'v100':decoder.decode_32bit_float() } print decoded encoder = BinaryPayloadBuilder(endian=Endian.Big) encoder.add_16bit_uint(0x1234) buf = encoder.build() #buf[0] = charswap(buf[0]) client.write_registers(51234, buf, unit=1, skip_encode=True) encoder = BinaryPayloadBuilder(endian=Endian.Big) encoder.add_32bit_float(1.0114) encoder.add_32bit_float(-6) buf = encoder.build() #buf[0] = charswap(buf[0]) #buf[1] = charswap(buf[1]) #buf[2] = charswap(buf[2]) #buf[3] = charswap(buf[3]) client.write_registers(50000 + 8 * 5, buf, unit=1, skip_encode=True) while True: result = client.read_input_registers(100, 6, unit=1)
def write(self): try: lb = 00000000 hb = 00000000 #### byte besteht immer aus 16 bits for byte in self._db['out']: for bit in sorted(self._db['out'][byte]): if bit in self._db['out'][byte]: bitpos = bit[0] #startbit/bitposition des binärwertes type = bit[1] value = bit[2] name = bit[3] bit[2] = bit[3]() ##aktueller wert des items abrufen und value updaten! builder = BinaryPayloadBuilder(endian=Endian.Little) ##unterscheidung dateityp if type == '5' or type == '5.001' or type == '6' : ##8bit uint / int length = 8 if bitpos < 8: #lb lb = value else: #hb hb = value if type == '5': builder.add_8bit_uint(lb) builder.add_8bit_uint(hb) #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) elif type == '5.001': ##0-100 in 0-255 umwandeln! #print(dpts.en5001(lb)) #print(dpts.en5001(hb)) lb = self.de5001(lb) hb = self.de5001(hb) #print("lb geschrieben", lb ) #print("hb geschrieben", hb ) builder.add_8bit_uint(lb) builder.add_8bit_uint(hb) #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) elif type == '6': if lb > 127: lb = 127 elif lb < -128: lb = -128 if hb > 127: hb = 127 elif hb < -128: hb = -128 builder.add_8bit_int(lb) builder.add_8bit_int(hb) #logger.debug('MODBUS: 8bit int {0} ; {1}'.format(lb.hb)) elif type == '7' or type == '8': #16bit uint / int length = 16 if type == '7': #0...65535 builder.add_16bit_uint(value) #logger.debug('MODBUS: 16bit uint {0} '.format(value)) else: #-32768...32767 builder.add_16bit_int(value) #logger.debug('MODBUS: 16bit int {0}'.format(value)) elif type == '1': length = 1 #nur pro byte einmal die bits wandeln if bitpos < 8: #lb lb = lb | int(value) << bitpos #logger.debug('MODBUS: 8bit int{0}'.format(lb)) else: #hb hb = hb | int(value) << bitpos #logger.debug('MODBUS: 8bit int{0}'.format(hb)) builder.add_8bit_uint(lb) builder.add_8bit_uint(hb) payload = builder.build() logger.debug('MODBUS: write to PLC: WORD {0} set to {1} '.format(byte,payload)) self._modbuspy.write_registers(byte, payload, skip_encode=True) builder.reset() except Exception as e: logger.error('MODBUS: Could not write an OutWord, because {}'.format(e)) self._lock.release() return None