Example #1
0
def main():
    if len(sys.argv) != 2:
        return

    fileName = sys.argv[1]
    file = None
    try:
        # ファイルから問題の条件などを取得
        file = open(fileName, "r")
        limits = __getMoveLimit(file.readline())
        numBoard = __getNumBoard(file.readline())

        Logging.debug('Start solving ' + str(numBoard) + ' problems')

        # 問題を解くループ
        noProblem = 1
        numSolved = 0
        for row in file:
            Logging.debug('Start solving No.%d problem' % noProblem)
            solve = solve_exercises(row, limits)
            if limits.isOver():
                break

            # 問題の回答を出力
            if str(solve) == '':
                Logging.debug('Failed!')
            else:
                Logging.debug('Success!')
                numSolved += 1

            Logging.output(solve)

            noProblem += 1

        Logging.debug('Solving ' + str(numBoard) + ' problems finished -- ' +
                      str(numSolved))

    finally:
        if file != None:
            file.close()
def main():
	if len(sys.argv) != 2:
		return

	fileName = sys.argv[1]
	file	  = None
	try:
		# ファイルから問題の条件などを取得
		file		= open(fileName, "r")
		limits		= __getMoveLimit(file.readline())
		numBoard	= __getNumBoard(file.readline())
		
		Logging.debug('Start solving ' + str(numBoard) + ' problems')
		
		# 問題を解くループ
		noProblem = 1
		numSolved = 0
		for row in file:
			Logging.debug('Start solving No.%d problem' % noProblem)
			solve = solve_exercises(row, limits)
			if limits.isOver():
				break
			
			# 問題の回答を出力
			if str(solve) == '':
				Logging.debug('Failed!')
			else:
				Logging.debug('Success!')
				numSolved += 1

			Logging.output(solve)

			noProblem += 1
		
		Logging.debug('Solving ' + str(numBoard) + ' problems finished -- ' + str(numSolved))
		
	finally:
		if file != None:
			file.close()
    def receive_forever(self):
        """
        Puts the receiver in receiving mode forever. In this mode the receiver
        blocks until new data is received from the sender. Every time a new
        chunk of data is received it calls the registered handlers'
        on_new_data() method.
        """

        while True:  # allow reconnecting on error
            try:
                Logging.debug("Trying to connect to %s:%s..." %
                              (self._sender_address[0],
                               self._sender_address[1]))
                with sock.create_connection(self._sender_address,
                                            timeout=30) as connection:

                    for handler in self._connection_handlers:
                        handler.on_new_connection(self, connection,
                                                  self._sender_address)

                    Logging.debug("Connected successfully")

                    while True:
                        try:
                            Logging.info("Waiting for data...")
                            data = self.receive(connection)
                            Logging.info("Received data")

                            for handler in self._data_handlers:
                                handler.on_new_data(data)

                        except InvalidFormatException as error:
                            # data was not correct
                            Logging.warning("Received data with invalid format:"
                                            " %s" % str(error))

            except ConnectionAbortedError:
                Logging.warning("connection aborted by the sender")
            except sock.timeout:
                Logging.warning("connection timed out")
            except (sock.herror, sock.gaierror):
                Logging.error("the address of the sender is not valid")
                break  # leave the function
            except ConnectionRefusedError:
                Logging.warning("can not reach the sender")

            # retry in connecting in 10 seconds
            Logging.debug(
                "connection failed: will try to connect in 10 seconds")
            sleep(10)
Example #4
0
class pf_openhab(Singleton):
    def __init__(self):
        try:
            if self.loadingdone:
                pass
        except:
            self.loadingdone = True
            self.logging = Logging()
            settings_c = Settings()
            self.openhab_server = settings_c.get_setting("main", "openhab_ip")
            self.openhab_port = settings_c.get_setting("main", "openhab_port")
            self.host = settings_c.get_setting("main", "hostname")
            self.port = settings_c.get_setting("main", "port")
            self.sitemap_name = settings_c.get_setting("main", "sitemap")
            self.sitemap_name = "main" if self.sitemap_name == None else self.sitemap_name
            self.resize_icons = settings_c.get_setting("main", "resize_icons")
            self.iconh = 64
            self.iconw = 64
            self.name = "pf_openhab"
            self.http = urllib3.PoolManager()

    def get_pages(self, filter):
        if type(filter) != list:
            filter = [filter]
        self.load_sitemap()
        data = []
        n = 0
        for i in range(len(self.sitemap["homepage"]["widgets"][0]["widgets"])):
            key = self.sitemap["homepage"]["widgets"][0]["widgets"][i]
            found = False
            for filt in filter:
                if key["label"][0:len(filt)] == filt and not found:
                    icon_url = "/item/icon/" + key["icon"] + ".png"
                    data.append({
                        "label": key["label"],
                        "icon": icon_url,
                        "id": n
                    })
                    found = True
            n += 1
        return data

    def get_page(self, name):
        for i in range(len(self.sitemap["homepage"]["widgets"][0]["widgets"])):
            key = self.sitemap["homepage"]["widgets"][0]["widgets"][i]
            if key["label"] == name:
                return key

    def get_items(self, pagename, subpage="none", subsubpage=0):
        self.load_sitemap()
        page = self.get_page(pagename)
        data = []
        n_subp = 1
        n = 0
        page_type = [page["label"], page["icon"]]
        for key in page["linkedPage"]["widgets"]:
            n += 1
            item = self.convert_item_data(key)
            item["id"] = item["name"] + "__" + pagename + "__" + str(
                subpage) + "__" + str(n)
            if subpage == "none" or str(subpage) == "0":
                if item["type"] == "Frame":
                    item["page"] = pagename
                    item["subpage"] = item["label"]
                data.append(item)
            elif item["type"] == "Frame" and item["label"] == subpage:
                page_type[0] = page_type[0] + " / " + key["label"]
                sub_n = 0
                for k in key["widgets"]:
                    sub_n += 1
                    item = self.convert_item_data(k)
                    item["id"] = item["name"] + "__" + pagename + "__" + str(
                        subpage) + "__" + str(sub_n)
                    if item["type"] == "Frame":
                        item["type"] = "Text"
                    data.append(item)
        return [data, page_type]

    def load_sitemap(self):
        if self.host == None or self.openhab_server == None:
            #if self.openhab_server == None:
            data = self.load_error_sitemap(False)
        else:
            try:
                url = "http://" + self.openhab_server + ":" + self.openhab_port + "/rest/sitemaps/" + self.sitemap_name
                #print(url)
                content = self.http.request('GET', url)
                data = content.data.decode("utf-8")
            except:
                self.logging.error(
                    "Error connecting to openHAB server, please check settings",
                    location=self.name)
                data = self.load_error_sitemap(True)
        data = data.replace("true", "True").replace("false", "False")
        data = eval(data)
        self.sitemap = data

    def load_error_sitemap(self, exception):
        PATH = os.path.dirname(os.path.abspath(__file__))
        errorfile = PATH + "/files/error_sitemap.txt"
        with open(errorfile, 'r') as f:
            data = f.read()
        if exception:
            data = data.replace("{{HOST_CONFIG_ERROR}}", "No error detected")
            data = data.replace("{{OPENHAB_CONFIG_ERROR}}",
                                "Error connecting to server, check settings")
        else:
            data = data.replace("{{HOST_CONFIG_ERROR}}", "Check settings")
            data = data.replace("{{OPENHAB_CONFIG_ERROR}}", "Check settings")
        data = data.replace("{{IP}}", str(self.openhab_server))
        data = data.replace("{{PORT}}", str(self.openhab_port))
        data = data.replace("{{SITEMAP}}", str(self.sitemap_name))
        data = data.replace("{{RESIZE}}", str(self.resize_icons))
        data = data.replace("{{HOST_IP}}", str(self.host))
        data = data.replace("{{HOST_PORT}}", str(self.port))
        return data

    def get_item(self, item_name):
        name, pagename, subpage, n = self.split_item_name(item_name)
        #print(name, pagename, subpage, n)
        item = self.get_item_data(name, pagename, subpage, n)
        self.logging.debug("Item from get_item: " + str(item),
                           location=self.name)
        return item

    def get_item_data(self, item_name, pagename, subpage, n):
        #search for the item
        self.load_sitemap()
        #print("Name: " + item_name)
        o = 1
        subpage_o = 1
        for i in range(len(self.sitemap["homepage"]["widgets"][0]["widgets"])):
            if self.sitemap["homepage"]["widgets"][0]["widgets"][i][
                    "label"] == pagename:
                for key in self.sitemap["homepage"]["widgets"][0]["widgets"][
                        i]["linkedPage"]["widgets"]:
                    if key["label"].find("[") != -1:
                        comp_label = key["label"][0:key["label"].find("[")]
                        while comp_label[-1:] == " ":
                            comp_label = comp_label[0:-1]
                    else:
                        comp_label = key["label"]
                    try:
                        if key["type"] == "Frame" and (
                                str(subpage_o) == subpage
                                or comp_label == subpage):
                            #print(subpage)
                            sub_o = 0
                            for k in key["widgets"]:
                                sub_o += 1
                                try:
                                    if k["item"][
                                            "name"] == item_name and sub_o == n:
                                        item = self.convert_item_data(k)
                                        item["id"] = item[
                                            "name"] + "__" + pagename + "__" + str(
                                                subpage) + "__" + str(n)
                                        item["page"] = pagename
                                        item["subpage"] = str(subpage)
                                        self.logging.debug("Item found, id: " +
                                                           item["id"],
                                                           location=self.name)
                                        return item
                                except Exception as e:
                                    self.logging.warn(
                                        "Invalid item found in sitemap 2 %s" %
                                        (str(e)),
                                        location=self.name)
                        elif "item" in key and key["item"][
                                "name"] == item_name and o == n:
                            item = self.convert_item_data(key)
                            item["id"] = item[
                                "name"] + "__" + pagename + "__" + str(
                                    subpage) + "__" + str(n)
                            item["page"] = pagename
                            item["subpage"] = str(subpage)
                            self.logging.debug("Item found, id: " + item["id"],
                                               location=self.name)
                            return item
                        elif str(subpage) == "0" or subpage == "none":
                            o += 1
                        elif key["type"] == "Frame":
                            subpage_o += 1
                            o += 1
                    except Exception as e:
                        self.logging.warn(
                            "Invalid item found in sitemap 1: %s, %s" %
                            (str(key), str(e)),
                            location=self.name)

    def convert_item_data(self, key):
        #print(key)
        item_data = {
            "icon": key["icon"],
            "type": key["type"],
            "name": key["label"],
            "state": ""
        }
        if "item" in key:
            item_data.update({
                "state": key["item"]["state"],
                "link": key["item"]["link"],
                "name": key["item"]["name"]
            })
            if key["item"]["state"] != "" and key["item"]["state"].find(
                    " ") == -1:
                item_data["icon"] = key["icon"] + "-" + key["item"]["state"]
            if "transformedState" in key["item"]:
                transformedState = key["item"]["transformedState"]
                if len(str(transformedState)) < 15:
                    item_data.update(
                        {"icon": key["icon"] + "-" + transformedState})
            if "mappings" in key:
                item_data.update({"mappings": key["mappings"]})
        if "label" in key:
            item_data.update({"label": key["label"]})

        #### correct icon for state
        try:
            state = float(item_data["state"])
            if state < 0.0:
                item_data["icon"] = key["icon"] + "-" + str(-1 * state + 100)
        except:
            if item_data["state"] == "NULL":
                item_data["state"] = "OFF"
                item_data["icon"] = key["icon"] + "-off"
            elif len(str(item_data["state"])) > 15:
                item_data["icon"] = key["icon"]

        #### transform state name
        if item_data["label"].find("[") != -1:
            label = item_data["label"][0:item_data["label"].find("[")]
            while label[-1:] == " ":
                label = label[0:-1]
            state = item_data["label"][item_data["label"].find("[") +
                                       1:item_data["label"].find("]")]
            item_data.update({"state": state, "label": label})

        if key["type"] == "Colorpicker":
            if item_data["state"].lower() != "off":
                item_data["state"] = self.convert_color_to_rgb(
                    item_data["state"])
                item_data["icon"] = key["icon"] + "-on"
            if len(item_data["state"].split(",")) > 2:
                if item_data["state"].split(",")[2] == "0" or item_data[
                        "state"].split(",")[2] == "0.0":
                    item_data.update({
                        "state": "off",
                        "icon": key["icon"] + "-off"
                    })
        elif key["type"] == "Selection":
            item_state = ""
            if len(key["mappings"]) == 1:
                item_data["type"] = "Switch_single"
                item_state = key["mappings"][0]["label"]
            for mapp in key["mappings"]:
                if mapp["command"].lower() == item_data["state"].lower():
                    ## mappings are like [ displayed state, actual state ]
                    item_state = mapp["label"]
                elif mapp["label"].lower() == item_data["state"].lower():
                    item_state = mapp[
                        'label']  ##sometimes a state is 0 ==> OFF, which is not mapped correctly with Off or 0
            try:
                ##why is this?????
                #print(item_state)
                int(item_state)
                item_data.update({"item_state": item_data["label"]})
                item_data.update({"label": "_"})
            except:
                item_data.update({"state": item_state})
        elif key["type"] == "Setpoint":
            try:
                step = round(float(key["step"]), 1)
                if int(step) == step:
                    step = int(step)
                item_data.update({
                    "setpoint":
                    [int(key["minValue"]),
                     int(key["maxValue"]), step]
                })
            except:
                pass
        elif key["type"] == "Slider":
            item_data.update({"setpoint": [0, 100, 10]})

        ##update the icon to the right url:
        if self.resize_icons == "1":
            item_data["icon"] = "/item/icon/" + item_data["icon"] + ".png"
        else:
            item_data[
                "icon"] = "http://" + self.openhab_server + ":" + self.openhab_port + "/icon/" + item_data[
                    "icon"] + ".png"

        return item_data

    def set_state(self, item_name, state):
        item, pagename, subpage, n = self.split_item_name(item_name)
        if state[0:5] == "Color":
            state = self.convert_color_to_hsv(state[5:])
        #cmd = "curl --header \"Content-Type: text/plain\" --request POST --data \"" + state+ "\" " + self.openhab_server + ":" + self.openhab_port + "/rest/items/" + item
        url = "http://" + self.openhab_server + ":" + self.openhab_port + "/rest/items/" + item
        headers = {'Content-Type': 'text/plain'}
        requests.post(url, data=state, headers=headers)
        self.logging.info("Put state openhab: " + url + " " + str(state),
                          location="openhab")
        #os.system(cmd)
        #print(cmd)
        self.load_sitemap()
        return self.get_item(item_name)

    def get_mappings(self, item_name, occurrence=1):
        ##self.load_sitemap()
        item = self.get_item(item_name)
        mappings = []
        for mapping in item["mappings"]:
            mappings.append([mapping["label"], mapping["command"]])
        return mappings

    def convert_color_to_rgb(self, color):
        if color == "":
            color = "0.0,0.0,0"
        color = color.split(",")
        color = colorsys.hsv_to_rgb(
            float(color[0]) / 360,
            float(color[1]) / 100,
            float(color[2]) / 100)
        red = hex(int(color[0] * 255))[2:]
        if len(red) < 2:
            red = "0" + red
        blue = hex(int(color[1] * 255))[2:]
        if len(blue) < 2:
            blue = "0" + blue
        green = hex(int(color[2] * 255))[2:]
        if len(green) < 2:
            green = "0" + green
        return "#" + red + blue + green

    def convert_color_to_hsv(self, color):
        color = colorsys.rgb_to_hsv(
            float(int("0x" + color[0:2], 0)) / 255.0,
            float(int("0x" + color[2:4], 0)) / 255.0,
            float(int("0x" + color[4:6], 0)) / 255.0)
        return str(color[0] * 360) + "," + str(color[1] * 100) + "," + str(
            color[2] * 100)

    def get_icon(self, name):
        URL = "http://" + self.openhab_server + ":" + self.openhab_port + "/icon/" + name
        response = requests.get(URL)
        with Image.open(BytesIO(response.content)) as image:
            imgByteArr = BytesIO()
            cover = Image.Image.resize(image, [self.iconh, self.iconw])
            cover.save(imgByteArr, image.format)
        return imgByteArr.getvalue()

    def get_chart_data(self, item, period):
        try:
            p = int(period[0:len(period) - 1])
        except:
            p = 1
        if period[-1:] == "D":
            dt = datetime.datetime.now() - datetime.timedelta(days=p)
        elif period[-1:] == "H":
            p += 1
            dt = datetime.datetime.now() - datetime.timedelta(hours=p)
        elif period[-1:] == "W":
            dt = datetime.datetime.now() - datetime.timedelta(weeks=p)
        elif period[-1:] == "M":
            dt = datetime.datetime.now() - relativedelta(months=p)
        start = dt.strftime("%Y-%m-%dT%H:%M:%S.000+01:00")
        self.logging.info("Starting date for data: " + start,
                          location="openhab")
        start = start.replace("+", "%2B").replace(":", "%3A")
        name, pagename, subpage, n = self.split_item_name(item)
        URL = "http://" + self.openhab_server + ":" + self.openhab_port + "/rest/persistence/items/" + name + "?serviceId=rrd4j&starttime=" + start
        response = requests.get(URL)
        ## get item info
        i = self.get_item(item)
        if i == None:
            return None
        else:
            if i["icon"].lower().find("temp") != -1:
                typ = "temp"
            elif i["icon"].lower().find("humi") != -1:
                typ = "humi"
            elif i["icon"].lower().find("press") != -1:
                typ = "pres"
            elif i["icon"].lower().find("energy") != -1:
                typ = "watt"
            else:
                typ = "value"
        return {"data": response.content, "type": typ}

    def split_item_name(self, item_name):
        a = item_name.split("__")
        if len(a) > 1:
            name = a[0]
            pagename = a[1]
            subpage = a[2]
            n = int(a[3])
        else:
            return item_name
        return name, pagename, subpage, n
Example #5
0
class widgets_handler:
    def __init__(self):
        self.openhab = pf_openhab()
        self.logging = Logging()
        self.name = "widget_handler"
        PATH = os.path.dirname(os.path.abspath(__file__))
        self.template_dir = PATH + "/../templates/"
        self.imported_widget_classes = {}

    def render_widget(self, page, lowerpage):
        w_info = self.get_widget_info(lowerpage, main_page=page)

        data = self.openhab.get_items(page, lowerpage)
        item_data = self.render_item_data_for_widget(data[0])

        try:
            item_data = self.get_widget_data(w_info, item_data)
            if "error" in item_data:
                return render_template("error.html", data=item_data)
        except Exception as e:
            self.logging.error("Error creating widget %s" % str(e),
                               location=self.name)
            er = self.render_widget_error(e, lowerpage)
            return render_template("error.html", data={"error": str(er)})

        item_data["gen_name"] = w_info["name"]
        item_data["pagename"] = page
        try:
            self.logging.debug("Rendering widget: %s" % w_info["template"],
                               location=self.name)
            return render_template("widgets/%s.html" %
                                   w_info["template"].lower(),
                                   data=item_data)
        except Exception as e:
            self.logging.error("Error creating widget %s" % str(e),
                               location=self.name)
            er = self.render_widget_error(e, lowerpage)
            return render_template("error.html", data={"error": str(er)})

    def create_mainpage_popup(self, page, subpage, menuwidget=False):
        if page == "none":
            ##in case the widget is on the main page
            data = self.openhab.get_items(subpage, page)
        else:
            data = self.openhab.get_items(page, subpage)
        item_data = self.render_item_data_for_widget(data[0])
        if len(item_data) == 0:
            #return "widget not in sitemap"
            self.logging.error("Widget is not in sitemap", location=self.name)
            er = self.render_widget_error("widget not in sitemap", subpage)
            return render_template("popups/error.html",
                                   data={"error": str(er)})
        info = self.get_widget_info(subpage, main_page=page)
        try:
            item_data = self.get_widget_data(info, item_data)
            if "error" in item_data:
                return render_template("popups/error.html", data=item_data)
        except Exception as e:
            self.logging.error("Error creating widget %s" % str(e),
                               location=self.name)
            er = self.render_widget_error(e, subpage)
            if menuwidget:
                return render_template("popups/error.html",
                                       data={"error": str(er)}), "Error"
            else:
                return render_template("popups/error.html",
                                       data={"error": str(er)})

        item_data["page_name"] = page
        item_data["widget_name"] = subpage
        item_data["menuwidget"] = menuwidget
        if info == None:
            return render_template(
                "popups/error.html",
                data={
                    "error":
                    "Popup widget template for %s does not exist" %
                    subpage.lower()
                })
        elif info["template"] == "generic_button_page":
            return info["template"]
        else:
            try:
                self.logging.debug("Rendering popup widget: %s" %
                                   info["template"],
                                   location=self.name)
                data = render_template("popup_widgets/" + info["template"] +
                                       ".html",
                                       data=item_data)
                if menuwidget:
                    title = self.find_var(data, "Title")
                    if title == None:
                        title = ""
                    return data, title
                else:
                    return data
            except Exception as e:
                self.logging.error("Error creating popup widget %s" % str(e),
                                   location=self.name)
                er = self.render_widget_error(e, subpage)
                if menuwidget:
                    return render_template("popups/error.html",
                                           data={"error": str(er)}), "Error"
                else:
                    return render_template("popups/error.html",
                                           data={"error": str(er)})

    def get_widget_data(self, w_info, item_data):
        if w_info["name"] not in self.imported_widget_classes:
            try:
                a = __import__(w_info["name"] + "_widget")
                self.imported_widget_classes[w_info["name"]] = getattr(
                    a, w_info["name"] + "_widget")()
            except Exception as e:
                self.logging.warn("Could not create widget %s" % str(e),
                                  location=self.name)
                self.logging.warn("Could not create widget %s" %
                                  str(w_info["name"]),
                                  location=self.name)
                self.logging.warn("Importing normal widget",
                                  location=self.name)
                a = __import__("widget")
                self.imported_widget_classes[w_info["name"]] = a.widget()
        cl = self.imported_widget_classes[w_info["name"]]
        item_data = cl.get_data(item_data)
        return item_data

    def check_widget_type(self, name):
        if name[0:2] == "m_":
            return "menu_button"
        if name[0:2] in ["a_"]:
            return "menu_popup"
        if name[0:2] in ["b_"]:
            return "widget_popup"
        if name[0:2] in ["c_"]:
            return "widget_subpage"
        if name[0:2] == "s_":
            info = self.get_widget_info(name)
            return "widget_" + str(info["rows"])
        else:
            return name

    def get_widget_label(self, name):
        for n in ["b_"]:
            if name.find(n) != -1:
                return name[name.find(n) + 2:]
        if name.find("[") != -1 and name.find("]") != -1:
            name = name[name.find("[") + 1:name.find("]")]
            return name
        for n in ["m_", "a_", "b_", "c_", "d_"]:
            if name.find("/ " + n) != -1:
                return name[name.find("/ " + n) + 4:]
            if name.find(n) != -1:
                return name[name.find(n) + 2:]
        i = self.get_widget_info(name)
        if i == None:
            return name
        else:
            return i["name"]

    def get_widget_info(self, name, main_page="none"):
        ##  s_  frontpage widget with possible popup widget
        ##  a_  generic button page (with large button on frontpage
        ##  b_  bottom page
        ##  c_  popup widget with button
        ##  d_  popup widget with button
        ##  m_  generic button linking to a page instead of popup
        widget_data = {}
        widget_data["a_"] = {
            "type": "popup_widget",
            "name": name[2:],
            "template": "generic_button_page"
        }

        if name[0:2] in widget_data:
            return widget_data[name[0:2]]
        else:
            ##try to find the info from the widget template
            data = "_"
            name_lower = name[2:].lower()
            if name[0:2] == "s_":  ##widget
                f_name = self.template_dir + "widgets/" + name_lower + ".html"
                if Path(f_name).is_file():
                    with open(f_name, 'r') as myfile:
                        data = myfile.read().replace('\n', '')
                    n = self.find_var(data, "Name")
                    rows = self.find_var(data, "Rows")
                    title = self.find_var(data, "Title")
                    if rows != None and n != None:
                        return {
                            "title": title,
                            "name": n,
                            "rows": int(rows),
                            "template": name_lower,
                            "type": "frontpage_widget",
                            "pagename": main_page
                        }
            else:  ##popup
                f_name = self.template_dir + "popup_widgets/" + name_lower + ".html"
                if Path(f_name).is_file():
                    with open(f_name, 'r') as myfile:
                        data = myfile.read().replace('\n', '')
                    n = self.find_var(data, "Name")
                    if n != None:
                        return {
                            "name": n,
                            "template": name_lower,
                            "type": "popup_widget",
                            "pagename": main_page
                        }
            return None

    def find_var(self, data, var):
        if data.find(var + "=") != -1:
            pos = data.find(var + "=")
            pos2 = data[pos + len(var) + 1:].find("/")
            return data[pos + len(var) + 1:pos + len(var) + 1 + pos2]
        else:
            return None

    def render_item_data_for_widget(self, data):
        d = {}
        for dat in data:
            dat["state_length"] = len(dat["state"])
            d[dat["label"].lower()] = dat
        return d

    def render_widget_error(self, e, w):
        e = str(e)
        if e.find("attribute") != -1:
            pos = e.find("attribute")
            n = e[pos + 10:]
            return "Please add an item labeled %s to the widget named %s" % (
                n, str(w))
        else:
            return "Widget: " + str(w) + "  " + str(e)
Example #6
0
class mqtt(Singleton):
    def __init__(self):
        try:
            if self.loadingdone:
                pass
        except:
            self.loadingdone = True
            self.started = True
            self.logging = Logging()
            self.name = "mqtt"
            self.settings_c = Settings()
            try:
                self.server = self.settings_c.get_setting("mqtt", "server")
                self.port = int(self.settings_c.get_setting("mqtt", "port"))
                self.timeout = int(
                    self.settings_c.get_setting("mqtt", "timeout"))
            except Exception as e:
                self.logging.error("Configuration not correct, check settings",
                                   location=self.name)
            self.listeners = []
            self.client = mqtt_cl.Client()
            self.client.on_connect = self.on_connect
            self.client.on_message = self.on_message
            self.client.connect(self.server, self.port, self.timeout)
            self.client.loop_start()
            self.logging.info("Connected to mqtt broker at: " + self.server,
                              location=self.name)

    def on_connect(self, client, userdata, flags, rc):
        self.logging.info("Resubscribing for all listeners at " + self.server,
                          location=self.name)
        for listen in self.listeners:
            self.client.subscribe(listen[0])

    def on_message(self, client, userdata, msg):
        self.logging.info("Received message: " + msg.topic + " " +
                          str(msg.payload),
                          location=self.name)
        if self.started:
            for listen in self.listeners:
                topic = listen[0][0:-1]
                if msg.topic.find(topic) != -1:
                    self.logging.debug("Topic match for %s at %s" %
                                       (listen[1].get_name(), listen[0]),
                                       location=self.name)
                    try:
                        data = ast.literal_eval(msg.payload.decode("utf-8"))
                    except:
                        data = msg.payload.decode("utf-8")
                    try:
                        p = getattr(listen[1], listen[2])
                        p(msg.topic, data)
                    except Exception as e:
                        self.logging.error("Error executing: " + str(e),
                                           location=self.name)

    def add_listener(self, topic, class_item, functionname):
        self.listeners.append([topic, class_item, functionname])
        self.client.subscribe(topic)
        try:
            name = class_item.get_name()
        except:
            name = "unknown"
        self.logging.info("Added listener for %s at %s" % (name, topic),
                          location=self.name)

    def publish(self, topic, payload):
        self.logging.info("Publish %s, %s " % (topic, str(payload)),
                          location=self.name)
        self.client.publish(topic, payload)
Example #7
0
class message_handler(Singleton):
    def __init__(self):
        try:
            if self.loadingdone:
                pass
        except:
            self.loadingdone = True
            self.database = main_database()
            self.popupflag = False
            self.popupactive = False
            self.logging = Logging()
            self.setting_handler = setting_handler()
            self.setting_popup_timeout = self.setting_handler.get_setting(
                "message_timeout")
            self.page_handler = page_handler.page_handler()
            self.toast_flag = False
            self.toast_db = []
            self.toast_message = "none"
            self.toast_sender = "none"
            self.toast_received = 0
            self.mqtt = mqtt()
            settings_c = Settings()
            self.mqtt_topics = settings_c.get_setting("messaging",
                                                      "mqtt_topics").split(",")
            for topic in self.mqtt_topics:
                self.mqtt.add_listener(topic, self, "received_mqtt_message")
            ##send information messages on first run
            if not self.database.data["settings"]["first_run_messages_flag"]:
                self.database.data["settings"][
                    "first_run_messages_flag"] = True
                message = "On a black screen, clock or photoframe, click on the bottom left corner to return to the main screen. "
                self.database.data["messages"].append([
                    time.time(), "HABframe", "Return from screensaver",
                    message, False
                ])
                message = "Thank you for using HABframe!"
                self.database.data["messages"].append([
                    time.time(), "HABframe", "welcome message", message, False
                ])
                self.database.save_datafile()
                self.del_popup_flag()

    def get_name(self):
        return "message_handler"

    def message_request(self, request, data_get):
        if request[0] == "new":
            try:
                if "message" in data_get:
                    message = data_get["message"].replace("@20", "/").replace(
                        "%3B", ":")
                else:
                    message = request[2].replace("@20",
                                                 "/").replace("%3B", ":")
                if "sender" in data_get:
                    sender = data_get["sender"]
                else:
                    sender = request[1]
                if "subject" in data_get:
                    subject = data_get["subject"]
                else:
                    subject = "-"
                self.new_message(sender, subject, message)
                return ["Message received"]
            except Exception as e:
                self.logging.error("Error in message: " + str(e),
                                   location="messages")
                return ["Invalid new message"]
        elif request[0] == "message_popup":
            i = 0
            found = False
            while i < len(self.database.data["messages"]) and not found:
                message = self.database.data["messages"][i]
                if not message[-1]:
                    show_message = [i] + message
                    #we want the last unread message
                    #found = True
                i += 1
            n_unread = self.check_amount_unread()
            times = datetime.datetime.fromtimestamp(float(
                show_message[1])).strftime('%a %d-%m, %H:%M')
            return self.page_handler.create_popup("message", {
                "id": show_message[0],
                "from": show_message[2],
                "time": times,
                "message": show_message[4],
                "subject": show_message[3],
                "n_unread": n_unread
            },
                                                  renew_screensaver=False)
        elif request[0] == "markread_popup":
            message_id = int(request[1])
            self.logging.info("Marking message as read " + str(message_id),
                              location="messages")
            self.database.data["messages"][message_id][-1] = True
            self.database.save_datafile()
            self.popupactive = False
            self.del_popup_flag()
            return ["Marked as read"]
        elif request[0] == "markallread_popup":
            message_id = int(request[1])
            self.logging.info("Marking all messages as read ",
                              location="messages")
            for i in range(len(self.database.data["messages"])):
                self.database.data["messages"][i][-1] = True
            self.database.save_datafile()
            self.popupactive = False
            self.del_popup_flag()
            return ["Marked as read"]
        elif request[0] == "message_timeout":
            timeout = self.setting_handler.get_setting("message_timeout")
            return [str(timeout)]
        elif request[0] == "toast_timeout":
            timeout = self.setting_handler.get_setting("toast_timeout")
            return [str(timeout)]
        elif request[0] == "delete_popup":
            message_id = int(request[1])
            del (self.database.data["messages"][message_id])
            self.logging.info("Deleting message: " + str(message_id),
                              location="messages")
            if len(self.database.data["messages"]) == 0:
                self.database.data["messages"] = []
                #self.database.data["messages"].append([time.time(), "none", "message database is empty", True])
            self.database.save_datafile()
            self.popupactive = False
            self.del_popup_flag()
            return ["Message deleted"]
        elif request[0] == "deactivate_popup":
            self.popupactive = False
            return ["popup deactive"]
        elif request[0] == "showmessage":
            message_id = int(request[1])
            return self.format_message(message_id=message_id)
        elif request[0] == "deletemessage":
            if request[1] == "all":
                self.database.data["messages"] = []
                #self.database.data["messages"].append([time.time(), "none", "message database is empty", True])
            else:
                message_id = int(request[1])
                del (self.database.data["messages"][message_id])
                self.logging.info("Deleting message: " + str(message_id),
                                  location="messages")
                if len(self.database.data["messages"]) == 0:
                    self.database.data["messages"] = []
                    #self.database.data["messages"].append([time.time(), "none", "message database is empty", True])
            self.database.save_datafile()
            return self.format_message_list(start=0)
        elif request[0] == "showmessagepage":
            message_id = int(request[1])
            return self.format_message_list(start=message_id)
        elif request[0] == "toast":
            if "message" in data_get:
                self.toast_message = data_get["message"].replace(
                    "@20", "/").replace("%3B", ":")
            else:
                self.toast_message = request[2].replace("@20", "/").replace(
                    "%3B", ":")
            if "sender" in data_get:
                self.toast_sender = data_get["sender"].replace("@20",
                                                               "/").replace(
                                                                   "%3B", ":")
            else:
                self.toast_sender = request[1].replace("@20", "/").replace(
                    "%3B", ":")
            self.logging.debug("Received new toast message from http",
                               location="messages")
            self.new_toast()
            return ["Toast received"]
        elif request[0] == "get_toast":
            return self.create_toast(len_max=31)

    def new_message(self, sender, subject, message):
        self.database.data["messages"].append(
            [time.time(), sender, subject, message, False])
        self.database.save_datafile()
        self.del_popup_flag()  ##popup flag when a popup was activated
        self.logging.write("Received new message from " + sender + ": " +
                           message,
                           level="info",
                           location="messages")

    def new_toast(self):
        self.toast_received = time.time()
        self.toast_db.append(
            [self.toast_sender, self.toast_message,
             time.time(), False, 0])
        self.logging.info("Received new toast message: " + self.toast_message,
                          location="messages")

    def create_toast(self, len_max):
        toast = self.get_toast_message()
        data = {
            "text": toast[0],
            "from": toast[1],
            "len": len(toast[0]),
            "max": len_max
        }
        return self.page_handler.create_popup("toast",
                                              data=data,
                                              renew_screensaver=False)

    def get_messages(self):
        messages = []
        for i in reversed(range(len(self.database.data["messages"]))):
            m = self.database.data["messages"][i]
            messages.append({
                "id": i,
                "date": m[0],
                "from": m[1],
                "subject": m[2],
                "message": m[3]
            })
        return messages

    def check_amount_unread(self):
        unread = 0
        for message in self.database.data["messages"]:
            if not message[-1]:
                unread += 1
        return unread

    def check_unread(self):
        unread = False
        for message in self.database.data["messages"]:
            if not message[-1]:
                unread = True
        return unread

    def get_popup_flag(
        self
    ):  ##The popup flag is set when a new message has generated a popup
        return self.popupflag

    def set_popup_flag(self):
        self.logging.write("Setting popup flag",
                           level="warn",
                           location="messages")
        self.popupflag = True

    def del_popup_flag(self):  ##Only a new message can delete a popup
        if self.popupflag:
            self.logging.write("Removing popup flag",
                               level="warn",
                               location="messages")
        self.popupflag = False

    def get_popup_active(self):
        if time.time(
        ) > self.popup_time_activated + self.setting_popup_timeout + 1:  ##seconds
            return False
        else:
            return True

    def set_popup_active(self, state):
        self.popup_time_activated = time.time()

    def check_toast(self):
        #print("=========================, checking toast")
        timeout = self.setting_handler.get_setting("toast_timeout")
        new_toast = False
        last_toast_send = 0
        for i in range(len(self.toast_db)):
            if self.toast_db[i][3]:
                last_toast_send = self.toast_db[i][4]
            if self.toast_db[i][2] < time.time() - 600:
                self.toast_db[i][3] = True
            if not self.toast_db[i][3]:
                new_toast = True
        if len(self.toast_db) > 50:
            del self.toast_db[0:25]
        if self.toast_received > time.time(
        ) - 600 and new_toast and last_toast_send < time.time() - timeout - 3:
            return True
        else:
            return False

    def get_toast_message(self):
        ##return the first unread toast message
        for i in range(len(self.toast_db)):
            if not self.toast_db[i][3]:  ##toast is unread
                self.toast_db[i][3] = True
                self.toast_db[i][4] = time.time()
                self.logging.write("Sending toast message: " +
                                   self.toast_db[i][0] + " / " +
                                   self.toast_db[i][1],
                                   level=2,
                                   location="messages")
                return [self.toast_db[i][1], self.toast_db[i][0]]
        self.logging.write("No unread toast message, sending last one: " +
                           self.toast_message + " / " + self.toast_sender,
                           level="warning",
                           location="messages")
        return [self.toast_message, self.toast_sender]

    def format_message_list(self, start=0):
        messages = self.get_messages()
        page_data = {"next_page": False, "prev_page": False, "messages": []}
        try:
            start_page = int(start)
        except:
            start_page = 0
        if start_page == 0:
            start_message = 0
            stop_message = 6
        else:
            page_data["prev_page"] = start_page
            start_message = start_page * 5 + 1
            stop_message = start_page * 5 + 6
        n_messages = len(messages)
        if stop_message >= n_messages:
            stop_message = n_messages
        else:
            page_data["next_page"] = start_page + 1
        for i in range(start_message, stop_message):
            messages[i]["date"] = datetime.datetime.fromtimestamp(
                messages[i]["date"]).strftime('%a %d-%m, %H:%M')
            page_data["messages"].append(messages[i])
        return render_template("message_list.html", data=page_data)

    def format_message(self, message_id=0):
        messages = self.get_messages()
        if message_id == -1:
            message_id = len(messages) - 1
        if len(messages) > 0:
            for m in messages:
                if m["id"] == message_id:
                    message = m
            message["date"] = datetime.datetime.fromtimestamp(
                message["date"]).strftime('%a %d-%m, %H:%M')
        else:
            message = {"date": "", "message": "No messages", "from": ""}
        if len(messages) > 0 and message["subject"] == "-":
            message["subject"] = message["date"]
        return render_template("message.html", data=message)

    def received_mqtt_message(self, topic, payload):
        try:
            message = payload['message']
            if "message" in topic.lower():
                t = "message"
            elif "toast" in topic.lower():
                t = "toast"
            else:
                try:
                    t = payload['type']
                except:
                    t = 'message'
            try:
                sender = payload['sender']
            except:
                sender = "unknown"
            if t == "message":
                subject = payload['subject']
                self.new_message(sender, subject, message)
            else:
                self.toast_sender = sender
                self.toast_message = message
                self.new_toast()
        except Exception as e:
            raise Exception(e)
Example #8
0
class item_handler():
    def __init__(self):
        self.openhab = pf_openhab()
        self.name = "item_handler"
        self.database = main_database()
        self.setting_handler = setting_handler()
        self.page_handler = page_handler()
        self.message_handler = message_handler()
        self.logging = Logging()
        settings_c = Settings()
        self.host = settings_c.get_setting("main", "hostname")
        self.port = settings_c.get_setting("main", "port")
        self.enable_clock = settings_c.get_setting("main", "enable_clock")
        self.enable_album = settings_c.get_setting("main", "enable_album")
        self.openhab_server = settings_c.get_setting("main", "openhab_ip")
        self.openhab_port = settings_c.get_setting("main", "openhab_port")
        self.http = urllib3.PoolManager()
        self.timeout_message_popup = 0
        self.saved_chart_periods = {}
        self.screentrigger = 0

    def item_request(self, request):
        action = request[0]
        if len(request) > 1:
            item = request[1]
        if action != "photoframe" and action != "popup_chart" and action != "icon":
            item_info = self.openhab.get_item(item)
            self.logging.debug("Item info for request: " + str(item_info),
                               location=self.name)
        ##handle a button press per type of item:
        #print(item)
        if action == "set":
            if item_info == None:
                return "none_none"
            elif item_info["type"] == "Switch_single":
                item_info = self.openhab.set_state(
                    item, item_info["mappings"][0]["command"])
            elif item_info["type"] == "Switch":
                if item_info["state"] == "ON":
                    item_info = self.openhab.set_state(item, "OFF")
                else:
                    item_info = self.openhab.set_state(item, "ON")
            return self.page_handler.create_item_button(item_info,
                                                        header=False)
        elif action == "cmd":
            command = request[2]
            item_info = self.openhab.set_state(item, command)
            if item_info == None:
                return "reload_widget_popup"
            elif item_info["subpage"][0:2] in ["a_", "c_", "d_", "s_"]:
                return "reload_widget_popup"
            else:
                return self.page_handler.create_item_button(item_info,
                                                            header=False)
        elif action == "popup":
            if item_info == None:
                return "none_none"
                #return self.page_handler.create_popup("error", data = { "error": "Invalid Item" })
            self.setting_handler.screen_timeout_start = time.time()
            if item_info["state"][-1:] == "%":
                s = item_info["state"][0:-1]
            elif item_info["state"][-1:] == "C":
                s = item_info["state"][0:-2]
            else:
                s = item_info["state"]
            if item_info["type"] == "Selection":
                mappings = self.openhab.get_mappings(item)
                return self.page_handler.create_popup("selection",
                                                      data={
                                                          "id": item,
                                                          "mappings": mappings,
                                                          "n": len(mappings)
                                                      })
            elif item_info["type"] == "Colorpicker":
                return self.page_handler.create_popup("colorpicker",
                                                      data=item_info)
            elif item_info["type"] == "Setpoint":
                item_info["state"] = s
                return self.page_handler.create_popup("setpoint",
                                                      data=item_info)
            elif item_info["type"] == "Slider":
                item_info["state"] = s
                return self.page_handler.create_popup("slider", data=item_info)
            elif item_info["type"] == "Chart":
                ##item_info.update( { "chart_period": request[2] } )
                return self.page_handler.create_popup("chart", data=item_info)
            else:
                return "none_none"
        elif action == "popup_chart":
            data = {
                "id":
                item,
                "periods": [["4 Hours", "4h"], ["Day", "D"], ["3 Days", "3D"],
                            ["Week", "W"], ["2 Weeks", "2W"]]
            }
            return self.page_handler.create_popup("chart_period", data)
        elif action == "chart_data":
            data = self.get_chart_data(item, request[2].upper())
            return data
        elif action == "icon":
            icon = self.openhab.get_icon(item)
            return ["jpg", icon]

    def get_chart_data(self, item, period):
        default_period = self.setting_handler.get_setting("chart_period")
        #print(default_period, period)
        if default_period == "auto" and period.lower() == "default":
            if item in self.saved_chart_periods:
                period = self.saved_chart_periods[item]
            else:
                period = "D"
        elif period.lower() == "default":
            period = default_period
        self.saved_chart_periods[item] = period
        data = self.openhab.get_chart_data(item, period)
        if data == None:
            self.logging.warn("No Chart data returned for %s" % item,
                              location=self.name)
            return "None"
        d = eval(data["data"])
        try:
            p = int(period[0:len(period) - 1])
            e = "s"
        except:
            p = 1
            e = ""
        formats = {
            "H": ["%H:%M", "Hour" + e],
            "D": ["%a %Hh", "Day" + e],
            "W": ["%d-%m", "Week" + e],
            "M": ["%d-%m", "Month" + e]
        }
        f = formats[period[-1:]]
        db = {
            "name": d["name"],
            "data": [],
            "labels": [],
            "fill": False,
            "grid": True,
            "color": "red",
            "xlabel": str(p) + " " + f[1],
            "ylabel": "Value",
            "points": 4
        }
        if data["type"] == "temp":
            db.update({"ylabel": "Temperature (°C)"})
        elif data["type"] == "humi":
            db.update({"ylabel": "Humidity (%)", "color": "blue"})
        elif data["type"] == "pres":
            db.update({"ylabel": "Pressure (mb)", "color": "green"})
        elif data["type"] == "watt":
            db.update({"ylabel": "Power (W)", "fill": True, "color": "yellow"})
        for i in range(len(d["data"])):
            t = str(d["data"][i]["time"])
            t = datetime.datetime.fromtimestamp(float(t[0:-3])).strftime(f[0])
            val = "%.4f" % (float(d["data"][i]["state"]))
            if i == 0 or val != db["data"][-1]:
                db["data"].append(val)
                db["labels"].append(t)
        ##do not show point when there are a lot of datapoints
        if len(db["data"]) > 25:
            db["points"] = 0
        return json.dumps(db)
Example #9
0
class state_handler(Singleton):
	
    def __init__(self):
        try:
            if self.loadingdone:
                pass
        except:
            self.loadingdone = True
            self.openhab = pf_openhab()
            self.name = "state_handler"
            self.database = main_database()
            self.setting_handler = setting_handler()
            self.message_handler = message_handler()
            self.logging = Logging()
            settings_c = Settings()
            self.host = settings_c.get_setting("main", "hostname")
            self.port = settings_c.get_setting("main", "port")
            self.http = urllib3.PoolManager()
            self.timeouts = {}
            self.update_timeout("screensaver", 60)
            self.update_timeout("message", -1)
            self.screentrigger = 0
            self.screen_state = True
            try:
                self.im_size = settings_c.get_setting("album", "image_size") 
                self.album_url = settings_c.get_setting("album", "random_picture_url") 
            except Exception as e:
                self.logging.error("Invalid album settings: " + str(e), location=self.name)
                self.album_url = "none"
            try:
                self.album_info_url = settings_c.get_setting("album", "picture_info_url") 
                if self.album_info_url == None:
                    raise Exception("No data")
            except:
                self.logging.warn("No album info url", location=self.name)
                self.album_info_url = "none"

    def state_request(self, request):
        action = request[0]
        if len(request) > 1:
            item = request[1]
        ##handle a button press per type of item:
        #print(item)
        if action == "photoframe":
            if item == "frame":
                ans = self.setting_handler.set_setting("frame", request[2])
                if ans != None:
                    return ans[0]
                return "Setting saved"
            elif item == "screen":
                ans = self.setting_handler.set_setting("screen", request[2])
                if ans != None:
                    return ans[0]
                return "Setting saved"
            elif item == "trigger":  
                self.screentrigger = time.time()
                self.refresh_screensaver()
                self.logging.info("Triggered frame on externally", location=self.name)
                return "Screen triggered"
            else:
                return "none_none"            
        elif action == "icon":
            icon = self.openhab.get_icon(item)
            return ["jpg", icon]
        elif action == "picture":
            try:
                if item == "new" and self.album_url != "none":
                    response = requests.get(self.album_url)
                    with Image.open(BytesIO(response.content)) as image:
                        imgByteArr = BytesIO()
                        cover = Image.Image.resize(image, [int(self.im_size.split("x")[0]), int(self.im_size.split("x")[1])])
                        cover.save(imgByteArr, image.format)
                    return ["jpg", imgByteArr.getvalue()]
                elif item == "info" and self.album_info_url != "none" and self.album_info_url != "":
                    content = self.http.request('GET', self.album_info_url)
                    return content.data.decode("utf-8") 
                elif item == "info":
                    return "no album info"
            except Exception as e:
                self.logging.error("Error occured in processing picture for album %s" %e, location=self.name)
            return "error"
        
        
    def state_check(self, request):
        page = []
        main_page = request[0]
        subpage = "none"
        if len(request) > 1:
            subpage = request[1]
        
        ## get used settings
        setting_album_timeout = self.setting_handler.get_setting("album_timeout") ##not used
        setting_popup_timeout = self.setting_handler.get_setting("message_timeout")
        setting_screen_user = self.setting_handler.get_setting("screen")  ##screen on or off
        
        main_setting_screen_control = self.setting_handler.get_setting("main_screen_control")
        current_screen_state = self.get_screen_state()
        screensaver_page = self.get_screensaver_page()

        desired_screen_state = "off"
        desired_page = "unchanged"
        
        ##reset old screen trigger
        if self.screentrigger != 0 and time.time() > self.screentrigger + 5*60:
            self.screentrigger = 0
        
        ##calculate desired screen state (on / off) ##switching is done depending on configuration
        if main_page in  ["main", "settings", "messages"]:
            if self.check_timeout("screensaver") and setting_screen_user == "off":
                desired_screen_state = "off"
            else:
                desired_screen_state = "on"
        elif main_page in ["photoframe", "clock", "black"]:
            desired_screen_state = setting_screen_user
            
        ## check desired screen state for messages
        self.logging.debug("Unread messages: %s" %(str(self.message_handler.check_unread())), location=self.name)
        self.logging.debug("Popup flag: %s" %(str(self.message_handler.get_popup_flag())), location=self.name)
        if self.message_handler.check_unread() and not self.message_handler.get_popup_flag():
            self.message_handler.set_popup_active(True)
            self.message_handler.set_popup_flag()
            self.logging.info("responding new message", location=self.name)
            desired_screen_state = "on"
            new_message = True ###turn on screen and make popup
        elif not self.check_timeout("message"):
            desired_screen_state = "on"   ##keep screen on for message
            new_message = False
        else:
            new_message = False
            
        ##calculate desired page (main, black, album or clock) ##switching is done depending on configuration
        if main_page in  ["main", "settings", "messages"]:
            if self.check_timeout("screensaver") and setting_screen_user == "on" and screensaver_page != "main":
                desired_page = screensaver_page
        elif main_page == "photoframe" and screensaver_page != "album":
            desired_page = screensaver_page
        elif main_page == "clock" and screensaver_page != "clock":
            desired_page = screensaver_page
        elif main_page == "black" and setting_screen_user == "on":
            desired_page = screensaver_page            
        
        self.logging.debug("Show new messages: %s" %(str(new_message)), location=self.name)
        self.logging.debug("Screensaver page: %s" %(screensaver_page), location=self.name)
        self.logging.debug("Desired page: %s, desired_screen_state: %s" %(desired_page, desired_screen_state), location=self.name)
        self.logging.debug("Message timeout: %s, Subpage timeout: %s" %(self.check_timeout("message"), self.check_timeout("screensaver_subpage")), location=self.name)
        
        ## switch screen off is desired state is off
        if desired_screen_state == "off" and main_setting_screen_control != "off" and current_screen_state:  ##=="on"
            return self.switch_off_screen(main_setting_screen_control)
        elif desired_screen_state == "off" and current_screen_state:  ##=="on"
            link = self.get_desired_page_link("clock")
            return [link]
        elif self.screentrigger != 0:
            self.toggle_screen(state = True)
            self.screentrigger = 0
            self.refresh_screensaver()
            self.logging.info("turn on screen for trigger", location=self.name)
            return ["close_return_main"]
        
        ##actions when we want the screen on
        elif new_message:
            if not current_screen_state:
                self.toggle_screen(state = "on")  ##no need for a page change
                self.update_timeout("message", self.setting_handler.get_setting("message_timeout") + 2) ##in seconds
            return ["new_message"]
        elif self.message_handler.check_toast():  ##even if the screen is off
            self.logging.write("responding new toast message", level=2, location="item_handle")
            return ["new_toast"]
        elif desired_screen_state == "on" and desired_page != "unchanged" and self.check_timeout("message"): ##except when there is a message popup
            self.toggle_screen(state = setting_screen_user)
            link = self.get_desired_page_link(desired_page)
            return [link]
        elif self.check_timeout("screensaver_subpage") and self.check_timeout("message") and main_page not in ["photoframe", "clock"]:  ##except when there is a message popup
            self.delete_timeout("screensaver_subpage")
            return ["close_return_main"]
        elif self.check_timeout("screensaver_subpage") and self.check_timeout("message"):
            self.delete_timeout("screensaver_subpage")
        
                     
        ##if for some reason it end here;
        return ["no_actionHERE"]
                    

    def switch_off_screen(self, main_setting_screen_control):
        self.toggle_screen(state = "off")
        if main_setting_screen_control == "black":
            link = self.get_desired_page_link("black")
            return [link]
        else:
            link = self.get_desired_page_link("main")
            return [link]
            
    def get_screensaver_page(self):
        enable_clock = self.setting_handler.get_setting("main_enable_clock")
        enable_album = self.setting_handler.get_setting("main_enable_album")
        setting_album_clock = self.setting_handler.get_setting("frame") ##photoframe or clock when screen is on
        
        if enable_album == "1" and setting_album_clock == "photoframe":
            return "album"
        elif enable_clock == "1" and setting_album_clock == "clock":
            return "clock"
        else:
            return "main"
        
       
    def get_desired_page_link(self, page):
        if page == "album":
            self.logging.info("http://"+self.host+":"+self.port+"/page/photoframe", location=self.name)
            return "http://"+self.host+":"+self.port+"/page/photoframe"
        elif page == "clock":
            type_clock = self.setting_handler.get_setting("clock_type")
            self.logging.info("http://"+self.host+":"+self.port+"/page/clock/"+type_clock, location=self.name)
            return "http://"+self.host+":"+self.port+"/page/clock/"+type_clock
        elif page == "main":
            main_setting_screen_control = self.setting_handler.enable_screen_control
            self.logging.info("External screen control: %s, no action, stay on main page" %main_setting_screen_control, location=self.name)
            return "http://"+self.host+":"+self.port+"/page/maindiv/screensaver"
        elif page == "black":
            self.logging.write("http://"+self.host+":"+self.port+"/black", level=2)
            return "http://"+self.host+":"+self.port+"/page/black"

    def update_timeout(self, name, delta): ##delta in seconds
        self.timeouts[name] = time.time() + delta
        
    def check_timeout(self, name):
        if name in self.timeouts:
            self.logging.debug(("Timeout %s: "%name).ljust(30) + str(time.ctime(int(self.timeouts[name]))), location=self.name)
            if self.timeouts[name] < time.time():
                return True
            else:
                return False
        else:
            return False
    
    def delete_timeout(self, name):
        if name in self.timeouts:
            del self.timeouts[name]
        else:
            self.logging.debug("Timeout %s not deleted, not existing" %name, location=self.name)
    
    def refresh_screensaver(self):
        to = self.setting_handler.get_setting("screen_timeout")
        if to == "off":
            to = 24*60*300
        self.logging.info("refreshing screensaver", location=self.name)
        self.update_timeout("screensaver", int(to)*60)
        self.delete_timeout("screensaver_subpage")
        
    def refresh_screensaver_subpage(self):
        self.refresh_screensaver()
        self.logging.info("refreshing screensaver for popup", location=self.name)
        self.update_timeout("screensaver_subpage", 25)
        
            
    def toggle_screen(self, state = True):
        screen_control = self.setting_handler.get_setting("main_screen_control")
        switch = False
        if str(self.screen_state) != str(state):
            self.logging.info("Switching screen state: %s, %s" %(str(self.screen_state), str(state)), location=self.name)
        else:
            self.logging.debug("Switching screen state: %s, %s" %(str(self.screen_state), str(state)), location=self.name)
        if (state == "off" or state == "0" or state == False) and self.get_screen_state() == True:
            state = False
            self.screen_state = False
            switch = True
        elif (state == "on" or state == "1" or state == True) and self.get_screen_state() == False:
            state = True
            self.screen_state = True
            switch = True
        if screen_control == "pi":
            if not state:
                self.logging.write("Turn off screen", level=2)
                cmd = "echo 1 > /sys/class/backlight/rpi_backlight/bl_power"
                os.system(cmd)
            else:
                self.logging.write("Turn on screen", level=2)
                cmd = "echo 0 > /sys/class/backlight/rpi_backlight/bl_power"
                os.system(cmd)
        elif screen_control == "url" and switch:
            if not state:
                self.logging.info("Turn off screen via url", location=self.name)
                url = self.setting_handler.get_setting("screen_control_off_url")
            else:
                self.logging.info("Turn on screen via url", location=self.name)
                url = self.setting_handler.get_setting("screen_control_on_url")
            self.logging.debug("Screensaver url: %s" %url, location=self.name) 
            self.http.request('GET', url)
        elif screen_control == "cmd" and switch:
            if not state:
                self.logging.info("Turn off screen via cmd", location=self.name)
                cmd = self.setting_handler.get_setting("screen_control_off_cmd")
            else:
                self.logging.info("Turn on screen via cmd", location=self.name)
                cmd = self.setting_handler.get_setting("screen_control_on_cmd")
            self.logging.debug("Screensaver cmd: %s" %cmd, location=self.name) 
            os.system(cmd)

    def get_screen_state(self):
        return self.screen_state