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
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
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)
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
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
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