예제 #1
0
def bytes_to_status(bytes_, status_type):
    """Convert bytes to trip and digital input statuses

    """
    # The 4 bits for a state is contained i 4 bytes, gather them up into one list
    all_states = []
    for byte_ in bytes_:
        pay = BinaryPayloadDecoder(byte_)
        bits_ = pay.decode_bits()  # 8 booleans
        all_states.extend([bits_[:4], bits_[4:]])

    # The 3 bit indicates whether status is used, sort out the rest
    all_states = [state for state in all_states if state[3]]
    
    states = {}
    for state_num, state_bits in enumerate(all_states, start=1):  # Enumeration starts at 1
        # The first 3 bits has 3 different meanings: on, inhibit and override
        # First make sure only one is set
        if sum(state_bits[:3]) > 1:
            raise ValueError('Bad state: {}'.format(state_bits))

        # Then translate, if none is set, default to off
        for bit_num, bit_meaning in enumerate(['on', 'inhibit', 'override']):
            if state_bits[bit_num]:
                states[status_type + str(state_num)] = bit_meaning
                break
        else:
            states[status_type + str(state_num)] = 'off'

    return states
예제 #2
0
 def testPayloadDecoderReset(self):
     """ Test the payload decoder reset functionality """
     decoder = BinaryPayloadDecoder(b'\x12\x34')
     self.assertEqual(0x12, decoder.decode_8bit_uint())
     self.assertEqual(0x34, decoder.decode_8bit_uint())
     decoder.reset()   
     self.assertEqual(0x3412, decoder.decode_16bit_uint())
예제 #3
0
    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]]
예제 #4
0
    def __init__(self, payload, byteorder):
        """ Initialize a new instance of the SunspecDecoder

        .. note:: This is always set to big endian byte order
        as specified in the protocol.
        """
        byteorder = Endian.Big
        BinaryPayloadDecoder.__init__(self, payload, byteorder)
예제 #5
0
    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"
예제 #6
0
    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()
예제 #7
0
    def testPayloadDecoderRegisterFactory(self):
        """ Test the payload decoder reset functionality """
        payload = [1, 2, 3, 4]
        decoder = BinaryPayloadDecoder.fromRegisters(payload, endian=Endian.Little)
        encoded = "\x00\x01\x00\x02\x00\x03\x00\x04"
        self.assertEqual(encoded, decoder.decode_string(8))

        decoder = BinaryPayloadDecoder.fromRegisters(payload, endian=Endian.Big)
        encoded = "\x00\x01\x00\x02\x00\x03\x00\x04"
        self.assertEqual(encoded, decoder.decode_string(8))

        self.assertRaises(ParameterException, lambda: BinaryPayloadDecoder.fromRegisters("abcd"))
예제 #8
0
    def testPayloadDecoderCoilFactory(self):
        """ Test the payload decoder reset functionality """
        payload = [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]
        decoder = BinaryPayloadDecoder.fromCoils(payload, endian=Endian.Little)
        encoded = "\x11\x88"
        self.assertEqual(encoded, decoder.decode_string(2))

        decoder = BinaryPayloadDecoder.fromCoils(payload, endian=Endian.Big)
        encoded = "\x11\x88"
        self.assertEqual(encoded, decoder.decode_string(2))

        self.assertRaises(ParameterException, lambda: BinaryPayloadDecoder.fromCoils("abcd"))
예제 #9
0
	def read(self):
		count = COUNTS.get(self.data_type)
		if not count:
			raise ValueError('Unsupported data type {}'.format(self.data_type))

		_logger.debug('read register: {}, count: {}, slave: {}, function: {}'.format(self.register_addr, count, self.slave_id, self.function_code))
		if self.function_code == 3:
			result = self.client.read_holding_registers(self.register_addr, count, unit=self.slave_id)
		elif self.function_code == 4:
			result = self.client.read_input_registers(self.register_addr, count, unit=self.slave_id)
		else:
			raise ValueError('Unsupported function code {}'.format(self.function_code))
		if result is None:
			raise IOError('No modbus reponse')
		if isinstance(result, ExceptionResponse):
			raise IOError(str(result))

		d = BinaryPayloadDecoder.fromRegisters(result.registers, endian=self.endian)

		if self.data_type == '16bit_int':
			value = d.decode_16bit_int()
		elif self.data_type == '16bit_uint':
			value = d.decode_16bit_uint()
		elif self.data_type == '32bit_int':
			value = d.decode_32bit_int()
		elif self.data_type == '32bit_uint':
			value = d.decode_32bit_uint()
		elif self.data_type == '32bit_float':
			value = d.decode_32bit_float()
		elif self.data_type == '64bit_float':
			value = d.decode_64bit_float()
		else:
			raise ValueError('Unsupported data type {}'.format(self.data_type))
		return value
예제 #10
0
파일: helper.py 프로젝트: bashwork/pymodbus
    def decode(self, formatters, byte_order='big', word_order='big'):
        """
        Decode the register response to known formatters.

        :param formatters: int8/16/32/64, uint8/16/32/64, float32/64
        :param byte_order: little/big
        :param word_order: little/big
        :return: Decoded Value
        """
        # Read Holding Registers (3)
        # Read Input Registers (4)
        # Read Write Registers (23)
        if not isinstance(formatters, (list, tuple)):
            formatters = [formatters]

        if self.function_code not in [3, 4, 23]:
            print_formatted_text(
                HTML("<red>Decoder works only for registers!!</red>"))
            return
        byte_order = (Endian.Little if byte_order.strip().lower() == "little"
                      else Endian.Big)
        word_order = (Endian.Little if word_order.strip().lower() == "little"
                      else Endian.Big)
        decoder = BinaryPayloadDecoder.fromRegisters(self.data.get('registers'),
                                                     byteorder=byte_order,
                                                     wordorder=word_order)
        for formatter in formatters:
            formatter = FORMATTERS.get(formatter)
            if not formatter:
                print_formatted_text(
                    HTML("<red>Invalid Formatter - {}"
                         "!!</red>".format(formatter)))
                return
            decoded = getattr(decoder, formatter)()
            self.print_result(decoded)
예제 #11
0
    def checkPump(self,client_p):
        self.p_count += 1
        rq = client_p.write_register(550,self.p_count,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)                
        self.setPumpFlowAndPressure()
예제 #12
0
 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 requestLoop(self):

        meterreadings = {}

        try:
            if (self.client.connect() is False):
                print('not connected')
                self.client = self.client.connect()
                print('trying to connecto to ' + str(self.pfcIp))
#==============================================================================
#       Read current timestamp from PFC
#==============================================================================
            timestampSys = round(time.time() * 1000)
            result2 = self.client.read_holding_registers(4, 4)
            decoder = BinaryPayloadDecoder.fromRegisters(result2.registers, endian=Endian.Little)
            timestampPFC = decoder.decode_64bit_int()

#==============================================================================
#       Reads the values from modbus registers clamp by clamp
#       and buffers the results in  meterreadings{}
#		It is not possible to read all registers in one request because of the limitation of the Modbus-Message size to 255kb
# 		When the results of all clamps are buffered, they are published
#==============================================================================
            result = self.client.read_coils(16, 4)
            meterreadings = {'shStarr': result.bits[0],
                             'sh4QS': result.bits[1],
                             'speicherSh': result.bits[2],
                             'speicher4QS': result.bits[3]}
#==============================================================================
#        standardize both TimestampPFC and TimestampSYS precision to be millisecond
#==============================================================================
            meterreadingsToCompare = {}
            meterreadingsToCompare = meterreadings
            self.oldState.pop('TimestampPFC', None)
            self.oldState.pop('TimestampSYS', None)
            self.elapsedTime = self.elapsedTime + 1
            if (self.oldState != meterreadingsToCompare) or (self.elapsedTime >= 60):
                self.elapsedTime = 0
                self.oldState = meterreadingsToCompare
                meterreadings['TimestampPFC'] = str(timestampPFC)[0:13]
                meterreadings['TimestampSYS'] = round(time.time() * 1000)
                self.publish(u'eshl.wago.v1.readout.misc.4qs', json.dumps(meterreadings, sort_keys=True))
                self.publish(u'eshl.wago.v2.readout.misc.4qs', meterreadings)
#==============================================================================
#      If there is no connection to the pfc-modbus slave or no connection to the pfc at all
#      the blankDataSet is published
#==============================================================================
#==============================================================================
#         except ConnectionException as connErr:
#              for x in range(0, len(self.clamps)):
#                         meterreadings[self.clamps[x]] = json.dumps(self.blankDataSetGen(), sort_keys=True)
#              self.publish(u'org.eshl.wago.readout.meter.494', json.dumps(meterreadings,sort_keys=True))
#              print(str(connErr))
#==============================================================================
        except Exception as err:

            print("error: {}".format(err), file=sys.stdout)
            traceback.print_exc(file=sys.stdout)
예제 #14
0
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
예제 #15
0
 def __decodeData(self, data):
     """Decode MODBUS data to float
     
     Function decodes a list of MODBUS 32bit float data passed to it
     into its respective list of floats.
     
     Arguments:
     :param data: Data to be decoded
     :type data: list
     """
     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
예제 #16
0
def readChannels():
    # voltage phase 1 to neutral
    print "New measurement readings: ", int(time.time())
    listValues = list()
    for c in listChannels:
    	handle = client.read_holding_registers(c['register'],c['words'],unit=c['unit'])
    	# print c['description'], ":"
    	if c['words'] > 1:
    		decoder = BinaryPayloadDecoder.fromRegisters(handle.registers, endian=Endian.Big)
    		value = decoder.decode_32bit_int()/float(c['factor'])
    	else:
    		value = handle.registers[0]/float(c['factor'])
    	#print c['description'], ":", str(value)
    	listValues.append(value)	

    for i, channel in enumerate(listChannels):
    	# print channel['description'],":", channel['uuid'], int(time.time()*1000), listValues[i]
    	# Here fire values into VZ middleware
    	addValue(channel['uuid'], int(time.time()*1000), listValues[i])
예제 #17
0
def read_register(client, register):    
    logger.info("---- Read register " + str(register))

    try:
        rr = client.read_holding_registers(register, count=2, unit=1)
        logger.info("Register value are " + str(rr.registers))
        
        # build register
        reg=[0, 0]
        reg[0] = rr.registers[0]
        reg[1] = rr.registers[1]
    
        # decode register 
        decoder = BinaryPayloadDecoder.fromRegisters(reg, endian=Endian.Big)
        decoded = decoder.decode_32bit_float()
        
        logger.info("Register decoded value are " + str(decoded))
        return decoded
    except ConnectionException:
        raise ConnectionExceptionRest("")
    def __get_mc602(self, address):

        try:
            log.debug("Attempting to read from MC602")
            registers = self.read_input_registers( \
                address = address, count = 2, unit = 65)
            log.debug("Successfully read registers from MC602")
            log.debug("Attempting to convert registers")

            # registers are encoded in "big endian", however the attribute
            # to convert to a float value in pymodbus therefore is Little
            # (and not Big as expected)! Details in class Constants/Endian

            decoder = BinaryPayloadDecoder.fromRegisters(registers, \
                endian = Endian.Little)
            float_value = decoder.decode_32bit_float()
            log.debug("Successfully converted registers to float_value")
            
            return float_value

        except:
            log.error("Failed to read from MC602")
예제 #19
0
    def read(self):
        for x in self.queue[self.current]:
            try:
                t = util.now()
                self.res = self.client.read_holding_registers(3900, 100, unit=x.Id)

                if (self.res == None):
                    continue

                for y in xrange(0, len(self.parameters[x.Model])):
                    read_reg = self.reading_registers[x.Model][y]
                    if (read_reg == 92 or read_reg == 98):
                        decoder = BinaryPayloadDecoder.fromRegisters(self.res.registers[read_reg:read_reg + 2],
                                                                     endian=Endian.Big)
                        value = decoder.decode_32bit_uint()
                    else:
                        value = convert((self.res.registers[read_reg + 1] << 16) + self.res.registers[read_reg])
                    self.add('/Meter' + str(x.Id) + '/' + self.parameters[x.Model][y], t, value)

            except SerialException:
                print "Serial Exception encountered. Looking for new tty port."
                self.client = self.CONNECT_TO_METER()

        pop_count = len(self.queue[self.current])
        for x in xrange(0, pop_count):
            popped = self.queue[self.current].pop(0)
            next_index = (self.current + popped.Rate) % self.SLOWEST_POSSIBLE_RATE

            while (len(self.queue[next_index]) == 2):
                next_index += 1
                if (next_index == self.SLOWEST_POSSIBLE_RATE):
                    next_index = 0

            self.queue[next_index].append(popped)

        self.current = (self.current + 1) % self.SLOWEST_POSSIBLE_RATE
예제 #20
0
    def on_btnShow_clicked(self,button):
        # show dlgRegistries
        self.lstDialog = builder.get_object("dlgRegistries")
        self.liststore = builder.get_object("liststore1")
        if not self.ret_p:
            self.ret_p = self.client_p.connect()
        if self.ret_p:
            self.liststore.clear()
            rr = self.client_p.read_holding_registers(500,100,unit=1)
            for idx in [0,2,4,6,12,13,14,15,16,20,50,52,60,62]:
                if idx in (2,4,6,52):
                    decoder = BinaryPayloadDecoder.fromRegisters(rr.registers[idx:idx+1],endian=Endian.Little)
                    bits = decoder.decode_bits()
                    bits += decoder.decode_bits()
                    for ib, b in enumerate(bits):
                        if b:
                            sCode = "%MW5{0:02d}:X{1}".format(idx,ib)
                            self.liststore.append([sCode,reg_descr[sCode], str( b ) ])
                else:
                    sCode = "%MW5{0:02d}".format(idx)
                    self.liststore.append([sCode, reg_descr[sCode], str( rr.registers[idx]) ])    
        response = self.lstDialog.run()

        self.lstDialog.hide()
예제 #21
0
 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)
예제 #22
0
def run_binary_payload_ex():
    # ----------------------------------------------------------------------- #
    # We are going to use a simple client to send our requests
    # ----------------------------------------------------------------------- #
    client = ModbusClient('127.0.0.1', port=5440)
    client.connect()
    
    # ----------------------------------------------------------------------- #
    # If you need to build a complex message to send, you can use the payload
    # builder to simplify the packing logic.
    #
    # Here we demonstrate packing a random payload layout, unpacked it looks
    # like the following:
    #
    # - a 8 byte string 'abcdefgh'
    # - a 32 bit float 22.34
    # - a 16 bit unsigned int 0x1234
    # - another 16 bit unsigned int 0x5678
    # - an 8 bit int 0x12
    # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
    # - an 32 bit uint 0x12345678
    # - an 32 bit signed int -0x1234
    # - an 64 bit signed int 0x12345678

    # The packing can also be applied to the word (wordorder) and bytes in each
    # word (byteorder)

    # The wordorder is applicable only for 32 and 64 bit values
    # Lets say we need to write a value 0x12345678 to a 32 bit register

    # The following combinations could be used to write the register

    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #
    # Word Order - Big                      Byte Order - Big
    # word1 =0x1234 word2 = 0x5678

    # Word Order - Big                      Byte Order - Little
    # word1 =0x3412 word2 = 0x7856

    # Word Order - Little                   Byte Order - Big
    # word1 = 0x5678 word2 = 0x1234

    # Word Order - Little                   Byte Order - Little
    # word1 =0x7856 word2 = 0x3412
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #

    # ----------------------------------------------------------------------- #
    builder = BinaryPayloadBuilder(byteorder=Endian.Little,
                                   wordorder=Endian.Big)
    builder.add_string('abcdefgh')
    builder.add_32bit_float(22.34)
    builder.add_16bit_uint(0x1234)
    builder.add_16bit_uint(0x5678)
    builder.add_8bit_int(0x12)
    builder.add_bits([0, 1, 0, 1, 1, 0, 1, 0])
    builder.add_32bit_uint(0x12345678)
    builder.add_32bit_int(-0x1234)
    builder.add_64bit_int(0x1234567890ABCDEF)
    payload = builder.build()
    address = 0
    client.write_registers(address, payload, skip_encode=True, unit=1)
    # ----------------------------------------------------------------------- #
    # If you need to decode a collection of registers in a weird layout, the
    # payload decoder can help you as well.
    #
    # Here we demonstrate decoding a random register layout, unpacked it looks
    # like the following:
    #
    # - a 8 byte string 'abcdefgh'
    # - a 32 bit float 22.34
    # - a 16 bit unsigned int 0x1234
    # - another 16 bit unsigned int which we will ignore
    # - an 8 bit int 0x12
    # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
    # ----------------------------------------------------------------------- #
    address = 0x00
    count = len(payload)
    result = client.read_holding_registers(address, count,  unit=1)
    print("-" * 60)
    print("Registers")
    print("-" * 60)
    print(result.registers)
    print("\n")
    decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                 byteorder=Endian.Little,
                                                 wordorder=Endian.Big)
    decoded = {
        'string': decoder.decode_string(8),
        'float': decoder.decode_32bit_float(),
        '16uint': decoder.decode_16bit_uint(),
        'ignored': decoder.skip_bytes(2),
        '8int': decoder.decode_8bit_int(),
        'bits': decoder.decode_bits(),
        "32uints": decoder.decode_32bit_uint(),
        "32ints": decoder.decode_32bit_int(),
        "64ints": decoder.decode_64bit_int(),
    }
    
    print("-" * 60)
    print("Decoded Data")
    print("-" * 60)
    for name, value in iteritems(decoded):
        print("%s\t" % name, hex(value) if isinstance(value, int) else value)
    
    # ----------------------------------------------------------------------- #
    # close the client
    # ----------------------------------------------------------------------- #
    client.close()
예제 #23
0
 def ReadUInt64(self, addr):
     data = self.client.read_holding_registers(addr, 4, unit=71)
     UInt64register = BinaryPayloadDecoder.fromRegisters(
         data.registers, byteorder=Endian.Big, wordorder=Endian.Big)
     result = UInt64register.decode_64bit_uint()
     return (result)
예제 #24
0
idslave = 0x01

if len(sys.argv) == 2:
    try:
        idslave = int(sys.argv[1])
    except:
        print "usage: %s [idslave]" % sys.argv[0]
        sys.exit(-1)

# get running mode
print "modbus cmd: 0x03 value: 0x0000 length: 0x01\n"
result = client.read_holding_registers(address=0x0000,
                                       count=0x01,
                                       unit=idslave)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                             endian=Endian.Big)
print decoder.decode_16bit_int(), " (running mode)\n",

print

# get loader version
print "modbus cmd: 0x03 value: 0x0001 length: 0x02\n"
result = client.read_holding_registers(address=0x0001,
                                       count=0x02,
                                       unit=idslave)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                             endian=Endian.Big)
x = decoder.decode_32bit_int()
print ''.join(chr((x >> 8 * (4 - byte - 1)) & 0xFF)
              for byte in range(4)), " (software version)\n",
예제 #25
0
 def __read_s16(self, adr_dec):
     result = self.client.read_holding_registers(adr_dec, 1, unit=71)
     s16_value = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                    byteorder=Endian.Big,
                                                    wordorder=Endian.Little)
     return s16_value.decode_16bit_uint()
예제 #26
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
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #

    # ----------------------------------------------------------------------- #
    combos = [(wo, bo) for wo in [Endian.Big, Endian.Little]
              for bo in [Endian.Big, Endian.Little]]
    for wo, bo in combos:
        print("-" * 60)
        print("Word Order: {}".format(ORDER_DICT[wo]))
        print("Byte Order: {}".format(ORDER_DICT[bo]))
        print()
        builder = BinaryPayloadBuilder(byteorder=bo, wordorder=wo)
        strng = "abcdefgh"
        builder.add_string(strng)
        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(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=bo,
                                                     wordorder=wo)

        assert decoder._byteorder == builder._byteorder, \
                "Make sure byteorder is consistent between BinaryPayloadBuilder and BinaryPayloadDecoder"

        assert decoder._wordorder == builder._wordorder, \
                "Make sure wordorder is consistent between BinaryPayloadBuilder and BinaryPayloadDecoder"

        decoded = OrderedDict([
            ('string', decoder.decode_string(len(strng))),
            ('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()),
            ('16float', decoder.decode_16bit_float()),
            ('16float2', decoder.decode_16bit_float()),
            ('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()
예제 #27
0
    def get_current_status(self):
        """
        Gets the current status of the motor, including running data, operating data, and error data.
        :return: A dictionary containing the current data of the motor. Please use the converter class to convert each value into the appropriate unit.
        """
        motor_running_data = self.modbus_client.read_holding_registers(
            MOTOR_POS, 4, unit=self.address)
        motor_voltage_data = self.modbus_client.read_holding_registers(
            MOTOR_VOLTAGE, 1, unit=self.address)
        motor_current_data = self.modbus_client.read_holding_registers(
            TORQUE_CURRENT, 1, unit=self.address)
        motor_operating_data = self.modbus_client.read_holding_registers(
            TEMP_ELECTRONICS, 2, unit=self.address)
        motor_error_data = self.modbus_client.read_holding_registers(
            ERROR, 1, unit=self.address)
        if motor_running_data.isError() or motor_error_data.isError(
        ) or motor_voltage_data.isError() or motor_current_data.isError(
        ) or motor_operating_data.isError():
            raise Exception('Unable to get motor data. {}'.format(
                motor_running_data, motor_operating_data, motor_current_data,
                motor_voltage_data, motor_error_data))
        decoder = BinaryPayloadDecoder.fromRegisters(
            motor_running_data.registers[0:2],
            byteorder=Endian.Big,
            wordorder=Endian.Big)
        decoder2 = BinaryPayloadDecoder.fromRegisters(
            motor_voltage_data.registers,
            byteorder=Endian.Big,
            wordorder=Endian.Big)
        decoder3 = BinaryPayloadDecoder.fromRegisters(
            motor_current_data.registers,
            byteorder=Endian.Big,
            wordorder=Endian.Big)
        decoder4 = BinaryPayloadDecoder.fromRegisters(
            motor_running_data.registers[3:4],
            byteorder=Endian.Big,
            wordorder=Endian.Big)
        error = motor_error_data.registers[0]

        if error == 0:
            error = "No error"
        if error == 1:
            error = "General internal error"
        if error == 2:
            error = "Internal software timing error"
        if error == 3:
            error = "Error in application: code not terminating"
        if error == 4097:
            error = "General communication error"
        if error == 4098:
            error = "Invalid register error"
        if error == 4353:
            error = "Modbus parity error"
        if error == 4354:
            error = "Modbus framing error"
        if error == 4355:
            error = "Modbus overrun error"
        if error == 4356:
            error = "Modbus checksum error"
        if error == 4357:
            error = "Modbus illegal function code error"
        if error == 4358:
            error = "Modbus illegal diagnostics function code error"
        if error == 8193:
            error = "Hardware overcurrent protection triggered"
        if error == 12289:
            error = "Supply voltage too low"
        if error == 12290:
            error = "Supply voltage too high"
        if error == 16385:
            error = "Temperature of electronics is too high"
        if error == 16386:
            error = "Temperature of motor winding is too high"
        if error == 20481:
            error = "Torque limiting is active"
        if error == 24577:
            error = "Locked shaft condition detected"
        if error == 28673:
            error = "Regulator error is large"

        # TIP: You can get true current drawn by the motor, by multiplying the torque value, and it's corresponding
        # speed.
        return {
            "position": decoder.decode_32bit_int(),
            "speed": motor_running_data.registers[2],
            "torque": decoder4.decode_16bit_int(),
            "voltage": decoder2.decode_16bit_int(),
            "current": decoder3.decode_16bit_int(),
            "electronics_temp": motor_operating_data.registers[0],
            "motor_temp": motor_operating_data.registers[1],
            "error": error
        }
예제 #28
0
def readmodbus(modbusid, register, fieldtype, readtype, serialport,
               current_baud):
    instrument = ModbusSerialClient(method='rtu',
                                    port=serialport,
                                    baudrate=current_baud,
                                    parity='E')
    instrument.connect()

    #print("Reading ModbusID %d register %d"%(modbusid,register)),
    x = None
    read = False
    validread = True
    while read == False:
        lock = True

        if lock:

            read = True
            # instrument.serial.reset_input_buffer()
            signed = False
            try:
                if fieldtype in ['int', 'sint']:
                    readlen = 1
                if fieldtype in ['long', 'slong', 'float']:
                    readlen = 2
                if fieldtype == 'string':
                    readlen = 10
                #print(".")
                if readtype == 3:
                    x = instrument.read_holding_registers(register,
                                                          readlen,
                                                          unit=modbusid,
                                                          timeout=.5)
                if readtype == 4:
                    x = instrument.read_input_registers(register,
                                                        readlen,
                                                        unit=modbusid,
                                                        timeout=.5)
                #print("..")
                instrument.close()
                #print(x)
                decoder = BinaryPayloadDecoder.fromRegisters(
                    x.registers, byteorder=Endian.Big)
                if fieldtype == 'slong':
                    x = decoder.decode_32bit_int()
                if fieldtype == 'long':
                    x = decoder.decode_32bit_uint()
                if fieldtype == 'sint':
                    x = decoder.decode_16bit_int()
                if fieldtype == 'int':
                    x = decoder.decode_16bit_uint()
                if fieldtype == 'float':
                    x = decoder.decode_32bit_float()
                if fieldtype == 'string':
                    x = decoder.decode_string(10)

            except Exception as e:
                print(e)
                x = 0
                validread = False
    #print(x,validread)
    #if fieldtype in ['sint','slong','int','long']:
    #    print("%X"%x)
    #time.sleep(.1)
    return x
예제 #29
0
def adquisicion():
    #try:
    global PStotal, PLtotal, PTred, PBtotal, sw, VpanelT, IpanelT
    k = 1
    while True:

        #tic = tm.default_timer()
        #Inicializacion de variables antes de entrar al loop y obtener los promedios
        IpanelT = 0
        VpanelT = 0

        IcargaT = 0
        VcargaT = 0

        IbatT = 0
        VbatT = 0

        for j in range(501):

            ##potencia del panel solar

            Ipanel = mcp.read_adc(7)  ## Corriente del panel solar
            Ipanel = ((Ipanel) * (5.15 / 1023)) + 0.03
            #Ipanel=(-25.3+10*Ipanel)-0.2
            Ipanel = (-2.6 + Ipanel) * (1 / 0.09693)
            IpanelT = IpanelT + Ipanel  ## Suma de corriente del panel solar sin promediar

            Vpanel = mcp.read_adc(4)
            Vpanel = Vpanel * (5.15 / 1023)
            #*(37.5/7.5)  ## voltaje del panel solar
            Vpanel = 4.093 * Vpanel + 3.4444
            VpanelT = VpanelT + Vpanel  #  Suma de voltaje del panel solar sin promediar

            ## potencia de la carga
            Vcarga = mcp.read_adc(6)
            Vcarga = ((Vcarga) * (5.15 / 1023)) * (37000.0 / 7500.0)
            VcargaT = VcargaT + Vcarga
            Icarga = mcp.read_adc(0)  ##
            Icarga = round(((Icarga) * (5.15 / 1023)),
                           2)  ## voltaje desde el MCP
            #S_5=(-25.3+10*S_5m)-0.2
            Icarga = (-2.54 + Icarga) * (1 / 0.095
                                         )  ## calculo de corriente de la carga
            IcargaT = IcargaT + Icarga

            ## potencia de la bateria
            Ibat = mcp.read_adc(1)
            Ibat = ((Ibat) * (5.15 / 1023))
            #Vsensor=Vsensor+Ibat
            #Ibat=(-2.54+Ibat)*(1/0.1852)
            IbatT = IbatT + Ibat
            Vbat = mcp.read_adc(5)
            Vbat = ((Vbat) * (5.15 / 1023)) * (37000.0 / 7500.0)
            VbatT = VbatT + Vbat

            #j=j+1
        #toc = tm.default_timer()
        ## potencia del panel solar
        PStotal = round((IpanelT * VpanelT) / (j * j),
                        2)  ## potencia del panel solar promedio

        ## potencia de la carga
        IcargaT = (IcargaT / j) - 0.2
        PLtotal = (VcargaT / j) * IcargaT
        PLtotal = round(
            (-6.96327 + 0.742732 * PLtotal + 0.00062677 * PLtotal * PLtotal) +
            2, 2)

        ## potencia de la bateria
        IbatT = IbatT / j

        if IbatT < 2.4:
            IbatT = 6 * IbatT - 14.28
        elif IbatT > 2.46:
            IbatT = 5 * IbatT - 11.86
        else:
            Ibat = 0

        PBtotal = (round((IbatT * VbatT) / (j), 2)) - 13

        if PLtotal < 2:
            PLtotal = 0

        elif PStotal < 2:
            PStotal = 0

        result = client.read_holding_registers(11729, 2,
                                               unit=1)  #Current A 1100
        decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                     byteorder=Endian.Big)
        PTred = decoder.decode_32bit_float()
        #if Pred<6:
        #	Pred=8.1

        sw = 1

        k = k + 1

        VpanelT = (VpanelT / j)
        IpanelT = IpanelT / j

        #hoja.write(k, 0,     str(state))

        #hoja.write(k, 1,     str(VpanelT))

        #hoja.write(k, 2,     str(IpanelT))

        #hoja.write(k, 3,     str(PTred))

        #hoja.write(k, 4,     str(PLtotal))

        #hoja.write(k, 5,     str(PBtotal))

        #hoja.write(k, 6,     time.strftime("%X"))

        #	print("Voltaje del panel solar = "+str(VpanelT))
        #	print("Corriente del panel solar ="+str(IpanelT))
        #	print("Potencia de la red = "+str(PTred))
        #	print("Potencia del panel = "+str(PStotal))
        #	print("Potencia de la bat = "+str(PBtotal))
        #	print("Corriente de la bat = "+str(IbatT))
        #	print("Voltaje de la bat = "+str(VbatT/j))
        #	print("Potencia de la carga = "+str(PLtotal))
        #	print(state)

        to5 = False
        Estados(state, to5)

        time.sleep(2)
        Potencias = [PTred, PStotal, PBtotal, PLtotal]
        return Potencias
예제 #30
0
    def read(self):
        """ Read registers from client"""

        time.sleep(float(self._settings["interval"]))
        f = []
        c = Cargo.new_cargo(rawdata="")
        if not self._modcon:
            self._con.close()
            self._log.info("Not connected, retrying connect" +
                           str(self.init_settings))
            self._con = self._open_modTCP(self.init_settings["modbus_IP"],
                                          self.init_settings["modbus_port"])

        if self._modcon:
            #self._log.info(" names " + str(self._settings["rName"]))
            rNameList = self._settings["rName"]
            #self._log.info("rNames type: " + str(type(rNameList)))
            registerList = self._settings["register"]
            nRegList = self._settings["nReg"]
            rTypeList = self._settings["rType"]

            for idx, rName in enumerate(rNameList):
                register = int(registerList[idx])
                qty = int(nRegList[idx])
                rType = rTypeList[idx]
                self._log.debug("register # : " + str(register))

                try:
                    self.rVal = self._con.read_holding_registers(register - 1,
                                                                 qty,
                                                                 unit=1)
                    assert (self.rVal.function_code < 0x80)
                except Exception as e:
                    self._log.error("Connection failed on read of register: " +
                                    str(register) + " : " + str(e))
                    self._modcon = False
                else:
                    #self._log.debug("register value:" + str(self.rVal.registers)+" type= " + str(type(self.rVal.registers)))
                    #f = f + self.rVal.registers
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        self.rVal.registers, endian=Endian.Big)
                    self._log.debug("register type: " + str(rType))

                    if rType == "uint16":
                        rValD = decoder.decode_16bit_uint()
                        t = emonhub_coder.encode('H', rValD)
                        f = f + list(t)
                    elif rType == "uint32":
                        rValD = decoder.decode_32bit_uint()
                        t = emonhub_coder.encode('I', rValD)
                        f = f + list(t)
                    elif rType == "uint64":
                        rValD = decoder.decode_64bit_uint()
                        t = emonhub_coder.encode('Q', rValD)
                        f = f + list(t)
                    elif rType == "int16":
                        rValD = decoder.decode_16bit_int()
                        t = emonhub_coder.encode('h', rValD)
                        f = f + list(t)
                    elif rType == "string":
                        rValD = decoder.decode_string(qty * 2)
                    elif rType == "float32":
                        rValD = decoder.decode_32bit_float() * 10
                        t = emonhub_coder.encode('f', rValD)
                        f = f + list(t)
                    else:
                        self._log.error("Register type not found: " +
                                        str(rType) + " Register:" +
                                        str(register))
                    self._log.debug("Encoded value: " + str(t))

            self._log.debug("reporting data: " + str(f))
            if int(self._settings['nodeId']):
                c.nodeid = int(self._settings['nodeId'])
                c.realdata = f
            else:
                c.nodeid = int(12)
                c.realdata = f
            self._log.debug("Return from read data: " + str(c.realdata))

        return c
예제 #31
0
        reg2_324 = client2.read_holding_registers(324, 2, unit=71)
        # Plenticore Register 326: Monthly_yield [Wh]
        # ist PV Monatsertrag
        reg2_326 = client2.read_holding_registers(326, 2, unit=71)
    except:
        # Lesefehler bei den Registern, also Abbruch und mit 0 initialisierte Variablen in die Ramdisk
        write_log_entry(
            'Fehler beim Lesen der Modbus-Register WR2 (falsche IP oder WR offline?)'
        )
        write_to_ramdisk()
        exit()

# ausgelesene Register WR 1 dekodieren
#FRegister_100 = BinaryPayloadDecoder.fromRegisters(reg_100.registers, byteorder=Endian.Big, wordorder=Endian.Little)
FRegister_150 = BinaryPayloadDecoder.fromRegisters(reg_150.registers,
                                                   byteorder=Endian.Big,
                                                   wordorder=Endian.Little)
FRegister_220 = BinaryPayloadDecoder.fromRegisters(reg_220.registers,
                                                   byteorder=Endian.Big,
                                                   wordorder=Endian.Little)
FRegister_222 = BinaryPayloadDecoder.fromRegisters(reg_222.registers,
                                                   byteorder=Endian.Big,
                                                   wordorder=Endian.Little)
FRegister_224 = BinaryPayloadDecoder.fromRegisters(reg_224.registers,
                                                   byteorder=Endian.Big,
                                                   wordorder=Endian.Little)
FRegister_230 = BinaryPayloadDecoder.fromRegisters(reg_230.registers,
                                                   byteorder=Endian.Big,
                                                   wordorder=Endian.Little)
FRegister_232 = BinaryPayloadDecoder.fromRegisters(reg_232.registers,
                                                   byteorder=Endian.Big,
예제 #32
0
def decode(value):
	value_d = decode.fromRegisters(value.registers, endian=Endian.Little)
	value_d ={'float':A_d.decode_32bit_float(),}
	for i, value in value_d.iteritems():
	      value=value
	return value
예제 #33
0
    def onHeartbeat(self):
        #Domoticz.Log("onHeartbeat called")

        # Wich serial port settings to use?
        if (Parameters["Mode3"] == "S1B7PN"): StopBits, ByteSize, Parity = 1, 7, "N"
        if (Parameters["Mode3"] == "S1B7PE"): StopBits, ByteSize, Parity = 1, 7, "E"
        if (Parameters["Mode3"] == "S1B7PO"): StopBits, ByteSize, Parity = 1, 7, "O"
        if (Parameters["Mode3"] == "S1B8PN"): StopBits, ByteSize, Parity = 1, 8, "N"
        if (Parameters["Mode3"] == "S1B8PE"): StopBits, ByteSize, Parity = 1, 8, "E"
        if (Parameters["Mode3"] == "S1B8PO"): StopBits, ByteSize, Parity = 1, 8, "O"
        if (Parameters["Mode3"] == "S2B7PN"): StopBits, ByteSize, Parity = 2, 7, "N"
        if (Parameters["Mode3"] == "S2B7PE"): StopBits, ByteSize, Parity = 2, 7, "E"
        if (Parameters["Mode3"] == "S2B7PO"): StopBits, ByteSize, Parity = 2, 7, "O"
        if (Parameters["Mode3"] == "S2B8PN"): StopBits, ByteSize, Parity = 2, 8, "N"
        if (Parameters["Mode3"] == "S2B8PE"): StopBits, ByteSize, Parity = 2, 8, "E"
        if (Parameters["Mode3"] == "S2B8PO"): StopBits, ByteSize, Parity = 2, 8, "O"

        # How many registers to read (depending on data type)?
	    # Added additional options for byte/word swapping
        registercount = 1 # Default
        if (Parameters["Mode6"] == "noco"): registercount = 1
        if (Parameters["Mode6"] == "int8LSB"): registercount = 1
        if (Parameters["Mode6"] == "int8MSB"): registercount = 1
        if (Parameters["Mode6"] == "int16"): registercount = 1
        if (Parameters["Mode6"] == "int16s"): registercount = 1
        if (Parameters["Mode6"] == "int32"): registercount = 2
        if (Parameters["Mode6"] == "int32s"): registercount = 2
        if (Parameters["Mode6"] == "int64"): registercount = 4
        if (Parameters["Mode6"] == "int64s"): registercount = 4
        if (Parameters["Mode6"] == "uint8LSB"): registercount = 1
        if (Parameters["Mode6"] == "uint8MSB"): registercount = 1
        if (Parameters["Mode6"] == "uint16"): registercount = 1
        if (Parameters["Mode6"] == "uint16s"): registercount = 1
        if (Parameters["Mode6"] == "uint32"): registercount = 2
        if (Parameters["Mode6"] == "uint32s"): registercount = 2
        if (Parameters["Mode6"] == "uint64"): registercount = 4
        if (Parameters["Mode6"] == "uint64s"): registercount = 4
        if (Parameters["Mode6"] == "float32"): registercount = 2
        if (Parameters["Mode6"] == "float32s"): registercount = 2
        if (Parameters["Mode6"] == "float64"): registercount = 4
        if (Parameters["Mode6"] == "float64s"): registercount = 4
        if (Parameters["Mode6"] == "string2"): registercount = 2
        if (Parameters["Mode6"] == "string4"): registercount = 4
        if (Parameters["Mode6"] == "string6"): registercount = 6
        if (Parameters["Mode6"] == "string8"): registercount = 8

        # Split address to support TCP/IP device ID
        AddressData = Parameters["Address"].split("/") # Split on "/"
        UnitAddress = AddressData[0]

        # Is there a unit ID given after the IP? (e.g. 192.168.2.100/56)
        UnitIdForIp = 1 # Default
        if len(AddressData) > 1:
          UnitIdForIp = AddressData[1]

        ###################################
        # pymodbus: RTU / ASCII
        ###################################
        if (Parameters["Mode1"] == "rtu" or Parameters["Mode1"] == "ascii"):
          Domoticz.Debug("MODBUS DEBUG USB SERIAL HW - Port="+Parameters["SerialPort"]+", BaudRate="+Parameters["Mode2"]+", StopBits="+str(StopBits)+", ByteSize="+str(ByteSize)+" Parity="+Parity)
          Domoticz.Debug("MODBUS DEBUG USB SERIAL CMD - Method="+Parameters["Mode1"]+", Address="+UnitAddress+", Register="+Parameters["Password"]+", Function="+Parameters["Username"]+", Data type="+Parameters["Mode6"])
          try:
            client = ModbusSerialClient(method=Parameters["Mode1"], port=Parameters["SerialPort"], stopbits=StopBits, bytesize=ByteSize, parity=Parity, baudrate=int(Parameters["Mode2"]), timeout=1, retries=2)
          except:
            Domoticz.Log("Error opening Serial interface on "+Parameters["SerialPort"])
            Devices[1].Update(0, "0") # Update device in Domoticz

        ###################################
        # pymodbus: RTU over TCP
        ###################################
        if (Parameters["Mode1"] == "rtutcp"):
          Domoticz.Debug("MODBUS DEBUG TCP CMD - Method="+Parameters["Mode1"]+", Address="+UnitAddress+", Port="+Parameters["Port"]+", Register="+Parameters["Password"]+", Data type="+Parameters["Mode6"])
          try:
            client = ModbusTcpClient(host=UnitAddress, port=int(Parameters["Port"]), framer=ModbusRtuFramer, auto_open=True, auto_close=True, timeout=5)
          except:
            Domoticz.Log("Error opening TCP interface on address: "+UnitAddress)
            Devices[1].Update(0, "0") # Update device in Domoticz

        ###################################
        # pymodbusTCP: TCP/IP
        ###################################
        if (Parameters["Mode1"] == "tcpip"):
          Domoticz.Debug("MODBUS DEBUG TCP CMD - Method="+Parameters["Mode1"]+", Address="+UnitAddress+", Port="+Parameters["Port"]+", Unit ID="+UnitIdForIp+", Register="+Parameters["Password"]+", Data type="+Parameters["Mode6"])
          try:
            client = ModbusClient(host=UnitAddress, port=int(Parameters["Port"]), unit_id=UnitIdForIp, auto_open=True, auto_close=True, timeout=5)
          except:
            Domoticz.Log("Error opening TCP/IP interface on address: "+UnitAddress)
            Devices[1].Update(0, "0") # Update device in Domoticz

        ###################################
        # pymodbus section
        ###################################
        if (Parameters["Mode1"] == "rtu" or Parameters["Mode1"] == "ascii" or Parameters["Mode1"] == "rtutcp"):
          try:
            # Which function to execute? RTU/ASCII/RTU over TCP
            if (Parameters["Username"] == "1"): data = client.read_coils(int(Parameters["Password"]), registercount, unit=int(UnitIdForIp))
            if (Parameters["Username"] == "2"): data = client.read_discrete_inputs(int(Parameters["Password"]), registercount, unit=int(UnitIdForIp))
            if (Parameters["Username"] == "3"): data = client.read_holding_registers(int(Parameters["Password"]), registercount, unit=int(UnitIdForIp))
            if (Parameters["Username"] == "4"): data = client.read_input_registers(int(Parameters["Password"]), registercount, unit=int(UnitIdForIp))
            Domoticz.Debug("MODBUS DEBUG RESPONSE: " + str(data))
          except:
            Domoticz.Log("Modbus error communicating! (RTU/ASCII/RTU over TCP), check your settings!")
            Devices[1].Update(0, "0") # Update device to OFF in Domoticz

          try:
            # How to decode the input?
            # Added option to swap bytes (little endian)
            if (Parameters["Mode6"] == "int16s" or Parameters["Mode6"] == "uint16s"): 
              decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Little, wordorder=Endian.Big)
            # Added option to swap words (little endian)
            elif (Parameters["Mode6"] == "int32s" or Parameters["Mode6"] == "uint32s" or Parameters["Mode6"] == "int64s" or Parameters["Mode6"] == "uint64s" 
                  or Parameters["Mode6"] == "float32s" or Parameters["Mode6"] == "float64s"):
              decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Little)
            # Otherwise always big endian
            else:
              decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)

            if (Parameters["Mode6"] == "noco"): value = data
            if (Parameters["Mode6"] == "int8LSB"):
              ignored = decoder.skip_bytes(1)
              value = decoder.decode_8bit_int()
            if (Parameters["Mode6"] == "int8MSB"): value = decoder.decode_8bit_int()
            if (Parameters["Mode6"] == "int16"): value = decoder.decode_16bit_int()
            if (Parameters["Mode6"] == "int16s"): value = decoder.decode_16bit_int()
            if (Parameters["Mode6"] == "int32"): value = decoder.decode_32bit_int()
            if (Parameters["Mode6"] == "int32s"): value = decoder.decode_32bit_int()
            if (Parameters["Mode6"] == "int64"): value = decoder.decode_64bit_int()
            if (Parameters["Mode6"] == "int64s"): value = decoder.decode_64bit_int()
            if (Parameters["Mode6"] == "uint8LSB"):
              ignored = decoder.skip_bytes(1)
              value = decoder.decode_8bit_uint()
            if (Parameters["Mode6"] == "uint8MSB"): value = decoder.decode_8bit_uint()
            if (Parameters["Mode6"] == "uint16"): value = decoder.decode_16bit_uint()
            if (Parameters["Mode6"] == "uint16s"): value = decoder.decode_16bit_uint()
            if (Parameters["Mode6"] == "uint32"): value = decoder.decode_32bit_uint()
            if (Parameters["Mode6"] == "uint32s"): value = decoder.decode_32bit_uint()
            if (Parameters["Mode6"] == "uint64"): value = decoder.decode_64bit_uint()
            if (Parameters["Mode6"] == "uint64s"): value = decoder.decode_64bit_uint()
            if (Parameters["Mode6"] == "float32"): value = decoder.decode_32bit_float()
            if (Parameters["Mode6"] == "float32s"): value = decoder.decode_32bit_float()
            if (Parameters["Mode6"] == "float64"): value = decoder.decode_64bit_float()
            if (Parameters["Mode6"] == "float64s"): value = decoder.decode_64bit_float()
            if (Parameters["Mode6"] == "string2"): value = decoder.decode_string(2)
            if (Parameters["Mode6"] == "string4"): value = decoder.decode_string(4)
            if (Parameters["Mode6"] == "string6"): value = decoder.decode_string(6)
            if (Parameters["Mode6"] == "string8"): value = decoder.decode_string(8)
            Domoticz.Debug("MODBUS DEBUG VALUE: " + str(value))

            # Divide the value (decimal)?
            if (Parameters["Mode5"] == "div0"): value = str(value)
            if (Parameters["Mode5"] == "div10"): value = str(round(value / 10, 1))
            if (Parameters["Mode5"] == "div100"): value = str(round(value / 100, 2))
            if (Parameters["Mode5"] == "div1000"): value = str(round(value / 1000, 3))
            if (Parameters["Mode5"] == "div10000"): value = str(round(value / 10000, 4))
            
            Devices[1].Update(0, value) # Update value in Domoticz

          except:
            Domoticz.Log("Modbus error decoding or received no data (RTU/ASCII/RTU over TCP)!, check your settings!")
            Devices[1].Update(0, "0") # Update value in Domoticz

        ###################################
        # pymodbusTCP section
        ###################################
        if (Parameters["Mode1"] == "tcpip"):
          try:
            # Which function to execute? TCP/IP
            if (Parameters["Username"] == "1"): data = client.read_coils(int(Parameters["Password"]), registercount)
            if (Parameters["Username"] == "2"): data = client.read_discrete_inputs(int(Parameters["Password"]), registercount)
            if (Parameters["Username"] == "3"): data = client.read_holding_registers(int(Parameters["Password"]), registercount)
            if (Parameters["Username"] == "4"): data = client.read_input_registers(int(Parameters["Password"]), registercount)
            Domoticz.Debug("MODBUS DEBUG RESPONSE: " + str(data))
          except:
            Domoticz.Log("Modbus error communicating! (TCP/IP), check your settings!")
            Devices[1].Update(0, "0") # Update device to OFF in Domoticz

          try:
            # How to decode the input?
            # Added option to swap bytes (little endian)
            if (Parameters["Mode6"] == "int16s" or Parameters["Mode6"] == "uint16s"):
              decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Little, wordorder=Endian.Big)
            # Added option to swap words (little endian)
            elif (Parameters["Mode6"] == "int32s" or Parameters["Mode6"] == "uint32s" or Parameters["Mode6"] == "int64s" or Parameters["Mode6"] == "uint64s" 
                  or Parameters["Mode6"] == "float32s" or Parameters["Mode6"] == "float64s"):
              decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Little)
            # Otherwise always big endian
            else:
              decoder = BinaryPayloadDecoder.fromRegisters(data, byteorder=Endian.Big, wordorder=Endian.Big)

            if (Parameters["Mode6"] == "noco"): value = data
            if (Parameters["Mode6"] == "int8LSB"):
              ignored = decoder.skip_bytes(1)
              value = decoder.decode_8bit_int()
            if (Parameters["Mode6"] == "int8MSB"): value = decoder.decode_8bit_int()
            if (Parameters["Mode6"] == "int16"): value = decoder.decode_16bit_int()
            if (Parameters["Mode6"] == "int16s"): value = decoder.decode_16bit_int()
            if (Parameters["Mode6"] == "int32"): value = decoder.decode_32bit_int()
            if (Parameters["Mode6"] == "int32s"): value = decoder.decode_32bit_int()
            if (Parameters["Mode6"] == "int64"): value = decoder.decode_64bit_int()
            if (Parameters["Mode6"] == "int64s"): value = decoder.decode_64bit_int()
            if (Parameters["Mode6"] == "uint8LSB"):
              ignored = decoder.skip_bytes(1)
              value = decoder.decode_8bit_uint()
            if (Parameters["Mode6"] == "uint8MSB"): value = decoder.decode_8bit_uint()   
            if (Parameters["Mode6"] == "uint16"): value = decoder.decode_16bit_uint()
            if (Parameters["Mode6"] == "uint16s"): value = decoder.decode_16bit_uint()
            if (Parameters["Mode6"] == "uint32"): value = decoder.decode_32bit_uint()
            if (Parameters["Mode6"] == "uint32s"): value = decoder.decode_32bit_uint()
            if (Parameters["Mode6"] == "uint64"): value = decoder.decode_64bit_uint()
            if (Parameters["Mode6"] == "uint64s"): value = decoder.decode_64bit_uint()
            if (Parameters["Mode6"] == "float32"): value = decoder.decode_32bit_float()
            if (Parameters["Mode6"] == "float32s"): value = decoder.decode_32bit_float()
            if (Parameters["Mode6"] == "float64"): value = decoder.decode_64bit_float()
            if (Parameters["Mode6"] == "float64s"): value = decoder.decode_64bit_float()
            if (Parameters["Mode6"] == "string2"): value = decoder.decode_string(2)
            if (Parameters["Mode6"] == "string4"): value = decoder.decode_string(4)
            if (Parameters["Mode6"] == "string6"): value = decoder.decode_string(6)
            if (Parameters["Mode6"] == "string8"): value = decoder.decode_string(8)
            Domoticz.Debug("MODBUS DEBUG VALUE: " + str(value))

            # Divide the value (decimal)?
            if (Parameters["Mode5"] == "div0"): value = str(value)
            if (Parameters["Mode5"] == "div10"): value = str(round(value / 10, 1))
            if (Parameters["Mode5"] == "div100"): value = str(round(value / 100, 2))
            if (Parameters["Mode5"] == "div1000"): value = str(round(value / 1000, 3))
            if (Parameters["Mode5"] == "div10000"): value = str(round(value / 10000, 4))

            if (value != "0"): Devices[1].Update(1, value) # Update value in Domoticz
            
          except:
            Domoticz.Log("Modbus error decoding or received no data (TCP/IP)!, check your settings!")
            Devices[1].Update(0, "0") # Update value in Domoticz
예제 #34
0
 def __read_float(self, adr_dec):
     result = self.client.read_holding_registers(adr_dec, 2, unit=71)
     float_value = BinaryPayloadDecoder.fromRegisters(
         result.registers, byteorder=Endian.Big, wordorder=Endian.Little)
     return round(float_value.decode_32bit_float(), 2)
예제 #35
0
    f1.write(str(status))
    f1.close()

if os.path.isfile(file_string):
    f = open( file_string , 'a')
else:
    f = open( file_string , 'w')

ipaddress=str(sys.argv[1])
newcurr=int(sys.argv[2])

client = ModbusTcpClient(ipaddress, port=502)

# maxcurr state 1100
resp= client.read_holding_registers(1100,2,unit=255)
decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big)
final = float( decoder.decode_32bit_uint()) / 1000
oldcurr = int("%.f" % final)

# cabel state 1004
resp= client.read_holding_registers(1004,2,unit=255)
decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big)
final2 = float( decoder.decode_32bit_uint())
plugs  = "%.f" % final2

# max supported curr 1110
resp= client.read_holding_registers(1110,2,unit=255)
decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big)
final2 = float( decoder.decode_32bit_uint()) / 1000
supcur = int("%.f" % final2)
if plugs == "7":
예제 #36
0
    def onHeartbeat(self):
        Domoticz.Log("onHeartbeat called")

        ########################################
        # SET HARDWARE - pymodbus: RTU / ASCII
        ########################################
        if (self.Domoticz_Setting_Communication_Mode == "rtu"
                or self.Domoticz_Setting_Communication_Mode == "ascii"):
            Domoticz.Debug("MODBUS DEBUG - INTERFACE: Port=" +
                           self.Domoticz_Setting_Serial_Port + ", BaudRate=" +
                           self.Domoticz_Setting_Baudrate + ", StopBits=" +
                           str(self.StopBits) + ", ByteSize=" +
                           str(self.ByteSize) + " Parity=" + self.Parity)
            Domoticz.Debug("MODBUS DEBUG - SETTINGS: Method=" +
                           self.Domoticz_Setting_Communication_Mode +
                           ", Device ID=" + self.Domoticz_Setting_Device_ID +
                           ", Register=" +
                           self.Domoticz_Setting_Register_Number +
                           ", Function=" +
                           self.Domoticz_Setting_Modbus_Function +
                           ", Data type=" + self.Domoticz_Setting_Data_Type +
                           ", Pollrate=" +
                           self.Domoticz_Setting_Device_Pollrate)
            try:
                client = ModbusSerialClient(
                    method=self.Domoticz_Setting_Communication_Mode,
                    port=self.Domoticz_Setting_Serial_Port,
                    stopbits=self.StopBits,
                    bytesize=self.ByteSize,
                    parity=self.Parity,
                    baudrate=int(self.Domoticz_Setting_Baudrate),
                    timeout=2,
                    retries=2)
            except:
                Domoticz.Error("Error opening Serial interface on " +
                               self.Domoticz_Setting_Serial_Port)
                Devices[1].Update(1, "0")  # Set value to 0 (error)

        ########################################
        # SET HARDWARE - pymodbus: RTU over TCP
        ########################################
        if (self.Domoticz_Setting_Communication_Mode == "rtutcp"):
            Domoticz.Debug("MODBUS DEBUG - INTERFACE: IP=" +
                           self.Domoticz_Setting_TCP_IP + ", Port=" +
                           self.Domoticz_Setting_TCP_PORT)
            Domoticz.Debug("MODBUS DEBUG - SETTINGS: Method=" +
                           self.Domoticz_Setting_Communication_Mode +
                           ", Device ID=" + self.Domoticz_Setting_Device_ID +
                           ", Register=" +
                           self.Domoticz_Setting_Register_Number +
                           ", Function=" +
                           self.Domoticz_Setting_Modbus_Function +
                           ", Data type=" + self.Domoticz_Setting_Data_Type +
                           ", Pollrate=" +
                           self.Domoticz_Setting_Device_Pollrate)
            try:
                client = ModbusTcpClient(host=self.Domoticz_Setting_TCP_IP,
                                         port=int(
                                             self.Domoticz_Setting_TCP_PORT),
                                         framer=ModbusRtuFramer,
                                         auto_open=True,
                                         auto_close=True,
                                         timeout=2)
            except:
                Domoticz.Error(
                    "Error opening RTU over TCP interface on address: " +
                    self.Domoticz_Setting_TCP_IPPORT)
                Devices[1].Update(1, "0")  # Set value to 0 (error)

        ########################################
        # SET HARDWARE - pymodbusTCP: TCP/IP
        ########################################
        if (self.Domoticz_Setting_Communication_Mode == "tcpip"):
            Domoticz.Debug("MODBUS DEBUG - INTERFACE: IP=" +
                           self.Domoticz_Setting_TCP_IP + ", Port=" +
                           self.Domoticz_Setting_TCP_PORT)
            Domoticz.Debug("MODBUS DEBUG - SETTINGS: Method=" +
                           self.Domoticz_Setting_Communication_Mode +
                           ", Device ID=" + self.Domoticz_Setting_Device_ID +
                           ", Register=" +
                           self.Domoticz_Setting_Register_Number +
                           ", Function=" +
                           self.Domoticz_Setting_Modbus_Function +
                           ", Data type=" + self.Domoticz_Setting_Data_Type +
                           ", Pollrate=" +
                           self.Domoticz_Setting_Device_Pollrate)
            try:
                client = ModbusClient(host=self.Domoticz_Setting_TCP_IP,
                                      port=int(self.Domoticz_Setting_TCP_PORT),
                                      unit_id=int(
                                          self.Domoticz_Setting_Device_ID),
                                      auto_open=True,
                                      auto_close=True,
                                      timeout=2)
            except:
                Domoticz.Error("Error opening TCP/IP interface on address: " +
                               self.Domoticz_Setting_TCP_IPPORT)
                Devices[1].Update(1, "0")  # Set value to 0 (error)

        ########################################
        # GET DATA - pymodbus: RTU / ASCII / RTU over TCP
        ########################################
        if (self.Domoticz_Setting_Communication_Mode == "rtu"
                or self.Domoticz_Setting_Communication_Mode == "ascii"
                or self.Domoticz_Setting_Communication_Mode == "rtutcp"):
            try:
                # Function to execute
                if (self.Domoticz_Setting_Modbus_Function == "1"):
                    data = client.read_coils(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count,
                        unit=int(self.Domoticz_Setting_Device_ID))
                if (self.Domoticz_Setting_Modbus_Function == "2"):
                    data = client.read_discrete_inputs(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count,
                        unit=int(self.Domoticz_Setting_Device_ID))
                if (self.Domoticz_Setting_Modbus_Function == "3"):
                    data = client.read_holding_registers(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count,
                        unit=int(self.Domoticz_Setting_Device_ID))
                if (self.Domoticz_Setting_Modbus_Function == "4"):
                    data = client.read_input_registers(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count,
                        unit=int(self.Domoticz_Setting_Device_ID))
                if (self.Read_Scale_Factor == 1):
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data, byteorder=Endian.Big, wordorder=Endian.Big)
                    decoder.skip_bytes((self.Register_Count - 1) * 2)
                    sf_value = decoder.decode_16bit_int()
                    data = data[0:self.Register_Count - 1]
                else:
                    sf_value = 0
                Domoticz.Debug("MODBUS DEBUG - RESPONSE: " + str(data))
            except:
                Domoticz.Error(
                    "Modbus error communicating! (RTU/ASCII/RTU over TCP), check your settings!"
                )
                Devices[1].Update(1, "0")  # Set value to 0 (error)

        ########################################
        # GET DATA - pymodbusTCP: TCP/IP
        ########################################
        if (self.Domoticz_Setting_Communication_Mode == "tcpip"):
            try:
                # Function to execute
                if (self.Domoticz_Setting_Modbus_Function == "1"):
                    data = client.read_coils(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count)
                if (self.Domoticz_Setting_Modbus_Function == "2"):
                    data = client.read_discrete_inputs(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count)
                if (self.Domoticz_Setting_Modbus_Function == "3"):
                    data = client.read_holding_registers(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count)
                if (self.Domoticz_Setting_Modbus_Function == "4"):
                    data = client.read_input_registers(
                        int(self.Domoticz_Setting_Register_Number),
                        self.Register_Count)
                if (self.Read_Scale_Factor == 1):
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data, byteorder=Endian.Big, wordorder=Endian.Big)
                    decoder.skip_bytes((self.Register_Count - 1) * 2)
                    sf_value = decoder.decode_16bit_int()
                    data = data[0:self.Register_Count - 1]
                else:
                    sf_value = 0
                Domoticz.Debug("MODBUS DEBUG RESPONSE: " + str(data))
            except:
                Domoticz.Error(
                    "Modbus error communicating! (TCP/IP), check your settings!"
                )
                Devices[1].Update(1, "0")  # Set value to 0 (error)

        ########################################
        # DECODE DATA TYPE
        ########################################
        # pymodbus (RTU/ASCII/RTU over TCP) will reponse in ARRAY, no matter what values read e.g. MODBUS DEBUG RESPONSE: [2] = data.registers
        # pymodbusTCP (TCP/IP) will give the value back e.g. MODBUS DEBUG RESPONSE: [61, 44] = data
        if (self.Domoticz_Setting_Communication_Mode == "rtu"
                or self.Domoticz_Setting_Communication_Mode == "ascii"
                or self.Domoticz_Setting_Communication_Mode == "rtutcp"):
            try:
                Domoticz.Debug("MODBUS DEBUG - VALUE before conversion: " +
                               str(data.registers[0]))
                # Added option to swap bytes (little endian)
                if (self.Domoticz_Setting_Data_Type == "int16s"
                        or self.Domoticz_Setting_Data_Type == "uint16s"):
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data.registers,
                        byteorder=Endian.Little,
                        wordorder=Endian.Big)
                # Added option to swap words (little endian)
                elif (self.Domoticz_Setting_Data_Type == "int32s"
                      or self.Domoticz_Setting_Data_Type == "uint32s"
                      or self.Domoticz_Setting_Data_Type == "int64s"
                      or self.Domoticz_Setting_Data_Type == "uint64s"
                      or self.Domoticz_Setting_Data_Type == "float32s"
                      or self.Domoticz_Setting_Data_Type == "float64s"):
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data.registers,
                        byteorder=Endian.Big,
                        wordorder=Endian.Little)
                # Otherwise always big endian
                else:
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data.registers,
                        byteorder=Endian.Big,
                        wordorder=Endian.Big)
            except:
                Domoticz.Error(
                    "Modbus error decoding or received no data (RTU/ASCII/RTU over TCP)!, check your settings!"
                )
                Devices[1].Update(1, "0")  # Set value to 0 (error)

        if (self.Domoticz_Setting_Communication_Mode == "tcpip"):
            try:
                Domoticz.Debug("MODBUS DEBUG - VALUE before conversion: " +
                               str(data))
                #value = data[0]
                # Added option to swap bytes (little endian)
                if (self.Domoticz_Setting_Data_Type == "int16s"
                        or self.Domoticz_Setting_Data_Type == "uint16s"):
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data, byteorder=Endian.Little, wordorder=Endian.Big)
                # Added option to swap words (little endian)
                elif (self.Domoticz_Setting_Data_Type == "int32s"
                      or self.Domoticz_Setting_Data_Type == "uint32s"
                      or self.Domoticz_Setting_Data_Type == "int64s"
                      or self.Domoticz_Setting_Data_Type == "uint64s"
                      or self.Domoticz_Setting_Data_Type == "float32s"
                      or self.Domoticz_Setting_Data_Type == "float64s"):
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data, byteorder=Endian.Big, wordorder=Endian.Little)
                # Otherwise always big endian
                else:
                    decoder = BinaryPayloadDecoder.fromRegisters(
                        data, byteorder=Endian.Big, wordorder=Endian.Big)
            except:
                Domoticz.Error(
                    "Modbus error decoding or received no data (TCP/IP)!, check your settings!"
                )
                Devices[1].Update(1, "0")  # Set value to 0 (error)

        ########################################
        # DECODE DATA VALUE
        ########################################
        try:
            if (self.Domoticz_Setting_Data_Type == "noco"):
                value = data.registers[0]
            if (self.Domoticz_Setting_Data_Type == "bool"):
                value = bool(data.registers[0])
            if (self.Domoticz_Setting_Data_Type == "int8LSB"):
                ignored = decoder.skip_bytes(1)
                value = decoder.decode_8bit_int()
            if (self.Domoticz_Setting_Data_Type == "int8MSB"):
                value = decoder.decode_8bit_int()
            if (self.Domoticz_Setting_Data_Type == "int16"):
                value = decoder.decode_16bit_int()
            if (self.Domoticz_Setting_Data_Type == "int16s"):
                value = decoder.decode_16bit_int()
            if (self.Domoticz_Setting_Data_Type == "int32"):
                value = decoder.decode_32bit_int()
            if (self.Domoticz_Setting_Data_Type == "int32s"):
                value = decoder.decode_32bit_int()
            if (self.Domoticz_Setting_Data_Type == "int64"):
                value = decoder.decode_64bit_int()
            if (self.Domoticz_Setting_Data_Type == "int64s"):
                value = decoder.decode_64bit_int()
            if (self.Domoticz_Setting_Data_Type == "uint8LSB"):
                ignored = decoder.skip_bytes(1)
                value = decoder.decode_8bit_uint()
            if (self.Domoticz_Setting_Data_Type == "uint8MSB"):
                value = decoder.decode_8bit_uint()
            if (self.Domoticz_Setting_Data_Type == "uint16"):
                value = decoder.decode_16bit_uint()
            if (self.Domoticz_Setting_Data_Type == "uint16s"):
                value = decoder.decode_16bit_uint()
            if (self.Domoticz_Setting_Data_Type == "uint32"):
                value = decoder.decode_32bit_uint()
            if (self.Domoticz_Setting_Data_Type == "uint32s"):
                value = decoder.decode_32bit_uint()
            if (self.Domoticz_Setting_Data_Type == "uint64"):
                value = decoder.decode_64bit_uint()
            if (self.Domoticz_Setting_Data_Type == "uint64s"):
                value = decoder.decode_64bit_uint()
            if (self.Domoticz_Setting_Data_Type == "float32"):
                value = decoder.decode_32bit_float()
            if (self.Domoticz_Setting_Data_Type == "float32s"):
                value = decoder.decode_32bit_float()
            if (self.Domoticz_Setting_Data_Type == "float64"):
                value = decoder.decode_64bit_float()
            if (self.Domoticz_Setting_Data_Type == "float64s"):
                value = decoder.decode_64bit_float()
            if (self.Domoticz_Setting_Data_Type == "string2"):
                value = decoder.decode_string(2)
            if (self.Domoticz_Setting_Data_Type == "string4"):
                value = decoder.decode_string(4)
            if (self.Domoticz_Setting_Data_Type == "string6"):
                value = decoder.decode_string(6)
            if (self.Domoticz_Setting_Data_Type == "string8"):
                value = decoder.decode_string(8)

            # Apply a scale factor (decimal)
            if (self.Domoticz_Setting_Scale_Factor == "div0"):
                value = str(value)
            if (self.Domoticz_Setting_Scale_Factor == "div10"):
                value = str(round(value / 10, 1))
            if (self.Domoticz_Setting_Scale_Factor == "div100"):
                value = str(round(value / 100, 2))
            if (self.Domoticz_Setting_Scale_Factor == "div1000"):
                value = str(round(value / 1000, 3))
            if (self.Domoticz_Setting_Scale_Factor == "div10000"):
                value = str(round(value / 10000, 4))
            if (self.Domoticz_Setting_Scale_Factor == "mul10"):
                value = str(value * 10)
            if (self.Domoticz_Setting_Scale_Factor == "mul100"):
                value = str(value * 100, 2)
            if (self.Domoticz_Setting_Scale_Factor == "mul1000"):
                value = str(value * 1000, 3)
            if (self.Domoticz_Setting_Scale_Factor == "mul10000"):
                value = str(value * 10000, 4)
            if (self.Domoticz_Setting_Scale_Factor == "sfnextreg"):
                if (sf_value == 0): value = str(value)
                if (sf_value == 1): value = str(round(value * 10, 1))
                if (sf_value == 2): value = str(round(value * 100, 1))
                if (sf_value == -1): value = str(round(value / 10, 1))
                if (sf_value == -2): value = str(round(value / 100, 1))
            Domoticz.Debug("MODBUS DEBUG - VALUE after conversion: " +
                           str(value))
            Devices[1].Update(1, value)  # Update value

        except:
            Domoticz.Error(
                "Modbus error decoding or received no data!, check your settings!"
            )
            Devices[1].Update(1, "0")  # Set value to 0 (error)
예제 #37
0
async def write_to_influx(dbhost, dbport, period, dbname='solaredge'):
    global client

    def trunc_float(floatval):
        return float('%.2f' % floatval)

    try:
        solar_client = InfluxDBClient(host=dbhost, port=dbport, db=dbname)
        await solar_client.create_database(db=dbname)
    except ClientConnectionError as e:
        logger.error(f'Error during connection to InfluxDb {dbhost}: {e}')
        return

    logger.info('Database opened and initialized')
    while True:
        try:
            reg_block = client.read_holding_registers(40069, 38)
            if reg_block:
                # print(reg_block)
                data = BinaryPayloadDecoder.fromRegisters(reg_block,
                                                          byteorder=Endian.Big,
                                                          wordorder=Endian.Big)
                data.skip_bytes(12)
                scalefactor = 10**data.decode_16bit_int()
                data.skip_bytes(-10)
                # Register 40072-40075
                datapoint['fields']['AC Total Current'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                datapoint['fields']['AC Current phase A'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                datapoint['fields']['AC Current phase B'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                datapoint['fields']['AC Current phase C'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                data.skip_bytes(14)
                scalefactor = 10**data.decode_16bit_int()
                data.skip_bytes(-8)
                # register 40080-40082
                datapoint['fields']['AC Voltage phase A'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                datapoint['fields']['AC Voltage phase B'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                datapoint['fields']['AC Voltage phase C'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                data.skip_bytes(4)
                scalefactor = 10**data.decode_16bit_int()
                data.skip_bytes(-4)
                # register 40084
                datapoint['fields']['AC Power output'] = trunc_float(
                    data.decode_16bit_int() * scalefactor)
                data.skip_bytes(24)
                scalefactor = 10**data.decode_16bit_int()
                data.skip_bytes(-6)
                # register 40094
                datapoint['fields']['AC Lifetimeproduction'] = trunc_float(
                    data.decode_32bit_uint() * scalefactor)
                data.skip_bytes(2)
                scalefactor = 10**data.decode_16bit_int()
                data.skip_bytes(-2)
                # register 40097
                datapoint['fields']['DC Current'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                data.skip_bytes(4)
                scalefactor = 10**data.decode_16bit_int()
                data.skip_bytes(-4)
                # register 40099
                datapoint['fields']['DC Voltage'] = trunc_float(
                    data.decode_16bit_uint() * scalefactor)
                data.skip_bytes(4)
                scalefactor = 10**data.decode_16bit_int()
                data.skip_bytes(-4)
                # datapoint 40101
                datapoint['fields']['DC Power input'] = trunc_float(
                    data.decode_16bit_int() * scalefactor)

                datapoint['time'] = str(datetime.datetime.utcnow().replace(
                    tzinfo=datetime.timezone.utc).isoformat())
                logger.debug(f'Writing to Influx: {str(datapoint)}')

                await solar_client.write(datapoint)
            else:
                # Error during data receive
                if client.last_error() == 2:
                    logger.error(
                        f'Failed to connect to SolarEdge inverter {client.host()}!'
                    )
                elif client.last_error() == 3 or client.last_error() == 4:
                    logger.error('Send or receive error!')
                elif client.last_error() == 5:
                    logger.error('Timeout during send or receive operation!')
        except InfluxDBWriteError as e:
            logger.error(f'Failed to write to InfluxDb: {e}')
        except IOError as e:
            logger.error(f'I/O exception during operation: {e}')
        except Exception as e:
            logger.error(f'Unhandled exception: {e}')

        await asyncio.sleep(period)
예제 #38
0
    def onHeartbeat(self):
        self.client.connect()

        result = self.client.read_holding_registers(0, 11)
        if not result.isError():
            on_off = int(result.registers[0])
            eco = int(result.registers[2])
            auto = int(result.registers[3])
            mode = int(result.registers[4]) * 10
            temp_control = int(result.registers[10]) * 10 + 10

            UpdateDevice(self.UNITS['OnOff'], on_off, str(on_off), 0)
            UpdateDevice(self.UNITS['ECO'], eco, str(eco), 0)
            UpdateDevice(self.UNITS['Auto'], auto, str(auto), 0)
            UpdateDevice(self.UNITS['Mode'], mode, str(mode), 0)
            if mode == 50:  # Kitchen
                UpdateDevice(self.UNITS['Kitchen'], 5, str(5), 0)
            elif mode == 60:  # Fireplace
                UpdateDevice(self.UNITS['Fireplace'], 5, str(5), 0)
            else:
                UpdateDevice(self.UNITS['Kitchen'], 0, str(0), 0)
                UpdateDevice(self.UNITS['Fireplace'], 0, str(0), 0)

            UpdateDevice(self.UNITS['TempControlType'], temp_control,
                         str(temp_control), 0)

        registersStartingOffset = 20
        MonitoringDataResult = self.client.read_holding_registers(900, 47)

        if not MonitoringDataResult.isError():
            SupplyTemp = ConvertToFloat(MonitoringDataResult, 1)
            ExtractTemp = ConvertToFloat(MonitoringDataResult, 2)
            OutdoorTemp = ConvertToFloat(MonitoringDataResult, 3)
            WaterTemp = ConvertToFloat(MonitoringDataResult, 4)

            UpdateDevice(self.UNITS['OutdoorTemp'], 0, str(OutdoorTemp), 0)
            UpdateDevice(self.UNITS['SupplyTemp'], 0, str(SupplyTemp), 0)
            UpdateDevice(self.UNITS['ExtractTemp'], 0, str(ExtractTemp), 0)
            UpdateDevice(self.UNITS['WaterTemp'], 0, str(WaterTemp), 0)

            SupplyFanIntens = ConvertToFloat(MonitoringDataResult, 9)
            ExtractFanIntens = ConvertToFloat(MonitoringDataResult, 10)
            HeatExchanger = ConvertToFloat(MonitoringDataResult, 11)
            ElectricHeater = ConvertToFloat(MonitoringDataResult, 12)
            WaterHeater = ConvertToFloat(MonitoringDataResult, 13)
            WaterCooling = ConvertToFloat(MonitoringDataResult, 14)
            DXUnit = ConvertToFloat(MonitoringDataResult, 15)
            FiltersImupurity = float(MonitoringDataResult.registers[16])

            UpdateDevice(self.UNITS['SupplyFanIntensivity'], 0,
                         str(SupplyFanIntens), 0)
            UpdateDevice(self.UNITS['ExtractFanIntensivity'], 0,
                         str(ExtractFanIntens), 0)
            UpdateDevice(self.UNITS['HeatExchanger'], 0, str(HeatExchanger), 0)
            UpdateDevice(self.UNITS['ElectricHeater'], 0, str(ElectricHeater),
                         0)
            UpdateDevice(self.UNITS['WaterHeater'], 0, str(WaterHeater), 0)
            UpdateDevice(self.UNITS['WaterCooler'], 0, str(WaterCooling), 0)
            UpdateDevice(self.UNITS['DXUnit'], 0, str(DXUnit), 0)
            UpdateDevice(self.UNITS['FiltersImupurity'], 0,
                         str(FiltersImupurity), 0)

            CurrentPowerConsumption = int(
                MonitoringDataResult.registers[0 + registersStartingOffset])
            CurrentHeaterPower = int(
                MonitoringDataResult.registers[1 + registersStartingOffset])
            CurrentHeatRecovery = int(
                MonitoringDataResult.registers[2 + registersStartingOffset])
            CurrentExchangeEfficiency = int(
                MonitoringDataResult.registers[3 + registersStartingOffset])
            CurrentEnergySaving = int(
                MonitoringDataResult.registers[4 + registersStartingOffset])

            decoder = BinaryPayloadDecoder.fromRegisters(
                MonitoringDataResult.registers, byteorder=Endian.Big)

            decoder.skip_bytes(6 + 17 * 2 +
                               5 * 4)  # 6 * char + 17 * short + 5 * int
            TotalEnergyConsumtion = decoder.decode_32bit_uint(
            )  # reg[11-12] from byte[21]
            UpdateDevice(
                self.UNITS['TotalEnergyConsumtion'], 0,
                str(CurrentPowerConsumption) + ';' +
                str(TotalEnergyConsumtion), 0)

            decoder.skip_bytes(8)
            TotalHeaterConsumtion = decoder.decode_32bit_uint(
            )  # reg[17-18] from byte[32]
            UpdateDevice(
                self.UNITS['TotalHeaterConsumtion'], 0,
                str(CurrentHeaterPower) + ';' + str(TotalHeaterConsumtion), 0)

            decoder.skip_bytes(8)
            TotalEnergyRecovered = decoder.decode_32bit_uint(
            )  # reg[23-24] from byte[44]
            UpdateDevice(
                self.UNITS['TotalEnergyRecovered'], 0,
                str(CurrentHeatRecovery) + ';' + str(TotalEnergyRecovered), 0)

            temperature = ConvertToFloat(MonitoringDataResult,
                                         25 + registersStartingOffset)
            humidity = int(
                MonitoringDataResult.registers[26 + registersStartingOffset])

            UpdateDevice(self.UNITS['CurrentExchangeEfficiency'], 0,
                         str(CurrentExchangeEfficiency), 0)
            UpdateDevice(self.UNITS['CurrentEnergySaving'], 0,
                         str(CurrentEnergySaving), 0)

            UpdateDevice(self.UNITS['Temp'], 0, str(temperature), 0)
            UpdateDevice(self.UNITS['Hum'], humidity, str(humidity), 0)

            if self.debug:
                Domoticz.Log("CurrentPowerConsumption: " +
                             str(CurrentPowerConsumption))
                Domoticz.Log("CurrentHeaterPower: " + str(CurrentHeaterPower))
                Domoticz.Log("CurrentHeatRecovery: " +
                             str(CurrentHeatRecovery))
                Domoticz.Log("CurrentExchangeEfficiency: " +
                             str(CurrentExchangeEfficiency))
                Domoticz.Log("CurrentEnergySaving: " +
                             str(CurrentEnergySaving))
                Domoticz.Log("CurrentEnergySaving: " +
                             str(CurrentEnergySaving))
                Domoticz.Log("TotalEnergyConsumtion: " +
                             str(TotalEnergyConsumtion))
                Domoticz.Log("TotalHeaterConsumtion: " +
                             str(TotalHeaterConsumtion))
                Domoticz.Log("TotalEnergyRecovered: " +
                             str(TotalEnergyRecovered))
                Domoticz.Log("Temperature: " + str(temperature))
                Domoticz.Log("Humidity: " + str(humidity))

        self.client.close()
예제 #39
0
                   keyfile = private_key,
                   cert_reqs = ssl.CERT_REQUIRED,
                   tls_version = ssl.PROTOCOL_TLSv1_2,
                   ciphers = None)


client.on_connect = on_connect
client.on_message = on_message

client.connect(mqtt_url, port = 8883, keepalive=60)
client.loop_start()

                                                                

# Publish to the same topic in a loop forever                                                                           
loopCount = 0                                                                                                       
while True:         

    Watthour = modclient.read_holding_registers(0x009E, 2, unit=1)                                                
    decoder = BinaryPayloadDecoder.fromRegisters(Watthour.registers, Endian.Big, wordorder=Endian.Little) 

    Wh_val = float(decoder.decode_32bit_float())
    print("WattHour:",Wh_val)

    counter += 1

    client.publish("Aws_regor", "Watthour = " + str(Wh_val) + " " + str(loopCount), 1)
    loopCount += 1                                                                                                                                                    
    sleep(5)                      

예제 #40
0
def Read(Client,
         Tag_Number,
         Average=False,
         count=20,
         sleep_time=.010,
         Bool=False):
    '''
        -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.
            __ Average: Tells us wether or not to average these data points
            __ Count: The number of points that we will average over if Average == True
            __ sleep_time: Time (ms) that we will rest before grabbing the next piece of data

        -Must have established client before attempting to read from the client
        
        -Outputs: The value of that Moodbus tag

        Method: Grab holding register value
                - Decode that value into a 32 bit float
                - Convert from 32 bit float to regular float
        
        -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 = Read(Client,22201)

    '''
    Tag_Number = int(Tag_Number) - 1

    if Bool == False:

        if Average == True:

            temp_list = []
            for i in range(count):
                Payload = Client.read_holding_registers(Tag_Number, 2, unit=1)
                Tag_Value_Bit = BinaryPayloadDecoder.fromRegisters(
                    Payload.registers,
                    byteorder=Endian.Big,
                    wordorder=Endian.Big)
                Tag_Value = Tag_Value_Bit.decode_32bit_float()
                temp_list.append(Tag_Value)

                time.sleep(sleep_time)

            return (sum(temp_list) / count)
        else:
            Payload = Client.read_holding_registers(Tag_Number, 2, unit=1)
            Tag_Value_Bit = BinaryPayloadDecoder.fromRegisters(
                Payload.registers, byteorder=Endian.Big, wordorder=Endian.Big)
            Tag_Value = Tag_Value_Bit.decode_32bit_float()
            return Tag_Value

    if Bool == True:
        Tag_Value = Client.read_coils(Tag_Number, unit=1).bits[0]

    return Tag_Value
예제 #41
0
 def __get_mc602(self, address):
         registers = self.read_input_registers(address = address, count = 2, unit = 65)
         decoder = BinaryPayloadDecoder.fromRegisters(registers, endian = Endian.Little)
         float_value = decoder.decode_32bit_float()
         return float_value
예제 #42
0
 def testLittleEndianPayloadDecoder(self):
     ''' Test basic bit message encoding/decoding '''
     decoder = BinaryPayloadDecoder(self.little_endian_payload, endian=Endian.Little)
     self.assertEqual(1,      decoder.decode_8bit_uint())
     self.assertEqual(2,      decoder.decode_16bit_uint())
     self.assertEqual(3,      decoder.decode_32bit_uint())
     self.assertEqual(4,      decoder.decode_64bit_uint())
     self.assertEqual(-1,     decoder.decode_8bit_int())
     self.assertEqual(-2,     decoder.decode_16bit_int())
     self.assertEqual(-3,     decoder.decode_32bit_int())
     self.assertEqual(-4,     decoder.decode_64bit_int())
     self.assertEqual(1.25,   decoder.decode_32bit_float())
     self.assertEqual(6.25,   decoder.decode_64bit_float())
     self.assertEqual('test', decoder.decode_string(4).decode())
     self.assertEqual(self.bitstring, decoder.decode_bits())
예제 #43
0
 def convert(self, config, data):
     self.__result["telemetry"] = []
     self.__result["attributes"] = []
     for config_data in data:
         for tag in data[config_data]:
             try:
                 configuration = data[config_data][tag]["data_sent"]
                 response = data[config_data][tag]["input_data"]
                 if configuration.get("byteOrder") is not None:
                     byte_order = configuration["byteOrder"]
                 else:
                     byte_order = configuration.get("byteOrder", "LITTLE")
                 endian_order = Endian.Little if byte_order.upper(
                 ) == "LITTLE" else Endian.Big
                 decoded_data = None
                 if not isinstance(response, ModbusIOException):
                     if configuration["functionCode"] in [1, 2]:
                         result = response.bits
                         result = result if byte_order.upper(
                         ) == 'LITTLE' else result[::-1]
                         log.debug(result)
                         if configuration["type"].lower() == "bits":
                             decoded_data = result[:configuration.get(
                                 "objectsCount",
                                 configuration.
                                 get("registersCount",
                                     configuration.get("registerCount", 1)
                                     ))]
                             if len(decoded_data) == 1 and isinstance(
                                     decoded_data, list):
                                 decoded_data = decoded_data[0]
                         else:
                             decoded_data = result[0]
                     elif configuration["functionCode"] in [3, 4]:
                         decoder = None
                         registers = response.registers
                         log.debug("Tag: %s Config: %s registers: %s", tag,
                                   str(configuration), str(registers))
                         try:
                             decoder = BinaryPayloadDecoder.fromRegisters(
                                 registers, byteorder=endian_order)
                         except TypeError:
                             # pylint: disable=E1123
                             decoder = BinaryPayloadDecoder.fromRegisters(
                                 registers, endian=endian_order)
                         assert decoder is not None
                         decoded_data = self.__decode_from_registers(
                             decoder, configuration)
                         if configuration.get("divider"):
                             decoded_data = float(decoded_data) / float(
                                 configuration["divider"])
                         if configuration.get("multiplier"):
                             decoded_data = decoded_data * configuration[
                                 "multiplier"]
                 else:
                     log.exception(response)
                     decoded_data = None
                 if config_data == "rpc":
                     return decoded_data
                 log.debug("datatype: %s \t key: %s \t value: %s",
                           self.__datatypes[config_data], tag,
                           str(decoded_data))
                 self.__result[self.__datatypes[config_data]].append(
                     {tag: decoded_data})
             except Exception as e:
                 log.exception(e)
     log.debug(self.__result)
     return self.__result
예제 #44
0
 def ReadInt32(self, addr):
     data = self.client.read_holding_registers(addr, 2, unit=71)
     Int32register = BinaryPayloadDecoder.fromRegisters(
         data.registers, byteorder=Endian.Big, wordorder=Endian.Big)
     result = Int32register.decode_32bit_int()
     return (result)
예제 #45
0
파일: app.py 프로젝트: stephanlascar/home
def _get_modbus_message(client, adress, count, unit):
    data = client.read_holding_registers(adress, count, unit=unit)
    return BinaryPayloadDecoder.fromRegisters(data.registers,
                                              byteorder=Endian.Big)
예제 #46
0
import numpy as np
import Master as M
import Tag_Database as Tags
from pymodbus.client.sync import ModbusTcpClient
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.constants import Endian

Client = M.Make_Client('10.50.0.10')

Tag_Number = int('00015') - 1

Payload = Client.read_holding_registers(Tag_Number, 2, unit=1)
Tag_Value_Bit = BinaryPayloadDecoder.fromRegisters(Payload.registers,
                                                   byteorder=Endian.Big,
                                                   wordorder=Endian.Big)
Tag_Value = Tag_Value_Bit.decode_32bit_float()

print(True == int(Tag_Value))
예제 #47
0
    def requestLoop(self):

        numberOfRegPerClamp = 74  # max number of holding registers is 125 as the total number of bytes incl. CRC is 256 according to the spec (via 03 command)
        meterreadings = {}
        meterreadingsV2 = {}
        print(time.time())

        try:
            if (self.client.connect() is False):
                print('not connected')
                self.client = self.client.connect()
                print('trying to connecto to ' + str(self.pfcIp))
            address = 0
#==============================================================================
#       Read current timestamp from PFC
#==============================================================================
            timestampSys = round(time.time() * 1000)
            result2 = self.client.read_holding_registers(timestampPFCRegister, 4)
            decoder = BinaryPayloadDecoder.fromRegisters(result2.registers, endian=Endian.Little)
            timestampPFC = decoder.decode_64bit_int()

#==============================================================================
#       Reads the values from modbus registers clamp by clamp
#       and buffers the results in  meterreadings{}
#		It is not possible to read all registers in one request because of the limitation of the Modbus-Message size to 255kb
# 		When the results of all clamps are buffered, they are published
#==============================================================================
            for x in range(0, len(self.clamps)):
                result = self.client.read_holding_registers(address, numberOfRegPerClamp)

                decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
                decoded = {
                    'I1': decoder.decode_32bit_float(),
                    'I2': decoder.decode_32bit_float(),
                    'I3': decoder.decode_32bit_float(),
                    'U1': decoder.decode_32bit_float(),
                    'U2': decoder.decode_32bit_float(),
                    'U3': decoder.decode_32bit_float(),
                    'P1': decoder.decode_32bit_float(),
                    'P2': decoder.decode_32bit_float(),
                    'P3': decoder.decode_32bit_float(),
                    'Q1': decoder.decode_32bit_float(),
                    'Q2': decoder.decode_32bit_float(),
                    'Q3': decoder.decode_32bit_float(),
                    'S1': decoder.decode_32bit_float(),
                    'S2': decoder.decode_32bit_float(),
                    'S3': decoder.decode_32bit_float(),
                    'CosPhi1': decoder.decode_32bit_float(),
                    'CosPhi2': decoder.decode_32bit_float(),
                    'CosPhi3': decoder.decode_32bit_float(),
                    'PF1': decoder.decode_32bit_float(),
                    'PF2': decoder.decode_32bit_float(),
                    'PF3': decoder.decode_32bit_float(),
                    'Qua1': decoder.decode_32bit_float(),
                    'Qua2': decoder.decode_32bit_float(),
                    'Qua3': decoder.decode_32bit_float(),
                    'AEI1': decoder.decode_32bit_float(),
                    'AED1': decoder.decode_32bit_float(),
                    'REI1': decoder.decode_32bit_float(),
                    'REC1': decoder.decode_32bit_float(),
                    'AEI2': decoder.decode_32bit_float(),
                    'AED2': decoder.decode_32bit_float(),
                    'REI2': decoder.decode_32bit_float(),
                    'REC2': decoder.decode_32bit_float(),
                    'AEI3': decoder.decode_32bit_float(),
                    'AED3': decoder.decode_32bit_float(),
                    'REI3': decoder.decode_32bit_float(),
                    'REC3': decoder.decode_32bit_float(),
                    'DataValid' : decoder.decode_32bit_float()}
#==============================================================================
#        standardize both TimestampPFC and TimestampSYS precision to be millisecond
#==============================================================================
                decoded['TimestampPFC'] = str(timestampPFC)[0:13]
                decoded['TimestampSYS'] = timestampSys

#==============================================================================
#                 PFC measures energy values in mWh --> convert to watt-seconds
#==============================================================================
                decoded['AEI1'] = float(decoded['AEI1']) * 3.6
                decoded['AED1'] = float(decoded['AED1']) * 3.6
                decoded['REI1'] = float(decoded['REI1']) * 3.6
                decoded['REC1'] = float(decoded['REC1']) * 3.6
                decoded['AEI2'] = float(decoded['AEI2']) * 3.6
                decoded['AED2'] = float(decoded['AED2']) * 3.6
                decoded['REI2'] = float(decoded['REI2']) * 3.6
                decoded['REC2'] = float(decoded['REC2']) * 3.6
                decoded['AEI3'] = float(decoded['AEI3']) * 3.6
                decoded['AED3'] = float(decoded['AED3']) * 3.6
                decoded['REI3'] = float(decoded['REI3']) * 3.6
                decoded['REC3'] = float(decoded['REC3']) * 3.6

                meterreadingsV2[self.clampsV2[x]] = decoded
                meterreadings[self.clamps[x]] = decoded
                address += numberOfRegPerClamp

            self.publish(u'eshl.wago.v1.readout.wiz.494', json.dumps(meterreadings, sort_keys=True))
            self.publish(u'eshl.wago.v2.readout.wiz.494', meterreadingsV2)

#==============================================================================
#      If there is no connection to the pfc-modbus slave or no connection to the pfc at all
#      the blankDataSet is published
#==============================================================================
        except ConnectionException as connErr:
            for x in range(0, len(self.clamps)):
                    meterreadings[self.clamps[x]] = self.blankDataSetGen()
            self.publish(u'eshl.wago.v1.readout.wiz.494', json.dumps(meterreadings, sort_keys=True))
            self.publish(u'eshl.wago.v2.readout.wiz.494', meterreadings)
            sys.__stdout__.write('ConnectionException in-wago-wiz-494' + '\n' + 'Timestamp: ' + str(timestampSys) + ', Errorcode --> ' + str(connErr))
            sys.__stdout__.flush()
        except Exception as err:
            sys.__stdout__.write('Exception in-wago-wiz-494' + '\n' + 'Timestamp: ' + str(timestampSys) + ', Errorcode --> ' + str(err))
            sys.__stdout__.flush()
예제 #48
0
    def read(self, iO='in'):
        #print('DATEN VOM BUS LESEN')
        i = 0
        if iO !='in':
            x = 'out'
        else:
            x = 'in'
        try:
            for byte in self._db[x]:
                rr = self._modbuspy.read_holding_registers(byte,2)
                pprint(rr)
                decodert2 = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Little)
                ##prüfen welcher dpt typ vorliegt und  dann das registerabfrage ergebnis aufdröseln:
                #->decode_16bit_uint()  -> 7 / 8
                #->decode_8bit_uint()   -> 5 | 5.001
                #->decode_8bit_int()    -> 6
                #->decode_bits()        -> 1
                for bit in self._db[x][byte]:                                                    ##eintraege in dict durchgehen
                    bitpos = bit[0]
                    type =  bit[1]
                    name =  bit[3]
                    
                    if type == '5' or type == '5.001' or type == '6':                                              ##8bit uint / int
                        length = 8
                        
                        if type == '6':
                            lb = decodert2.decode_8bit_int()
                            hb = decodert2.decode_8bit_int()
                            
                        elif type == '5' or type == '5.001':
                            lb = decodert2.decode_8bit_uint()
                            hb = decodert2.decode_8bit_uint()
                            
                        if bitpos < 8:#lb
                            value = hb
                            #logger.debug('MODBUS: byte{0} startpos{1} wert (5) {2}'.format(bit, bitpos,value)) 
                        else:#hb
                            value = lb
                            #logger.debug('MODBUS: byte{0} startpos{1} wert (5) {2}'.format(bit, bitpos,value)) 
                        
                        if type == '5.001':
                            #print('lb/hb Daten gelesen', value)
                            value = self.en5001(value)
                            #logger.debug('MODBUS: byte{0} startpos{1} wert (5.001) {2}'.format(bit, bitpos, value)) 
                    elif type == '7' or type == '8':                                                #16bit uint / int
                        length = 16
                        if type == '7':                                                             #0...65535
                            value = decodert2.decode_16bit_uint()
                            #logger.debug('MODBUS: 16bit uint{0}'.format(value)) 
                        else:                                                                       #-32768...32767
                            value  = decodert2.decode_16bit_int()    
                            #logger.debug('MODBUS: 16bit int{0}'.format(value)) 
                        
                    elif type == '1':
                        length = 1
                        hb = decodert2.decode_bits()
                        lb = decodert2.decode_bits()
                        bits = lb+hb
                     
                        value = bits[bitpos]
                        #logger.debug('MODBUS: Bits{0}'.format(bits))   
                        
                    bit[2] = value                                                                  #zurückspeichern   
                    
                    decodert2.reset() 
            ##Debug#################################################################################
                    bit[3](value, caller='modbus')
                i = i+1
                lb = decodert2.decode_bits()
                hb = decodert2.decode_bits()
                bits = hb+lb
                decodert2.reset() 
                logger.debug('MODBUS: read from PLC {0}-{1} {2}'.format(byte, bits, bytes))

        except Exception as e:
            logger.error('MODBUS: Could not read an InputWord, because {}'.format( e))
            self._lock.release()
            return None
        i = 0
        return None        
예제 #49
0
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)
예제 #50
0
def get_pv_data(config):

    host = config.get('inv_host')
    port = config.get('inv_port', 502)
    modbusid = config.get('inv_modbus', 3)
    manufacturer = config.get('inv_modbus', 'Default')
    registers = eval(config.get('registers'))
    client = ModbusClient(host=host, port=port)
    try:
        client.connect()
    except:
        print('Modbus Connection Error', 'could not connect to target. Check your settings, please.')
        return None




    data = {}  ## empty data store for current values

    for myreg in registers:
        ## if the connection is somehow not possible (e.g. target not responding)
        #  show a error message instead of excepting and stopping
        try:
            received = client.read_input_registers(address=int(myreg[0]),
                                                        count=modbusdatatype[myreg[1]],
                                                        unit=modbusid)
        except:
            thisdate = str(datetime.datetime.now()).partition('.')[0]
            thiserrormessage = thisdate + ': Connection not possible. Check settings or connection.'
            print(thiserrormessage)
            return  None ## prevent further execution of this function

        name = myreg[3]
        message = BinaryPayloadDecoder.fromRegisters(received.registers, byteorder=Endian.Big, wordorder=Endian.Big)
        ## provide the correct result depending on the defined datatype
        if myreg[1] == 'S32':
            interpreted = message.decode_32bit_int()
        elif myreg[1] == 'U32':
            interpreted = message.decode_32bit_uint()
        elif myreg[1] == 'U64':
            interpreted = message.decode_64bit_uint()
        elif myreg[1] == 'STR32':
            interpreted = message.decode_string(32)
        elif myreg[1] == 'S16':
            interpreted = message.decode_16bit_int()
        elif myreg[1] == 'U16':
            interpreted = message.decode_16bit_uint()
        else:  ## if no data type is defined do raw interpretation of the delivered data
            interpreted = message.decode_16bit_uint()

        ## check for "None" data before doing anything else
        if ((interpreted == MIN_SIGNED) or (interpreted == MAX_UNSIGNED)):
            value = None
        else:
        ## put the data with correct formatting into the data table
            if myreg[2] == 'FIX3':
                value = float(interpreted) / 1000
            elif myreg[2] == 'FIX2':
                value = float(interpreted) / 100
            elif myreg[2] == 'FIX1':
                value = float(interpreted) / 10
            elif myreg[2] == 'UTF8':
                value = str(interpreted,'UTF-8').rstrip("\x00")
            elif myreg[2] == 'ENUM':
                e=pvenums.get(name,{})
                value = e.get(interpreted,str(interpreted))
            else:
                value = interpreted
        data[name] = value

    client.close()
    return data
예제 #51
0
    def _refresh(self):
        readCacheDictionary = {}

        for item in self._itemReadDictionary:
            pluggit_key = self._itemReadDictionary[item]
            pluggit_paramList = self._modbusRegisterDictionary[pluggit_key]

            # read values from pluggit via modbus client registers, if not in cache
            if pluggit_paramList[self.DICT_READ_ADDRESS] != -1:
                if pluggit_key in readCacheDictionary:
                    registerValue = readCacheDictionary[pluggit_key]
                else:
                    registerValue = self._Pluggit.read_holding_registers(
                        pluggit_paramList[self.DICT_READ_ADDRESS],
                        pluggit_paramList[self.DICT_ADDRESS_QUANTITY])
                    # TODO: auswerten, wenn Reigister nicht auslesbar
                    readCacheDictionary[pluggit_key] = registerValue
                vdecoder = BinaryPayloadDecoder.fromRegisters(
                    registerValue.registers,
                    byteorder=Endian.Big,
                    wordorder=Endian.Little)

                readItemValue = None

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'uint':
                    if pluggit_paramList[
                            self.
                            DICT_ADDRESS_QUANTITY] == 1 or pluggit_paramList[
                                self.DICT_ADDRESS_QUANTITY] == 2:
                        readItemValue = vdecoder.decode_16bit_uint()
                    if pluggit_paramList[self.DICT_ADDRESS_QUANTITY] == 4:
                        readItemValue = vdecoder.decode_64bit_uint()

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'float':
                    if pluggit_paramList[self.DICT_ADDRESS_QUANTITY] == 2:
                        readItemValue = vdecoder.decode_32bit_float()
                        if pluggit_paramList[self.DICT_ROUND_VALUE] != -1:
                            readItemValue = round(
                                readItemValue,
                                pluggit_paramList[self.DICT_ROUND_VALUE])

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'bool':
                    if pluggit_paramList[self.DICT_ADDRESS_QUANTITY] == 1:
                        readItemValue = bool(vdecoder.decode_16bit_uint())

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'timestamp':
                    if pluggit_paramList[self.DICT_ADDRESS_QUANTITY] == 2:
                        readItemValue = vdecoder.decode_32bit_uint()

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'str':
                    readItemValue = self.BinWordToString(
                        registerValue.registers)

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'ip':
                    readItemValue = '{}.{}.{}.{}'.format(
                        registerValue.registers[1] >> 8,
                        registerValue.registers[1] & 0xFF,
                        registerValue.registers[0] >> 8,
                        registerValue.registers[0] & 0xFF)

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'mac':
                    readItemValue = '{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}'.format(
                        registerValue.registers[0] >> 8,
                        registerValue.registers[0] & 0xFF,
                        registerValue.registers[3] >> 8,
                        registerValue.registers[3] & 0xFF,
                        registerValue.registers[2] >> 8,
                        registerValue.registers[2] & 0xFF)

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'version':
                    vresult = vdecoder.decode_16bit_uint()
                    readItemValue = '{}.{}'.format(vresult >> 8 & 0xFF,
                                                   vresult & 0xFF)

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'version_bcd':
                    vresult = vdecoder.decode_16bit_uint()
                    readItemValue = '{}.{}{}'.format(vresult >> 12 & 0x0F,
                                                     vresult >> 8 & 0x0F,
                                                     vresult >> 4 & 0x0F,
                                                     vresult & 0x0F)

                if pluggit_paramList[self.DICT_VALUE_TYPE] == 'weekprogram':
                    # 6 Register, 1 h = 4 Bit, 2 h = 8 bit, 4 h = 16 bit = 1 Register
                    #readItemValue = registerValue.registers
                    #readItemValue = str(registerValue.registers[0] & 0x0F)
                    #self.logger.info('{}'.format(readItemValue))
                    pass

                # check for conversion
                convItemValue = None
                if readItemValue is not None:
                    if self.has_iattr(item.conf, 'pluggit_convert'):
                        convType = self.get_iattr_value(
                            item.conf, 'pluggit_convert')
                        if convType in pluggit_paramList[
                                self.DICT_ALLOWED_CONV_LIST]:
                            convItemValue = self.ConvertValueToItem(
                                readItemValue, convType, pluggit_key)
                            if convItemValue is not None:
                                item(convItemValue, 'Pluggit')
                            else:
                                self.logger.warning(
                                    "Fehler bei der Umwandlung von Item {}.".
                                    format(item))
                        else:
                            self.logger.warn(
                                "Umwandlung von {} zu {} bei Item {} nicht zulässig."
                                .format(
                                    pluggit_paramList[self.DICT_VALUE_TYPE],
                                    convType, item))
                    else:
                        if readItemValue is not None:
                            item(readItemValue, 'Pluggit')
                        else:
                            self.logger.warning(
                                "Unbekannter Wert-Typ: {} bei Item {}.".format(
                                    pluggit_paramList[self.DICT_VALUE_TYPE]),
                                item)

            time.sleep(0.1)
예제 #52
0
파일: modbus.py 프로젝트: smtwkla/daq-3i
    def decode_data_format(self, chl, res):

        value = None
        byteorder = Endian.Big
        wordorder = Endian.Little

        if chl.format == MODBUS_UINT16:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_SINT16:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_UINT32:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_UINT32_RWORDS:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_SINT32:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_SINT32_RWORDS:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_SKIP2:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_FLOAT:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_FLOAT_SKIP2:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_FLOAT_RBYTES:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_FLOAT_RWORDS:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_FLOAT_RSKIP2:
            byteorder = Endian.Big
            wordorder = Endian.Little

        if chl.format == MODBUS_ABB_REAL32_U or chl.format == MODBUS_ABB_REAL32_S:
            byteorder = Endian.Big
            wordorder = Endian.Big

        decoder = BinaryPayloadDecoder.fromRegisters(res.response.registers,
                                                     byteorder=byteorder,
                                                     wordorder=wordorder)

        if chl.format == MODBUS_UINT16:
            value = decoder.decode_16bit_uint()

        if chl.format == MODBUS_SINT16:
            value = decoder.decode_16bit_int()

        if chl.format == MODBUS_SINT32:
            value = decoder.decode_32bit_int()

        if chl.format == MODBUS_UINT32:
            value = decoder.decode_32bit_uint()

        if chl.format == MODBUS_SINT32_RWORDS:
            value = decoder.decode_32bit_int()

        if chl.format == MODBUS_SKIP2:
            pass

        if chl.format == MODBUS_UINT32_RWORDS:
            pass

        if chl.format == MODBUS_FLOAT:
            value = decoder.decode_32bit_float()

        if chl.format == MODBUS_FLOAT_SKIP2:
            pass

        if chl.format == MODBUS_FLOAT_RBYTES:
            pass

        if chl.format == MODBUS_FLOAT_RWORDS:
            pass

        if chl.format == MODBUS_FLOAT_RSKIP2:
            pass

        if chl.format == MODBUS_ABB_REAL32_U:
            value = decoder.decode_16bit_uint()
            # print("Reg 1 : %d" % res.response.registers[0])
            # print("Reg 2 : %d" % res.response.registers[1])

        if chl.format == MODBUS_ABB_REAL32_S:

            value = int(
                format(res.response.registers[1], "b").zfill(16) +
                format(res.response.registers[0], "b").zfill(16), 2)

        # decoder.decode_bits()
        return value
예제 #53
0
 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
예제 #54
0
 def from_registers(self, r):
     return BinaryPayloadDecoder.fromRegisters(r.registers,
                                               byteorder=self.byte_order,
                                               wordorder=self.word_order)
예제 #55
0
 def testBigEndianPayloadDecoder(self):
     """ Test basic bit message encoding/decoding """
     decoder = BinaryPayloadDecoder(self.big_endian_payload, 
                                    byteorder=Endian.Big)
     self.assertEqual(1,      decoder.decode_8bit_uint())
     self.assertEqual(2,      decoder.decode_16bit_uint())
     self.assertEqual(3,      decoder.decode_32bit_uint())
     self.assertEqual(4,      decoder.decode_64bit_uint())
     self.assertEqual(-1,     decoder.decode_8bit_int())
     self.assertEqual(-2,     decoder.decode_16bit_int())
     self.assertEqual(-3,     decoder.decode_32bit_int())
     self.assertEqual(-4,     decoder.decode_64bit_int())
     self.assertEqual(1.25,   decoder.decode_32bit_float())
     self.assertEqual(6.25,   decoder.decode_64bit_float())
     self.assertEqual(None,   decoder.skip_bytes(2))
     self.assertEqual(b'test', decoder.decode_string(4))
     self.assertEqual(self.bitstring, decoder.decode_bits())
예제 #56
0
def load_sma_register(registers):
  from pymodbus.payload import BinaryPayloadDecoder
  from pymodbus.constants import Endian
  import datetime

  ## request each register from datasets, omit first row which contains only column headers
  for thisrow in registers:
    name = thisrow[0]
    startPos = thisrow[1]
    type = thisrow[2]
    format = thisrow[3]
    
    ## if the connection is somehow not possible (e.g. target not responding)
    #  show a error message instead of excepting and stopping
    try:
      received = client.read_input_registers(address=startPos,
                                             count=sma_moddatatype[type],
                                              unit=config.slave)
    except:
      thisdate = str(datetime.datetime.now()).partition('.')[0]
      thiserrormessage = thisdate + ': Connection not possible. Check settings or connection.'
      print( thiserrormessage)
      return  ## prevent further execution of this function
    
    message = BinaryPayloadDecoder.fromRegisters(received.registers, endian=Endian.Big)
    ## provide the correct result depending on the defined datatype
    if type == 'S32':
      interpreted = message.decode_32bit_int()
    elif type == 'U32':
      interpreted = message.decode_32bit_uint()
    elif type == 'U64':
      interpreted = message.decode_64bit_uint()
    elif type == 'STR16':
      interpreted = message.decode_string(16)
    elif type == 'STR32':
      interpreted = message.decode_string(32)
    elif type == 'S16':
      interpreted = message.decode_16bit_int()
    elif type == 'U16':
      interpreted = message.decode_16bit_uint()
    else: ## if no data type is defined do raw interpretation of the delivered data
      interpreted = message.decode_16bit_uint()
    
    ## check for "None" data before doing anything else
    if ((interpreted == MIN_SIGNED) or (interpreted == MAX_UNSIGNED)):
      displaydata = None
    else:
      ## put the data with correct formatting into the data table
      if format == 'FIX3':
        displaydata = float(interpreted) / 1000
      elif format == 'FIX2':
        displaydata = float(interpreted) / 100
      elif format == 'FIX1':
        displaydata = float(interpreted) / 10
      else:
        displaydata = interpreted
    
    #print '************** %s = %s' % (name, str(displaydata))
    inverter[name] = displaydata
  
  # Add timestamp
  inverter["00000 - Timestamp"] = str(datetime.datetime.now()).partition('.')[0]
예제 #57
0
# implementations differentiate holding/input discrete/coils and as such
# you will not be able to write to these, therefore the starting values
# are not known to these tests. Furthermore, some use the same memory
# blocks for the two sets, so a change to one is a change to the other.
# Keep both of these cases in mind when testing as the following will
# _only_ pass with the supplied async modbus server (script supplied).
#---------------------------------------------------------------------------# 
#rr = client.read_holding_registers(1,1)
#
#rr = client.read_holding_registers(address=0xF900, count=1)
#decoder = BcdPayloadDecoder.fromRegisters(rr.registers)
#Time_Interval = decoder.decode_int(2)
#Time_Interval = rs485.read_string(0xF900, functioncode=3, numberOfRegisters=2)[0]
#
rr = client.read_input_registers(address=0x0000, count=2)
decoder = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Big)
Volts = decoder.decode_32bit_float()
#
rr = client.read_input_registers(address=0x0006, count=2)
decoder = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Big)
Current = decoder.decode_32bit_float()
#
rr = client.read_input_registers(address=0x000C, count=2)
decoder = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Big)
Active_Power = decoder.decode_32bit_float()
#
rr = client.read_input_registers(address=0x0012, count=2)
decoder = BinaryPayloadDecoder.fromRegisters(rr.registers, endian=Endian.Big)
Apparent_Power = decoder.decode_32bit_float()
#
rr = client.read_input_registers(address=0x0018, count=2)
예제 #58
0
    def read(self):
        """ Read registers from client"""
        if pymodbus_found:
            time.sleep(float(self._settings["interval"]))
            f = []
            c = Cargo.new_cargo(rawdata="")
            # valid datacodes list and number of registers associated
            # in modbus protocol, one register is 16 bits or 2 bytes
            valid_datacodes = ({
                'h': 1,
                'H': 1,
                'i': 2,
                'l': 2,
                'I': 2,
                'L': 2,
                'f': 2,
                'q': 4,
                'Q': 4,
                'd': 4
            })

            if not self._modcon:
                self._con.close()
                self._log.info("Not connected, retrying connect" +
                               str(self.init_settings))
                self._con = self._open_modTCP(
                    self.init_settings["modbus_IP"],
                    self.init_settings["modbus_port"])

            if self._modcon:
                # fetch nodeid
                if 'nodeId' in self._settings:
                    node = str(self._settings["nodeId"])
                else:
                    self._log.error("please provide a nodeId")
                    return

                # stores registers
                if 'register' in self._settings:
                    registers = self._settings["register"]
                else:
                    self._log.error(
                        "please provide a register number or a list of registers"
                    )
                    return

                # fetch unitids if present
                UnitIds = self._settings.get("nUnit", None)

                # stores names
                # fetch datacode or datacodes
                if node in ehc.nodelist and 'rx' in ehc.nodelist[node]:
                    rNames = ehc.nodelist[node]['rx']['names']
                    if 'datacode' in ehc.nodelist[node]['rx']:
                        datacode = ehc.nodelist[node]['rx']['datacode']
                        datacodes = None
                    elif 'datacodes' in ehc.nodelist[node]['rx']:
                        datacodes = ehc.nodelist[node]['rx']['datacodes']
                    else:
                        self._log.error(
                            "please provide a datacode or a list of datacodes")
                        return

                # check if number of registers and number of names are the same
                if len(rNames) != len(registers):
                    self._log.error(
                        "You have to define an equal number of registers and of names"
                    )
                    return
                # check if number of names and number of datacodes are the same
                if datacodes is not None:
                    if len(datacodes) != len(rNames):
                        self._log.error(
                            "You are using datacodes. You have to define an equal number of datacodes and of names"
                        )
                        return

                # calculate expected size in bytes and search for invalid datacode(s)
                expectedSize = 0
                if datacodes is not None:
                    for code in datacodes:
                        if code not in valid_datacodes:
                            self._log.debug("-" * 46)
                            self._log.debug("invalid datacode")
                            self._log.debug("-" * 46)
                            return
                        else:
                            expectedSize += valid_datacodes[code] * 2
                else:
                    if datacode not in valid_datacodes:
                        self._log.debug("-" * 46)
                        self._log.debug("invalid datacode")
                        self._log.debug("-" * 46)
                        return
                    else:
                        expectedSize = len(
                            rNames) * valid_datacodes[datacode] * 2

                self._log.debug("expected bytes number after encoding: " +
                                str(expectedSize))

                # at this stage, we don't have any invalid datacode(s)
                # so we can loop and read registers
                for idx, rName in enumerate(rNames):
                    register = int(registers[idx])
                    if UnitIds is not None:
                        unitId = int(UnitIds[idx])
                    else:
                        unitId = 1
                    if datacodes is not None:
                        datacode = datacodes[idx]

                    self._log.debug("datacode " + datacode)
                    qty = valid_datacodes[datacode]
                    self._log.debug("reading register # :" + str(register) +
                                    ", qty #: " + str(qty) + ", unit #: " +
                                    str(unitId))

                    try:
                        self.rVal = self._con.read_holding_registers(
                            register - 1, qty, unit=unitId)
                        assert self.rVal.function_code < 0x80
                    except Exception as e:
                        self._log.error(
                            "Connection failed on read of register: " +
                            str(register) + " : " + str(e))
                        self._modcon = False
                        #missing datas will lead to an incorrect encoding
                        #we have to drop the payload
                        return
                    else:
                        #self._log.debug("register value:" + str(self.rVal.registers) + " type= " + str(type(self.rVal.registers)))
                        #f = f + self.rVal.registers
                        decoder = BinaryPayloadDecoder.fromRegisters(
                            self.rVal.registers,
                            byteorder=Endian.Big,
                            wordorder=Endian.Big)
                        if datacode == 'h':
                            rValD = decoder.decode_16bit_int()
                        elif datacode == 'H':
                            rValD = decoder.decode_16bit_uint()
                        elif datacode == 'i':
                            rValD = decoder.decode_32bit_int()
                        elif datacode == 'l':
                            rValD = decoder.decode_32bit_int()
                        elif datacode == 'I':
                            rValD = decoder.decode_32bit_uint()
                        elif datacode == 'L':
                            rValD = decoder.decode_32bit_uint()
                        elif datacode == 'f':
                            rValD = decoder.decode_32bit_float() * 10
                        elif datacode == 'q':
                            rValD = decoder.decode_64bit_int()
                        elif datacode == 'Q':
                            rValD = decoder.decode_64bit_uint()
                        elif datacode == 'd':
                            rValD = decoder.decode_64bit_float() * 10

                        t = ehc.encode(datacode, rValD)
                        f = f + list(t)
                        self._log.debug("Encoded value: " + str(t))
                        self._log.debug("value: " + str(rValD))

                #test if payload length is OK
                if len(f) == expectedSize:
                    self._log.debug("payload size OK (" + str(len(f)) + ")")
                    self._log.debug("reporting data: " + str(f))
                    c.nodeid = node
                    c.realdata = f
                    self._log.debug("Return from read data: " +
                                    str(c.realdata))
                    return c
                else:
                    self._log.error("incorrect payload size :" + str(len(f)) +
                                    " expecting " + str(expectedSize))
예제 #59
0
# If you need to decode a collection of registers in a weird layout, the
# payload decoder can help you as well.
#
# Here we demonstrate decoding a random register layout, unpacked it looks
# like the following:
#
# - a 8 byte string 'abcdefgh'
# - a 32 bit float 22.34
# - a 16 bit unsigned int 0x1234
# - an 8 bit int 0x12
# - an 8 bit bitstring [0,1,0,1,1,0,1,0]
# ---------------------------------------------------------------------------#
address = 0x01
count = 8
result = client.read_input_registers(address, count)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
decoded = {
    "string": decoder.decode_string(8),
    "float": decoder.decode_32bit_float(),
    "16uint": decoder.decode_16bit_uint(),
    "8int": decoder.decode_8bit_int(),
    "bits": decoder.decode_bits(),
}

print "-" * 60
print "Decoded Data"
print "-" * 60
for name, value in decoded.iteritems():
    print ("%s\t" % name), value

# ---------------------------------------------------------------------------#
예제 #60
0
            IbatT = 5 * IbatT - 11.86
        else:
            Ibat = 0

        PBtotal = round((IbatT * VbatT) / (j), 2) - 13
        #print(IbatT/j)

        if PLtotal < 2:
            PLtotal = 0

        elif PStotal < 2:
            PStotal = 0

        result = client.read_holding_registers(11729, 2,
                                               unit=1)  #Current A 1100
        decoder = BinaryPayloadDecoder.fromRegisters(result.registers,
                                                     byteorder=Endian.Big)
        PTred = decoder.decode_32bit_float()
        sw = 1
        hoja.write(k, 0, str(A))

        hoja.write(k, 1, str(VpanelT / j))

        hoja.write(k, 2, str(IpanelT / j))

        hoja.write(k, 3, str(PTred))

        hoja.write(k, 4, str(PLtotal))

        hoja.write(k, 5, str(PBtotal))

        hoja.write(k, 6, time.strftime("%X"))