def setValues(self, address, values): ''' Sets the requested values of the datastore :param address: The starting address :param values: The new values to be set ''' if not isinstance(values, list): values = [values] start = address - self.address self.values[start:start + len(values)] = values if start <= 550 < start + len(values): if self.values[500] != values[550-start]: logInfo.debug("ModbusMySequentialDataBlock.setValues updating 500({0}) with new value {1}".format(self.values[500],values[550-start])) self.values[500] = values[550-start] if start <= 552 < start + len(values): global g_Time global s_Time decoder = BinaryPayloadDecoder.fromRegisters(self.values[502:503],endian=Endian.Little) bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(self.values[506:507],endian=Endian.Little) bits_506 = decoder.decode_bits() bits_506 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(values[552-start:553-start],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() logInfo.debug("ModbusMySequentialDataBlock.setValues updating 552({0}) {1}".format(values[552-start], bits_552)) if bits_552[2]: print "ModbusMySequentialDataBlock.setValues start iniettore da remoto" logInfo.debug("ModbusMySequentialDataBlock.setValues start iniettore da remoto") g_Time = 0 bits_502[7] = 1 # START INIETTORE self.hndlr.pumpStarted = True bits_506[2] = 1 bits_506[3] = 0 bits_552[2] = 0 bits_builder = BinaryPayloadBuilder(endian=Endian.Little) bits_builder.add_bits(bits_502) bits_builder.add_bits(bits_506) bits_builder.add_bits(bits_552) bits_reg = bits_builder.to_registers() self.values[502:503]=[bits_reg[0]] self.values[506:507]=[bits_reg[1]] self.values[552:553]=[bits_reg[2]] if bits_552[3]: print "ModbusMySequentialDataBlock.setValues stop iniettore da remoto" logInfo.debug("ModbusMySequentialDataBlock.setValues stop iniettore da remoto") bits_502[7] = 0 # STOP INIETTORE bits_506[2] = 0 self.hndlr.pumpStarted = False bits_506[3] = 1 bits_552[3] = 0 bits_builder = BinaryPayloadBuilder(endian=Endian.Little) bits_builder.add_bits(bits_502) bits_builder.add_bits(bits_506) bits_builder.add_bits(bits_552) bits_reg=bits_builder.to_registers() self.values[502:503]=[bits_reg[0]] self.values[506:507]=[bits_reg[1]] self.values[552:553]=[bits_reg[2]]
def testPayloadBuilderWithRawPayload(self): """ Test basic bit message encoding/decoding """ _coils1 = [ False, False, True, True, False, True, False, False, False, False, False, True, False, False, True, False, False, True, True, True, True, False, False, False, False, True, False, True, False, True, True, False ] _coils2 = [ False, False, False, True, False, False, True, False, False, False, True, True, False, True, False, False, False, True, False, True, False, True, True, False, False, True, True, True, True, False, False, False ] builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], repack=True) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([13330, 30806], builder.to_registers()) c = builder.to_coils() self.assertEqual(_coils1, c) builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], byteorder=Endian.Big) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([4660, 22136], builder.to_registers()) self.assertEqual('\x12\x34\x56\x78', str(builder)) c = builder.to_coils() self.assertEqual(_coils2, c)
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 testPayloadBuilderWithRawPayload(self): """ Test basic bit message encoding/decoding """ _coils1 = [False, False, True, True, False, True, False, False, False, False, False, True, False, False, True, False, False, True, True, True, True, False, False, False, False, True, False, True, False, True, True, False] _coils2 = [False, False, False, True, False, False, True, False, False, False, True, True, False, True, False, False, False, True, False, True, False, True, True, False, False, True, True, True, True, False, False, False] builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], repack=True) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([13330, 30806], builder.to_registers()) c = builder.to_coils() self.assertEqual(_coils1, c) builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], byteorder=Endian.Big) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([4660, 22136], builder.to_registers()) self.assertEqual('\x12\x34\x56\x78', str(builder)) c = builder.to_coils() self.assertEqual(_coils2, c)
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 on_switchPumpStatus_state_set(self, switch,gparam): self.ret_p=self.client_p.connect() rr = self.client_p.read_holding_registers(500,100,unit=1) # conversione in bit array da 552 decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[52:53],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[2:7],endian=Endian.Little) # 502 bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() # 503 bits_503 = decoder.decode_bits() bits_503 += decoder.decode_bits() # 504 bits_504 = decoder.decode_bits() bits_504 += decoder.decode_bits() # 505 bits_505 = decoder.decode_bits() bits_505 += decoder.decode_bits() # 506 bits_506 = decoder.decode_bits() bits_506 += decoder.decode_bits() bSendCommand = False if switch.get_active(): # %MW552:X2 START INIET. DA REMOTO bSendCommand = not bits_502[7] bits_552[2] = True bits_552[3] = False bits_552[14] = True else: # %MW552:X2 STOP INIET. DA REMOTO bSendCommand = bits_502[7] bits_552[2] = False bits_552[3] = True bits_552[14] = False builder = BinaryPayloadBuilder(endian=Endian.Little) # builder.add_bits(bits_502) builder.add_bits(bits_552) reg_552 = builder.to_registers() rr.registers[52:53] = reg_552 self.p_count += 1 rr.registers[50] = self.p_count if bSendCommand: self.client_p.write_registers(500, rr.registers,unit=1) if bits_552[2]: bits_552[2] = False builder = BinaryPayloadBuilder(endian=Endian.Little) # builder.add_bits(bits_502) builder.add_bits(bits_552) reg_552 = builder.to_registers() self.client_p.write_register(552, reg_552[0]) print "pulsante rilasciato" self.client_p.close()
def checkPump(self,client_p): rr = client_p.read_holding_registers(500,100,unit=1) # conversione in bit array da 552 decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[52:53],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() bits_552[10] = True b_builder = BinaryPayloadBuilder(endian=Endian.Little) b_builder.add_bits(bits_552) reg_552 = b_builder.to_registers() rr.registers[52:53] = reg_552 for it in range(10): self.p_count += 1 rr.registers[50] = self.p_count rq = client_p.write_registers(500, rr.registers,unit=1) if rq.function_code < 0x80: rr_p = client_p.read_holding_registers(500,100,unit=1) if len(rr_p.registers)==100 and rr_p.registers[0]==self.p_count: decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[2:7],endian=Endian.Little) # 502 bits_502 = decoder.decode_bits() bits_502 += decoder.decode_bits() # 503 bits_503 = decoder.decode_bits() bits_503 += decoder.decode_bits() # 504 bits_504 = decoder.decode_bits() bits_504 += decoder.decode_bits() # 505 bits_505 = decoder.decode_bits() bits_505 += decoder.decode_bits() # 506 bits_506 = decoder.decode_bits() bits_506 += decoder.decode_bits() if bits_502[7]: builder.get_object("switchPumpStatus").set_active(True) else: builder.get_object("switchPumpStatus").set_active(False) if bits_502[4] == False and bits_502[10] == True: builder.get_object("switchPumpStatus").set_sensitive(True) else: builder.get_object("switchPumpStatus").set_sensitive(False) else: print "errore checkPump %d" % self.p_count bits_552[10] = False print str(bits_552) b_builder = BinaryPayloadBuilder(endian=Endian.Little) b_builder.add_bits(bits_552) reg_552_2 = b_builder.to_registers() rr.registers[52:53] = reg_552_2 rq = client_p.write_registers(500, rr.registers,unit=1) if rq.function_code < 0x80: pass else: print "checkPump terminato con scrittura KO"
def testPayloadBuilderWithRawPayload(self): """ Test basic bit message encoding/decoding """ builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78']) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([13330, 30806], builder.to_registers()) builder = BinaryPayloadBuilder([b'\x12', b'\x34', b'\x56', b'\x78'], byteorder=Endian.Big) self.assertEqual(b'\x12\x34\x56\x78', builder.to_string()) self.assertEqual([4660, 22136], builder.to_registers()) self.assertEqual('\x12\x34\x56\x78', str(builder))
def updateData(self): if self.mode == self.MODE_ANGLE: builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) builder.add_16bit_int(self.angle) payload = builder.to_registers() self.client.write_register(4, payload[0], unit=self.id) elif self.mode == self.MODE_SPEED: builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) builder.add_16bit_int(self.speed) payload = builder.to_registers()[0] self.client.write_register(3, payload, unit=self.id)
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 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 prefil_registers(a): context=a[0] # Values to be filled: # 4000 SERIAL NUMBER, length 2, 13070001 HEX # 4002 MeterCode, length 1, 0102 HEX # 4003 Meter ID, Length 1, 0001 # 4004 Baud, Length 1, 9600 # 4005 Protocol Version, Lenth 2, 3.2 # 4007 Software Version, Length 2, 1.18 # 4009 Hardware Version, Length 2, 1.03 # 400B Meter Amps, Length 1, 45 # 400D S0 Rate, Length 2, 1000 # 400F Combination Code, Length 1, 10 (Forward - Reverse) # 4010 LCD LifeCycle, Lenght 1, 01 HEX # 4011 Parity Setting, Length 1, 01 # 4012 Current Direction, Lenght 1, FW ASCII builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_float(0x13070001) builder.add_16bit_int(0x0102) builder.add_16bit_int(1) builder.add_16bit_int(9600) builder.add_32bit_float(3.2) builder.add_32bit_float(1.18) builder.add_32bit_float(1.03) builder.add_16bit_int(45) # builder.add_16bit_int(0) payload = builder.to_registers() context[0x01].setValues(0x10, 0x4000, payload) # Skip Address builder2 = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder2.add_32bit_float(1000) builder2.add_16bit_int(10) builder2.add_16bit_int(0x10) builder2.add_16bit_int(01) builder2.add_string('FW') payload2 = builder2.to_registers() context[0x01].setValues(0x10, 0x400D, payload2) # 5000 builder3 = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder3.add_32bit_float(230) builder3.add_32bit_float(230) builder3.add_32bit_float(230) builder3.add_32bit_float(230) builder3.add_32bit_float(50) payload3 = builder3.to_registers() context[0x01].setValues(0x10, 0x5000, payload3)
def encode(self, slave_id, block_name, offset, value, formatter): builder = BinaryPayloadBuilder(byteorder=self.byte_order, wordorder=self.word_order) add_method = ENCODERS.get(formatter) getattr(builder, add_method)(value) payload = builder.to_registers() return self.set_values(slave_id, block_name, offset, payload)
def on_btnSetPump_clicked(self,button): rr_p = self.client_p.read_holding_registers(500,100,unit=1) decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[52:53],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() self.pmax = self.adjustPMax.get_value() _qmax = self.adjustQMax.get_value() self.p_count += 1 rr_p.registers[50] = self.p_count rr_p.registers[60] = int(self.pmax) if self.chkPAna.get_active(): self.qmax = getFlowRateAsVolts(_qmax) v = getVoltsFromFlowRate(self.qmax) print "_qmax => {0} self.qmax => {1} c => {2}".format(_qmax, self.qmax, v) rr_p.registers[64] = self.qmax rr_p.registers[62] = int(_qmax/litCiclo) bits_552[12] = True else: self.qmax = _qmax rr_p.registers[62] = int(self.qmax) rr_p.registers[64] = cicli_volt[int(self.qmax)] bits_552[12] = False b_builder = BinaryPayloadBuilder(endian=Endian.Little) # builder.add_bits(bits_502) b_builder.add_bits(bits_552) reg_552 = b_builder.to_registers() rr_p.registers[52:53] = reg_552 rr_p = self.client_p.write_registers(500,rr_p.registers,unit=1)
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 read_holding_registers(self, addr, num, unit): builder = BinaryPayloadBuilder(byteorder=cinergiaByteOrder, wordorder=cinergiaWordOrder) builder.add_32bit_uint(self._mockRegisters[addr]) ret = ReadHoldingRegistersResponse() ret.registers = builder.to_registers() return ret
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 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 set_target(self, target): builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_int(target) request = self.sync_client.write_registers(SET_MOTOR_TARGET, builder.to_registers(), unit=self.address) return not request.isError()
def setSpeed(self, speed): # Set up aim to speed and set up speed if self.mode != self.MODE_SPEED: self.mode = self.MODE_SPEED builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) builder.add_16bit_int(int(speed)) payload = builder.to_registers()[0] self.client.write_register(3, payload, unit=self.id)
def setPWM(self, pwm): # Set up aim to pwm and set up pwm if self.mode != self.MODE_PWM: self.mode = self.MODE_NONE self.mode = self.MODE_PWM builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little) builder.add_16bit_int(int(pwm)) payload = builder.to_registers()[0] self.client.write_register(2, payload, unit=self.id)
def stop_iniettore(p_client): b_ok = False bits_552 = [False]*16 bits_552[3] = True # %MW552:X3 STOP INIET.DA REMOTO builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_bits(bits_552) reg_552 = builder.to_registers() rq = p_client.write_register(552, reg_552[0],unit=1) b_ok = rq.function_code < 0x80 # test that we are not an error return b_ok
def start_iniettore(p_client): b_ok = False n_numReg = 5 # leggo 502 a 506 per verificare bit di controllo p_rr = p_client.read_holding_registers(502,n_numReg,unit=1) decoder = BinaryPayloadDecoder.fromRegisters(p_rr.registers,endian=Endian.Little) reg={} regnum = 502 for i in range(n_numReg): bits_50x = decoder.decode_bits() bits_50x += decoder.decode_bits() reg[regnum+i] = bits_50x if reg[502][4]: log.error("Pompa in allarme") else: if reg[502][6]: log.debug("Pompa olio on") if reg[502][7]: log.error("Ciclo Iniettore ON") else: log.debug("Ciclo Iniettore OFF") # %MW502:X10 Macchina pronta per comando remoto b_ok = reg[502][10] if b_ok: log.debug("Macchina pronta per comando remoto") else: log.error(u"Macchina non è pronta per comando remoto") b_ok &= check_alarms(reg[504]) if b_ok: log.debug("...nessun allarme rilevato") p_comandi_remoto = p_client.read_holding_registers(560,3,unit=1) remote_reg = [0]*3 remote_reg = p_comandi_remoto.registers log.debug("COMANDO BAR DA REMOTO IMPOSTATO a %d" % remote_reg[0]) # %MW560 16 bit 0-100 bar COMANDO BAR DA REMOTO log.debug("COMANDO NUMERO CICLI MINUTO DA REMOTO a %d" % remote_reg[2]) # %MW562 16 bit < 40 COMANDO NUMERO CICLI MINUTO DA REMOTO remote_reg[0] = DEFAULT_BAR remote_reg[2] = DEFAULT_CICLI rq = p_client.write_registers(560, remote_reg,unit=1) b_ok = rq.function_code < 0x80 # test that we are not an error if b_ok: bits_552 = [False]*16 bits_552[2] = True # %MW552:X2 START INIET. DA REMOTO builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_bits(bits_552) reg_552 = builder.to_registers() rq = p_client.write_register(552, reg_552[0],unit=1) b_ok = rq.function_code < 0x80 # test that we are not an error else: log.error("start_iniettore SET Comandi BAR e CICLI REMOTO fallito!") else: log.debug("...verificare allarmi rilevati") else: log.error("Pompa olio OFF") return b_ok
def write_uint32(self, addr, value): ''' Writes 32 bits unsigned integer value into the cinergia registers :param addr: register address :param value: register value ''' builder = BinaryPayloadBuilder( byteorder=cinergiaByteOrder, wordorder=cinergiaWordOrder) builder.add_32bit_uint(value) registers = builder.to_registers() return self._modbusClient.write_registers(addr, registers, unit=255)
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 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 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 _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 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
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 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 set_target(self, target): """ Sets the target for the motor :param target: Units of acceleration measured in SMunits. Please use the converter class to convert from desired units to steps. :return: Boolean indicating if the write was successful """ builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Big) builder.add_32bit_int(target) request = self.modbus_client.write_registers(SET_MOTOR_TARGET, builder.to_registers(), unit=self.address) return not request.isError()
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 _write(self, value): builder = BinaryPayloadBuilder(byteorder='>', wordorder='<') builder.add_16bit_uint(value) payload = builder.to_registers() try: with ModbusTcpClient(self.host, self.port) as client: result = client.write_registers(self.COMMAND_ADDRESS, payload) except ConnectionException as e: raise ttypes.LesediException(str(e)) if result.isError(): raise ttypes.LesediException(str(result))
def write_registers(self, address, count, 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(v) for v in value.split(',')] LOG.debug('packing value: {}'.format(value)) for val in value: method = self.get_builder_method(eval_mode, 1) LOG.debug('using method: {}'.format(method)) getattr(builder, method)(val) payload = builder.to_registers() else: method = self.get_builder_method(eval_mode, count) LOG.debug('value: {} method: {} count: {}'.format( value, method, count)) getattr(builder, method)(value) payload = builder.to_registers() LOG.debug("payload: {}".format(payload)) # decode just to verify... decoder = BinaryPayloadDecoder.fromRegisters(payload, byteorder=byteorder, wordorder=wordorder) dmethod = self.get_decoder_method(eval_mode, count) decoded = getattr(decoder, dmethod)() LOG.debug("decoded: {}".format(decoded)) LOG.debug("encoded == decoded: {}".format(value == decoded)) LOG.debug(payload) with self.__device_lock: response = self.client.write_registers(address, payload, unit=self.slave_id) return resposne
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 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 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 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 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 __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 on_btnSetPump_clicked(self,button): rr_p = self.client_p.read_holding_registers(500,100,unit=1) decoder = BinaryPayloadDecoder.fromRegisters(rr_p.registers[52:53],endian=Endian.Little) bits_552 = decoder.decode_bits() bits_552 += decoder.decode_bits() self.pmax = self.adjustPMax.get_value() self.qmax = self.adjustQMax.get_value() self.p_count += 1 rr_p.registers[50] = self.p_count rr_p.registers[60] = int(self.pmax) if self.chkPAna.get_active(): rr_p.registers[64] = int(self.qmax) # TODO rr_p.registers[62] = equivalente mappato bits_552[12] = True else: rr_p.registers[62] = int(self.qmax) rr_p.registers[64] = cicli_volt[int(self.qmax)] bits_552[12] = False b_builder = BinaryPayloadBuilder(endian=Endian.Little) # builder.add_bits(bits_502) b_builder.add_bits(bits_552) reg_552 = b_builder.to_registers() rr_p.registers[52:53] = reg_552 rr_p = self.client_p.write_registers(500,rr_p.registers,unit=1)
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
print "Macchina senza allarmi e pronta per comando remoto" # Leggo START INIETTORE DA REMOTO reg 522 rr = client.read_holding_registers(40552,1) decoder = BinaryPayloadDecoder.fromRegisters(rr.registers,endian=Endian.Little) as_bits = decoder.decode_bits() as_bits += decoder.decode_bits() print "522 " + str(as_bits) if bits_506[2]: print u"Macchina già avviata con comando remoto" if as_bits[3] == False: print u"STOP INIETTORE DA REMOTO è abassato" # Accendo bit STOP INIETTORE DA REMOTO as_bits[3] = 1 builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_bits(as_bits) reg=builder.to_registers() print reg rq = client.write_register(40552, reg[0]) assert(rq.function_code < 0x80) # test that we are not an error else: print u"STOP INIETTORE DA REMOTO è ancora alzato" else: if as_bits[2] == False: print u"START INIETTORE DA REMOTO è abassato" # Accendo bit START INIETTORE DA REMOTO as_bits[2] = 1 builder = BinaryPayloadBuilder(endian=Endian.Little) builder.add_bits(as_bits) reg=builder.to_registers() print reg rq = client.write_register(40552, reg[0])
# build your payload #---------------------------------------------------------------------------# 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]) #---------------------------------------------------------------------------# # 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.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=5020) 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.Big, 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(0x12345678DEADBEEF) builder.add_64bit_float(123.45) builder.add_64bit_float(-123.45) payload = builder.to_registers() print("-" * 60) print("Writing Registers") print("-" * 60) print(payload) print("\n") payload = builder.build() address = 0 # Can write registers # registers = builder.to_registers() # client.write_registers(address, registers, unit=1) # Or can write encoded binary string 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 = 0x0 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.Little) decoded = OrderedDict([ ('string', decoder.decode_string(8)), ('bits', decoder.decode_bits()), ('8int', decoder.decode_8bit_int()), ('8uint', decoder.decode_8bit_uint()), ('16int', decoder.decode_16bit_int()), ('16uint', decoder.decode_16bit_uint()), ('32int', decoder.decode_32bit_int()), ('32uint', decoder.decode_32bit_uint()), ('32float', decoder.decode_32bit_float()), ('32float2', decoder.decode_32bit_float()), ('64int', decoder.decode_64bit_int()), ('64uint', decoder.decode_64bit_uint()), ('ignore', decoder.skip_bytes(8)), ('64float', decoder.decode_64bit_float()), ('64float2', decoder.decode_64bit_float()), ]) 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()
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)
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)