예제 #1
0
    def plot_live_minutes(self):
        """returns plotly graph with minute information up to 10 hours back.

        example:
        :plot_live_minutes()
        """
        date = Runtime.td('date_live')
        time = Runtime.td('time_live')
        e = read_youless().read_minutes()
        live = e['watts'][-1]
        # maxusage = max(e['watts']) # variable to calculate max height of figure
        graphtitle = Youless.lang('liveminutegraphtitle').format(
            live, date, time)
        fig = px.line(
            x=e['time'],
            y=e['watts'],
            title=graphtitle,
            # width=1300,  # static figure width
            # height=(maxusage + (maxusage / 3)  # calculate max figure height
            height=500,  # static figure height
            labels={
                "x": Youless.lang('T'),  # x-axis naming
                "y": Youless.lang('W')  # y-axis naming
            })
        logger.debug("Plotting live minutes %s %s" % (date, time))
        return fig
예제 #2
0
    def read_days(self, etype):
        """read all Electricity or Gas hour values from Youless 120 with a maximum history of 70 days back (youless max).
        returns a list with tuples of data.

        example:
            read_days(etype)

        args:
        :etype is 'E' or 'G' for Electricity or Gas
        """
        self.__urltype = self.__ele if etype == 'E' and etype != (
            'G', 'S') else self.__gas if etype == 'G' else self.__snul
        self.max_page = Youless.web("maxDayPage")
        self.min_page = Youless.web("minDayPage")
        self.max_hour = Youless.web("maxHour")
        self.min_hour = Youless.web("minHour")
        self.counter = self.max_page
        self.return_list = []
        while (self.counter >= self.min_page):
            self.api = requests.get(self.__url + self.__urltype + self.__json +
                                    self.__day + str(self.counter))
            readapi = self.api.json()
            json_date = datetime.datetime.strptime(readapi['tm'],
                                                   '%Y-%m-%dT%H:%M:%S')
            date = json_date.date()
            year = json_date.date().strftime('%Y')
            week_no = json_date.date().strftime('%W')
            month_no = json_date.date().strftime('%m')
            month_name = json_date.date().strftime('%B')
            month_day = json_date.date().strftime('%d')
            year_day = json_date.date().strftime('%j')
            raw_values = readapi['val']
            lst = []
            self.hours = self.min_hour
            for y, s in enumerate(raw_values):
                try:
                    raw_values[y] = s.strip()
                    raw_values[y] = float(s.replace(',', '.'))
                except AttributeError:
                    pass
                except IndexError:
                    break
                finally:
                    lst.append(raw_values[y])
            if raw_values[y] is None:
                lst.pop()
            strlst = '{}'.format(lst)
            task = (str(date), int(year), int(week_no), int(month_no),
                    month_name, int(month_day), int(year_day), strlst)
            self.return_list.append(task)
            lst.clear()
            self.counter -= 1
        return self.return_list
예제 #3
0
    def read_months(self, etype):
        """Function to retrieve days per month from Youless 120 up to 11 months back for Electricity and Gas.
        returns a list with tuples of data.

        eaxmple:
            read_months(etype)

        args:
        :etype is 'E' or 'G' for Electricity or Gas
        """

        self.__urltype = self.__ele if etype == 'E' and etype != (
            'G', 'S') else self.__gas if etype == 'G' else self.__snul
        self.__type = self.__kwh if etype == 'E' and etype != 'G' else self.__m3
        self.max_page = Youless.web("maxMonthPage")
        self.min_page = Youless.web("minMonthPage")
        self.counter = self.max_page
        self.return_list = []
        while (self.counter >= self.min_page):
            self.api = requests.get(self.__url + self.__urltype + self.__json +
                                    self.__month + str(self.counter))
            readapi = self.api.json()
            json_date = datetime.datetime.strptime(readapi['tm'],
                                                   '%Y-%m-%dT%H:%M:%S')
            date = json_date.date()
            year = json_date.date().strftime('%Y')
            month_no = json_date.date().strftime('%m')
            month_name = json_date.date().strftime('%B')
            raw_values = readapi['val']
            lst = []
            for y, s in enumerate(raw_values):
                try:
                    raw_values[y] = s.strip()
                    raw_values[y] = float(s.replace(',', '.'))
                except AttributeError:
                    pass
                except IndexError:
                    break
                finally:
                    lst.append(raw_values[y])
            if raw_values[y] is None:
                lst.pop()
            strlst = '{}'.format(lst)
            task = (str(date), int(year), int(month_no), month_name, strlst)
            self.return_list.append(task)
            lst.clear()
            self.counter -= 1
        return self.return_list
예제 #4
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
예제 #5
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
예제 #6
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])
예제 #7
0
    def read_minutes(self):
        """read per minute energy data from Youless 120, data is always 1 minute behind live.
        returns a dictionary with 2 lists consisting of time values and watts values.

        example return:
            {'time': ['value', 'value'], 'watts': ['value', 'value']}
        """
        self.maxPage = Youless.web("maxMinutePage")
        self.minPage = Youless.web("minMinutePage")
        self.maxMinute = Youless.web("maxMinute")
        self.minMinute = Youless.web("minMinute")
        self.counter = self.maxPage
        data = {}
        time = []
        watts = []

        while (self.counter >= self.minPage):
            self.api = requests.get(self.__url + self.__ele + self.__json +
                                    self.__D + str(self.counter)).json()
            self.date = datetime.datetime.strptime(self.api['tm'],
                                                   '%Y-%m-%dT%H:%M:%S')
            i = self.minMinute
            while (i <= self.maxMinute):
                h = self.date.hour
                m = self.date.minute + i
                if (m >= 60):
                    m -= 60
                    h += 1
                self.time = '%02d:%02d' % (h, m)  # str(self.date.time())[0:5]
                self.watt = int(self.api['val'][i])
                time.append(self.time)
                watts.append(self.watt)

                logger.debug('Time: {} Usage: {} Watt'.format(
                    self.time, self.watt))
                i += 1
            self.counter -= 1
        data['time'] = time
        data['watts'] = watts
        logger.debug(data)
        return data
예제 #8
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
예제 #9
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
예제 #10
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
예제 #11
0
    def plot_live(self):
        """returns plotly graph with live information.

        example:
        :plot_live()
        """
        date = Runtime.td('date_live')
        time = Runtime.td('secs_live')
        if (len(livedict['timelst']) == 20):
            livedict['timelst'].pop(0)
        livedict['timelst'].append(time)

        lvd = read_youless().read_live()
        live = lvd['pwr']
        if (len(livedict['wattlst']) == 20):
            livedict['wattlst'].pop(0)
        livedict['wattlst'].append(live)

        total = lvd['cnt']
        graphtitle = Youless.lang('livegraphtitle').format(
            live, date, time, total, Youless.lang('KWH'))
        maxusage = max(livedict['wattlst'])

        fig = px.line(
            x=livedict['timelst'],
            y=livedict['wattlst'],
            title=graphtitle,
            range_y=(0, (maxusage + (maxusage / 3))),
            width=500,  # static figure widt
            # height = (maxusage + (maxusage / 3) # calculate max figure height
            height=500,  # static figure height
            labels={
                "x": Youless.lang('T'),  # x-axis naming
                "y": Youless.lang('W')  # y-axis naming
            })
        logger.debug("Plotting live %s %s" % (date, time))
        return fig
예제 #12
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
예제 #13
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...")
예제 #14
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...")
예제 #15
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])
예제 #16
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
예제 #17
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
예제 #18
0
 def __init__(self) -> None:
     self.elist = Youless.sql('energytypes')[
         'list']  # retrieve energy types
예제 #19
0
"""
import sys
import datetime

# web
import requests

# Youless setup
from LS120 import Youless

# initialize logging
import logging
logger = logging.getLogger(__name__)
logger.debug("read_youless.py started")

sys.stdin.reconfigure(encoding=Youless.web("ENCODING"))  # set encoding
sys.stdout.reconfigure(encoding=Youless.web("ENCODING"))  # set encoding


class read_youless:
    """class to read data from the Youless LS120"""
    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.__stats = Youless.web("STATS")
예제 #20
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
예제 #21
0
    def create_dash_page(self, ip, port):
        """Plot one or more graphs with dash and plotly for testing purposes"""
        self.ip = ip
        self.port = port

        # define the app
        app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

        # define tables to show on page
        live_table_e = web_elements.table_header(Youless.lang('LIVE_TEN_E'),
                                                 "e_tenMinuteGraph")
        live_table_g = web_elements.table_header(Youless.lang('LIVE_TEN_G'),
                                                 "g_tenMinuteGraph")
        dual_energy_table = web_elements.dual_table(Youless.lang('TOYE'),
                                                    "e_today", "e_yesterday")
        dual_gas_table = web_elements.dual_table(Youless.lang('TOYE'),
                                                 "g_today", "g_yesterday")

        # define layout with defined tables
        app.layout = web_elements.layout_with_intervals(
            live_table_e, live_table_g, dual_energy_table, dual_gas_table)

        # start callback with update interval
        @app.callback(  # update every minute (60 seconds)
            Output('e_tenMinuteGraph',
                   'figure'),  # electricity ten minute graph output
            Output('g_tenMinuteGraph',
                   'figure'),  # gas ten minute graph output
            Input('interval-component-quarterhour',
                  'n_intervals')  # interval input
        )
        # the callback function
        def update_tenminutegraph_live(n):
            fig1 = plot_live().plot_live_ten_minutes(
                etype='E',
                start=datetime.datetime.now().replace(
                    hour=0, minute=0, second=0, microsecond=0) -
                datetime.timedelta(days=2))  # 2 days back from today)
            fig2 = plot_live().plot_live_ten_minutes(
                etype='G',
                start=datetime.datetime(2021, 7, 22))  # plot live minute graph
            return fig1, fig2

        # start the callback with update interval
        @app.callback([
            Output('e_today', 'figure'),
            Output('e_yesterday', 'figure'),
            Output('g_today', 'figure'),
            Output('g_yesterday', 'figure')
        ], [Input('interval-component-halfhour', 'n_intervals')])
        def multi_output(n):  # the callback function
            fig1 = plot_dbdata().plot_day_hour(Runtime.td('year_now'),
                                               Runtime.td('month_now'),
                                               Runtime.td('day_now'),
                                               self.elist[0])
            fig2 = plot_dbdata().plot_day_hour(Runtime.td('year_now'),
                                               Runtime.td('month_now'),
                                               Runtime.td('day_yesterday'),
                                               self.elist[0])
            fig3 = plot_dbdata().plot_day_hour(Runtime.td('year_now'),
                                               Runtime.td('month_now'),
                                               Runtime.td('day_now'),
                                               self.elist[1])
            fig4 = plot_dbdata().plot_day_hour(Runtime.td('year_now'),
                                               Runtime.td('month_now'),
                                               Runtime.td('day_yesterday'),
                                               self.elist[1])
            return fig1, fig2, fig3, fig4

        # run the webserver
        app.run_server(debug=Dash_Settings.DASHDEBUG, host=ip, port=port)
예제 #22
0
    def create_dash_page(self, ip, port, debug, reloader):
        """Plot all information with plotly and dash"""
        self.ip = ip
        self.port = port
        self.debug = debug
        self.reloader = reloader

        # define the app
        app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

        # define tables to show on page
        live_table = web_elements.dual_table(Youless.lang('LIVE'), "liveGraph",
                                             "minuteGraph")
        live_ten_minutes_e_table = web_elements.table_header(
            Youless.lang('LIVE_TEN_E'), "e_tenMinuteGraph")
        live_ten_minutes_g_table = web_elements.table_header(
            Youless.lang('LIVE_TEN_G'), "g_tenMinuteGraph")
        today_yesterday_table = web_elements.quad_table_header(
            Youless.lang('TOYE'), "e_today", "e_yesterday", "g_today",
            "g_yesterday")
        thismonth_lastmonth_table = web_elements.quad_table_header(
            Youless.lang('CMLM'), "e_currmonth", "e_lastmonth", "g_currmonth",
            "g_lastmonth")
        thisyear_lastyear_month_table = web_elements.quad_table_header(
            Youless.lang('TYLYM'), "e_year1", "e_year2", "g_year1", "g_year2")
        thisyear_lastyear_day_table = web_elements.quad_table_header(
            Youless.lang('TYLYD'), "e_fullyear1", "e_fullyear2", "g_fullyear1",
            "g_fullyear2")

        # define layout with defined tables
        app.layout = web_elements.layout_with_intervals(
            live_table, live_ten_minutes_e_table, live_ten_minutes_g_table,
            today_yesterday_table, thismonth_lastmonth_table,
            thisyear_lastyear_month_table, thisyear_lastyear_day_table)

        # start callback with update interval
        @app.callback(  # update every 15 minutes (quarter hour)
            Output('updatedb', 'children'),  # database update output
            Input('interval-component-quarterhour',
                  'n_intervals')  # interval input
        )
        # the callback function
        def quarter_hour(n):
            db.main()  # update database
            return

        # start callback with update interval
        @app.callback(  # live update (every 5 seconds)
            Output('liveGraph', 'figure'),  # live graph output
            Input('interval-component-live', 'n_intervals')  # interval input
        )
        # the callback function
        def update_graph_live(n):
            fig = plot_live().plot_live()  # plot live graph
            return fig

        # start callback with update interval
        @app.callback(  # update every minute (60 seconds)
            Output('minuteGraph', 'figure'),  # minute graph output
            Input('interval-component-minute', 'n_intervals')  # interval input
        )
        # the callback function
        def update_minutegraph_live(n):
            fig = plot_live().plot_live_minutes()  # plot live minute graph
            return fig

        # start callback with update interval
        @app.callback(  # update every 10 minutes (600 seconds)
            [
                Output('e_tenMinuteGraph', 'figure'),
                Output('g_tenMinuteGraph', 'figure'),
            ], [Input('interval-component-tenminutes', 'n_intervals')])
        def update_tenminutegraph(n):
            fig1 = plot_live().plot_live_ten_minutes(
                etype='E',
                start=datetime.datetime.now().replace(
                    hour=0, minute=0, second=0, microsecond=0) -
                datetime.timedelta(days=2))  # 2 days back from today)
            fig2 = plot_live().plot_live_ten_minutes(
                etype='G',
                start=datetime.datetime.now().replace(
                    hour=0, minute=0, second=0, microsecond=0) -
                datetime.timedelta(days=2))  # 2 days back from today)
            return fig1, fig2

        # start callback with update interval
        @app.callback(  # update every 30 minutes (half hour)
            Output('e_today', 'figure'),  # energy today output
            Output('g_today', 'figure'),  # gas today output
            Input('interval-component-halfhour',
                  'n_intervals')  # interval input
        )
        def update_halfhour(n):  # the callback function
            fig1 = plot_dbdata().plot_day_hour(
                Runtime.td('year_now'), Runtime.td('month_now'),
                Runtime.td('day_now'), self.elist[0])  # plot energy today
            fig2 = plot_dbdata().plot_day_hour(Runtime.td('year_now'),
                                               Runtime.td('month_now'),
                                               Runtime.td('day_now'),
                                               self.elist[1])  # plot gas today
            return fig1, fig2

        # start callback with update interval
        @app.callback(  # update every 360 minutes (six hours)
            [
                Output('e_yesterday', 'figure'),  # energy yesterday
                Output('g_yesterday', 'figure'),  # gas yesterday
                Output('e_currmonth', 'figure'),  # energy current month
                Output('e_lastmonth', 'figure'),  # energy last month
                Output('g_currmonth', 'figure'),  # gas current month
                Output('g_lastmonth', 'figure'),  # gas last month
                Output('e_year1', 'figure'),  # energy current year per month
                Output('e_year2', 'figure'),  # energy last year per month
                Output('g_year1', 'figure'),  # gas current year per month
                Output('g_year2', 'figure'),  # gas last year per month
                Output('e_fullyear1', 'figure'),  # energy current year per day
                Output('e_fullyear2', 'figure'),  # energy last year per day
                Output('g_fullyear1', 'figure'),  # gas current year per day
                Output('g_fullyear2', 'figure')  # gas last year per day
            ],
            [
                Input('interval-component-sixhours',
                      'n_intervals')  # interval input
            ])
        def update_sixhours(n):  # the callback function
            fig1 = plot_dbdata().plot_day_hour(
                Runtime.td('year_now'), Runtime.td('month_now'),
                Runtime.td('day_yesterday'),
                self.elist[0])  # plot energy yesterday
            fig2 = plot_dbdata().plot_day_hour(
                Runtime.td('year_now'), Runtime.td('month_now'),
                Runtime.td('day_yesterday'),
                self.elist[1])  # plot gas yesterday
            fig3 = plot_dbdata().plot_month_day(
                Runtime.td('year_now'), Runtime.td('month_now'),
                self.elist[0])  # plot energy current month
            fig4 = plot_dbdata().plot_month_day(
                Runtime.td('year_now'), Runtime.td('last_month'),
                self.elist[0])  # plot energy last month
            fig5 = plot_dbdata().plot_month_day(
                Runtime.td('year_now'), Runtime.td('month_now'),
                self.elist[1])  # plot gas current month
            fig6 = plot_dbdata().plot_month_day(
                Runtime.td('year_now'), Runtime.td('last_month'),
                self.elist[1])  # plot gas last month
            fig7 = plot_dbdata().plot_year_month(
                Runtime.td('year_now'),
                self.elist[0])  # plot energy current year per month
            fig8 = plot_dbdata().plot_year_month(
                Runtime.td('last_year'),
                self.elist[0])  # plot energy last year per month
            fig9 = plot_dbdata().plot_year_month(
                Runtime.td('year_now'),
                self.elist[1])  # plot gas current year per month
            fig10 = plot_dbdata().plot_year_month(
                Runtime.td('last_year'),
                self.elist[1])  # plot gas last year per month
            fig11 = plot_dbdata().plot_year_day(
                Runtime.td('year_now'),
                self.elist[0])  # plot energy current year per day
            fig12 = plot_dbdata().plot_year_day(
                Runtime.td('last_year'),
                self.elist[0])  # plot energy last year per day
            fig13 = plot_dbdata().plot_year_day(
                Runtime.td('year_now'),
                self.elist[1])  # plot gas current year per day
            fig14 = plot_dbdata().plot_year_day(
                Runtime.td('last_year'),
                self.elist[1])  # plot gas last year per day
            return fig1, fig2, fig3, fig4, fig5, fig6, fig7, fig8, fig9, fig10, fig11, fig12, fig13, fig14

        # Display json structure in frame below graph
        # @app.callback(
        #     Output("structure", "children"),
        #     [Input("graph", "figure")])
        # def display_structure(fig_json):
        #     return json.dumps(fig_json, indent=2)

        # run the webserver
        app.run_server(debug=self.debug,
                       host=self.ip,
                       port=self.port,
                       use_reloader=self.reloader)
예제 #23
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
예제 #24
0
    def __init__(self) -> None:
        global update_db
        update_db = -1

        self.elist = Youless.sql('energytypes')[
            'list']  # retrieve energy types
예제 #25
0
from LS120 import Runtime, Youless
from LS120.plotly_graphs import plot_live, plot_dbdata
import LS120.db_auto_import as db

# Dash setup
from dash_settings import Dash_Settings, ip_validation
from dash_web_elements import web_elements  # dash web page elements

# initialize logging
# from LS120 import logger
import logging
logger = logging.getLogger(__name__)
logger.debug("dash_allgraphs_live.py started")

# set language
Youless.youless_locale()

# database variable
update_db = 1


class all_graphs_view:
    """class to create dash page with all graphs from LS120.plotly_graphs.plot_data"""
    def __init__(self) -> None:
        global update_db
        update_db = -1

        self.elist = Youless.sql('energytypes')[
            'list']  # retrieve energy types

    def create_dash_page(self, ip, port, debug, reloader):
예제 #26
0
    def plot_live_ten_minutes(self, **kwargs):
        """returns plotly graph with ten minute information up to 10 days back.
        :when supplied it returns a graph from date start=

        examples:
        :plot_live_ten_minutes(etype='E')
        :plot_live_ten_minutes(etype='G', start=datetime.datetime(2020, 1, 31, 0, 0))

        kwargs:
             :etype= str 'E' or 'G' (mandatory)
             :start= datetime.datetime object with date
                example: datetime.datetime(2020, 1, 31, 0, 0)
        """
        if 'etype' not in kwargs:
            return None
        else:
            self.etype = kwargs.get('etype')
            self.ename = Youless.lang(
                "W") if self.etype == 'E' else Youless.lang(
                    "L") if self.etype == 'G' else None

        if 'start' in kwargs:
            self.start_date = kwargs.get(
                'start')  # 2021-01-01 00:00:00 <class 'datetime.datetime'>

        date_now = Runtime.td('date_live')
        time_now = Runtime.td('time_live')
        d = read_youless().read_ten_minutes(self.etype)
        today = d.get(Runtime.td('current_date'))
        live_usage = list(today[1][0].values())[0]
        graphtitle = Youless.lang('tenminutegraphtitle').format(
            live_usage, self.ename, date_now, time_now)

        if 'start_date' in dir(self):
            del_lst = []
            for key in d.keys():
                s_key = datetime.datetime.strptime(
                    key, '%Y-%m-%d'
                )  # 2021-01-01 00:00:00 <class 'datetime.datetime'>
                if self.start_date > s_key:
                    del_lst.append(key)
            for i in del_lst:
                del d[i]

        fig_dict = {}  # dictionary for storing date time, values
        date_time = []  # list for storing date time strings
        values = []  # list for storing usage values
        for key in d.keys():  # for date key in d
            for sub_key in d[key][1]:  # for every time key in the list
                date_time.append(f'{key} {list(sub_key.keys())[0]}')
                values.append(list(sub_key.values())[0])
        fig_dict['time'] = date_time
        fig_dict['usage'] = values

        fig = px.line(
            x=fig_dict['time'],
            y=fig_dict['usage'],
            title=graphtitle,
            height=500,  # static figure height
            labels={
                "x": Youless.lang('T'),  # x-axis naming
                "y": self.ename  # y-axis naming
            })
        logger.debug("Plotting live ten minutes %s %s" % (date_now, time_now))
        return fig
예제 #27
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.__stats = Youless.web("STATS")
     self.__D = Youless.web("D")
     self.__H = Youless.web("H")
     self.__kwh = Youless.sql("valuenaming")[0]
     self.__m3 = Youless.sql("valuenaming")[1]
     self.__watt = Youless.sql("valuenaming")[2]
     self.__ltr = Youless.sql("valuenaming")[3]
예제 #28
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
예제 #29
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)
예제 #30
0
    def read_ten_minutes(self, etype):
        """Read per ten minute data from Youless 120.
        Returned data is always 10 minutes behind last occuring rounded 10 minute interval.
            e.g. at 18.58hours the newest entry is 18.40hours and at 19.00hours it will be 18.50hours
        Returns dictionary with date as key containing a lists with time:value key/value dictionaries\n

        example:
            read_ten_minutes(etype)

        args:
        :etype is 'E' or 'G' for Electricity or Gas
        """
        self.__urltype = self.__ele if etype == 'E' and etype != (
            'G', 'S') else self.__gas if etype == 'G' else self.__snul
        self.max_page = Youless.web("max_tenminutepage")
        self.min_page = Youless.web("min_tenminutepage")
        self.max_ten = Youless.web("max_ten")
        self.min_ten = Youless.web("min_ten")
        self.counter = self.min_page
        self.period = 10  # 10 minute steps
        data = {}

        while (self.counter <= self.max_page):
            self.api = requests.get(self.__url + self.__urltype + self.__json +
                                    self.__H + str(self.counter)).json()
            self.date = datetime.datetime.strptime(self.api['tm'],
                                                   '%Y-%m-%dT%H:%M:%S')
            hour = self.date.hour
            minute = self.date.minute - 10  # current time is 10 minutes less then json start time. subtract 10 minutes from json start time
            year = self.date.date().strftime('%Y')
            week_no = self.date.date().strftime('%W')
            month_no = self.date.date().strftime('%m')
            month_name = self.date.date().strftime('%B')
            month_day = self.date.date().strftime('%d')
            year_day = self.date.date().strftime('%j')
            if self.date.date().strftime('%Y-%m-%d') not in data.keys():
                data[self.date.date().strftime('%Y-%m-%d')] = []
                data[self.date.date().strftime('%Y-%m-%d')].insert(
                    0,
                    (year, week_no, month_no, month_name, month_day, year_day))
                data[self.date.date().strftime('%Y-%m-%d')].insert(1, [])
            i = self.min_ten
            while (i <= self.max_ten):
                minute += self.period
                if minute >= 60:
                    minute = 0
                    hour += 1
                if hour >= 24:
                    hour = 0
                    self.date += datetime.timedelta(days=1)
                self.time = '%02d:%02d' % (hour, minute
                                           )  # str(self.date.time())[0:5]
                self.value = int(self.api['val'][i])
                logger.debug('Time: {} Usage: {} {}'.format(
                    self.time, self.value, etype))
                data[self.date.date().strftime('%Y-%m-%d')][1].insert(
                    0, {self.time: self.value})
                i += 1
            self.counter += 1

        for key in data.keys():  # for date in dictionary
            sorted_values = sorted(
                data[key][1], key=lambda d: list(d.keys()), reverse=True
            )  # order the list hour/value dictionaries in reverse
            data[key][
                1] = sorted_values  # write the sorted list over the original list

        logger.debug(data)
        return data