Exemple #1
0
    def getAdditionalDataLength(cls, ds=None):
        """
         Returns length of additional data buffer
         according to ds parameter
         @param ds: Data structure definition (2 byte)
         @return: Size of additional data buffer in bytes
        """
        # exit if dataStructure is empty
        if (ds == None) or (ds == 0):
            return 0

        size = 0
        for key in cls.__dsMap:
            if bits.bitTest(ds, key):
                size += cls.__dsMap[key]
        return size
Exemple #2
0
 def parseProtocolStatus(cls, status):
     """
      Parses protocol status
      @param status: Device status value
      @return:
     """
     data = {}
     data["bad_ext_voltage"] = int(bits.bitTest(status, 0))
     data["moving"] = int(bits.bitTest(status, 1))
     data["armed"] = int(bits.bitTest(status, 2))
     data["gsm_sim_card_1_enabled"] = int(bits.bitTest(status, 3))
     data["gsm_sim_card_2_enabled"] = int(bits.bitTest(status, 4))
     data["gsm_no_gprs_connection"] = int(bits.bitTest(status, 5))
     data["sat_antenna_connected"] = 1 - int(bits.bitTest(status, 6))
     return data
Exemple #3
0
    def __parse(self):
        """
         Parses rawData
        """
        buffer = self.__rawData
        if buffer == None: return

        # read header and length
        archive = False
        header, length = unpack("<BH", buffer[:3])
        if self.isHalved(header):
            archive = bits.bitTest(length, 15)
            length = bits.bitClear(length, 15)

        if length > len(buffer) + 5:
            raise NeedMoreDataException('Not enough data in buffer')

        crc = unpack("<H", buffer[length + 3:length + 5])[0]
        crc_data = buffer[:length + 3]
        if not self.isCorrectCrc(crc_data, crc):
            raise Exception('Crc Is incorrect!')

        # now let's read packet data
        # but before this, check tagsdata length
        body = buffer[3:length + 3]
        if len(body) != length:
            raise Exception('Body length Is incorrect!')

        # apply new data
        self.__rawDataTail = buffer[length + 5:]
        self.__rawData = buffer[:length + 5]
        self.__archive = archive
        self.__header = header
        self.__length = length
        self.__body = body
        self.__crc = crc

        # parse packet body
        self._parseBody(body)
Exemple #4
0
    def _parseBody(self):
        """
         Parses packet's head
         @return: self
        """
        super(AvlDataCodec7, self)._parseBody()
        self._body = self._rawData
        self._params = {}
        self._sensors = {}

        time = self.readFrom('>L')
        priority = bits.bitRangeValue(time, 30, 32)
        if priority == 2:
            self._sensors['sos'] = 1
        time = bits.bitClear(time, 30)
        time = bits.bitClear(time, 31)
        self._params['time'] = datetime(2007, 1, 1) + timedelta(seconds=time)
        globalMask = self.readFrom('>B')

        hasGpsElement = bits.bitTest(globalMask, 0)
        ioElements = []
        ioElementsFormats = ['>B', '>H', '>L']
        for index in range(len(ioElementsFormats)):
            if bits.bitTest(globalMask, index + 1):
                ioElements.append(ioElementsFormats[index])

        if hasGpsElement:
            mask = self.readFrom('>B')
            # Latitude and longitude
            if bits.bitTest(mask, 0):
                self._params['latitude'] = self.readFrom('>f')
                self._params['longitude'] = self.readFrom('>f')
            # Altitude
            if bits.bitTest(mask, 1):
                self._params['altitude'] = self.readFrom('>h')
            # Angle
            if bits.bitTest(mask, 2):
                self._params['azimuth'] = self.readFrom('>B') * 360 / 256
            # Speed
            if bits.bitTest(mask, 3):
                self._params['speed'] = self.readFrom('>B')
            # Satellites
            if bits.bitTest(mask, 4):
                self._params['satellitescount'] = self.readFrom('>B')
            # CellID
            if bits.bitTest(mask, 5):
                self._params['gsm_cell_lac'] = self.readFrom('>H')
                self._params['gsm_cell_id'] = self.readFrom('>H')
            # Signal quality
            if bits.bitTest(mask, 6):
                self._params['gsm_signal_quality'] = self.readFrom('>B')
            # Operator code
            if bits.bitTest(mask, 7):
                self._params['gsm_operator_code'] = self.readFrom('>L')

        items = []
        for fmt in ioElements:
            cnt = self.readFrom('>B')
            for i in range(cnt):
                items.append({
                    'id': self.readFrom('>B'),
                    'value': self.readFrom(fmt)
                })

        self._parseElements(items)
        self._params['sensors'] = self._sensors
        self._ioElement = {
            # Event IO ID – if data is acquired on event – this field
            # defines which IO property has changed and generated an event.
            # If data cause is not event – the value is 0.
            'eventIoId': 0,
            # List of IO elements
            'items': items
        }
        return self
Exemple #5
0
    def _parseBody(self):
        """
         Parses packet tail
         @return: self
        """
        seqId, unitId  = unpack('>HQ', self._body[:10])
        self.__sequenceId = seqId
        self.__unitId = str(unitId)

        # store current offset
        savedOffset = self._offset
        self._offset = 0

        buffer = self._body[10:]
        self.__items = []
        while self._offset < len(buffer):
            item = {}
            sensor = {}
            item['time'] = self.getTimeFromBuffer(buffer)
            item['time_rtc'] = self.getTimeFromBuffer(buffer)
            item['time_send'] = self.getTimeFromBuffer(buffer)
            item['longitude'] = self.readFrom('>l', buffer) / 1000000
            item['latitude'] = self.readFrom('>l', buffer) / 1000000
            item['azimuth'] = self.readFrom('>H', buffer)
            item['report_id'] = self.readFrom('>B', buffer)
            item['odometer'] = self.readFrom('>L', buffer) * 100
            item['hdop'] = self.readFrom('>H', buffer) / 10
            dInp = self.readFrom('>B', buffer)
            item['speed'] = self.readFrom('>H', buffer)
            dOut = self.readFrom('>B', buffer)
            # digital inputs and outputs
            for i in range(0, 8):
                sensor['din%d' % i] = int(bits.bitTest(dInp, i))
                sensor['dout%d' % i] = int(bits.bitTest(dOut, i))

            sensor['ain0'] = self.readFrom('>H', buffer)
            sensor['driver_id'] =\
                buffer[self._offset:].split(b'\x00')[0].decode()
            self._offset += len(sensor['driver_id']) + 1
            sensor['ext_temperature_0'] = self.readFrom('>h', buffer)
            sensor['ext_temperature_1'] = self.readFrom('>h', buffer)
            sensor['message'] =\
                buffer[self._offset:].split(b'\x00')[0].decode()
            self._offset += len(sensor['message']) + 1

            # read custom information
            fields = self.customInfo.split('%')
            for field in fields:
                if not field: continue
                if field in self.customInfoTable:
                    fmt, alias = self.customInfoTable[field]
                    if fmt:
                        sensor[alias] = self.readFrom(fmt, buffer)
                    else:
                        sensor[alias] =\
                            buffer[self._offset:].split(b'\x00')[0].decode()
                        self._offset += len(sensor[alias]) + 1
                    if alias in ['can_total_fuel_consumption']:
                        sensor[alias] /= 10
                    if alias in ['ext_battery_voltage',
                                 'int_battery_voltage']:
                        sensor[alias] *= 100

            item['sensors'] = sensor
            self.__items.append(item)

        # restore offset
        self._offset = savedOffset
Exemple #6
0
 def parseAdditionalData(self):
     """
      Parses additional data of the packet
      @return: dict
     """
     sensors = {}
     buffer = self.__additional
     offset = 0
     for key in range(0, 16):
         if not bits.bitTest(self.__dataStructure, key):
             continue
         size = self.__dsMap[key]
         data = buffer[offset : offset + size]
         offset += size
         if key == 0:
             status = unpack("<B", data)[0]
             parsedStatus = self.parseProtocolStatus(status)
             for key in parsedStatus:
                 sensors[key] = parsedStatus[key]
         elif key == 1:
             vExt, vInt = unpack("<HH", data)
             sensors["ext_battery_voltage"] = vExt
             sensors["int_battery_voltage"] = vInt
         elif key == 2:
             sensors["int_temperature"] = unpack("<b", data)[0]
         elif key == 3:
             dInp, dOut = unpack("<BB", data)
             for i in range(0, 8):
                 sensors["din%d" % i] = int(bits.bitTest(dInp, i))
                 sensors["dout%d" % i] = int(bits.bitTest(dOut, i))
         elif key in range(4, 8):
             vInp1, vInp2 = unpack("<HH", data)
             index = 2 * (key - 4)
             sensors["ain%d" % index] = vInp1
             sensors["ain%d" % (index + 1)] = vInp2
         elif key in range(8, 10):
             t = unpack("<bbbb", data)
             index = 4 * (key - 8)
             for i in range(0, 4):
                 if t[i] > -100:
                     sensors["ext_temperature_%d" % (i + index)] = t[i]
         elif key == 10:
             vH, vI = unpack("<HI", data)
             sensors["ibutton_0"] = vH | (vI << 16)
         elif key == 11:
             fInp1, fInp2 = unpack("<HH", data)
             sensors["fin0"] = fInp1
             sensors["fin1"] = fInp2
         elif key == 12:  # Omnicomm fuel level
             fInp1, fInp2 = unpack("<HH", data)
             sensors["omnicomm_fuel_0"] = fInp1
             sensors["omnicomm_fuel_1"] = fInp2
         elif key == 13:  # Omnicomm temperature
             fInp1, fInp2 = unpack("<bb", data)
             sensors["omnicomm_temperature_0"] = fInp1
             sensors["omnicomm_temperature_1"] = fInp2
         elif key == 14:  # CAN data 1
             fuel, rpm, coolantTemp = unpack("<BHb", data)
             fuelPercent = fuel * 0.4
             if fuelPercent > 100:
                 fuelPercent = 100
             sensors["can_fuel_percent"] = fuelPercent
             sensors["can_rpm"] = rpm
             sensors["can_coolant_temperature"] = coolantTemp
         elif key == 15:  # CAN data 2
             fuelConsumption, totalMileage = unpack("<LL", data)
             sensors["can_total_fuel_consumption"] = fuelConsumption * 0.5
             sensors["can_total_mileage"] = totalMileage * 5
     return sensors