From 957c962294cde93c4c649ed18dedd16df071878d Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Sat, 13 Nov 2021 07:06:31 -0800 Subject: [PATCH] Small bugfixes; also, add a new machine to the remote executor pool. --- cached/weather_forecast.py | 8 +++++--- executors.py | 25 +++++++++++++++++++++++++ profanity_filter.py | 4 ++-- smart_home/lights.py | 26 ++++++++++++++++++++++++++ smart_home/registry.py | 6 +++++- 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/cached/weather_forecast.py b/cached/weather_forecast.py index 7855658..d1e7540 100644 --- a/cached/weather_forecast.py +++ b/cached/weather_forecast.py @@ -4,6 +4,7 @@ from dataclasses import dataclass import datetime import logging import os +from typing import Any import urllib.request import astral # type: ignore @@ -50,7 +51,7 @@ class WeatherForecast: @persistent.persistent_autoloaded_singleton() -class CachedDetailedWeatherForecast(object): +class CachedDetailedWeatherForecast(persistent.Persistent): def __init__(self, forecasts = None): if forecasts is not None: self.forecasts = forecasts @@ -131,7 +132,7 @@ class CachedDetailedWeatherForecast(object): @classmethod @overrides - def load(cls): + def load(cls) -> Any: if persistent.was_file_written_within_n_seconds( config.config['weather_forecast_cachefile'], config.config['weather_forecast_stalest_acceptable'].total_seconds(), @@ -143,7 +144,7 @@ class CachedDetailedWeatherForecast(object): return None @overrides - def save(self): + def save(self) -> bool: import pickle with open(config.config['weather_forecast_cachefile'], 'wb') as wf: pickle.dump( @@ -151,3 +152,4 @@ class CachedDetailedWeatherForecast(object): wf, pickle.HIGHEST_PROTOCOL, ) + return True diff --git a/executors.py b/executors.py index d5049a2..6723bb9 100644 --- a/executors.py +++ b/executors.py @@ -843,6 +843,7 @@ class DefaultExecutors(object): self.remote_executor: Optional[RemoteExecutor] = None def ping(self, host) -> bool: + logger.debug(f'RUN> ping -c 1 {host}') command = ['ping', '-c', '1', host] return subprocess.call( command, @@ -861,9 +862,11 @@ class DefaultExecutors(object): return self.process_executor def remote_pool(self) -> RemoteExecutor: + logger.info('Looking for some helper machines...') if self.remote_executor is None: pool: List[RemoteWorkerRecord] = [] if self.ping('cheetah.house'): + logger.info('Found cheetah.house') pool.append( RemoteWorkerRecord( username = 'scott', @@ -873,6 +876,7 @@ class DefaultExecutors(object): ), ) if self.ping('video.house'): + logger.info('Found video.house') pool.append( RemoteWorkerRecord( username = 'scott', @@ -882,6 +886,7 @@ class DefaultExecutors(object): ), ) if self.ping('wannabe.house'): + logger.info('Found wannabe.house') pool.append( RemoteWorkerRecord( username = 'scott', @@ -891,6 +896,7 @@ class DefaultExecutors(object): ), ) if self.ping('meerkat.cabin'): + logger.info('Found meerkat.cabin') pool.append( RemoteWorkerRecord( username = 'scott', @@ -900,6 +906,7 @@ class DefaultExecutors(object): ), ) if self.ping('backup.house'): + logger.info('Found backup.house') pool.append( RemoteWorkerRecord( username = 'scott', @@ -908,7 +915,18 @@ class DefaultExecutors(object): count = 4, ), ) + if self.ping('kiosk.house'): + logger.info('Found kiosk.house') + pool.append( + RemoteWorkerRecord( + username = 'pi', + machine = 'kiosk.house', + weight = 1, + count = 2, + ), + ) if self.ping('puma.cabin'): + logger.info('Found puma.cabin') pool.append( RemoteWorkerRecord( username = 'scott', @@ -917,6 +935,13 @@ class DefaultExecutors(object): count = 4, ), ) + + # The controller machine has a lot to do; go easy on it. + for record in pool: + if record.machine == platform.node() and record.count > 1: + logger.info(f'Reducing workload for {record.machine}.') + record.count = 1 + policy = WeightedRandomRemoteWorkerSelectionPolicy() policy.register_worker_pool(pool) self.remote_executor = RemoteExecutor(pool, policy) diff --git a/profanity_filter.py b/profanity_filter.py index 31577e0..5621cef 100755 --- a/profanity_filter.py +++ b/profanity_filter.py @@ -489,14 +489,14 @@ class ProfanityFilter(object): for bigram in string_utils.ngrams_presplit(words, 2): bigram = ' '.join(bigram) if self.is_bad_word(bigram): - logger.debug('"{bigram}" is profanity') + logger.debug(f'"{bigram}" is profanity') return True if len(words) > 2: for trigram in string_utils.ngrams_presplit(words, 3): trigram = ' '.join(trigram) if self.is_bad_word(trigram): - logger.debug('"{trigram}" is profanity') + logger.debug(f'"{trigram}" is profanity') return True return False diff --git a/smart_home/lights.py b/smart_home/lights.py index 76b1500..dd211eb 100644 --- a/smart_home/lights.py +++ b/smart_home/lights.py @@ -77,6 +77,10 @@ class BaseLight(dev.Device): color = color.lower() return ansi.COLOR_NAMES_TO_RGB.get(color, None) + @abstractmethod + def status(self) -> str: + pass + @abstractmethod def turn_on(self) -> bool: pass @@ -130,6 +134,12 @@ class GoogleLight(BaseLight): ask_google(f"turn {self.goog_name()} off") ) + @overrides + def status(self) -> str: + if self.is_on(): + return 'ON' + return 'off' + @overrides def is_on(self) -> bool: r = ask_google(f"is {self.goog_name()} on?") @@ -211,6 +221,13 @@ class TuyaLight(BaseLight): def get_status(self) -> Dict[str, Any]: return self.bulb.status() + @overrides + def status(self) -> str: + ret = '' + for k, v in self.bulb.status().items(): + ret += f'{k} = {v}\n' + return ret + @overrides def turn_on(self) -> bool: self.bulb.turn_on() @@ -237,12 +254,14 @@ class TuyaLight(BaseLight): @overrides def set_dimmer_level(self, level: int) -> bool: + logger.debug(f'Setting brightness to {level}') self.bulb.set_brightness(level) return True @overrides def make_color(self, color: str) -> bool: rgb = BaseLight.parse_color_string(color) + logger.debug(f'Light color: {color} -> {rgb}') if rgb is not None: self.bulb.set_colour(rgb[0], rgb[1], rgb[2]) return True @@ -328,6 +347,13 @@ class TPLinkLight(BaseLight): self.info_ts = None return None + @overrides + def status(self) -> str: + ret = '' + for k, v in self.get_info().items(): + ret += f'{k} = {v}\n' + return ret + def get_on_duration_seconds(self, child: str = None) -> int: self.info = self.get_info() if child is None: diff --git a/smart_home/registry.py b/smart_home/registry.py index 2d23981..ae57a73 100644 --- a/smart_home/registry.py +++ b/smart_home/registry.py @@ -60,7 +60,11 @@ class SmartHomeRegistry(object): if line == "": continue logger.debug(f'SH-CONFIG> {line}') - (mac, name, keywords) = line.split(",") + try: + (mac, name, keywords) = line.split(",") + except ValueError: + logger.warning(f'SH-CONFIG> {line} is malformed?!') + continue mac = mac.strip() name = name.strip() keywords = keywords.strip() -- 2.47.1