def handle_report_info(self, info): """These reports should be handled here: POWERLOW/POWERFULL/POWEROFF/POWERDOWN ILLEGALMOVE ILLEGALSHAKE EMERGENCY REGION_ENTER REGION_OUT STOP SPEED_LIMIT """ if not info: return # 1: get available location from lbmphelper report = lbmphelper.handle_location(info, self.redis, cellid=True, db=self.db) if not (report['cLat'] and report['cLon']): #NOTE: Get latest location last_location = QueryHelper.get_location_info(report.dev_id, self.db, self.redis) if last_location: #NOTE: Try to make the location is complete. locations = [last_location,] locations = lbmphelper.get_locations_with_clatlon(locations, self.db) last_location = locations[0] report['lat'] = last_location['latitude'] report['lon'] = last_location['longitude'] report['cLat'] = last_location['clatitude'] report['cLon'] = last_location['clongitude'] report['name'] = last_location['name'] report['type'] = last_location['type'] logging.info("[EVENTER] The report has invalid location and use last_location. report: %s", report) else: logging.info("[EVENTER] The report has invalid location and last_location is invalid. report: %s", report) current_time = int(time.time()) alarm_mobile = get_alarm_mobile(report.dev_id, self.db, self.redis) #NOTE: in pvt, timestamp is no used, so use gps_time as timestamp if not report.get('timestamp',None): report['timestamp'] = report['gps_time'] if report['timestamp'] > (current_time + 24*60*60): logging.info("[EVENTER] The report's (gps_time - current_time) is more than 24 hours, so drop it:%s", report) return #NOTE: If undefend, just save location into db if info['rName'] in [EVENTER.RNAME.ILLEGALMOVE, EVENTER.RNAME.ILLEGALSHAKE]: if str(info.get('is_notify','')) == '1': # send notify even if CF logging.info("[EVENTER] Send notify forever, go ahead. Terminal: %s, is_notify: %s", report.dev_id, info.get('is_notify','')) elif alarm_mobile: logging.info("[EVENTER] Send notify forever , go ahead. Terminal: %s, alarm_mobile: %s", report.dev_id, alarm_mobile) else: mannual_status = QueryHelper.get_mannual_status_by_tid(info['dev_id'], self.db) if int(mannual_status) == UWEB.DEFEND_STATUS.NO: report['category'] = EVENTER.CATEGORY.REALTIME insert_location(report, self.db, self.redis) update_terminal_dynamic_info(self.db, self.redis, report) logging.info("[EVENTER] %s mannual_status is undefend, drop %s report.", info['dev_id'], info['rName']) return if info['rName'] in [EVENTER.RNAME.POWERDOWN, EVENTER.RNAME.POWERLOW]: # if alert_freq_key is exists,return alert_freq_key = get_alert_freq_key(report.dev_id + info['rName']) alert_freq = QueryHelper.get_alert_freq_by_tid(info['dev_id'], self.db) if alert_freq != 0: if self.redis.exists(alert_freq_key): logging.info("[EVENTER] Don't send duplicate %s alert to terminal:%s in %s seconds", info["rName"], report.dev_id, alert_freq) return else: self.redis.setvalue(alert_freq_key, 1, time=alert_freq) #NOTE: keep alarm info alarm = dict(tid=report['dev_id'], category=report['category'], type=report['type'], timestamp=report.get('timestamp',0), latitude=report.get('lat',0), longitude=report.get('lon',0), clatitude=report.get('cLat',0), clongitude=report.get('cLon',0), name=report['name'] if report.get('name',None) is not None else '', degree=report.get('degree',0), speed=report.get('speed',0)) if info['rName'] in [EVENTER.RNAME.REGION_OUT, EVENTER.RNAME.REGION_ENTER]: region = report['region'] alarm['region_id'] = region.region_id record_alarm_info(self.db, self.redis, alarm) # 2: save into database. T_LOCATION, T_EVENT lid = insert_location(report, self.db, self.redis) update_terminal_dynamic_info(self.db, self.redis, report) self.event_hook(report.category, report.dev_id, report.get('terminal_type',1), report.get('timestamp'), lid, report.pbat, report.get('fobid'), report.get('region_id', -1)) # 3: notify the owner user = QueryHelper.get_user_by_tid(report.dev_id, self.db) if not user: logging.error("[EVENTER] Cannot find USER of terminal: %s", report.dev_id) return # send sms to owner if report.rName in [EVENTER.RNAME.STOP]: logging.info("[EVENTER] %s alert needn't to push to user. Terminal: %s", report.rName, report.dev_id) return #NOTE: notify user by sms sms_option = QueryHelper.get_sms_option_by_uid(user.owner_mobile, EVENTER.SMS_CATEGORY[report.rName].lower(), self.db) if sms_option == UWEB.SMS_OPTION.SEND: logging.info("[EVENTER] Notify report to user by sms. category: %s, tid: %s, mobile: %s", report.rName, report.dev_id, user['owner_mobile']) self.notify_report_by_sms(report, user['owner_mobile']) else: logging.info("[EVENTER] Remind option of %s is closed. Terminal: %s", report.rName, report.dev_id) if alarm_mobile: logging.info("[EVENTER] Notify report to user by sms. category: %s, tid: %s, alarm_mobile: %s", report.rName, report.dev_id, alarm_mobile) self.notify_report_by_sms(report, alarm_mobile) #NOTE: notify user by push terminal = self.db.get("SELECT push_status FROM T_TERMINAL_INFO" " WHERE tid = %s", report.dev_id) if terminal and terminal.push_status == 1: logging.info("[EVENTER] Notify report to user by push. category: %s, tid: %s, mobile: %s", report.rName, report.dev_id, user['owner_mobile']) self.notify_report_by_push(report, user['owner_mobile']) else: logging.info("[EVENTER] Push option of %s is closed. Terminal: %s", report.rName, report.dev_id) #NOTE: notify alarm_mobile if alarm_mobile: logging.info("[EVENTER] Notify report to user by push. category: %s, tid: %s, alarm_mobile: %s", report.rName, report.dev_id, alarm_mobile) self.notify_report_by_push(report, alarm_mobile)
def handle_position_info(self, location): """Handle the info of position, include PVT(T11), CALL(T3) """ location = DotDict(location) current_time = int(time.time()) #NOTE: Now, it is seldom appears if location.Tid == EVENTER.TRIGGERID.CALL: if location['gps_time'] > (current_time + 24*60*60): logging.info("[EVENTER] The location's (gps_time - current_time) is more than 24 hours, so drop it:%s", location) return location = lbmphelper.handle_location(location, self.redis, cellid=True, db=self.db) ## check regions #for region in regions: # region_location = self.check_region_event(location, region) # if region_location and region_location['t'] == EVENTER.INFO_TYPE.REPORT: # self.handle_report_info(region_location) location['category'] = EVENTER.CATEGORY.REALTIME update_terminal_dynamic_info(self.db, self.redis, location) if location.get('lat') and location.get('lon'): self.realtime_location_hook(location) # NOTE: For pvt(T11) elif location.Tid == EVENTER.TRIGGERID.PVT: #NOTE: get speed_limit # make pvts sortd according gsp_time pvts = sorted(location['pvts'], key=lambda x:x['gps_time']) for pvt in pvts: #for pvt in location['pvts']: # The 'future time' is drop if pvt['gps_time'] > (current_time + 24*60*60): logging.info("[EVENTER] The location's (gps_time - current_time) is more than 24 hours, so drop it:%s", pvt) continue # get available location from lbmphelper pvt['dev_id'] = location['dev_id'] pvt['Tid'] = location['Tid'] pvt['valid'] = GATEWAY.LOCATION_STATUS.SUCCESS pvt['type'] = 0 #NOTE: handle stop self.handle_stop(pvt) #NOTE: handle region self.handle_region(pvt) #NOTE: handle single self.handle_single(pvt) #NOTE: handle speed self.handle_speed(pvt) #NOTE: the time of keep last_pvt is import. First check single, then keep pvt last_pvt_key = get_last_pvt_key(location['dev_id']) last_pvt = pvt self.redis.setvalue(last_pvt_key, last_pvt, time=EVENTER.STOP_EXPIRY) # NOTE: not offset it #location = lbmphelper.handle_location(pvt, self.redis, # cellid=False, db=self.db) #NOTE: mileage pvt['category'] = EVENTER.CATEGORY.REALTIME if pvt.get('lat') and pvt.get('lon'): insert_location(pvt, self.db, self.redis) #NOTE: handle mileage self.handle_mileage(pvt) self.push_to_client(pvt) else: location.category = EVENTER.CATEGORY.UNKNOWN self.unknown_location_hook(location)
def handle_stop(self, pvt): """Handle the stop point. """ flag = self.check_timestamp(int(pvt['gps_time'])) if not flag: return tid = pvt['dev_id'] stop_key = get_stop_key(tid) stop = self.redis.getvalue(stop_key) distance_key = get_distance_key(tid) distance = self.redis.get(distance_key) if not distance: distance = 0 last_pvt_key = get_last_pvt_key(tid) last_pvt = self.redis.getvalue(last_pvt_key) if last_pvt: distance = float(distance) + lbmphelper.get_distance(int(last_pvt["lon"]), int(last_pvt["lat"]), int(pvt["lon"]), int(pvt["lat"])) self.redis.setvalue(distance_key, distance, time=EVENTER.STOP_EXPIRY) if pvt['speed'] > LIMIT.SPEED_LIMIT: # is moving if stop: #NOTE: time_diff is too short, drop the point. if pvt["gps_time"] - stop['start_time'] < 60: # 60 seconds _stop = self.db.get("SELECT distance FROM T_STOP WHERE lid =%s", stop['lid']) if _stop: tmp_dis = _stop['distance'] else: tmp_dis = 0 distance = float(distance) + tmp_dis self.db.execute("DELETE FROM T_STOP WHERE lid = %s", stop['lid']) self.redis.delete(stop_key) self.redis.setvalue(distance_key, distance, time=EVENTER.STOP_EXPIRY) logging.info("[EVENTER] Stop point is droped: %s", stop) else: # close a stop point self.redis.delete(stop_key) self.db.execute("UPDATE T_STOP SET end_time = %s WHERE lid = %s", pvt["gps_time"], stop['lid']) logging.info("[EVENTER] Stop point is closed: %s", stop) else: pass else: # low speed, may stop if stop: logging.info("[EVENTER] Stop point is updated: %s", stop) stop['end_time'] = pvt["gps_time"] self.redis.setvalue(stop_key, stop, time=EVENTER.STOP_EXPIRY) logging.info("[EVENTER] Stop point is updated: %s", stop) else: # create a new stop point pvt = lbmphelper.handle_location(pvt, self.redis, cellid=True, db=self.db) lid = insert_location(pvt, self.db, self.redis) stop = dict(lid=lid, tid=tid, start_time=pvt["gps_time"], end_time=0, pre_lon=pvt["lon"], pre_lat=pvt["lat"], distance=distance) self.db.execute("INSERT INTO T_STOP(lid, tid, start_time, distance) VALUES(%s, %s, %s, %s)", lid, tid, pvt["gps_time"], distance) self.redis.setvalue(stop_key, stop, time=EVENTER.STOP_EXPIRY) self.redis.delete(distance_key) logging.info("[EVENTER] Stop point is created: %s", stop)
def realtime_location_hook(self, location): """Handle realtime. It's deprecated now. """ insert_location(location, self.db, self.redis)
def request_realtime(self, query, callback=None): """ All realtime requests in REALTIME_VALID_INTERVAL will be considered as only one. If not, invoke gf and use handle_location of lbmphelper. """ location = QueryHelper.get_location_info(self.current_user.tid, self.db, self.redis) if location and location['name'] is None: location['name'] = '' ret = DotDict(status=ErrorCode.SUCCESS, message='', location=None) locations = [location,] locations = get_locations_with_clatlon(locations, self.db) location = locations[0] if (location and location.clatitude and location.clongitude): if location.has_key('id'): del location['id'] location['degree'] = float(location.degree) location['tid'] = self.current_user.tid ret.location = location if callback: callback(ret) return lat, lon = get_latlon_from_cellid(0,0,0,0, self.current_user.sim) clat, clon = get_clocation_from_ge([lat,],[lon,]) clat = int(clat[0]) if len(clat)>0 else 0 clon = int(clon[0]) if len(clon)>0 else 0 name = get_location_name(clat, clon, self.redis) location = DotDict(category = 1, # cellid dev_id = self.current_user.tid, lat = lat, lon = lon, cLat = clat, cLon = clon, alt = 0, gps_time = int(time.time()), type = 1, speed = 0.0, degree = 0.0, name = name, cellid = None, locate_error = 20) if clat and clon: ret.location = DotDict() ret.location.latitude = lat ret.location.longitude = lon ret.location.clongitude = clon ret.location.clatitude = clat ret.location.timestamp = int(time.time()) ret.location.name = name ret.location.speed = 0 ret.location.type = 1 ret.location.tid = self.current_user.tid ret.location.degree = 0.0 ret.location.locte_error = 20 insert_location(location, self.db, self.redis) logging.info("[UWEB] tid %s cellid query success", self.current_user.tid) else: ret.status = ErrorCode.LOCATION_CELLID_FAILED ret.message = ErrorCode.ERROR_MESSAGE[ret.status] logging.info("[UWEB] Do not find any location, and cellid query failed. tid: %s", self.current_user.tid) if callback: callback(ret)
def handle_locationdesc(info, address, connection, channel, exchange, gw_binding, db, redis): """ S10 locationdesc packet 0: success, then return locationdesc to terminal and record new terminal's address 1: invalid SessionID """ try: head = info.head body = info.body dev_id = head.dev_id if len(body) == 6: body.append(20) logging.info("[GW] old version is compatible, append locate_error") resend_key, resend_flag = get_resend_flag(redis, dev_id, head.timestamp, head.command) go_ahead = False args = DotDict(success=GATEWAY.RESPONSE_STATUS.SUCCESS, locationdesc="", ew="E", lon=0.0, ns="N", lat=0.0) sessionID = QueryHelper.get_terminal_sessionID(dev_id, redis) if sessionID != head.sessionID: args.success = GATEWAY.RESPONSE_STATUS.INVALID_SESSIONID logging.error("[GW] Invalid sessionID, terminal: %s", head.dev_id) else: if resend_flag: logging.warn("[GW] Recv resend packet, head: %s, body: %s and drop it!", info.head, info.body) else: go_ahead = True #NOTE: Check ydcw or ajt ajt = QueryHelper.get_ajt_whitelist_by_mobile(head.dev_id, db) if ajt: url_out = ConfHelper.UWEB_CONF.ajt_url_out else: url_out = ConfHelper.UWEB_CONF.url_out if go_ahead: redis.setvalue(resend_key, True, GATEWAY.RESEND_EXPIRY) ldp = LocationDescParser(body, head) location = ldp.ret logging.info("[GW] T10 packet parsered:%s", location) if not location.has_key('gps_time'): location['gps_time'] = int(time.time()) logging.info("[GW] what's up? location:%s hasn't gps_time.", location) location['t'] = EVENTER.INFO_TYPE.POSITION if location['valid'] != GATEWAY.LOCATION_STATUS.SUCCESS: cellid = True else: cellid = False location = lbmphelper.handle_location(location, redis, cellid=cellid, db=db) location.name = location.get('name') if location.get('name') else "" location.name = safe_unicode(location.name) user = QueryHelper.get_user_by_tid(head.dev_id, db) tname = QueryHelper.get_alias_by_tid(head.dev_id, redis, db) dw_method = u'GPS' if not cellid else u'基站' if location.cLat and location.cLon: if user: current_time = get_terminal_time(int(time.time())) sms = SMSCode.SMS_DW_SUCCESS % (tname, dw_method, location.name, safe_unicode(current_time)) url = url_out + '/wapimg?clon=' +\ str(location.cLon/3600000.0) + '&clat=' + str(location.cLat/3600000.0) tiny_id = URLHelper.get_tinyid(url) if tiny_id: base_url = url_out + UWebHelper.URLS.TINYURL tiny_url = base_url + '/' + tiny_id logging.info("[GW] get tiny url successfully. tiny_url:%s", tiny_url) redis.setvalue(tiny_id, url, time=EVENTER.TINYURL_EXPIRY) sms += u"点击 " + tiny_url + u" 查看定位器位置。" else: logging.info("[GW] get tiny url failed.") SMSHelper.send(user.owner_mobile, sms) else: if user: sms = SMSCode.SMS_DW_FAILED % (tname, dw_method) SMSHelper.send(user.owner_mobile, sms) if not (location.lat and location.lon): args.success = GATEWAY.RESPONSE_STATUS.CELLID_FAILED else: insert_location(location, db, redis) lc = LocationDescRespComposer(args) request = DotDict(packet=lc.buf, address=address, dev_id=dev_id) update_terminal_status(redis, head.dev_id, address) append_gw_request(request, connection, channel, exchange, gw_binding) except: logging.exception("[GW] Handle locationdesc exception.") GWException().notify()
def post(self): """Retrive various event. """ status = ErrorCode.SUCCESS try: data = DotDict(json_decode(self.request.body)) mobile = data.mobile sn = data.sn category = int(data.category) location = data.location gps = int(data.gps) gsm = int(data.gsm) pbat = int(data.pbat) attendance_time = data.get('attendance_time', '') logging.info("[UWEB] upload request: %s", data) except Exception as e: status = ErrorCode.ILLEGAL_DATA_FORMAT logging.exception("[UWEB] Invalid data format. Exception: %s, data: %s", e.args, self.request.body) self.write_ret(status) return try: terminal = self.db.get("SELECT id, service_status, mobile" " FROM T_TERMINAL_INFO" " WHERE mobile = %s" " AND sn = %s" " AND service_status = %s" " AND biz_type = %s LIMIT 1", mobile, sn, UWEB.SERVICE_STATUS.ON, UWEB.BIZ_TYPE.YDWQ) if not terminal: status = ErrorCode.ACCOUNT_NOT_MATCH logging.info('mobile: %s, sn: %s not match, drop it.', mobile, sn) self.write_ret(status) return terminal = QueryHelper.get_terminal_by_tmobile(mobile, self.db) tid = terminal['tid'] # NOTE: location may be a dict or list if type(location) != list: locations = [location,] else: locations = location if category == UWEB.UPLOAD_CATEGORY.HEARTBEAT: pass elif category == UWEB.UPLOAD_CATEGORY.LOCATION: for location in locations: location = DotDict(dev_id=tid, lat=location['clatitude'], lon=location['clongitude'], alt=0, cLat=location['clatitude'], cLon=location['clongitude'], gps_time=location['timestamp'], name=location.get('name', ''), category=1, type=int(location['type']), speed=location['speed'], degree=location['degree'], cellid='', locate_error=int(location['locate_error'])) insert_location(location, self.db, self.redis) elif category == UWEB.UPLOAD_CATEGORY.ATTENDANCE: location = locations[0] if len(locations) >= 1 else None if location: location = DotDict(dev_id=tid, lat=location['clatitude'], lon=location['clongitude'], alt=0, cLat=location['clatitude'], cLon=location['clongitude'], gps_time=location['timestamp'], name=location.get('name', ''), category=1, type=int(location['type']), speed=location['speed'], degree=location['degree'], cellid='', locate_error=int(location['locate_error'])) lid = insert_location(location, self.db, self.redis) a_info=dict(mobile=mobile, comment=u'', timestamp=attendance_time if attendance_time else location['gps_time'], lid=lid) record_attendance(self.db, a_info) else: logging.error("[UWEB] Invalid attendance data, location is missed.") else: #TODO: handle power-event location = locations[0] if len(locations) >= 1 else None if location: location = DotDict(dev_id=tid, lat=location['clatitude'], lon=location['clongitude'], alt=0, cLat=location['clatitude'], cLon=location['clongitude'], gps_time=location['timestamp'], name=location.get('name', ''), category=1, type=int(location['type']), speed=location['speed'], degree=location['degree'], cellid='', locate_error=int(location['locate_error'])) lid = insert_location(location, self.db, self.redis) #a_info=dict(mobile=mobile, # comment=u'', # timestamp=attendance_time if attendance_time else location['gps_time'], # lid=lid) #record_attendance(self.db, a_info) t_info = DotDict(gps=gps, gsm=gsm, login=1, pbat=pbat, tid=tid) update_terminal_info_ydwq(self.db, self.redis, t_info) update_terminal_status(self.redis, tid) self.write_ret(status) except Exception as e: logging.exception("[UWEB] tmobile:%s upload failed. Exception: %s", mobile, e.args) status = ErrorCode.SERVER_BUSY self.write_ret(status)