예제 #1
0
 def __init__(self) -> None:
     self.__headers = Youless.web("HEADERS")  # acceptable html headers
     self.__url = Youless.web("URL")  # base url
     self.__ele = Youless.web("ELE")
     self.__gas = Youless.web("GAS")
     self.__snul = Youless.web("S0")
     self.__json = Youless.web("JSON")
     self.__month = Youless.web("M")
     self.__day = Youless.web("W")
     self.__kwh = Youless.sql("valuenaming")[0]
     self.__m3 = Youless.sql("valuenaming")[1]
     self.__watt = Youless.sql("valuenaming")[2]
     self.__ltr = Youless.sql("valuenaming")[3]
예제 #2
0
    def plot_month_day(self, year, month, etype):
        """Reads from table yeardays_X and returns figure.
        plot one month of the year into a graph with daily totals.

        examples:
        :plot_month_day(2021, 1, 'E')
        :plot_month_day(2021, 'January', 'G')

        args:
        :year as integer
        :month as integer or string
        :etype as string ('E' for Electricity, 'G' for Gas)
        """
        self.year = year
        self.month = month
        self.etype = etype
        self.table = Youless.sql("dbtables")[self.etype][0]
        self.columns = [
            Youless.lang("D"),
            Youless.lang("KH"),
            Youless.lang("KWH")
        ] if self.etype == 'E' else [
            Youless.lang("D"),
            Youless.lang("KM"),
            Youless.lang("M3")
        ] if self.etype == 'G' else None

        if (type(self.month) == str):
            self.mN = datetime.datetime.strptime(self.month, '%B')
            self.month = int(self.mN.date().strftime('%m'))
        self.monthName = datetime.date(1900, self.month, 1).strftime('%B')
        lst = self.data.retrieve_month(
            self.year, self.month, self.table)  # retrieve data from database
        if lst == 0:
            logger.error("No Data")
            return 0
        data = {}
        high = max(lst[2]) + max(lst[2]) / 3
        totalUsage = 0
        for n, elem in enumerate(lst[2]):
            data[n +
                 1] = elem  # Add kWh values to dictionary with the day as key
            totalUsage += elem

        df = pd.DataFrame(data.items(), columns=self.columns[:2])

        fig = px.bar(
            df,
            x=df[self.columns[0]],
            y=df[self.columns[1]],
            range_y=(0, high),
            title=(Youless.lang('yearmonthtitle') %
                   (self.monthName, self.year, self.columns[1], totalUsage,
                    self.columns[2])),
        )
        logger.debug("Plotting month %d of year %d" % (self.month, self.year))
        return fig
예제 #3
0
def main():
    if not youless_sql.isSqlite3Db(path):
        logger.warning("Database {} non existant, creating database".format(Settings.dbname))
        for v in Youless.sql("dbtables").values():
            for i in v:
                con = sl.connect(path)
                with con:
                    con.execute(Youless.sql("queries")[i])
                    logger.warning("Table {} created".format(i))
    else:
        logger.warning("Database {} exists, checking and creating tables".format(Settings.dbname))
        for v in Youless.sql("dbtables").values():
            for i in v:
                if (youless_sql.is_table_exists(i)):
                    logger.warning("Table {} already exists, doing nothing".format(i))
                else:
                    logger.warning("Table {} does not exist, creating".format(i))
                    con = sl.connect(path)
                    with con:  # CREATE TABLE
                        con.execute(Youless.sql("queries")[i])
예제 #4
0
    def plot_year_month(self, year, etype):
        """Reads from table yeardays_X and returns figure.
        plot the year with month totals into a graph.

        example:
        :plot_year(2021, 'E')

        args:
        :year as integer
        :etype as string ('E' for Electricity, 'G' for Gas)
        """
        self.year = year
        self.etype = etype
        self.table = Youless.sql("dbtables")[self.etype][0]
        self.columns = [
            Youless.lang("M"),
            Youless.lang("KH"),
            Youless.lang("KWH")
        ] if self.etype == 'E' else [
            Youless.lang("M"),
            Youless.lang("KM"),
            Youless.lang("M3")
        ] if self.etype == 'G' else None
        self.type = 1  # equals year with month totals
        lst = self.data.retrieve_year(self.year, self.type, self.table)
        if lst == 0:
            logger.error("No Data")
            return 0
        data = {}
        months = {}
        totalUsage = 0.0
        maxLst = []
        for n, elem in enumerate(lst):
            data[lst[n][1]] = lst[n][3]
            months[lst[n][1]] = datetime.date(1900, int(lst[n][1]),
                                              1).strftime('%B')
            totalUsage += lst[n][3]
            maxLst.append(lst[n][3])
        high = max(maxLst) + max(maxLst) / 3
        df = pd.DataFrame(data.items(), columns=(self.columns[:2]))
        fig = px.bar(
            df,
            x=df[self.columns[0]],
            y=df[self.columns[1]],
            range_y=(0, high),
            title=(Youless.lang('yeartitle') %
                   (self.year, self.columns[1], totalUsage, self.columns[2])),
        )
        fig.update_layout(xaxis=dict(tickmode='array',
                                     tickvals=list(months.keys()),
                                     ticktext=list(months.values())))
        logger.debug("Plotting year %d" % (self.year))
        return fig
예제 #5
0
    def is_table_exists(table):
        """youless_sql.is_table_exists(table_name) -> True if exists, False if not"""
        con = sl.connect(path)
        with con:
            check = Youless.sql("queries")["table_exist"]
            table = (table,)
            run = con.execute(check, table)
            e = int(run.fetchone()[0])  # returns 1 if exists

            rtn = True if (e != 0) else False  # 1 == True else False
            logger.debug("table {} existence is {}".format(table, rtn))
            return rtn
예제 #6
0
    def plot_year_day(self, year, etype):
        """Reads from table yeardays_X and returns figure.
        plot the year with daily totals into a graph.

        example:
        :plot_year_day(2021, 'E')

        args:
        :year as integer
        :etype as string ('E' for Electricity, 'G' for Gas)
        """
        self.year = year
        self.etype = etype
        self.table = Youless.sql("dbtables")[self.etype][0]
        self.columns = [
            Youless.lang("D"),
            Youless.lang("KH"),
            Youless.lang("KWH")
        ] if self.etype == 'E' else [
            Youless.lang("D"),
            Youless.lang("KM"),
            Youless.lang("M3")
        ] if self.etype == 'G' else None
        self.type = 2  # equals year with month totals
        lst = self.data.retrieve_year(self.year, self.type, self.table)
        if lst == 0:
            logger.error("No Data")
            return 0
        data = {}
        totalUsage = 0.0
        maxLst = []
        for n, elem in enumerate(lst):
            self.month = int(lst[n][1])
            for y, value in enumerate(lst[n][3]):
                tempkey = ("%d-%d-%d" % (self.year, self.month, y + 1)
                           )  # year-month-day
                data[tempkey] = value
                totalUsage += value
                maxLst.append(value)
        high = max(maxLst) + max(maxLst) / 3
        df = pd.DataFrame(data.items(), columns=self.columns[:2])
        fig = px.bar(
            df,
            x=df[self.columns[0]],
            y=df[self.columns[1]],
            range_y=(0, high),
            title=(Youless.lang('yeardaytitle') %
                   (self.year, self.columns[1], totalUsage, self.columns[2])),
        )
        logger.debug("Plotting year %d" % (self.year))
        return fig
예제 #7
0
    def retrieve_year(self, year, totals, table):
        """Retrieve data from table yeardays_X and return list with items.
        Retrieves available data for given year per month and day in values.
        Returns either month totals or day totals for the entire year.

        example:
        retrieve_year(2021, 2, 'yeardays_g')

        args:
        :year as integer
        :totals as integer (1 is month totals, 2 is day per month totals)
        :table as string
        """
        self.year = year
        self.totals = totals
        self.table = table
        if (self.totals != 1 and self.totals != 2):
            logger.error("error: type can only be 1 or 2")
            return "error: type can only be 1 or 2"
        logger.debug("Starting year retrieval %d" % (self.year))
        self.cur = self.conn.cursor()
        with self.conn:
            self.query = (Youless.sql("queries")["so_yeardays"] %
                          (self.table, str(self.year)))
            data = self.conn.execute(self.query)
            rows = len(data.fetchall())
            logger.debug("Rows retrieved: %d" % rows)
            if (rows >= 1):
                data = self.conn.execute(self.query)
                self.lst = []
                for row in data:
                    self.values = row[4]  # x is string representation of list
                    self.values = ast.literal_eval(
                        self.values)  # convert x to real list
                    total = 0
                    for v, n in enumerate(self.values):
                        self.values[v] = float(self.values[v])
                        total += float(self.values[v])
                    if (self.totals == 1):  # month totals
                        self.tmplst = [[row[1], row[2], row[3], int(total)]]
                    elif (self.totals == 2):  # day totals
                        self.tmplst = [[row[1], row[2], row[3], self.values]]
                    self.lst.extend(self.tmplst)
                    self.tmplst.clear()
            else:
                return 0
        self.conn.close()
        logger.debug("Retrieved list:")
        logger.debug(self.lst)
        return self.lst
예제 #8
0
    def retrieve_day(self, year, month, day, table):
        """Retrieve data from table dayhours_X and return list with items.
        Retrieves day data for given year, month and day in a list with hours and values.

        example:
        retrieve_day(2021, 1, 19, 'dayhours_e')

        args:
        :year as integer
        :month as integer
        :day as integer
        :table as string
        """
        self.year = year
        self.month = month
        self.day = day
        self.table = table
        logger.debug("Starting day retrieval %d %d %d from table %s" %
                     (self.year, self.month, self.day, self.table))
        self.cur = self.conn.cursor()
        with self.conn:
            self.query = (
                Youless.sql("queries")["s_dayhours"] %
                (self.table, str(self.year), str(self.month), str(self.day)))
            data = self.cur.execute(self.query)
            rows = len(self.cur.fetchall())
            logger.debug("Rows retrieved: %d" % rows)
            if (rows >= 1):
                data = self.cur.execute(
                    self.query
                )  # execute query again because fetchall() mangles the data to a list of tuples with strings
                for row in data:
                    self.values = row[7]  # x is string representation of list
                    self.values = ast.literal_eval(
                        self.values)  # convert x to real list
                    for v, n in enumerate(self.values):
                        self.values[v] = float(self.values[v])
            else:
                return 0
        self.conn.close()

        self.lst = [self.year, self.month, self.day, self.values]
        logger.debug("Retrieved list:")
        logger.debug(self.lst)
        return self.lst
예제 #9
0
    def parse_tenminutes(self, etype, data):
        """Function to parse the information retrieved by read_ten_minutes

        example:
        parse_tenminutes(etype, data)

        args:
        :etype is 'E' or 'G' for Electricity or Gas
        :data is a list with tuples retrieved by read_ten_minutes
        """
        self.__table = Youless.sql("dbtables")[etype][2]
        self.__type = self.__watt if etype == 'E' and etype != 'G' else self.__ltr
        logger.debug("Connected to table {}".format(self.__table))
        for key in data.keys():
            write_data().write_tenminutes(self.conn, (key, data[key]),
                                          self.__table, self.__type)
        self.conn.close()
        logger.debug("Database connection closed...")
예제 #10
0
    def parse_months(self, etype, data):
        """Function to parse the information retrieved by retrieve_months

        example:
        parse_months(etype, data)

        args:
        :etype is 'E' or 'G' for Electricity or Gas
        :data is a list with tuples retrieved by retrieve_months
        """
        self.__table = Youless.sql("dbtables")[etype][0]
        self.__type = self.__kwh if etype == 'E' and etype != 'G' else self.__m3
        logger.debug("Connected to table {}".format(self.__table))
        for item in data:
            write_data().write_yeardays(self.conn, item, self.__table,
                                        self.__type)
        self.conn.close()
        logger.debug("Database connection closed...")
예제 #11
0
    def check_existence(self, **kwargs):
        """function to check if item exists in sqlite database.\n
        returns 1 if row exists and 0 if not.

        :table= str
        :column= str
        :item= str/int (int gets transformed to str in process)
        """
        if self.conn is None:
            return None
        self.table = kwargs.get('table')
        self.column = kwargs.get('column')
        self.item = kwargs.get('item')
        self.q = Youless.sql('queries')['if_exists']
        self.query = self.q.format(self.table, self.column, self.item)
        self.cur = self.conn.cursor()
        with self.conn:
            self.data = self.cur.execute(self.query)
        self.outcome = [row for row in self.data]
        self.conn.close()
        return int(self.outcome[0][0])
예제 #12
0
    def retrieve_month(self, year, month, table):
        """Retrieve data from table yeardays_X and return list.
        Retrieves monthdata for given month of given year in a list with days and values

        example:
        retrieve_month(2021, 1, 'yeardays_e')

        args:
        :year as integer
        :month as integer
        :table as string
        """
        self.year = year
        self.month = month
        self.table = table
        logger.debug("Starting month retrieval %d %d from table %s" %
                     (self.year, self.month, self.table))
        self.cur = self.conn.cursor()
        with self.conn:
            self.query = (Youless.sql("queries")["s_yeardays"] %
                          (self.table, str(self.year), str(self.month)))
            data = self.conn.execute(self.query)
            rows = len(data.fetchall())
            logger.debug("Rows retrieved: %d" % rows)
            if (rows >= 1):
                data = self.conn.execute(self.query)
                for row in data:
                    self.values = row[4]  # x is string representation of list
                    self.values = ast.literal_eval(
                        self.values)  # convert x to real list
                    for v, n in enumerate(self.values):
                        self.values[v] = float(self.values[v])
            else:
                return 0
        self.conn.close()

        self.lst = [self.year, self.month, self.values]
        logger.debug("Retrieved list:")
        logger.debug(self.lst)
        return self.lst
예제 #13
0
    def get_item(self, **kwargs):
        """returns item from database corresponding to the given query and kwargs

        examples:
            retrieve_custom_data().get_item(query='select_one_and',
                                            select=('*'),
                                            table='dayhours_e',
                                            id='year',
                                            item='2021',
                                            id2='yearday',
                                            item2='44')
            retrieve_custom_data().get_item(query='select_one',
                                            select='yearday,watt',
                                            table='dayhours_e',
                                            id='year',
                                            item='2021')

        kwargs:
        :query= str
        :select= str
        :table= str
        :id= str
        :item= str
        :id2= str (optional)
        :item2= str (optional)
        """
        if self.conn is None:
            return None
        self.q = Youless.sql('queries')[kwargs.get('query')]
        self.query = self.q % tuple(kwargs.values())[1:]
        self.cur = self.conn.cursor()
        with self.conn:
            self.data = self.cur.execute(self.query)
        self.outcome = [row for row in self.data]
        self.conn.close()
        return self.outcome
예제 #14
0
    def get_dayhours_average(self, **kwargs):
        """gets data from table dayhours_X based on yearday numbers and return average for:
            :specified weekday in a year,
            :specified week in a year,
            :specified month in a year,
            :specified weekday in a month in a year.

        kwargs:
        :year= int: 2021
        :day= dayname
        :month= monthname
        :etype= 'E' or 'G'
        """
        if 'year' in kwargs:  # check if year is passed as keyword argument
            self.year = kwargs.get('year')
            self.start = parser.parse(
                f'{self.year} 1 1'
            )  # a full year is always from january 1st to december 31st
            self.end = parser.parse(
                f'{self.year} 12 31'
            )  # a full year is always from january 1st to december 31st
            # self.start = datetime(self.year, 1, 1)  # a full year is always from january 1st to december 31st
            # self.end = datetime(self.year, 12, 31)  # a full year is always from january 1st to december 31st
        if 'year' in kwargs and 'month' in kwargs:
            self.month = kwargs.get('month').lower().capitalize()
            self.start = parser.parse(
                f'{self.year} {self.month} 1'
            )  # a month always starts at day 1, it is always the same
            self.end = parser.parse(
                f'{self.year} {self.month} {calendar.monthrange(self.year, self.start.month)[1]}'
            )  # get last day of month from calendar
            # self.start = datetime(self.year, datetime.strptime(self.month, '%B').month, 1)  # a month always starts at day 1, it is always the same
            # self.end = datetime(self.year,
            #                     datetime.strptime(self.month, '%B').month,
            #                     calendar.monthrange(self.year, datetime.strptime(self.month, '%B').month)[1])  # get last day of month from calendar
        if 'day' in kwargs:
            self.day = kwargs.get('day').lower().capitalize()
        if 'week' in kwargs:
            self.week = kwargs.get('week')
            self.start = retrieve_custom_data().get_date_range_from_week(
                year=self.year, week=self.week)[2]
            self.end = retrieve_custom_data().get_date_range_from_week(
                year=self.year, week=self.week)[3]
        if 'etype' in kwargs:
            self.table = Youless.sql('dbtables')[kwargs.get('etype')][1]
            self.select = Youless.sql('av_select')[kwargs.get('etype')]

        if 'day' not in kwargs:
            self.get_yeardays = retrieve_custom_data().get_yeardays(
                start=self.start, end=self.end)
        else:
            self.get_yeardays = retrieve_custom_data().get_yeardays(
                start=self.start, end=self.end, day=self.day)
        logger.debug("get_yeardays: %s" % self.get_yeardays)

        check_exist = [
            yearday.lstrip('0') for yearday in self.get_yeardays
            if retrieve_custom_data().check_existence(
                table=self.table, column='yearday', item=yearday) == 1
        ]
        logger.debug("exists yearday check: %s" % check_exist)
        if check_exist == []:
            return None

        self.get_item = [[
            i for i in retrieve_custom_data().get_item(query='select_one_and',
                                                       select=self.select,
                                                       table=self.table,
                                                       id='year',
                                                       item=self.year,
                                                       id2='yearday',
                                                       item2=n)
        ] for n in check_exist]
        logger.debug("get_item: %s" % self.get_item)

        lists = [list(elem[0]) for elem in self.get_item
                 ]  # remove nested tuple and change to list
        lists = [
            [elem[0], ast.literal_eval(elem[1])] for elem in lists
        ]  # convert every 2nd item in the list to a real list (was a string)
        lists = [[elem[0], int(sum(elem[1]) / len(elem[1]))] for elem in lists
                 ]  # get the sum of all values of retrieved day
        average = int(sum(elem[1] for elem in lists) /
                      len(lists))  # get the average over all said days

        # return the average and the amount of days the average is based on including the provided kwargs
        if 'day' in dir(self):
            if 'month' in dir(self):
                return self.year, self.day, self.month, self.table, average, len(
                    lists)
            else:
                return self.year, self.day, self.table, average, len(lists)
        elif 'month' in dir(self):
            return self.year, self.month, self.table, average, len(lists)
        else:
            return self.year, self.week, self.table, average, len(lists)
예제 #15
0
    def retrieve_hours(self, table, year, month, startday, starthour, *args):
        """Retrieve data from table dayhours_X and return list with items.
        Retrieve hour data for given year, month and days with a minimum of 1 hour and a maximum of 24 hours in a list with hours and values.
        Since we dont know if the end day/hour is the same as the start day/hour we use *args to accept this.
        When only startday and starthour is given, only that single hour will be retrieved.

        Examples:
            retrieve_hours('dayhours_g', 2021, 3, 2, 3, 3, 6) # year: 2021, month: 3, startday: 2, starthour: 5, endday: 3, endhour: 6\n
            retrieve_hours('dayhours_e', 2020, 10, 1, 12) # year: 2020, month: 10, startday: 1, starthour: 12\n
            retrieve_hours('dayhours_e', 2020, 11, 2, 11, 18) # year: 2020, month: 11, startday: 2, starthour: 11, endhour: 18\n

        args:
        :table as string
        :year as integer
        :month as integer (min is 1, max is 12)
        :startday as integer (min is 1, max is 30)
        :endday as integer (min is 2, max is 31)
        :starthour as integer (min is 0 (00:00), max is 23 (23:00))
        :endhour as integer (min is 1 (01:00), max is 24 (24:00))
        """
        self.table = table
        self.year = year
        self.month = month
        self.startday = startday
        self.starthour = starthour
        self.hourlist = []
        if (len(args) == 2):
            self.endday = args[0]
            self.endhour = args[1]
            self.query = (Youless.sql("queries")["s_dayhours2"] %
                          (self.table, self.year, self.month, self.startday,
                           self.endday))
            self.lst = [
                self.year, self.month, self.startday, self.starthour,
                self.endday, self.endhour, self.hourlist
            ]
        elif (len(args) == 1):
            self.endhour = args[0]
            self.query = (Youless.sql("queries")["s_dayhours"] %
                          (self.table, self.year, self.month, self.startday))
            self.lst = [
                self.year, self.month, self.startday, self.starthour,
                self.endhour, self.hourlist
            ]
        else:
            self.query = (Youless.sql("queries")["s_dayhours"] %
                          (self.table, self.year, self.month, self.startday))
            self.lst = [
                self.year, self.month, self.startday, self.starthour,
                self.hourlist
            ]
        logger.debug("Starting hour retrieval from table %s" % self.table)
        self.cur = self.conn.cursor()
        with self.conn:
            data = self.cur.execute(self.query)
            rows = (len(self.cur.fetchall()))
            logger.debug("Rows retrieved: %d" % rows)
            if (rows >= 1):
                data = self.cur.execute(
                    self.query
                )  # execute query again because fetchall() mangles the data to a list of tuples with strings
                rowcount = 0
                for row in data:
                    rowcount += 1
                    self.values = row[7]  # x is string representation of list
                    self.values = ast.literal_eval(
                        self.values)  # convert x to real list

                    for n, v in enumerate(self.values):
                        self.values[n] = int(self.values[n])
                        if (rowcount == 1) and (n >= self.starthour):
                            self.hourlist.append((n, v))
                            if (len(args) == 1) and (n == self.endhour):
                                break
                        elif (rowcount == 2) and (n <= self.endhour):
                            self.hourlist.append((n, v))
            else:
                return 0

        self.conn.close()
        logger.debug("Retrieved list:")
        logger.debug(self.lst)
        return self.lst
예제 #16
0
    def __init__(self) -> None:
        global update_db
        update_db = -1

        self.elist = Youless.sql('energytypes')[
            'list']  # retrieve energy types
예제 #17
0
    def plot_hours(self, *args):
        """Reads from table dayhours_X and return figure.
        Plot hours from given starthour up to endhour.
        Plot spans a max of 2 days with a minimum of 1 hour and a maximum of 24 hours.

        Minimum arguments is 5, maximum is 7 in this order:
            :energytype: 'E', year: 2021, month: 3, startday: 2, starthour: 5, endday: 3, endhour: 6
            :energytype: 'E', year: 2021, month: 3, startday: 2, starthour: 5, endhour: 6
            :energytype: 'E', year: 2021, month: 3, startday: 2, starthour: 5

        plot_hours(arguments) examples:
            :plot_hours("E", 2021, 3, 2, 12, 3, 11)
            :plot_hours("E", 2021, 3, 2, 12, 11)
            :plot_hours("E", 2021, 3, 2, 12)
        """
        if (len(args) > 7):
            return logger.warning("Maximum arguments of 7 exceeded")
        elif (len(args) < 5):
            return logger.warning("Minimum arguments is 5")

        self.etype = args[0]
        self.table = Youless.sql("dbtables")[self.etype][1]
        self.year = args[1]
        self.month = args[2]
        self.startday = args[3]
        self.starthour = args[4]
        if (len(args) == 7):
            self.endday = args[5]
            self.endhour = args[6]
            lst = self.data.retrieve_hours(
                self.table, self.year, self.month, self.startday,
                self.starthour, self.endday,
                self.endhour)  # retrieve data from database
        elif (len(args) == 6):
            self.endhour = args[5]
            lst = self.data.retrieve_hours(
                self.table, self.year, self.month, self.startday,
                self.starthour, self.endhour)  # retrieve data from database
        else:
            lst = self.data.retrieve_hours(
                self.table, self.year, self.month, self.startday,
                self.starthour)  # retrieve data from database

        if lst == 0:
            logger.error("No Data")
            return 0

        self.columns = [
            Youless.lang("U"),
            Youless.lang("W"),
            Youless.lang("KWH")
        ] if self.etype == 'E' else [
            Youless.lang("U"),
            Youless.lang("L"),
            Youless.lang("M3")
        ] if self.etype == 'G' else None

        self.hours = lst[-1]
        data = {}
        highlst = []
        total = 0
        for n, v in enumerate(self.hours):
            data[self.hours[n][0]] = int(self.hours[n][1])
            highlst.append(self.hours[n][1])
            total += int(self.hours[n][1])
        high = int(max(highlst) + max(highlst) / 3)

        df = pd.DataFrame(data.items(), columns=self.columns[:2])
        logger.debug(df)

        self.month = datetime.date(1900, int(self.month), 1).strftime('%B')

        self.title = (Youless.lang('dayhourtitle') %
                      (self.month, self.startday, self.year, self.columns[1],
                       int(total / 1000), self.columns[2]) if
                      ('endday'
                       not in dir(self)) else Youless.lang('customhourtitle') %
                      (self.startday, self.endday, self.month, self.year,
                       self.columns[1], int(total / 1000), self.columns[2]))

        fig = px.bar(
            df,
            x=df[self.columns[0]],
            y=df[self.columns[1]],
            range_y=(0, high),
            title=(self.title),
            height=500,
        )
        fig.update_layout(
            xaxis_type=
            'category'  # change x axis type so that plotly does not arrange overlapping day hours
        )

        logger.debug(fig)
        return fig
예제 #18
0
    def write_dayhours(self, conn, insertion, table, type):
        """Internal function to store values in sqlite3 database in the following format (all strings):
            date, year, week, month, monthname, day, yearday, values per hour

        example insertion:
            ('2021-04-03', 2021, 13, 4, 'April', 3, 93, '[428.0, 385.0, 400.0, 391.0, 386.0, 398.0, 403.0, 485.0, 759.0, 611.0, 650.0, 1225.0, 626.0, 940.0, 534.0, 630.0, 751.0, 630.0, 1194.0, 951.0, 934.0, 893.0, 628.0, 581.0]')
        """
        self.table = table
        self.type = type
        self.sql = Youless.sql("queries")["i_dayhours"]
        self.query = Youless.sql("queries")["s_table"]
        self.datequery = (insertion[0].strip(), )  # create primary key check
        self.date = insertion[0]  # create primary key check

        cur = conn.cursor()
        self.check = cur.execute(
            (self.query % self.table),
            self.datequery)  # check the database for existing primary keys

        x = insertion[7]  # x is string representation of list
        x = ast.literal_eval(x)  # convert x to real list
        lenX = len(x)

        existing_entry = self.check.fetchall(
        )  # fetch the complete entry from the database

        try:
            existing_key = existing_entry[0][0]  # assign existing key
            existing_values = existing_entry[0][
                7]  # assign existing value string
            existing_values = ast.literal_eval(
                existing_values
            )  # convert string representation of list to real list
            first_set = set(existing_values)  # create set from existing values
            sec_set = set(x)  # create set from new values
            differences = (first_set - sec_set).union(
                sec_set - first_set)  # compare differences between two sets
            differences = len(differences)
        except Exception:
            logger.debug("no existing Primary Key for {}".format(insertion[0]))
            if ('existing_key' not in locals()):
                logger.debug("double check for existing_key, no existing_key.")
                existing_key = None

        if (existing_key is not None) and (
                differences == 0
        ):  # check if the primary key exists and list has 24 hour values
            logger.debug(
                "Primary key %s exists, has %i entries and %i differences, skipping!"
                % (self.date, lenX, differences))
            return
        else:
            try:
                logger.debug(
                    "Primarykey %s has %i entries and/or %i differences. Overwriting and appending data!"
                    % (self.date, lenX, differences))
            except Exception:
                logger.debug(
                    "existing_key variable was not created, assigning None")
        try:
            cur.execute((self.sql % (self.table, self.type)), insertion)
            logger.debug("Updating the database with: {}".format(insertion))
        except Exception as E:
            logger.error(
                "An error occured, skipping the update.\n Error: {}\n sql: {}".
                format(E, insertion))
            pass
        conn.commit()
        return cur.lastrowid
예제 #19
0
    def write_tenminutes(self, conn, insertion, table, type):
        """Internal function to store values in sqlite3 database in the following format (all strings):
            date, year, week, month, monthname, day, yearday, values per hour

        example insertion:
            ('2021-07-16', [('2021', '28', '07', 'July', '16', '197'), [{'23:50': 264}, {'23:40': 432}, {'23:30': 600}, {'23:20': 648}, {'23:10': 540}]])
        example converted_insertion:
            ('2021-07-16', '2021', '28', '07', 'July', '16', '197', "[{'23:50': 264}, {'23:40': 432}]")
        """
        self.table = table
        self.type = type
        self.sql = Youless.sql("queries")["i_daytenminutes"]
        self.query = Youless.sql("queries")["s_table"]
        self.datequery = (insertion[0].strip(), )  # create primary key check
        self.date = insertion[0]  # create primary key check
        converted_insertion = (insertion[0], insertion[1][0][0],
                               insertion[1][0][1], insertion[1][0][2],
                               insertion[1][0][3], insertion[1][0][4],
                               insertion[1][0][5], f'{insertion[1][1]}')

        cur = conn.cursor()
        self.check = cur.execute(
            (self.query % self.table),
            self.datequery)  # check the database for existing primary keys
        new_list = insertion[1][1]  # x list of key:value dictionaries
        lenX = len(
            new_list
        )  # amount of key:value items (144 items of 10 minutes for a 24 hour day)

        existing_entry = self.check.fetchall(
        )  # fetch the complete entry from the database
        try:
            existing_key = existing_entry[0][0]  # assign existing key
            existing_values = ast.literal_eval(
                existing_entry[0]
                [7])  # convert string representation of list to real list
            existing_list = existing_values
            # source: https://stackoverflow.com/questions/9845369/comparing-2-lists-consisting-of-dictionaries-with-unique-keys-in-python
            list_pair = zip(existing_list, new_list)  # create zipped list pair
            if any(
                    x != y for x, y in list_pair
            ) is True:  # compare the lists with dictionaries for differences
                differences = [(x, y) for x, y in list_pair if x != y
                               ]  # if there are any then get the differences
                differences = len(differences)  # get the amount of differences
            else:
                differences = 0
        except Exception as E:
            logger.debug("{}, no existing Primary Key for {}".format(
                E, insertion[0]))
            if ('existing_key' not in locals()):
                logger.debug(
                    "double check for existing_key {}, no existing_key.".
                    format(insertion[0]))
                differences = 0
                existing_key = None

        if (existing_key is not None) and (
                differences == 0
        ):  # check if the primary key exists and list has 24 hour values
            logger.debug(
                "Primary key %s exists, has %i entries and %i differences, skipping!"
                % (self.date, lenX, differences))
            return
        else:
            try:
                logger.debug(
                    "Creating primary key %s with %i entries and/or %i differences. Overwriting and appending data!"
                    % (self.date, lenX, differences))
            except Exception as E:
                logger.debug(
                    "existing_key variable was not created, assigning None")
                logger.error(E)

        try:
            cur.execute((self.sql % (self.table, self.type)),
                        converted_insertion)
            logger.debug(
                "Updating the database with: {}".format(converted_insertion))
        except Exception as E:
            logger.error(
                "An error occured, skipping the update.\n Error: {}\n sql: {}".
                format(E, converted_insertion))
            pass
        conn.commit()
        return cur.lastrowid
예제 #20
0
    def write_yeardays(self, conn, insertion, table, type):
        """Internal function to store values in sqlite3 database in the following format (all strings):
            date, year, month, monthname, values per day

        example insertion:
            ('2020-12-01', 2020, 12, 'December',
            '[18.85, 15.12, 19.72, 13.76, 13.93, 20.7, 17.66, 18.57, 14.14, 13.23, 12.72, 15.38, 16.89, 16.06,
            15.39, 22.16, 15.0, 15.34, 12.61, 17.17, 18.85, 15.25, 20.22, 13.51, 15.35, 13.49, 12.99, 21.87, 14.2, 16.7, 15.45]')
        """
        self.table = table
        self.type = type
        self.sql = Youless.sql("queries")["i_yeardays"]
        self.query = Youless.sql("queries")["s_table"]
        self.datequery = (insertion[0].strip(), )  # create primary key check
        self.date = insertion[0]  # create primary key check

        cur = conn.cursor()
        self.check = cur.execute(
            (self.query % self.table),
            self.datequery)  # check the database for existing primary keys

        x = insertion[4]  # x is string representation of list
        x = ast.literal_eval(x)  # convert x to real list
        lenX = len(x)

        m = int(insertion[2])

        existing_entry = self.check.fetchall(
        )  # fetch the complete entry from the database

        try:
            existing_key = existing_entry[0][0]  # assign existing key
            existing_values = existing_entry[0][
                4]  # assign existing value string
            existing_values = ast.literal_eval(
                existing_values
            )  # convert string representation of list to real list
            first_set = set(existing_values)  # create set from existing values
            sec_set = set(x)  # create set from new values
            differences = (first_set - sec_set).union(
                sec_set - first_set)  # compare differences between two sets
            differences = len(differences)
        except Exception:
            logger.debug("no existing Primary Key for {}".format(insertion[0]))
            if ('existing_key' not in locals()):
                logger.debug(
                    "existing_key variable was not created, assigning None")
                existing_key = None

        if (existing_key is not None) and (differences == 0):
            logger.debug(
                "Primary key %s exists and has %i differences, skipping!" %
                (insertion[0], differences))
            return
        else:
            try:
                logger.debug(
                    "Primary key is %s and has %i differences. Overwriting and appending data!"
                    % (insertion[0], differences))
            except Exception:
                logger.debug("Primarykey did not exist. Creating new entry")

        try:
            cur.execute((self.sql % (self.table, self.type)), insertion)
            logger.debug("Updating the database with: {}".format(insertion))
        except Exception as E:
            logger.error(
                "An error occured, skipping the update.\n Error: {}\n sql: {}".
                format(E, insertion))
            pass
        conn.commit()
        return cur.lastrowid
예제 #21
0
    def plot_day_hour(self, year, month, day, etype):
        """Reads from table dayhours_X and return figure.
        Plot one day of the year into a graph with hourly totals.

        examples:
        :plot_day_hour(2021, 1, 19, 'E')
        :plot_day_hour(2021, January, 19, 'G')

        args:
        :year as integer
        :month as integer or string
        :day as integer
        :etype as string ('E' for Electricity, 'G' for Gas)
        """
        self.year = year
        self.month = month
        self.day = day
        self.etype = etype
        self.table = Youless.sql("dbtables")[self.etype][1]
        self.columns = [
            Youless.lang("U"),
            Youless.lang("W"),
            Youless.lang("KWH")
        ] if self.etype == 'E' else [
            Youless.lang("U"),
            Youless.lang("L"),
            Youless.lang("M3")
        ] if self.etype == 'G' else None

        if (type(self.month) == str):
            self.mN = datetime.datetime.strptime(self.month, '%B')
            self.month = int(self.mN.date().strftime('%m'))
        self.monthName = datetime.date(1900, self.month, 1).strftime('%B')
        lst = self.data.retrieve_day(self.year, self.month, self.day,
                                     self.table)  # retrieve data from database
        if lst == 0:
            logger.error("No Data")
            return 0
        data = {}
        high = max(lst[3]) + max(lst[3]) / 3
        totalWatt = 0
        for n, elem in enumerate(lst[3]):
            data[
                n +
                1] = elem  # Add watt values to dictionary with the hour as key
            totalWatt += elem

        df = pd.DataFrame(data.items(), columns=self.columns[:2])

        fig = px.bar(
            df,
            x=df[self.columns[0]],
            y=df[self.columns[1]],
            range_y=(0, high),
            title=(Youless.lang('dayhourtitle') %
                   (self.monthName, self.day, self.year, self.columns[1],
                    float(totalWatt / 1000), self.columns[2])),
        )
        logger.debug("Plotting month %d day %d of year %d from table %s" %
                     (self.month, self.day, self.year, self.table))
        return fig
예제 #22
0
 def __init__(self) -> None:
     self.elist = Youless.sql('energytypes')[
         'list']  # retrieve energy types