Add battery daily features and daily consumption rate plot

replace/53cf973e6233e99fe0c08a5b0ba86af8663a5202
Meng Li 2019-11-08 12:18:21 -05:00
parent bdb473411b
commit 54d8084db6
5 changed files with 106 additions and 0 deletions

View File

@ -22,9 +22,11 @@ rule all:
pid=config["PIDS"],
segment = config["BLUETOOTH"]["DAY_SEGMENTS"]),
expand("data/processed/{pid}/google_activity_recognition.csv",pid=config["PIDS"]),
expand("data/processed/{pid}/battery_daily.csv", pid=config["PIDS"]),
# Reports
expand("reports/figures/{pid}/{sensor}_heatmap_rows.html", pid=config["PIDS"], sensor=config["SENSORS"]),
expand("reports/figures/{pid}/compliance_heatmap.html", pid=config["PIDS"], sensor=config["SENSORS"]),
expand("reports/figures/{pid}/battery_consumption_rates_barchart.html", pid=config["PIDS"]),
# --- Packrat Rules --- #
## Taken from https://github.com/lachlandeer/snakemake-econ-r

View File

@ -59,3 +59,11 @@ rule activity_metrics:
"data/processed/{pid}/google_activity_recognition.csv"
script:
"../src/features/google_activity_recognition.py"
rule battery_metrics:
input:
"data/processed/{pid}/battery_deltas.csv"
output:
"data/processed/{pid}/battery_daily.csv"
script:
"../src/features/battery_metrics.py"

View File

@ -18,3 +18,13 @@ rule compliance_heatmap:
"reports/figures/{pid}/compliance_heatmap.html"
script:
"../src/visualization/compliance_heatmap.py"
rule battery_consumption_rates_barchart:
input:
"data/processed/{pid}/battery_daily.csv"
params:
pid = "{pid}"
output:
"reports/figures/{pid}/battery_consumption_rates_barchart.html"
script:
"../src/visualization/battery_consumption_rates_barchart.py"

View File

@ -0,0 +1,60 @@
import pandas as pd
import datetime
battery_data = pd.read_csv(snakemake.input[0])
if battery_data.empty:
battery_features = pd.DataFrame(columns=["battery_diff", "time_diff", "battery_decrease_times","battery_consumption_rate", "local_date"])
else:
for col in ["local_start_date_time", "local_end_date_time", "local_start_date", "local_end_date"]:
battery_data[col] = pd.to_datetime(battery_data[col])
# split the row into 2 rows when local_start_date + 1 = local_end_date
battery_data_overnight = battery_data[battery_data["local_start_date"] + datetime.timedelta(days=1) == battery_data["local_end_date"]]
if not battery_data_overnight.empty:
battery_data_overnight_first, battery_data_overnight_second = pd.DataFrame(columns=battery_data.columns), pd.DataFrame(columns=battery_data.columns)
battery_data_overnight_first["total_battery_diff"], battery_data_overnight_second["total_battery_diff"] = battery_data_overnight["battery_diff"], battery_data_overnight["battery_diff"]
battery_data_overnight_first["total_time_diff"], battery_data_overnight_second["total_time_diff"] = battery_data_overnight["time_diff"], battery_data_overnight["time_diff"]
# let start = start OR end = end, then fill the left col with the start+23:59:59.
battery_data_overnight_first["local_start_date_time"] = battery_data_overnight["local_start_date_time"]
battery_data_overnight_first["local_end_date_time"] = battery_data_overnight["local_start_date"].apply(lambda x: datetime.datetime.combine(x, datetime.time(23,59,59)))
battery_data_overnight_first["local_start_date"] = battery_data_overnight["local_start_date"]
battery_data_overnight_second["local_end_date_time"] = battery_data_overnight["local_end_date_time"]
battery_data_overnight_second["local_start_date_time"] = battery_data_overnight["local_start_date"].apply(lambda x: datetime.datetime.combine(x, datetime.time(23,59,59)))
battery_data_overnight_second["local_start_date"] = battery_data_overnight["local_end_date"]
battery_data_overnight = pd.concat([battery_data_overnight_first, battery_data_overnight_second])
# calculate battery_diff and time_diff
battery_data_overnight["time_diff"] = (battery_data_overnight["local_end_date_time"]-battery_data_overnight["local_start_date_time"]).apply(lambda x: x.total_seconds()/3600)
battery_data_overnight["battery_diff"] = battery_data_overnight["total_battery_diff"]*(battery_data_overnight["time_diff"]/battery_data_overnight["total_time_diff"])
del battery_data_overnight["total_battery_diff"], battery_data_overnight["total_time_diff"]
# filter out the rows when local_start_date + 1 < local_end_date
battery_data = battery_data[battery_data["local_start_date"] == battery_data["local_end_date"]]
# combine
battery_data = pd.concat([battery_data, battery_data_overnight])
# split into decrease table and charge table
battery_data_decrease = battery_data[battery_data["battery_diff"] > 0]
battery_data_charge = battery_data[battery_data["battery_diff"] <= 0]
# for battery_data_decrease:
battery_decrease_count = battery_data_decrease.groupby(["local_start_date"])["local_start_date"].count()
battery_data_decrease = battery_data_decrease.groupby(["local_start_date"]).sum()
battery_data_decrease["battery_decrease_count"] = battery_decrease_count
battery_data_decrease["battery_decrease_duration"] = battery_data_decrease["time_diff"]
battery_data_decrease["battery_consumption_rate"] = battery_data_decrease["battery_diff"]/battery_data_decrease["time_diff"]
del battery_data_decrease["battery_diff"], battery_data_decrease["time_diff"]
# for battery_data_charge:
battery_charge_count = battery_data_charge.groupby(["local_start_date"])["local_start_date"].count()
battery_data_charge = battery_data_charge.groupby(["local_start_date"]).sum()
battery_data_charge["battery_charge_count"] = battery_charge_count
battery_data_charge["battery_charge_duration"] = battery_data_charge["time_diff"]
del battery_data_charge["battery_diff"], battery_data_charge["time_diff"]
# combine decrease features and charge features
battery_features = pd.concat([battery_data_decrease, battery_data_charge], axis=1, sort=True)
battery_features["local_date"] = battery_features.index
battery_features.reset_index(inplace=True, drop=True)
battery_features.to_csv(snakemake.output[0], index=False)

View File

@ -0,0 +1,26 @@
import pandas as pd
import datetime
import plotly.io as pio
import plotly.graph_objects as go
def getBatteryConsumptionRatesBarChart(battery_data, pid):
plot = go.Figure(go.Bar(
x=battery_data["battery_consumption_rate"],
y=battery_data["local_date"].apply(lambda x: x.replace("-","/")).tolist(),
orientation='h'))
plot.update_layout(title="Daily battery consumption rates bar chart for " + pid,
xaxis_title="battery drains % per hour",
)
return plot
battery_data = pd.read_csv(snakemake.input[0])
pid = snakemake.params["pid"]
if battery_data.empty:
empty_html = open(snakemake.output[0], "w")
empty_html.write("There is no "+ sensor_name + " data for "+pid)
empty_html.close()
else:
plot = getBatteryConsumptionRatesBarChart(battery_data, pid)
pio.write_html(plot, file=snakemake.output[0], auto_open=False)