Esempio n. 1
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)
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
0
 def realtime_location_hook(self, location):
     """Handle realtime.
     It's deprecated now.
     """
     insert_location(location, self.db, self.redis)
Esempio n. 5
0
    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)
Esempio n. 6
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()
Esempio n. 7
0
    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)