Пример #1
0
def add_report_to_tracker(tracker_id, report):
    logger.info('Adding report to tracker_id "{}": {}'.format(tracker_id, report))
    day = set_tracker_day(tracker_id, report)
    
    # update train position
    if report.get_my_loc():
        update_coords(report, tracker_id)
    
    is_updated_stop_time = stop_detector.add_report(tracker_id, report)
    
    if is_updated_stop_time:
        logger.info('stop_time updated')
        stop_times = stop_detector.get_detected_stop_times(tracker_id)
        trip_delays_ids_list_of_lists = update_trips(tracker_id, day, stop_times)
        trip_ids = get_trusted_trips(trip_delays_ids_list_of_lists)
        for trip_id in trip_ids:
            trip_delays_ids_list = [x for x in trip_delays_ids_list_of_lists if x[0][1] == trip_id][0]
            if (len(stop_times)-1) in trip_delays_ids_list[0][2]:
                if len(trip_delays_ids_list[0][2]) == 2:  # Need to add the first station
                    if (len(stop_times)-2) in trip_delays_ids_list[0][2]:
                        stop_time = stop_times[trip_delays_ids_list[0][2][-2]]
                        logger.debug(stop_time)
                        save_stop_times_to_db(tracker_id, stop_time, trip_id) 
                    else:
                        logger.error('Two stops were detected for trip, last detected stop for tracker belongs to trip, but one before last does not, while it most probably should.')
                stop_time = stop_times[trip_delays_ids_list[0][2][-1]]
                logger.debug(stop_time)
                save_stop_times_to_db(tracker_id, stop_time, trip_id)
Пример #2
0
def get_trusted_trips(trip_delays_ids_list_of_lists):
    trip_ids = []
    if not trip_delays_ids_list_of_lists:
        return trip_ids
    for trip_delays_ids_list in trip_delays_ids_list_of_lists:
        trips = [x[1] for x in trip_delays_ids_list]
        time_deviation_in_seconds = [x[0] for x in trip_delays_ids_list]
        trip_id = get_trusted_trip_or_none(trips, time_deviation_in_seconds)
        if trip_id:
            trip_ids.append(trip_id)
    
    logger.info('Trusted trips={} for trip_delays_ids_list_of_lists={}'.format(trip_ids, trip_delays_ids_list_of_lists))
    return trip_ids
Пример #3
0
def get_trusted_trip_or_none(trips, time_deviation_in_seconds):
    # some heuristics to evaluate if we already have a trip we trust
    # enough to save it in db:
    if not trips:
        return None
    if len(time_deviation_in_seconds) > 1:
        time_deviation_ratio = time_deviation_in_seconds[0]/time_deviation_in_seconds[1] 
    else:
        time_deviation_ratio = 0;
    do_trust_trip = len(trips) > 0 and time_deviation_ratio < 0.5
    if do_trust_trip:
        logger.info('time_deviation_ratio={} and so we trust trip={}'.format(time_deviation_ratio, trips[0]))
        return trips[0] 
    else:
        logger.info('time_deviation_ratio={} and so we do not trust trip={}'.format(time_deviation_ratio, trips[0]))
        return None 
Пример #4
0
def update_coords(report, tracker_id):
    loc = report.get_my_loc()
    coords = [loc.lat, loc.lon]
    logger.info('Updating coords for tracker_id={} by report={} to coords={}'.format(tracker_id, report, coords))    
    res_shape_sampled_point_ids, _ = shapes.all_shapes.query_sampled_points(coords, loc.accuracy_in_coords)
     
    added_count = cl.sadd(get_train_tracker_visited_shape_sampled_point_ids_key(tracker_id), res_shape_sampled_point_ids)

    trip_delays_ids_list_of_lists = load_by_key(get_train_tracker_trip_delays_ids_list_of_lists_key(tracker_id))
    trips = get_trusted_trips(trip_delays_ids_list_of_lists)

    for trip in trips:
        cl.setex(get_current_trip_id_report_timestamp_key(trip), TRACKER_TTL, ot_utils.dt_time_to_unix_time(report.timestamp))
        if added_count > 0:
            save_by_key(get_current_trip_id_coords_key(trip),\
                        coords,\
                        timeout=TRACKER_TTL, cl=p)
            save_by_key(get_current_trip_id_coords_timestamp_key(trip),\
                        ot_utils.dt_time_to_unix_time(report.timestamp),\
                        timeout=TRACKER_TTL, cl=p)
        else: # extend expiration:
            p.expire(get_current_trip_id_coords_key(trip), TRACKER_TTL)
            p.expire(get_current_trip_id_coords_timestamp_key(trip), TRACKER_TTL)
        p.execute()          
Пример #5
0
def save_stop_times_to_db(tracker_id, detected_stop_time, trip_id):
    logger.info('Saving stop_time to db. trip_id={}, stop_time={}'.format(trip_id, detected_stop_time))
    stop = timetable.services.get_stop(detected_stop_time.stop_id)
    departure_time = detected_stop_time.departure
    arrival_time = detected_stop_time.arrival
    from analysis.models import RtStop
    try:
        rs = RtStop.objects.get(tracker_id=tracker_id,stop=stop,trip__gtfs_trip_id=trip_id)
        logger.info('RtStop exists. Overriding.')
    except RtStop.DoesNotExist:
        rs = RtStop()
        logger.info('RtStop does not exist. Creating new one.')
    rs.tracker_id = tracker_id
    rs.trip = timetable.services.get_trip(trip_id)
    rs.stop = stop
    rs.act_arrival = arrival_time
    rs.act_departure = departure_time
    rs.save() 
    logger.info('RtStop saved: {}'.format(rs))  
Пример #6
0
 def set_current(self, state, stop_id, timestamp):
     key = get_train_tracker_data_key(
         self.tracker_id)
     value = (state, str(stop_id), timestamp.isoformat())
     logger.info('key={}, value={}'.format(key, value))
     save_by_key(key, value, cl=p)
Пример #7
0
 def __init__(self, tracker_id):
     logger.info('init detector_state')
     self.tracker_id = tracker_id
Пример #8
0
def _try_add_report(tracker_id, report):
    logger.info('tracker_id={} report={}'.format(tracker_id, report))
    is_updated_stop_time = False
    
    logger.info('fetching detector_state.')
    detector_state = DetectorState(tracker_id)
    logger.info('fetched detector_state.')
    prev_state, prev_stop_id, prev_timestamp = detector_state.get_current()
    logger.info('prev_state={} prev_stop_id={} prev_timestamp={}'.format(prev_state, prev_stop_id, prev_timestamp))
    # new report is older than last report:
    if prev_timestamp and report.timestamp < prev_timestamp:
        logger.warning('New report is older than last report. New report timestamp={}. Last report timestamp={}'.format(report.timestamp, prev_timestamp))
        return is_updated_stop_time

    state, stop_id, timestamp = _get_report_data(report)
    logger.info('state={} stop_id={} timestamp={}'.format(state, stop_id, timestamp))
    if prev_timestamp and timestamp - prev_timestamp > config.no_report_timegap:
        detector_state_transition = DetectorState.transitions.NOREPORT_TIMEGAP
    else:
        detector_state_transition = DetectorState.transitions.NORMAL

    logger.info('Setting detector state: state={} stop_id={} timestamp={}'.format(state, stop_id, timestamp))
    detector_state.set_current(state, stop_id, timestamp)
    if prev_state in [DetectorState.states.INITIAL, DetectorState.states.NOSTOP]:
        if state == DetectorState.states.NOSTOP:
            logger.info('passing big if statement')
            pass
        elif state == DetectorState.states.STOP:
            _start_stop_time(tracker_id, stop_id, timestamp)
            is_updated_stop_time = True
        elif state == DetectorState.states.UNKNOWN_STOP:
            # TODO: Add handling of UNKNOWN_STOP stop_time
            logger.info('passing big if statement')
            pass
    elif prev_state == DetectorState.states.STOP:
        if state == DetectorState.states.NOSTOP:
            stop_time = get_last_detected_stop_time(tracker_id)
            _end_stop_time(
                tracker_id, prev_stop_id, stop_time.arrival, prev_timestamp, stop_time)
            is_updated_stop_time = True
        elif state == DetectorState.states.STOP:
            if detector_state_transition == DetectorState.transitions.NOREPORT_TIMEGAP:
                stop_time = get_last_detected_stop_time(tracker_id)
                print 'NOREPORT_TIMEGAP'
                _end_stop_time(tracker_id, prev_stop_id, stop_time.arrival, prev_timestamp, stop_time)
                _start_stop_time(tracker_id, prev_stop_id, timestamp, stop_time, True)
                is_updated_stop_time = True
            elif prev_stop_id != stop_id:
                stop_time = get_last_detected_stop_time(tracker_id)
                _end_stop_time(tracker_id, prev_stop_id, stop_time.arrival, prev_timestamp, stop_time)
                _start_stop_time(tracker_id, stop_id, timestamp, stop_time)                
                is_updated_stop_time = True
        elif state == DetectorState.states.UNKNOWN_STOP:
            # TODO: Add handling of UNKNOWN_STOP stop_time
            logger.info('passing big if statement')
            pass
    elif prev_state == DetectorState.states.UNKNOWN_STOP:
        if state == DetectorState.states.NOSTOP:
            # TODO: Add handling of UNKNOWN_STOP stop_time
            logger.info('passing big if statement')
            pass
        elif state == DetectorState.states.STOP:
            # TODO: Add handling of UNKNOWN_STOP stop_time
            logger.info('passing big if statement')
            pass
        elif state == DetectorState.states.UNKNOWN_STOP:
            # TODO: Add handling of UNKNOWN_STOP stop_time
            logger.info('passing big if statement')
            pass

    return is_updated_stop_time
Пример #9
0
def add_report(tracker_id, report):
    logger.info('adding report={}'.format(report))
    is_updated_stop_time = False
    report_id = cl.incr(get_train_tracker_report_id_key(tracker_id))
    updated_report_id_key = get_train_tracker_updated_report_id_key(
        tracker_id)
    # We try to update a report only if no report was updated with a more recent 
    # report_id than us. If one was updated, we don't update at all. 
    # This is done using check-and-set (see http://redis.io/topics/transactions)
    done = False
    while not done:
        logger.info('watching {}'.format(updated_report_id_key))
        p.watch(updated_report_id_key)
        updated_report_id = load_by_key(updated_report_id_key, logger=logger)
        logger.info('updated_report_id={}, report_id={}'.format(updated_report_id, report_id))
        if not updated_report_id or updated_report_id < report_id:
            try:
                p.multi()
                is_updated_stop_time = _try_add_report(tracker_id, report)
                p.set(updated_report_id_key, report_id)
                p.execute()
                done = True
            except WatchError:
                logger.info('WatchError: {}'.format(WatchError))
                done = False
                p.unwatch()
        else:
            logger.info('Report not used because of report_id.')
            done = True
            p.unwatch()
    logger.info('is_updated_stop_time={}, done={}'.format(is_updated_stop_time, done))
    return is_updated_stop_time and done
Пример #10
0
def _end_stop_time(tracker_id, stop_id, arrival_time, departure_time, prev_stop_time=None):
    logger.info('Calling _end_stop_time.')
    _update_stop_time(tracker_id, arrival_time, stop_id, departure_time, prev_stop_time)
Пример #11
0
def _start_stop_time(tracker_id, stop_id, arrival_time, prev_stop_time=None, is_report_timegap=False):
    logger.info('Calling _start_stop_time. is_report_timegap={}'.format(is_report_timegap))
    _update_stop_time(tracker_id, arrival_time, stop_id, None, prev_stop_time, is_report_timegap)
Пример #12
0
def update_trips(tracker_id, day, detected_stop_times):
    logger.info('Updating trips for tracker_id={}'.format(tracker_id))
    trip_delays_ids_list_of_lists = trip_matcher.get_matched_trips(tracker_id, detected_stop_times, day)
    logger.info('Updated trip_delays_ids_list_of_lists for tracker_id={}: {}'.format(tracker_id, trip_delays_ids_list_of_lists))
    save_by_key(get_train_tracker_trip_delays_ids_list_of_lists_key(tracker_id), trip_delays_ids_list_of_lists)
    return trip_delays_ids_list_of_lists