Small bugfixes; also, add a new machine to the remote executor pool.
authorScott Gasch <[email protected]>
Sat, 13 Nov 2021 15:06:31 +0000 (07:06 -0800)
committerScott Gasch <[email protected]>
Sat, 13 Nov 2021 15:06:31 +0000 (07:06 -0800)
cached/weather_forecast.py
executors.py
profanity_filter.py
smart_home/lights.py
smart_home/registry.py

index 78556586204dff83ac51926795ad9beff682d4cb..d1e754025eeaadeee84cfc12b38a1c53e8a547ee 100644 (file)
@@ -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
index d5049a264317c2f764d2068e7108a65d858f7cb2..6723bb9e2df4f1990f9780f15a813e6a4b3f0548 100644 (file)
@@ -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)
index 31577e0fbf1a4a76486dab066fff764aeb5bbc47..5621cef94489f6b5446a9e786777a8cb93e68be4 100755 (executable)
@@ -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
 
index 76b1500d5490693c939a025a49ecf886f2e38dab..dd211eb13cdb23361cc17e9129bfcf613dbb154e 100644 (file)
@@ -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:
index 2d23981d00ad9aaafef04a45c0761bd4cdefd5af..ae57a735794e07723311685ca994d0a5f936d258 100644 (file)
@@ -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()