def test_get_instructions_data_empty(): device = "PTL_NONEXISTING" day = date(2020, 3, 12) interval = (start_of_day(day), end_of_day(day)) with app.app_context(): data = get_instructions_data(device, interval) assert data.empty
def connection(device: str, start_date: date, end_date: date, max_delay: timedelta = timedelta(minutes=2), cut_intervals=False) -> pd.DataFrame: begin = start_of_day(start_date) end = end_of_day(end_date) fully_unconnected = pd.DataFrame(dict(begin=begin, end=end, duration=end-begin, connected=0, color=['#ff0000'])) data = _connection_for_device(device, max_delay=max_delay) if data.empty: return fully_unconnected data = data[(begin <= data.end) & (data.begin <= end)] if data.empty: return fully_unconnected if cut_intervals: data.begin = data.begin.apply(lambda dt: max(begin, dt)) data.end = data.end.apply(lambda dt: min(end, dt)) # fix duration of cut intervals data.duration = data.end - data.begin end_of_last_interval = data.iloc[-1].end # Fill the hole at the end of the time interval, if there is no connection at the end if data.iloc[-1].connected == 1 and end_of_last_interval < end: unconnected = dict(begin=end_of_last_interval, end=end, duration=end-begin, connected=0, color=['#ff0000']) data = data.append(pd.DataFrame(unconnected)) return data.reset_index(drop=True)
def get_keyboard_data(device: str, start_date: date, end_date: date) -> pd.DataFrame: since = start_of_day(start_date) until = end_of_day(end_date) kp = KeyboardPackage query = db.session.query(kp.frame_start, kp.key_press_count, kp.delete_press_count, kp.enter_press_count, kp.shift_press_count, kp.space_press_count, kp.press_pause_count, kp.pause_length, kp.keystroke_time, kp.press_to_press_time) \ .filter(kp.device == device) \ .filter(kp.frame_start >= since) \ .filter(kp.frame_start <= until) data = pd.DataFrame(query.all()) if data.empty: return data data = data.rename(columns=dict(frame_start='timestamp')) \ .set_index('timestamp') return data
def get_settings_durations(device: str, since: date, until: Optional[date] = None) -> pd.DataFrame: """Returns the total duration of time spend in the ptl windows settings and the number of time the settings where opened, per day. @returns: pandas DataFrame with columns 'duration' and 'count' and index column named 'date' containing date objects. 'duration': total duration of time spend in ptl windows settings 'count': number of times the settings where opened. """ if until is None: until = date.today() interval = (start_of_day(since), end_of_day(until)) state_data = get_state_data(device, interval, resample_rule='1S') settings_data = state_data[(state_data.power == 'ON') & (state_data.settings == 'ON')] settings_intervals = find_intervals(settings_data.reset_index()) if settings_intervals.empty: settings_data = pd.DataFrame(columns=['duration', 'count']) else: data_dict = dict(duration=settings_intervals.groupby( [settings_intervals.begin.dt.date]).duration.sum(), count=settings_intervals.groupby([ settings_intervals.begin.dt.date ]).duration.count()) settings_data = pd.DataFrame(data_dict).fillna(timedelta(seconds=0)) settings_data.index.name = 'date' return settings_data
def test_get_state_data_empty(): device = "PTL_NONEXISTING" day = date(2020, 3, 12) interval = (start_of_day(day), end_of_day(day)) with app.app_context(): data = get_state_data(device, interval, resample_rule="1s") print(data) assert data.empty
def get_power(device: str, start_date: date, end_date: Optional[date] = None, resample_rule='1S') -> pd.DataFrame: if end_date is None: end_date = date.today() interval = (start_of_day(start_date), end_of_day(end_date)) state_data = get_state_data(device, interval, resample_rule='1S') state_data.loc[:, 'power'] = (state_data.power == "ON").astype(int) power = state_data.drop(columns=["scene", "settings"]) if power.empty: return power if resample_rule != "1S": power = power.resample(resample_rule).mean() return power
def get_scene_durations(device: str, since: date, until: Optional[date] = None) -> pd.DataFrame: """Return the total duration of each lighting scene per day. @returns: pandas DataFrame with columns 'AUTO', 'TASK_HORI', 'TASK_VERT', 'LIGHT_SHOWER' and index column (named: 'date') containing date objects. Each column is the total time of the lighting scene (column name) for the day specified by the index column. The column entries are timedelta objects. The index column is sorted by day. """ if until is None: until = date.today() interval = (start_of_day(since), end_of_day(until)) state_data = get_state_data(device, interval, resample_rule='1S') on_data = state_data[(state_data.power == 'ON') & (state_data.settings == 'OFF')] scenes = ['AUTO', 'TASK_HORI', 'TASK_VERT', 'LIGHT_SHOWER'] if on_data.empty: duration_data = pd.DataFrame(columns=scenes) else: scene_data = { scene: find_intervals(on_data[on_data.scene == scene].reset_index()) for scene in scenes } def compute_total_duration(data_) -> timedelta: if data_.empty: return timedelta(0) return data_.groupby([data_.begin.dt.date]).duration.sum() # Compute sum of interval durations for each day duration_dict = { scene: compute_total_duration(data) for scene, data in scene_data.items() } duration_data = pd.DataFrame(duration_dict).fillna( timedelta(seconds=0)) duration_data.index.name = 'date' return duration_data
def connection_timeseries(device: str, start_date: date, end_date: Optional[date] = None, max_delay: timedelta = timedelta(minutes=2)) -> pd.DataFrame: if end_date is None: end_date = date.today() - timedelta(days=1) data_interval = connection(device, start_date, end_date, max_delay, cut_intervals=True) if data_interval.empty: return pd.DataFrame() data = data_interval[['begin', 'connected']] # Add a data row for the end of the time interval # To make sure the timeseries goes until the end. connected = data.iloc[-1].connected return data.append(pd.DataFrame(dict(begin=[end_of_day(end_date)], connected=[connected]))) \ .rename(columns=dict(begin='timestamp')) \ .set_index('timestamp') \ .resample('1s') \ .ffill()
def get_sensor_data_for_day(device: str, day: date, rule: str = "1s") -> pd.DataFrame: interval = TimeInterval(start_of_day(day), end_of_day(day)) return get_sensor_data_single_interval(device, interval, rule=rule)
def get_mouse_data_raw(device: str, start_date: date, end_date: date) -> pd.DataFrame: since = start_of_day(start_date) until = end_of_day(end_date) mcp = MouseClickPackage query = db.session.query(mcp.frame_start, mcp.click_count, mcp.double_click_count) \ .filter(mcp.device == device) \ .filter(mcp.frame_start >= since) \ .filter(mcp.frame_start <= until) data_click = pd.DataFrame(query.all()) if data_click.empty: data_click = pd.DataFrame( columns=["frame_start", "click_count", "double_click_count"]) mwp = MouseWheelPackage query = db.session.query(mwp.frame_start, mwp.rotation_distance, mwp.rotation_speed) \ .filter(mwp.device == device) \ .filter(mwp.frame_start >= since) \ .filter(mwp.frame_start <= until) data_wheel = pd.DataFrame(query.all()) if data_wheel.empty: data_wheel = pd.DataFrame( columns=["frame_start", "rotation_distance", "rotation_speed"]) if data_click.empty and data_wheel.empty: return pd.DataFrame() data_combined = pd.merge(data_click, data_wheel, how='outer', on='frame_start') mgp = MouseGesturePackage query = db.session.query(mgp.gesture_start.label('frame_start'), mgp.gesture_end, mgp.event_count, mgp.gesture_distance, mgp.gesture_speed, mgp.gesture_deviation) \ .filter(mgp.device == device) \ .filter(mgp.gesture_start >= since) \ .filter(mgp.gesture_start <= until) data_gesture = pd.DataFrame(query.all()) data_gesture[ 'gesture_duration'] = data_gesture.gesture_end - data_gesture.frame_start data_gesture[ 'gesture_duration_seconds'] = data_gesture.gesture_duration.dt.total_seconds( ) data_gesture = data_gesture.drop(columns=['gesture_end']) data = pd.merge(data_combined, data_gesture, how='outer', on='frame_start') if data.empty: return data data = data.rename(columns=dict(frame_start='timestamp')) \ .set_index('timestamp') \ .sort_index() return data