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 data_update(config, a): context = a[0] while True: for sensor in config['sensors']: # Sensor should be set to Adafruit_DHT.DHT11, # Adafruit_DHT.DHT22, or Adafruit_DHT.AM2302. if sensor['type'] == 'DHT22': sensor_type = Adafruit_DHT.DHT22 elif sensor['type'] == 'DHT11': sensor_type = Adafruit_DHT.DHT11 elif sensor['type'] == 'AM2302': sensor_type = Adafruit_DHT.AM2302 else: raise Exception("Unknown sensor type: " + sensor['type']) pin = int(sensor['pin']) humidity, temperature = Adafruit_DHT.read_retry(sensor_type, pin) if humidity is not None and temperature is not None: builder_t = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder_h = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder_t.add_32bit_float(temperature) builder_h.add_32bit_float(humidity) context.setValues(4, int(sensor['address_t']), builder_t.to_registers()) context.setValues(4, int(sensor['address_h']), builder_h.to_registers()) log.info('Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity)) else: log.warn('Failed to get reading. Try again!')
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 default_pump_val_factory(): default_val = [0x00]*600 # DA 500 A 549 DATI SCRITTI DA PLC POMPE default_val[0] = 12345 default_val[1] = 1 default_val[2] = 2 default_val[3] = 3 # qui inizia default_val[500] = 1 # APP_PER VERIFICA COMUNICAZIONE as_bits_502 = [0]*16 as_bits_502[0] = 1 as_bits_502[6] = 1 as_bits_502[10] = 1 builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_bits(as_bits_502) reg=builder.to_registers() print " STATO MACCHINA 1 ( IN BIT ) %d" % reg[0] default_val[502] = reg[0] # STATO MACCHINA 1 ( IN BIT ) default_val[503] = 0 # %MW503 STATO MACCHINA 2 ( IN BIT ) default_val[504] = 0 # %MW504 ALLARMI MACHINA 1 ( IN BIT ) default_val[505] = 0 # %MW505 ALLARMI MACHINA 2 ( IN BIT ) default_val[506] = 0 # %MW506 COPIA STATO COMANDO REMOTO 1 MOMENTANEO ( bit ) default_val[507] = 1 # %MW507 COPIA STATO COMANDO REMOTO 2 MOMENTANEO ( bit ) default_val[508] = 1 # %MW508 COPIA STATO COMANDO REMOTO 1 CONTINUO ( bit ) default_val[509] = 1 # %MW509 COPIA STATO COMANDO REMOTO 2 CONTINUO ( bit ) default_val[512] = 1 # %MW512 TEMPO DI ATTIVITA' DELLA POMPA default_val[513] = 1 # %MW513 TEMPO DI ATTIVITA' DELLA POMPA INIETTORE default_val[514] = 2 # %MW514 TEMPO DI ATTIVITA' DELLA POMPA GIORNALIERO default_val[515] = 2 # %MW515 TEMPO DI ATTIVITA' DELLA INIETTORE GIORNALIERO default_val[516] = 1 # %MW516 PRESSIONE ATTUALE default_val[517] = 3 # %MW517 default_val[518] = 4 # %MW518 default_val[519] = 4 # %MW519 cicli_min = 29 default_val[520] = cicli_min # %MW519 %MW520 CICLI / MINUTO q_default = cicli_min*liters_cycle q_m_ch = 60.0*q_default/1000.0 # conversione float - Endian.Little il primo è il meno significativo builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_32bit_float(q_default) builder.add_32bit_float(q_m_ch) reg=builder.to_registers() default_val[522:526]=reg # DA 550 A 599 DATI LETTI DA PLC POMPE default_val[550] = 1 # %MW550 CONTATORE PER VERIFICA COMUNICAZIONE default_val[551] = 1 # %MW551 default_val[552] = 0 # %MW552 COMANDO MACCHINA DA REMOTO 1 MOMENTANEO ( bit ) default_val[553] = 2 # %MW553 COMANDO MACCHINA DA REMOTO 2 MOMENTANEO ( bit ) default_val[554] = 3 # %MW554 COMANDO MACCHINA DA REMOTO 1 CONTINUO ( bit ) default_val[555] = 3 # %MW555 COMANDO MACCHINA DA REMOTO 2 CONTINUO ( bit ) default_val[556] = 4 # %MW556 default_val[557] = 4 # %MW557 default_val[558] = 5 # %MW558 default_val[559] = 5 # %MW559 default_val[560] = 0 # %MW560 COMANDO BAR DA REMOTO default_val[561] = 6 # %MW561 default_val[562] = 0 # %MW562 COMANDO NUMERO CICLI MINUTO DA REMOTO default_val[599] = 600 # logInfo.debug("default values: " + str(default_val)) return default_val
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 set_datastore(self): FUNCTION_CODE = 0x04 ADDRESS = 0x00 builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_float(3.14) self.store.setValues(FUNCTION_CODE, ADDRESS, builder.to_registers())
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 set_datastore(self): FUNCTION_CODE = 0x04 ADDRESS = 0x00 random_value = random.uniform(0, 10) builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_float(random_value) self.store.setValues(FUNCTION_CODE, ADDRESS, builder.to_registers()) print('Datastore updated - {0}'.format(random_value))
def _encode_value(self, data, dtype): builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) try: if dtype == registerDataType.FLOAT32: builder.add_32bit_float(data) else: raise NotImplementedError(dtype) except NotImplementedError: raise return builder.to_registers()
def Mbus(dop, register): import re from pymodbus.constants import Endian from pymodbus.payload import BinaryPayloadBuilder modDatatemp = re.sub('u' '', '', dop) modDataFloat = float(modDatatemp) #Convert floating point dop to Modbus 32-bit builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_32bit_float(modDataFloat) payload = builder.to_registers() #Write to Modbus register 40001 context[0x00].setValues(3, register, payload)
def set_value(self, value): if value is not None: builder = BinaryPayloadBuilder(byteorder=self.byteorder, wordorder=self.wordorder) if self.encoding in ['int8', 'uint8']: builder.add_8bit_int( value ) if self.encoding == 'int8' else builder.add_8bit_uint( value) elif self.encoding in ['int16', 'uint16']: builder.add_16bit_int( value ) if self.encoding == 'int16' else builder.add_16bit_uint( value) elif self.encoding in ['int32', 'uint32']: builder.add_32bit_int( value ) if self.encoding == 'int32' else builder.add_32bit_uint( value) elif self.encoding in ['float32', 'float64']: builder.add_32bit_float( value ) if self.encoding == 'float32' else builder.add_64bit_float( value) elif self.encoding in ['int64', 'uint64']: builder.add_64bit_int( value ) if self.encoding == 'int64' else builder.add_64bit_uint( value) elif self.encoding == 'boolean': builder.add_16bit_uint(value) elif self.encoding == 'string': builder.add_string(value) else: log.error("Unhandled encoding exception {enc}".format( enc=self.encoding)) payload = builder.to_registers() log.info( "Setting {type} {addr} to {enc} {val} as {list}".format( type=self.type, addr=self.address, enc=self.encoding, val=value, list=str(payload))) self.parent.context.setValues(self.get_function_code(), self.address, payload) self.value = value else: log.warning( "Attempt to set {type} {addr} to None (default={default})". format(type=self.type, addr=self.address, default=self.default))
def make_block(section, test_val, test_params): #print("Format", section) builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) # TYPES TO BE ADDED value = 0 data_size = 0 for s in section: field_name = test_params["field_name"].format(source=s[4], block=s[5], field=s[6] ) #print(field_name, test_val[field_name], s) print("Add: ", data_size, s, end="") value = test_val[field_name] #value += 1 if s[0] == "float16": builder.add_16bit_uint(round(value) ) data_size +=1 elif s[0] == "uint16": #print(value, float(value), s[2] , s[3] ) #print("values:", s, value) val = int( ( float(value) - float(s[3])) / float(s[2]) ) #print("values:", s, value, val) builder.add_16bit_uint(val) data_size+=1 elif s[0] == "uint32": val = int(float(value) / float(s[2]) - float(s[3]) ) builder.add_32bit_uint(val) data_size += 2 elif s[0] in ["int32", "sint32"]: val = int(float(value) / float(s[2]) - float(s[3]) ) builder.add_32bit_int(val) data_size +=2 elif s[0] == "float32": val = float(value) / float(s[2]) - float(s[3]) builder.add_32bit_float(val) data_size +=2 elif s[0] == "bit16": builder.add_bits([0, 0, 0, 0, 0, 0, 0, 0] ) builder.add_bits([0, 0, 0, 0, 0, 0, 0, 0] ) val = 0 data_size += 1 elif s[0][:3] == "str": data_length = int(s[1]) val = " " * (data_length - len(str(value))) + str(value) builder.add_string(val) data_size += data_length/2 else: print(" ------ ", s) print(val) #value += 1 block = ModbusSequentialDataBlock(1, builder.to_registers()) return block
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 run_payload_server(): # ----------------------------------------------------------------------- # # build your payload # ----------------------------------------------------------------------- # builder = BinaryPayloadBuilder(byteorder=Endian.Little, wordorder=Endian.Little) builder.add_string('abcdefgh') builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0]) builder.add_8bit_int(-0x12) builder.add_8bit_uint(0x12) builder.add_16bit_int(-0x5678) builder.add_16bit_uint(0x1234) builder.add_32bit_int(-0x1234) builder.add_32bit_uint(0x12345678) builder.add_16bit_float(12.34) builder.add_16bit_float(-12.34) builder.add_32bit_float(22.34) builder.add_32bit_float(-22.34) builder.add_64bit_int(-0xDEADBEEF) builder.add_64bit_uint(0x12345678DEADBEEF) builder.add_64bit_uint(0xDEADBEEFDEADBEED) builder.add_64bit_float(123.45) builder.add_64bit_float(-123.45) # ----------------------------------------------------------------------- # # use that payload in the data store # ----------------------------------------------------------------------- # # Here we use the same reference block for each underlying store. # ----------------------------------------------------------------------- # block = ModbusSequentialDataBlock(1, builder.to_registers()) store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block) context = ModbusServerContext(slaves=store, single=True) # ----------------------------------------------------------------------- # # initialize the server information # ----------------------------------------------------------------------- # # If you don't set this or any fields, they are defaulted to empty strings. # ----------------------------------------------------------------------- # identity = ModbusDeviceIdentification() identity.VendorName = 'Pymodbus' identity.ProductCode = 'PM' identity.VendorUrl = 'http://github.com/riptideio/pymodbus/' identity.ProductName = 'Pymodbus Server' identity.ModelName = 'Pymodbus Server' identity.MajorMinorRevision = version.short() # ----------------------------------------------------------------------- # # run the server you want # ----------------------------------------------------------------------- # StartTcpServer(context, identity=identity, address=("localhost", 5020))
def update_register(context, param): values = [] fn_code = HOLDING_REGISTER_FN_CODE if (param == "temperature"): address = TEMPERATURE_REGISTER newvalue = random.randint(TEMP_LO, TEMP_HI) log.debug("new temperatue value: " + str(newvalue)) elif (param == "humidity"): address = HUMIDITY_REGISTER newvalue = random.randint(HUMID_LO, HUMID_HI) log.debug("new humidity value: " + str(newvalue)) elif (param == "pressure"): address = PRESSURE_REGISTER newvalue = random.randint(PRESSURE_LO, PRESSURE_HI) log.debug("new pressure value: " + str(newvalue)) elif (param == "geolati"): address = GEO_LATI_REGISTER newvalue = random.uniform(LATI_LO, LATI_HI) log.debug("new latitude value = " + str(newvalue)) builder = BinaryPayloadBuilder(endian=Endian.Big) builder.add_32bit_float(newvalue) payload = builder.to_registers() context.setValues(fn_code, address, payload) return elif (param == "geolongi"): address = GEO_LONGI_REGISTER newvalue = random.uniform(LONGI_LO, LONGI_HI) log.debug("new longitude value = " + str(newvalue)) builder = BinaryPayloadBuilder(endian=Endian.Big) builder.add_32bit_float(newvalue) payload = builder.to_registers() context.setValues(fn_code, address, payload) return elif (param == "keyop"): address = KEY_OP_REGISTER context.setValues(fn_code, address, [0] * 8) newvalue = random.choice(operations) newvalue = newvalue log.debug("new key operation = " + newvalue) builder = BinaryPayloadBuilder(endian=Endian.Big) builder.add_string(newvalue) payload = builder.to_registers() context.setValues(fn_code, address, payload) return else: return values.append(newvalue) context.setValues(fn_code, address, values)
def run_payload_server(): # ----------------------------------------------------------------------- # # build your payload # ----------------------------------------------------------------------- # builder = BinaryPayloadBuilder(byteorder=Endian.Little, wordorder=Endian.Little) builder.add_string('abcdefgh') builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0]) builder.add_8bit_int(-0x12) builder.add_8bit_uint(0x12) builder.add_16bit_int(-0x5678) builder.add_16bit_uint(0x1234) builder.add_32bit_int(-0x1234) builder.add_32bit_uint(0x12345678) builder.add_32bit_float(22.34) builder.add_32bit_float(-22.34) builder.add_64bit_int(-0xDEADBEEF) builder.add_64bit_uint(0x12345678DEADBEEF) builder.add_64bit_uint(0xDEADBEEFDEADBEED) builder.add_64bit_float(123.45) builder.add_64bit_float(-123.45) # ----------------------------------------------------------------------- # # use that payload in the data store # ----------------------------------------------------------------------- # # Here we use the same reference block for each underlying store. # ----------------------------------------------------------------------- # block = ModbusSequentialDataBlock(1, builder.to_registers()) store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block) context = ModbusServerContext(slaves=store, single=True) # ----------------------------------------------------------------------- # # initialize the server information # ----------------------------------------------------------------------- # # If you don't set this or any fields, they are defaulted to empty strings. # ----------------------------------------------------------------------- # identity = ModbusDeviceIdentification() identity.VendorName = 'Pymodbus' identity.ProductCode = 'PM' identity.VendorUrl = 'http://github.com/bashwork/pymodbus/' identity.ProductName = 'Pymodbus Server' identity.ModelName = 'Pymodbus Server' identity.MajorMinorRevision = '1.5' # ----------------------------------------------------------------------- # # run the server you want # ----------------------------------------------------------------------- # StartTcpServer(context, identity=identity, address=("localhost", 5020))
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 float32_to_bytecode(self, value): ''' 将浮点型数据转化为整数数据,从而保证一个数据占用一个寄存器 :param value: 输入的浮点型数据数组 :return: 转化为整数型数据数据 ''' code_date = BinaryPayloadBuilder(payload=None, byteorder=Endian.Big, wordorder=Endian.Little, repack=False) # if value is dict: # for i in value: # code_date.add_32bit_float(i) code_date.add_32bit_float(value) return code_date.to_registers()
def lock_security_block(modbus_client, modbus_id): # 4. Cambiar valor block register a 0: # 4.1 Preparar payload builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_float(0.0) payload = builder.to_registers() logger.info(f"Payload 3 (bloque de seguridad = 1.0) preparado: {payload}") # 4.2. Escribir registro block: result = modbus_client.write_registers(32790, payload, unit=modbus_id) logger.debug(f"Fue un error? {result.isError()}") if result.isError(): return False else: return True
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 update_modbus_id(modbus_client, modbus_id, new_id): # 3. Cambiar modbus ID: # 3.1 Preparar payload try: builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_float(new_id) payload = builder.to_registers() logger.debug( f"Payload 2 (nuevo modbusID={new_id}) preparado: {payload}") # 3.2. Escribir registro block: result = modbus_client.write_registers(32782, payload, unit=modbus_id) except Exception as ex: logger.debug(ex) return True
def testBigEndianPayloadBuilder(self): ''' Test basic bit message encoding/decoding ''' builder = BinaryPayloadBuilder(endian=Endian.Big) builder.add_8bit_uint(1) builder.add_16bit_uint(2) builder.add_32bit_uint(3) builder.add_64bit_uint(4) builder.add_8bit_int(-1) builder.add_16bit_int(-2) builder.add_32bit_int(-3) builder.add_64bit_int(-4) builder.add_32bit_float(1.25) builder.add_64bit_float(6.25) builder.add_string(b'test') builder.add_bits(self.bitstring) self.assertEqual(self.big_endian_payload, builder.to_string())
def testLittleEndianPayloadBuilder(self): ''' Test basic bit message encoding/decoding ''' builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_8bit_uint(1) builder.add_16bit_uint(2) builder.add_32bit_uint(3) builder.add_64bit_uint(4) builder.add_8bit_int(-1) builder.add_16bit_int(-2) builder.add_32bit_int(-3) builder.add_64bit_int(-4) builder.add_32bit_float(1.25) builder.add_64bit_float(6.25) builder.add_string('test') builder.add_bits(self.bitstring) self.assertEqual(self.little_endian_payload, str(builder))
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 __encodeData(self, data): """Encode data to 32bit float Function encodes a list of data passed to it into a 32 bit float packet that can be written directly to the MODBUS server table. Arguments: :param data: Float to be encoded :type data: list """ builder = BinaryPayloadBuilder(endian=Endian.Little) try: for i in range(0,len(data)): builder.add_32bit_float(data[i]) except TypeError: builder.add_32bit_float(data) return builder.to_registers()
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 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 testLittleEndianPayloadBuilder(self): """ Test basic bit message encoding/decoding """ builder = BinaryPayloadBuilder(byteorder=Endian.Little, wordorder=Endian.Little) builder.add_8bit_uint(1) builder.add_16bit_uint(2) builder.add_32bit_uint(3) builder.add_64bit_uint(4) builder.add_8bit_int(-1) builder.add_16bit_int(-2) builder.add_32bit_int(-3) builder.add_64bit_int(-4) builder.add_32bit_float(1.25) builder.add_64bit_float(6.25) builder.add_16bit_uint(1) # placeholder builder.add_string(b'test') builder.add_bits(self.bitstring) self.assertEqual(self.little_endian_payload, builder.to_string())
def changeCurrent(self, current): def limitChargeStationCurrent(num, minimum=self.minimumCurrent, maximum=self.maximumCurrent): return max(min(num, maximum), minimum) chargeStationModbus = ModbusClient(self.ip, port=502, unit_id=1, auto_open=True, auto_close=True) time.sleep(0.1) builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_float(limitChargeStationCurrent(current)) registers = builder.to_registers() chargeStationModbus.write_registers(1210, registers, unit=1) chargeStationModbus.close()
class PayloadHandler: """ encodes/decodes values according to the way it is stored in registry SCALE stands for multiplying/dividing by a scaling factor COMB stands for storing the value of one field in two registers if none of those provided encodes only based on the type """ def __init__(self, env, store): self.byte_order = env["byte_order"] self.word_order = env["word_order"] self.d_s_factor = env["default_scaling_factor"] self.battery_store = store self.builder = BinaryPayloadBuilder(byteorder=self.byte_order, wordorder=self.word_order) def encode(self, value, encoding): self.builder.reset() encode_type = { INT8: lambda x: self.builder.add_8bit_int(x), UINT8: lambda x: self.builder.add_8bit_uint(x), INT16: lambda x: self.builder.add_16bit_int(x), UINT16: lambda x: self.builder.add_16bit_uint(x), INT32: lambda x: self.builder.add_32bit_int(x), UINT32: lambda x: self.builder.add_32bit_uint(x), FLOAT32: lambda x: self.builder.add_32bit_float(x), } if 'e_type' not in encoding or encoding['e_type'] == COMB: encode_type[encoding['d_type']](value) else: encode_type[encoding['d_type']](round( value * encoding.get('s_factor', self.d_s_factor))) return self.builder.to_registers() def decode(self, fx, addr, encoding): encoded_value = self.battery_store.getValues(fx, addr, 2) decoder = BinaryPayloadDecoder.fromRegisters(encoded_value, byteorder=self.byte_order, wordorder=self.word_order) decode_type = { INT8: lambda: decoder.decode_8bit_int(), UINT8: lambda: decoder.decode_8bit_uint(), INT16: lambda: decoder.decode_16bit_int(), UINT16: lambda: decoder.decode_16bit_uint(), INT32: lambda: decoder.decode_32bit_int(), UINT32: lambda: decoder.decode_32bit_uint(), FLOAT32: lambda: decoder.decode_32bit_float(), } if 'e_type' not in encoding or encoding['e_type'] == COMB: return decode_type[encoding['d_type']]() else: return decode_type[encoding['d_type']]() / encoding.get( 's_factor', self.d_s_factor)
def build_args(self, arg, kwargs): builder = BinaryPayloadBuilder( byteorder=Endian.Big) #, wordorder=Endian.Big) if 'arg_type' in kwargs: if kwargs['arg_type'] == 'float': builder.add_32bit_float(arg) elif kwargs['arg_type'] == 'uint64': builder.add_64bit_uint(arg) elif kwargs['arg_type'] == 'int64': builder.add_64bit_int(arg) elif kwargs['arg_type'] == 'uint32': builder.add_32bit_uint(arg) elif kwargs['arg_type'] == 'int32': builder.add_32bit_int(arg) elif kwargs['arg_type'] == 'uint16': builder.add_16bit_uint(arg) elif kwargs['arg_type'] == 'int16': builder.add_16bit_int(arg) elif kwargs['arg_type'] == 'int8': builder.add_8bit_int(arg) elif kwargs['arg_type'] == 'uint8': builder.add_8bit_uint(arg) elif kwargs['arg_type'] == 'string': builder.add_string(arg) else: raise Exception("unknown parameter type given: %s" % (kwargs['arg_type'])) else: builder.add_16bit_uint(arg) val = builder.build() return val
def run(self) -> None: builder = BinaryPayloadBuilder(byteorder=self.endian, wordorder=self.endian) builder.add_32bit_uint(42) builder.add_16bit_uint(12) builder.add_32bit_int(64) builder.add_16bit_int(128) builder.add_32bit_float(256) store = ModbusSlaveContext( di=ModbusSequentialDataBlock(18476, builder.to_registers()), co=ModbusSequentialDataBlock(18476, builder.to_registers()), hr=ModbusSequentialDataBlock(18476, builder.to_registers()), ir=ModbusSequentialDataBlock(18476, builder.to_registers()), zero_mode=True ) slaves = { 0x01: store, 0x02: store, 0x03: store, 0x04: store, } # context = ModbusServerContext(slaves=store, single=True) context = ModbusServerContext(slaves=slaves, single=False) identity = ModbusDeviceIdentification() identity.VendorName = 'Pymodbus' identity.ProductCode = 'PM' identity.VendorUrl = 'http://github.com/riptideio/pymodbus/' identity.ProductName = 'Pymodbus Server' identity.ModelName = 'Pymodbus Server' identity.MajorMinorRevision = '2.3.0' framer = ModbusSocketFramer self.server = ModbusTcpServer(context, framer, identity, address=("127.0.0.1", self.port)) self.server.serve_forever()
def write_context(a): log.debug("write the context") context = a[0] register = 4 slave_id = 0x01 address = 0x00 sensorpath = '/sys/bus/w1/devices/28-00000adfed51' try: f = open(sensorpath + "/w1_slave", 'r') except IOError as e: return -999 lines = f.readlines() f.close() crcLine = lines[0] tempLine = lines[1] result_list = tempLine.split("=") temp = float(result_list[-1]) / 1000 # temp in Celcius temp = temp + 1 # correction factor # if you want to convert to Celcius, comment this line #temp = (9.0 / 5.0) * temp + 32 if crcLine.find("NO") > -1: temp = -999 log.debug(temp) builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) builder.add_32bit_float(temp) payload = builder.to_registers() context[slave_id].setValues(register, address, payload) address = 0x03 effacement = GPIO.input(25) values = [1] if (effacement == 1): values[0] = 0 context[slave_id].setValues(register, address, values) lcd.lcd_clear() lcd.lcd_display_string(" Temperature :", 1) lcd.lcd_display_string(" "+str(round(temp, 2))+" .C", 3)
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 """ if (unit is None): unit = self.UNIT_ID builder = BinaryPayloadBuilder(byteorder=self.BYTE_ORDER, wordorder=self.WORD_ORDER) 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)
# ---------------------------------------------------------------------------# # 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 # - 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'
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()
print 'latitude ' , gpsd.fix.latitude print 'longitude ' , gpsd.fix.longitude print 'time utc ' , gpsd.utc,' + ', gpsd.fix.time print 'altitude (m)' , gpsd.fix.altitude print 'eps ' , gpsd.fix.eps print 'epx ' , gpsd.fix.epx print 'epv ' , gpsd.fix.epv print 'ept ' , gpsd.fix.ept print 'speed (m/s) ' , gpsd.fix.speed print 'climb ' , gpsd.fix.climb print 'track ' , gpsd.fix.track print 'mode ' , gpsd.fix.mode print print 'sats ' , gpsd.satellites builder.add_32bit_float(gpsd.fix.latitude) builder.add_32bit_float(gpsd.fix.longitude) payload = builder.build() #print payload client.write_registers(0, payload, skip_encode=True) time.sleep(1) #set to whatever payload = builder.reset() #except ConnectionException as e: #when you press ctrl+c # print "\nKilling Thread...Modbus server not running" # print e # gpsp.running=False # client.close()
def updating_pump_writer(a): ''' A worker process that runs every so often and updates live values of the context. It should be noted that there is a race condition for the update. :param arguments: The input arguments to the call ''' context = a[0] srv_id = a[1] handler = a[2] register = 3 slave_id = 0x00 values = context[slave_id].getValues(register, 0, count=600) # update P and Q with random values logInfo.debug("PUMP context values: " + str(values)) logInfo.debug("PUMP p_out=%d; q_out=%d" % (handler.p_out,handler.q_out)) decoder = BinaryPayloadDecoder.fromRegisters(values[502:503],endian=Endian.Little) bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(values[552:553],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(values[506:507],endian=Endian.Little) bits_506 = decoder.decode_bits() bits_506 += decoder.decode_bits() cicli_min = 0 p_new = 0 q_val = 0 # if iniettore Started if handler.pumpStarted and not bits_502[7]: handler.pumpStarted = False if bits_502[7]: #cicli_min = cicli_rand.rvs() q_val = handler.q_out if q_val < 0: q_val = 0 cicli_min = int(q_val / liters_cycle ) p_new = handler.p_out logInfo.debug("PUMP p_new=%d" % p_new) q_m_ch = 60.0*q_val/1000.0 handler.cicli_min = cicli_min handler.q_m_ch = q_m_ch logInfo.debug("PUMP cicli=%d, q=%f, mc=%f" % (cicli_min, q_val,q_m_ch)) # conversione float - Endian.Little il primo è il meno significativo handler.p_pump_out = p_new handler.q_pump_out = cicli_min values[516] = p_new # %MW516 PRESSIONE ATTUALE values[520] = cicli_min handler.qmax = values[562] handler.pmax = values[560] builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_32bit_float(q_val) builder.add_32bit_float(q_m_ch) reg=builder.to_registers() logInfo.debug("PUMP 2 x 32bit_float = %s" % str(reg)) values[522:526]=reg logInfo.debug("PUMP On Pump Server %02d new values (516-525): %s" % (srv_id, str(values[516:526]))) # assign new values to context values[599] = 699 context[slave_id].setValues(register, 0, values)
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) if result: #result.registers[0] = byteswap(result.registers[0]) #result.registers[1] = byteswap(result.registers[1]) #result.registers[2] = byteswap(result.registers[2]) #result.registers[3] = byteswap(result.registers[3])
#Its is the motor cos? and 0.5<motor_power_factor<0.97. ramp_mode=2# parm 30 Standard Std (2) without dynamic braking resistor, If with this resistor, should set to 0 or # Fast dynamicVtoF='OFF'# parm 32 - It should not be used when the drive is being used as a soft start to full speed. keep off voltage_mode_select=2 #parm 41 fixed boost mode(2) low_freq_voltage_boost=1 #% 0.5< low_freq_voltage_boost<1 __config__={ip:'127.0.0.1',min_speed:0.1,max_speed:60.0,acc_rate:33.0,dec_rate:33.0,motor_rated_speed:0, motor_rated_voltage:230,motor_power_factor:0.85,ramp_mode:2,dynamicVtoF:'OFF', voltage_mode_select:2, low_freq_voltage_boost:1} #open connection with sk commander # default port: 502 # change the ip below to the commander ip of your network #starting connection sk=ModbusTcpClient(ip) if sk.connect(): builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_32bit_float(321.57) payload = builder.build() result = sk.write_registers(4005, payload, skip_encode=True) sk.close() exit()
class modbusServer(): def __init__(self): self.__logging() self.cfg = yamlImport.importYAML("./cfg/modbusSettings.yaml") self.builder = BinaryPayloadBuilder(endian=Endian.Little) self.__setupContext() self.__serverInfo() self.__configureServer() def __logging(self): import logging logging.basicConfig() log = logging.getLogger() log.setLevel(logging.INFO) def __setupContext(self): #Setup Coils co = ModbusSequentialDataBlock(1, [0]*1) di = ModbusSequentialDataBlock(1, [0]*6) #Setup Registers (Inc floats) for i in range(0,3): self.builder.add_32bit_float(0.0) ir = ModbusSequentialDataBlock(1, self.builder.to_registers()) for i in range(0,3): self.builder.add_32bit_float(0.0) hr = ModbusSequentialDataBlock(1, self.builder.to_registers()) #Setup datastore store = ModbusSlaveContext(co=co,di=di,hr=hr,ir=ir) self.context = ModbusServerContext(slaves=store, single=True) def __serverInfo(self): self.identity = ModbusDeviceIdentification() self.identity.VendorName = self.cfg["VendorName"] self.identity.VendorUrl = self.cfg["VendorUrl"] self.identity.ProductName = self.cfg["ProductName"] self.identity.ModelName = self.cfg["ModelName"] self.identity.MajorMinorRevision = self.cfg["Revision"] def __getIPAddress(self): if self.cfg["manualIP"] == "N": return socket.gethostbyname(socket.gethostname()) return self.cfg["ip"] def __configureServer(self): if self.cfg["method"] == "tcp": self.servTCP = ModbusTcpServer(self.context, identity=self.identity, address=(self.__getIPAddress(), self.cfg["tcpPort"])) elif self.cfg["method"] == "rtu": self.servRTU = ModbusSerialServer(self.context, framer=ModbusRtuFramer, identity=self.identity, port=self.cfg["rtuPort"], stopbits=self.cfg["stopbits"], bytesize=self.cfg["bytesize"], parity=self.cfg["parity"], baudrate=self.cfg["baudrate"], timeout=self.cfg["timeout"]) else: raise ReferenceError("Invalid server type") def runServer(self): if self.cfg["method"] == "tcp": self.servTCP.serve_forever() elif self.cfg["method"] == "rtu": self.servRTU.serve_forever() else: raise ReferenceError("Invalid server type") def stopServer(self): if self.cfg["method"] == "tcp": self.servTCP.server_close() self.servTCP.shutdown() elif self.cfg["method"] == "rtu": self.servRTU.server_close() else: raise ReferenceError("Invalid server type") def encodeData(self,data): self.builder.reset() try: for i in range(0,len(data)): self.builder.add_32bit_float(data[i]) except TypeError: self.builder.add_32bit_float(data) return self.builder.to_registers() def decodeData(self,data): returnData = [0]*(len(data)/2) decoder = BinaryPayloadDecoder.fromRegisters(data, endian=Endian.Little) for i in range(0,len(data)/2): returnData[i] = round(decoder.decode_32bit_float(),2) return returnData
def updating_writer(a): ''' A worker process that runs every so often and updates live values of the context. It should be noted that there is a race condition for the update. :param arguments: The input arguments to the call ''' global g_Time global s_Time global g_increment if g_Time >= 60*20: g_Time = 0 log.debug("g_Time reset") print "g_Time reset" g_Time += 1 log.debug("updating the context at {0}".format(g_Time)) context = a[0] srv_id = a[1] register = 3 slave_id = 0x00 # gets current values if context[slave_id].zero_mode: START_ADDRESS = FIRST_REGISTER # if zero_mode=True else: START_ADDRESS = FIRST_REGISTER-1 # if zero_mode=False. inizia a leggere da 40000 e prendi gli N successivi,escluso il 40000 values = context[slave_id].getValues(register, START_ADDRESS, count=NUM_REGISTERS) # update P and Q with random values log.debug("pump context values: " + str(values)) decoder = BinaryPayloadDecoder.fromRegisters(values[502:503],endian=Endian.Little) bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(values[552:553],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(values[506:507],endian=Endian.Little) bits_506 = decoder.decode_bits() bits_506 += decoder.decode_bits() if g_Time >= s_Time > 0: print "start iniettore dopo {0} secondi".format(s_Time) log.debug("start iniettore dopo {0} secondi".format(s_Time)) s_Time = 0 bits_502[7] = 1 # START INIETTORE bits_builder = BinaryPayloadBuilder(endian=Endian.Little) bits_builder.add_bits(bits_502) bits_reg=bits_builder.to_registers() values[502:503]=[bits_reg[0]] cicli_min = 0 p_new = 0 # if iniettore Started if bits_502[7]: s_Time = 0 #cicli_min = cicli_rand.rvs() cicli_min = int( out_val_q(g_Time,50.) ) p_new = int(out_val_p(g_Time,values[560])) + delta_rand.rvs() + 1 if p_new < 1: cicli_min = 70. else: cicli_min = 70./p_new if g_Time % 13 == 0: g_increment += 1 p_new = p_new + g_increment ########################################## ### Verifica limite massimo P ############################# if p_new >= values[560]: log.debug("PMax exceeded: %d (516) > %d (560)" % (p_new,values[560]) ) p_new = values[560] + delta_rand.rvs() + 1 ########################################## ### Verifica limite massimo Q ############################# if cicli_min >= values[562]: log.debug("QMax exceeded: %d (520) > %d (562)" % (cicli_min,values[562]) ) cicli_min = values[562] else: if values[560] == 0: print "560 è zero" values[560] = 1 if p_new/values[560] >= 0.5: cicli_min = max(1,int((values[560])/max(1,p_new))) else: cicli_min = 3*values[560]/max(1,p_new) else: cicli_min = 0 p_new = 0 log.debug("p_new=%d" % p_new) q_val = cicli_min*liters_cycle q_m_ch = 60.0*q_val/1000.0 log.debug("cicli=%d, q=%f, mc=%f" % (cicli_min, q_val,q_m_ch)) # conversione float - Endian.Little il primo è il meno significativo if p_new < 0: p_new = 0 if cicli_min < 0: cicli_min = 0 values[516] = p_new # %MW516 PRESSIONE ATTUALE values[520] = cicli_min builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_32bit_float(q_val) builder.add_32bit_float(q_m_ch) reg=builder.to_registers() log.debug("2 x 32bit_float = %s" % str(reg)) values[522:526]=reg log.debug("On Pump Server %02d new values (516-525): %s" % (srv_id, str(values[516:526]))) # assign new values to context values[599] = 699 context[slave_id].setValues(register, START_ADDRESS, values)