Exemplo n.º 1
0
 def testPayloadBuilderReset(self):
     """ Test basic bit message encoding/decoding """
     builder = BinaryPayloadBuilder()
     builder.add_8bit_uint(0x12)
     builder.add_8bit_uint(0x34)
     builder.add_8bit_uint(0x56)
     builder.add_8bit_uint(0x78)
     self.assertEqual(b'\x12\x34\x56\x78', builder.to_string())
     self.assertEqual([b'\x12\x34', b'\x56\x78'], builder.build())
     builder.reset()
     self.assertEqual(b'', builder.to_string())
     self.assertEqual([], builder.build())
Exemplo n.º 2
0
 def testPayloadBuilderReset(self):
     """ Test basic bit message encoding/decoding """
     builder = BinaryPayloadBuilder()
     builder.add_8bit_uint(0x12)
     builder.add_8bit_uint(0x34)
     builder.add_8bit_uint(0x56)
     builder.add_8bit_uint(0x78)
     self.assertEqual(b'\x12\x34\x56\x78', builder.to_string())
     self.assertEqual([b'\x12\x34', b'\x56\x78'], builder.build())
     builder.reset()
     self.assertEqual(b'', builder.to_string())
     self.assertEqual([], builder.build())
 def testPayloadBuilderReset(self):
     ''' Test basic bit message encoding/decoding '''
     builder = BinaryPayloadBuilder()
     builder.add_8bit_uint(0x12)
     builder.add_8bit_uint(0x34)
     builder.add_8bit_uint(0x56)
     builder.add_8bit_uint(0x78)
     self.assertEqual('\x12\x34\x56\x78', str(builder))
     self.assertEqual(['\x12\x34', '\x56\x78'], builder.build())
     builder.reset()
     self.assertEqual('', str(builder))
     self.assertEqual([], builder.build())
Exemplo n.º 4
0
 def testPayloadBuilderReset(self):
     ''' Test basic bit message encoding/decoding '''
     builder = BinaryPayloadBuilder()
     builder.add_8bit_uint(0x12)
     builder.add_8bit_uint(0x34)
     builder.add_8bit_uint(0x56)
     builder.add_8bit_uint(0x78)
     self.assertEqual('\x12\x34\x56\x78', str(builder))
     self.assertEqual(['\x12\x34', '\x56\x78'], builder.build())
     builder.reset()
     self.assertEqual('', str(builder))
     self.assertEqual([], builder.build())
Exemplo n.º 5
0
 def testPayloadBuilderReset(self):
     """ Test basic bit message encoding/decoding """
     builder = BinaryPayloadBuilder()
     builder.add_8bit_uint(0x12)
     builder.add_8bit_uint(0x34)
     builder.add_8bit_uint(0x56)
     builder.add_8bit_uint(0x78)
     self.assertEqual("\x12\x34\x56\x78", str(builder))
     self.assertEqual(["\x12\x34", "\x56\x78"], builder.build())
     builder.reset()
     self.assertEqual("", str(builder))
     self.assertEqual([], builder.build())
Exemplo n.º 6
0
class PayloadHandler:
    """
    encodes/decodes values according to the way it is stored in registry
    SCALE stands for multiplying/dividing by a scaling factor
    COMB stands for storing the value of one field in two registers
    if none of those provided encodes only based on the type
    """
    def __init__(self, env, store):
        self.byte_order = env["byte_order"]
        self.word_order = env["word_order"]
        self.d_s_factor = env["default_scaling_factor"]
        self.battery_store = store
        self.builder = BinaryPayloadBuilder(byteorder=self.byte_order,
                                            wordorder=self.word_order)

    def encode(self, value, encoding):
        self.builder.reset()
        encode_type = {
            INT8: lambda x: self.builder.add_8bit_int(x),
            UINT8: lambda x: self.builder.add_8bit_uint(x),
            INT16: lambda x: self.builder.add_16bit_int(x),
            UINT16: lambda x: self.builder.add_16bit_uint(x),
            INT32: lambda x: self.builder.add_32bit_int(x),
            UINT32: lambda x: self.builder.add_32bit_uint(x),
            FLOAT32: lambda x: self.builder.add_32bit_float(x),
        }
        if 'e_type' not in encoding or encoding['e_type'] == COMB:
            encode_type[encoding['d_type']](value)
        else:
            encode_type[encoding['d_type']](round(
                value * encoding.get('s_factor', self.d_s_factor)))
        return self.builder.to_registers()

    def decode(self, fx, addr, encoding):
        encoded_value = self.battery_store.getValues(fx, addr, 2)
        decoder = BinaryPayloadDecoder.fromRegisters(encoded_value,
                                                     byteorder=self.byte_order,
                                                     wordorder=self.word_order)
        decode_type = {
            INT8: lambda: decoder.decode_8bit_int(),
            UINT8: lambda: decoder.decode_8bit_uint(),
            INT16: lambda: decoder.decode_16bit_int(),
            UINT16: lambda: decoder.decode_16bit_uint(),
            INT32: lambda: decoder.decode_32bit_int(),
            UINT32: lambda: decoder.decode_32bit_uint(),
            FLOAT32: lambda: decoder.decode_32bit_float(),
        }
        if 'e_type' not in encoding or encoding['e_type'] == COMB:
            return decode_type[encoding['d_type']]()
        else:
            return decode_type[encoding['d_type']]() / encoding.get(
                's_factor', self.d_s_factor)
Exemplo n.º 7
0
    def test_modbus_getting_values(self):
        test_modbus_config = {
            "attributes": [
                {
                    "string": {
                        "byteOrder": "BIG",
                        "tag": "string",
                        "type": "string",
                        "functionCode": 4,
                        "registerCount": 4
                    }
                },
                {
                    "bits": {
                        "byteOrder": "BIG",
                        "tag": "bits",
                        "type": "bits",
                        "functionCode": 4,
                        "registerCount": 1
                    }
                },
                {
                    "8int": {
                        "byteOrder": "BIG",
                        "tag": "8int",
                        "type": "8int",
                        "functionCode": 4,
                        "registerCount": 1
                    }
                },
                {
                    "16int": {
                        "byteOrder": "BIG",
                        "tag": "16int",
                        "type": "16int",
                        "functionCode": 4,
                        "registerCount": 1
                    }
                },
                {
                    "long": {
                        "byteOrder": "BIG",
                        "tag": "long",
                        "type": "long",
                        "functionCode": 4,
                        "registerCount": 1
                    }
                },
                {
                    "long_with_divider": {
                        "byteOrder": "BIG",
                        "tag": "long",
                        "type": "long",
                        "functionCode": 4,
                        "registerCount": 1,
                        "divider": 10
                    }
                },
                {
                    "32int": {
                        "byteOrder": "BIG",
                        "tag": "32int",
                        "type": "32int",
                        "functionCode": 4,
                        "registerCount": 2
                    }
                },
                {
                    "64int": {
                        "byteOrder": "BIG",
                        "tag": "64int",
                        "type": "64int",
                        "functionCode": 4,
                        "registerCount": 4
                    }
                },
            ],
            "timeseries": [
                {
                    "8uint": {
                        "byteOrder": "BIG",
                        "tag": "8uint",
                        "type": "8uint",
                        "functionCode": 4,
                        "registerCount": 1
                    }
                },
                {
                    "16uint": {
                        "byteOrder": "BIG",
                        "tag": "16uint",
                        "type": "16uint",
                        "functionCode": 4,
                        "registerCount": 2
                    }
                },
                {
                    "32uint": {
                        "byteOrder": "BIG",
                        "tag": "32uint",
                        "type": "32uint",
                        "functionCode": 4,
                        "registerCount": 4
                    }
                },
                {
                    "64uint": {
                        "byteOrder": "BIG",
                        "tag": "64uint",
                        "type": "64uint",
                        "functionCode": 4,
                        "registerCount": 1
                    }
                },
                {
                    "double": {
                        "byteOrder": "BIG",
                        "tag": "double",
                        "type": "double",
                        "functionCode": 4,
                        "registerCount": 2
                    }
                },
                {
                    "16float": {
                        "byteOrder": "BIG",
                        "tag": "16float",
                        "type": "16float",
                        "functionCode": 4,
                        "registerCount": 1
                    }
                },
                {
                    "32float": {
                        "byteOrder": "BIG",
                        "tag": "32float",
                        "type": "32float",
                        "functionCode": 4,
                        "registerCount": 2
                    }
                },
                {
                    "64float": {
                        "byteOrder": "BIG",
                        "tag": "64float",
                        "type": "64float",
                        "functionCode": 4,
                        "registerCount": 4
                    }
                },
            ]
        }
        test_modbus_body_to_convert = {}
        test_modbus_convert_config = {}
        test_modbus_result = {
            'deviceName':
            'Modbus Test',
            'deviceType':
            'default',
            'telemetry': [{
                '8uint': 18
            }, {
                '16uint': 4660
            }, {
                '32uint': 305419896
            }, {
                '64uint': 1311768468603649775
            }, {
                'double': 22.5
            }, {
                '16float': 1.240234375
            }, {
                '32float': 22.34000015258789
            }, {
                '64float': -123.45
            }],
            'attributes': [{
                'string': 'abcdefgh'
            }, {
                'bits': [False, True, False, True, True, False, True, False]
            }, {
                '8int': -18
            }, {
                '16int': -22136
            }, {
                'long': -22136
            }, {
                'long_with_divider': -2213.6
            }, {
                '32int': -4660
            }, {
                '64int': -3735928559
            }]
        }

        builder = BinaryPayloadBuilder(byteorder=Endian.Big)
        builder_registers = {
            "string": (builder.add_string, 'abcdefgh'),
            "bits": (builder.add_bits, [0, 1, 0, 1, 1, 0, 1, 0]),
            "8int": (builder.add_8bit_int, -0x12),
            "16int": (builder.add_16bit_int, -0x5678),
            "long": (builder.add_16bit_int, -0x5678),
            "long_with_divider": (builder.add_16bit_int, -0x5678),
            "32int": (builder.add_32bit_int, -0x1234),
            "64int": (builder.add_64bit_int, -0xDEADBEEF),
            "8uint": (builder.add_8bit_uint, 0x12),
            "16uint": (builder.add_16bit_uint, 0x1234),
            "32uint": (builder.add_32bit_uint, 0x12345678),
            "64uint": (builder.add_64bit_uint, 0x12345678DEADBEEF),
            "double": (builder.add_32bit_float, 22.5),
            "16float": (builder.add_16bit_float, 1.24),
            "32float": (builder.add_32bit_float, 22.34),
            "64float": (builder.add_64bit_float, -123.45),
        }

        class DummyResponse:
            def __init__(self, registers):
                self.registers = registers[:]

        for datatype in test_modbus_config:
            test_modbus_body_to_convert[datatype] = {}
            for tag_dict in test_modbus_config[datatype]:
                for tag in tag_dict:
                    builder_registers[tag][0](builder_registers[tag][1])
                    test_modbus_body_to_convert[datatype].update({
                        tag: {
                            "input_data":
                            DummyResponse(builder.to_registers()),
                            "data_sent": tag_dict[tag]
                        }
                    })
                    builder.reset()

        converter = BytesModbusUplinkConverter({
            "deviceName": "Modbus Test",
            "deviceType": "default",
            "unitId": 1
        })
        result = converter.convert(test_modbus_convert_config,
                                   test_modbus_body_to_convert)
        self.assertDictEqual(result, test_modbus_result)
Exemplo n.º 8
0
class modbusServer():

    def __init__(self):
        self.__logging()
        self.cfg = yamlImport.importYAML("./cfg/modbusSettings.yaml")
        self.builder = BinaryPayloadBuilder(endian=Endian.Little)
        self.__setupContext()
        self.__serverInfo()
        self.__configureServer()

    def __logging(self):
        import logging
        logging.basicConfig()
        log = logging.getLogger()
        log.setLevel(logging.INFO)
    
    def __setupContext(self):
        #Setup Coils
        co = ModbusSequentialDataBlock(1, [0]*1)
        di = ModbusSequentialDataBlock(1, [0]*6)
        
        #Setup Registers (Inc floats)
        for i in range(0,3):
            self.builder.add_32bit_float(0.0)
        ir = ModbusSequentialDataBlock(1, self.builder.to_registers())
        
        for i in range(0,3):
            self.builder.add_32bit_float(0.0)
        hr = ModbusSequentialDataBlock(1, self.builder.to_registers())
        
        #Setup datastore
        store = ModbusSlaveContext(co=co,di=di,hr=hr,ir=ir)
        self.context = ModbusServerContext(slaves=store, single=True)


    def __serverInfo(self):
        self.identity = ModbusDeviceIdentification()
        self.identity.VendorName  = self.cfg["VendorName"]
        self.identity.VendorUrl   = self.cfg["VendorUrl"]
        self.identity.ProductName = self.cfg["ProductName"]
        self.identity.ModelName   = self.cfg["ModelName"]
        self.identity.MajorMinorRevision = self.cfg["Revision"]
    
    def __getIPAddress(self):
        if self.cfg["manualIP"] == "N":
            return socket.gethostbyname(socket.gethostname())
        return self.cfg["ip"]
    
    def __configureServer(self):
        if self.cfg["method"] == "tcp":
            self.servTCP = ModbusTcpServer(self.context, 
                                           identity=self.identity, 
                                           address=(self.__getIPAddress(),
                                                    self.cfg["tcpPort"]))
        elif self.cfg["method"] == "rtu":
            self.servRTU = ModbusSerialServer(self.context,
                                             framer=ModbusRtuFramer,
                                             identity=self.identity,
                                             port=self.cfg["rtuPort"],
                                             stopbits=self.cfg["stopbits"],
                                             bytesize=self.cfg["bytesize"],
                                             parity=self.cfg["parity"],
                                             baudrate=self.cfg["baudrate"],
                                             timeout=self.cfg["timeout"])
        else:
            raise ReferenceError("Invalid server type")
            
    def runServer(self):
        if self.cfg["method"] == "tcp":
            self.servTCP.serve_forever()
        elif self.cfg["method"] == "rtu":
            self.servRTU.serve_forever()
        else:
            raise ReferenceError("Invalid server type")
    
    def stopServer(self):
        if self.cfg["method"] == "tcp":
            self.servTCP.server_close()
            self.servTCP.shutdown()
        elif self.cfg["method"] == "rtu":
            self.servRTU.server_close()
        else:
            raise ReferenceError("Invalid server type")
        
    def encodeData(self,data):
        self.builder.reset()
        try:
            for i in range(0,len(data)):
                self.builder.add_32bit_float(data[i])
        except TypeError:
            self.builder.add_32bit_float(data)
        return self.builder.to_registers()
    
    def decodeData(self,data):
        returnData = [0]*(len(data)/2)
        decoder = BinaryPayloadDecoder.fromRegisters(data, endian=Endian.Little)
        for i in range(0,len(data)/2):
            returnData[i] = round(decoder.decode_32bit_float(),2)
        return returnData
Exemplo n.º 9
0
    def write(self):
        try: 
            lb = 00000000
            hb = 00000000
            #### byte besteht immer aus 16 bits
            for byte in self._db['out']:
                for bit in sorted(self._db['out'][byte]):  
                    if bit in self._db['out'][byte]:
                        bitpos =    bit[0]                                                          #startbit/bitposition des binärwertes
                        type =      bit[1]
                        value =     bit[2]
                        name =      bit[3]
                        bit[2] =    bit[3]()                                                        ##aktueller wert des items abrufen und value updaten!
                        builder = BinaryPayloadBuilder(endian=Endian.Little)

                        ##unterscheidung dateityp
                        if type == '5' or type == '5.001' or type == '6' :                          ##8bit uint / int
                            length = 8
                            if bitpos < 8:  #lb
                                lb = value
                            else:           #hb
                                hb = value
                                
                            if type == '5':
                                builder.add_8bit_uint(lb)
                                builder.add_8bit_uint(hb)
                                #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) 
                            elif type == '5.001':                            ##0-100 in 0-255 umwandeln!
                                #print(dpts.en5001(lb))
                                #print(dpts.en5001(hb))
                                
                                lb = self.de5001(lb)
                                hb = self.de5001(hb)
                                #print("lb geschrieben", lb )
                                #print("hb geschrieben", hb )
                                builder.add_8bit_uint(lb)
                                builder.add_8bit_uint(hb)
                                #logger.debug('MODBUS: 8bit uint {0} ; {1}'.format(lb,hb)) 
                            elif type == '6':
                                if lb > 127:
                                    lb = 127
                                elif lb < -128:
                                    lb = -128
                                if hb > 127:
                                    hb = 127
                                elif hb < -128:
                                    hb = -128
                                builder.add_8bit_int(lb)
                                builder.add_8bit_int(hb)
                                #logger.debug('MODBUS: 8bit int {0} ; {1}'.format(lb.hb)) 
                        elif type == '7' or type == '8':                                            #16bit uint / int
                            length = 16
                            if type == '7':                                                         #0...65535
                                builder.add_16bit_uint(value)
                                #logger.debug('MODBUS: 16bit uint {0} '.format(value)) 
                            else:                                                                   #-32768...32767
                                builder.add_16bit_int(value)   
                                #logger.debug('MODBUS: 16bit int {0}'.format(value)) 
                            
                        elif type == '1':
                            length = 1
                                                                                                    #nur pro byte einmal die bits wandeln
                            if bitpos < 8:  #lb
                                lb  = lb | int(value) << bitpos
                                #logger.debug('MODBUS: 8bit int{0}'.format(lb)) 
                                
                            else:           #hb
                                hb  = hb | int(value) << bitpos
                                #logger.debug('MODBUS: 8bit int{0}'.format(hb)) 
                                
                            builder.add_8bit_uint(lb)
                            builder.add_8bit_uint(hb)
                            
                payload = builder.build()
                logger.debug('MODBUS: write to PLC: WORD {0} set to {1} '.format(byte,payload)) 
                self._modbuspy.write_registers(byte, payload, skip_encode=True)
                builder.reset()        
        except Exception as e:
            logger.error('MODBUS: Could not write an OutWord, because {}'.format(e))
            self._lock.release()
            return None
Exemplo n.º 10
0
            print 'speed (m/s) ', gpsd.fix.speed
            print 'climb       ', gpsd.fix.climb
            print 'track       ', gpsd.fix.track
            print 'mode        ', gpsd.fix.mode
            print
            print 'sats        ', gpsd.satellites

            builder.add_32bit_float(gpsd.fix.latitude)
            builder.add_32bit_float(gpsd.fix.longitude)
            payload = builder.build()
            #print payload

            client.write_registers(0, payload, skip_encode=True)

            time.sleep(1)  #set to whatever
            payload = builder.reset()

    #except ConnectionException as e: #when you press ctrl+c
    #  print "\nKilling Thread...Modbus server not running"
    #  print e
    #  gpsp.running=False
    #  client.close()

    except (KeyboardInterrupt, SystemExit):
        print "\nKilling Thread..."
        gpsp.running = False
        client.close()
        gpsp.join()  # wait for the thread to finish what it's doing

    print "Done.\nExiting."
Exemplo n.º 11
0
                      bytesize=8,
                      parity='N',
                      baudrate=115200,
                      timeout=0.5)

#Connect to the serial modbus server
connection = client.connect()
print(connection)

builder = BinaryPayloadBuilder(byteorder=Endian.Big, wordorder=Endian.Little)

builder.add_16bit_uint(5)  #Type of packet
payload = builder.to_registers()
payload = builder.build()
client.write_registers(0, payload, skip_encode=True, unit=mb_unit)
builder.reset()
#time.sleep(20)

builder.add_16bit_uint(6)  #Type of packet
payload = builder.to_registers()
payload = builder.build()
client.write_registers(0, payload, skip_encode=True, unit=mb_unit)
builder.reset()
#time.sleep(20)

builder.add_16bit_uint(0)  #Type of packet
payload = builder.to_registers()
payload = builder.build()
client.write_registers(0, payload, skip_encode=True, unit=mb_unit)
builder.reset()
Exemplo n.º 12
0
class modbusServer():
    def __init__(self):
        self.__logging()
        self.cfg = yamlImport.importYAML("./cfg/modbusSettings.yaml")
        self.builder = BinaryPayloadBuilder(endian=Endian.Little)
        self.__setupContext()
        self.__serverInfo()
        self.__configureServer()

    def __logging(self):
        import logging
        logging.basicConfig()
        log = logging.getLogger()
        log.setLevel(logging.INFO)

    def __setupContext(self):
        #Setup Coils
        co = ModbusSequentialDataBlock(1, [0] * 1)
        di = ModbusSequentialDataBlock(1, [0] * 6)

        #Setup Registers (Inc floats)
        for i in range(0, 3):
            self.builder.add_32bit_float(0.0)
        ir = ModbusSequentialDataBlock(1, self.builder.to_registers())

        for i in range(0, 3):
            self.builder.add_32bit_float(0.0)
        hr = ModbusSequentialDataBlock(1, self.builder.to_registers())

        #Setup datastore
        store = ModbusSlaveContext(co=co, di=di, hr=hr, ir=ir)
        self.context = ModbusServerContext(slaves=store, single=True)

    def __serverInfo(self):
        self.identity = ModbusDeviceIdentification()
        self.identity.VendorName = self.cfg["VendorName"]
        self.identity.VendorUrl = self.cfg["VendorUrl"]
        self.identity.ProductName = self.cfg["ProductName"]
        self.identity.ModelName = self.cfg["ModelName"]
        self.identity.MajorMinorRevision = self.cfg["Revision"]

    def __getIPAddress(self):
        if self.cfg["manualIP"] == "N":
            return socket.gethostbyname(socket.gethostname())
        return self.cfg["ip"]

    def __configureServer(self):
        if self.cfg["method"] == "tcp":
            self.servTCP = ModbusTcpServer(self.context,
                                           identity=self.identity,
                                           address=(self.__getIPAddress(),
                                                    self.cfg["tcpPort"]))
        elif self.cfg["method"] == "rtu":
            self.servRTU = ModbusSerialServer(self.context,
                                              framer=ModbusRtuFramer,
                                              identity=self.identity,
                                              port=self.cfg["rtuPort"],
                                              stopbits=self.cfg["stopbits"],
                                              bytesize=self.cfg["bytesize"],
                                              parity=self.cfg["parity"],
                                              baudrate=self.cfg["baudrate"],
                                              timeout=self.cfg["timeout"])
        else:
            raise ReferenceError("Invalid server type")

    def runServer(self):
        if self.cfg["method"] == "tcp":
            self.servTCP.serve_forever()
        elif self.cfg["method"] == "rtu":
            self.servRTU.serve_forever()
        else:
            raise ReferenceError("Invalid server type")

    def stopServer(self):
        if self.cfg["method"] == "tcp":
            self.servTCP.server_close()
            self.servTCP.shutdown()
        elif self.cfg["method"] == "rtu":
            self.servRTU.server_close()
        else:
            raise ReferenceError("Invalid server type")

    def encodeData(self, data):
        self.builder.reset()
        try:
            for i in range(0, len(data)):
                self.builder.add_32bit_float(data[i])
        except TypeError:
            self.builder.add_32bit_float(data)
        return self.builder.to_registers()

    def decodeData(self, data):
        returnData = [0] * (len(data) / 2)
        decoder = BinaryPayloadDecoder.fromRegisters(data,
                                                     endian=Endian.Little)
        for i in range(0, len(data) / 2):
            returnData[i] = round(decoder.decode_32bit_float(), 2)
        return returnData
Exemplo n.º 13
0
      print 'speed (m/s) ' , gpsd.fix.speed
      print 'climb       ' , gpsd.fix.climb
      print 'track       ' , gpsd.fix.track
      print 'mode        ' , gpsd.fix.mode
      print
      print 'sats        ' , gpsd.satellites

      builder.add_32bit_float(gpsd.fix.latitude)
      builder.add_32bit_float(gpsd.fix.longitude)
      payload = builder.build()
      #print payload

      client.write_registers(0, payload, skip_encode=True)

      time.sleep(1) #set to whatever
      payload = builder.reset()

  #except ConnectionException as e: #when you press ctrl+c
  #  print "\nKilling Thread...Modbus server not running"
  #  print e
  #  gpsp.running=False
  #  client.close()
  
  except (KeyboardInterrupt, SystemExit):
    print "\nKilling Thread..."
    gpsp.running = False
    client.close()
    gpsp.join() # wait for the thread to finish what it's doing
  
  print "Done.\nExiting."