Ejemplo n.º 1
0
 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) 
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
 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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
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()