from seleniumwire import webdriver from selenium.webdriver import ChromeOptions from selenium.webdriver import DesiredCapabilities from PIL import Image import time, os import yaml import datetime import croniter import logging logging.basicConfig(format='%(asctime)s [%(levelname)s]:%(message)s', level=logging.INFO) INTERNAL_HA_URL = "http://172.30.32.1:8123" image_path = os.environ.get("SCREEN_IMAGE_PATH", default='/tmp') config_file = os.environ.get("SCREEN_CONFIG", default="/app/config.yaml") width = os.environ.get("SCREEN_WIDTH", default="640") height = os.environ.get("SCREEN_HEIGHT", default="480") rotate = os.environ.get("SCREEN_ROTATE", default="0") wait = os.environ.get("SCREEN_WAIT", default="5") ha_token = os.environ.get("SCREEN_HA_TOKEN", default="") ha_language = os.environ.get("SCREEN_HA_LANGUAGE", default="en") # enable browser logging d = DesiredCapabilities.CHROME #d['loggingPrefs'] = {'browser': 'ALL'} # Open another headless browser with height extracted above chrome_options = ChromeOptions() chrome_options.add_argument("--headless") chrome_options.add_argument('--no-sandbox') chrome_options.add_argument(f"--window-size={width},{height}") chrome_options.add_argument(f"--lang={ha_language}") chrome_options.add_argument("--hide-scrollbars") chrome_options.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, ' 'like Gecko) Chrome/68.0.3440.84 Safari/537.36') chrome_options.add_experimental_option('prefs', {'intl.accept_languages': ha_language}) while True: config_file_modified_start = os.path.getmtime(config_file) logging.info(f"Reading config file {config_file}") config = None with open(config_file, "r") as stream: config = yaml.safe_load(stream) tasks = [] for image in config["images"]: now = datetime.datetime.now() image["croniter"] = croniter.croniter(image["cron"], now) image["next_execution"] = image["croniter"].get_next(datetime.datetime) logging.info(f"First execution of {image['name']} at {image['next_execution']}.") tasks += [image] while True: for i, task in enumerate(tasks): if task["next_execution"] > datetime.datetime.now(): continue logging.info(f"Running {task['name']}") driver = webdriver.Chrome(options=chrome_options, desired_capabilities=d) driver.implicitly_wait(10) if task.get("dashboard"): logging.info("Doing HA Auth") def response_interceptor(req, response): response.headers['Access-Control-Allow-Origin'] = '*' driver.response_interceptor = response_interceptor driver.get(INTERNAL_HA_URL) time.sleep(int(wait)) driver.execute_script(f"window.localStorage.setItem('hassTokens', JSON.stringify({{hassUrl: '{INTERNAL_HA_URL}', access_token: '{ha_token}', token_type: 'Bearer'}}));") driver.get(f'{INTERNAL_HA_URL}/{task["dashboard"]}') else: driver.get(task["url"]) time.sleep(int(wait)) logging.info("Making screenshot") # save screenshot file_name = f'/tmp/{task["name"]}.png' driver.save_screenshot(file_name) # print messages browser_out = "" for entry in driver.get_log('browser'): browser_out += f"{entry}\n" logging.info(browser_out) image = Image.open(file_name) if task.get("monochrome") and task.get("monochrome") == "true": image = image.convert('1', dither=Image.NONE) image = image.rotate(int(rotate), expand=True) file_name = f'{image_path}/{task["name"]}.png' image.save(file_name) tasks[i]["next_execution"] = task["croniter"].get_next(datetime.datetime) driver.quit() logging.info(f"Task finished, next execution: {tasks[i]['next_execution']}") config_file_modified = os.path.getmtime(config_file) if config_file_modified != config_file_modified_start: logging.info("reloading config file") break time.sleep(1)