def handle_speed(self, pvt): """Check the speed limit. """ tid = pvt['dev_id'] terminal = self.db.get("SELECT speed_limit " " FROM T_TERMINAL_INFO " " WHERE tid = %s AND group_id != -1", tid) speed_limit = terminal.get('speed_limit', '') if terminal else '' if speed_limit: speed_limit_key = get_speed_limit_key(tid) if int(pvt['speed']) > speed_limit: if self.redis.exists(speed_limit_key): logging.info("[EVENTER] speed_limit has reported, ignore it. pvt: %s", pvt) pass else: speed_pvt = lbmphelper.handle_location(pvt, self.redis, cellid=True, db=self.db) speed_pvt['category'] = EVENTER.CATEGORY.SPEED_LIMIT speed_pvt['t'] = EVENTER.INFO_TYPE.REPORT #NOTE: t is need speed_pvt['rName'] = EVENTER.RNAME.SPEED_LIMIT self.handle_report_info(speed_pvt) self.redis.setvalue(speed_limit_key, True, time=EVENTER.SPEED_LIMIT_EXPIRY) logging.info("[EVENTER] speed_limit works, pvt: %s", speed_pvt) else: self.redis.delete(speed_limit_key) logging.info("[EVENTER] speed_limit does not work, ignore it. pvt: %s", pvt) else: logging.info("[EVENTER] speed_limit is closed, ignore it. pvt: %s", pvt)
def handle_single(self, pvt): """Check single-event. """ tid = pvt['dev_id'] singles = QueryHelper.get_singles(tid, self.db) if singles: pvt = lbmphelper.handle_location(pvt, self.redis, cellid=True, db=self.db) for single in singles: #NOTE: report about single may be need in future single_pvt = self.check_single_event(pvt, single)
def handle_region(self, pvt): """Check single-event. """ tid = pvt['dev_id'] regions = QueryHelper.get_regions(tid, self.db) if regions: pvt = lbmphelper.handle_location(pvt, self.redis, cellid=True, db=self.db) for region in regions: region_pvt= self.check_region_event(pvt, region) if region_pvt and region_pvt['t'] == EVENTER.INFO_TYPE.REPORT: self.handle_report_info(region_pvt)
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_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_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 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()