import datetime import json from .convert import convert_to_dict now = datetime.datetime.now().strftime("%Y-%m-%d") def createDateList(start_date, end_date): start = datetime.datetime.strptime(start_date, "%Y-%m-%d") end = datetime.datetime.strptime(end_date, "%Y-%m-%d") # add a day to the end date to include it in the list end += datetime.timedelta(days=1) # remove a day from the start date to include it in the list start -= datetime.timedelta(days=1) date_generated = [ start + datetime.timedelta(days=x) for x in range(0, (end - start).days) ] date_generated = [date.strftime("%Y-%m-%d") for date in date_generated] return date_generated class Transform: """Takes the raw json data and creates a dictionary containing a dictionary per sensor. The inner dictionary contains the date as x and the number of activations as y. """ def __init__(self, data_source): self.data_source = data_source self.data_type = data_source.split(".")[-1] self.data = None def load_data(self)->"Transform": """loads the data from the data source and stores it in the data attribute Returns: self: The instance of the class """ match self.data_type: case "json": with open(self.data_source, "r") as file: self.data = json.load(file) case "log": self.data = convert_to_dict(self.data_source) case _: raise ValueError("Only JSON and log files are supported") return self def transform_data( self, addMissing=False, start_date="2024-04-05", end_date=now, split=False ): """Take the raw data and transform it into a format that can be used by the diagram generator. There should be one entry per sensor, where x is represented by date and y is represented by the number of activations. If the activations are equal or less than 1 in the on-state, set the sensor data to 0 for that day """ sensors = [] for key, value in self.data.items(): sensors.append({"id": key, "value": value}) temp = {} s_data = {} start_date = start_date end_date = end_date # create a list of all dates between the start and end date all_dates = createDateList(start_date, end_date) for sensor in sensors: tmp = {} sensor_values = {} name = sensor["id"] sensor_values[name] = sensor["value"] tmp[name] = {"x": [], "y": []} sensor_data = sensor["value"] sensor_dates = list(sensor_data.keys()) sum_activations = 0 for date in all_dates: if date not in sensor_dates: # print("Date not in sensor data", name, date) if addMissing: tmp[name]["x"].append(date) tmp[name]["y"].append(0) else: on_state = len(sensor_data[date]["on"]) off_state = len(sensor_data[date]["off"]) activations = (on_state + off_state) / 2 if activations == 1: activations = 0 else: activations = on_state sum_activations += activations # add the date to the tmp dictionary as x and the number of activations as y tmp[name]["x"].append(date) tmp[name]["y"].append(activations) # if on_state != off_state: # tmp[name]["x"].append(date) # tmp[name]["y"].append(activations) # else: # # add the date to the tmp dictionary as x and the number of activations, divided by two as y # tmp[name]["x"].append(date) # tmp[name]["y"].append(activations if activations > 1 else 0) temp.update(tmp) #create new entry in s_data for sensor, add key "total_activations" and the sum of all activations, as well as the usage, which is activation divided by the number of days s_data[name] = {"total_activations": sum_activations, "usage": round(sum_activations / 2)} return temp, s_data if __name__ == "__main__": transform = Transform("data.json") transform.load_data() result = transform.transform_data(True, end_date="2024-04-10", split=True) print(result) # print(createDateList("2024-01-01", "2024-03-04"))