Compare commits

...

5 Commits

8 changed files with 158 additions and 49 deletions

25
background.py Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env python
"Background Daemon"
import time
import logging
from mycroft_bus_client import MessageBusClient
import config
from daemon import Daemon
from plugins import plugins
def main():
"Main function"
logging.basicConfig(level=logging.DEBUG)
mycroft = MessageBusClient()
mycroft.run_in_thread()
daemon = Daemon(config.OSD_URL, config.CAR_API_URL, mycroft)
for plugin in plugins:
daemon.register_plugin(plugin)
while True:
daemon.check_all()
time.sleep(config.DELAY)
if __name__ == "__main__":
main()

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
import time
import requests
import config
from plugins import plugins
def emit(event, data):
json = {
"event": event,
"data": data
}
print(json)
return requests.post(config.OSD_URL, json=json)
def main():
data = requests.get(config.CAR_API_URL)
for plugin in plugins:
plugin.check(data.json(), emit)
if __name__ == "__main__":
while True:
main()
time.sleep(config.DELAY)

2
daemon/__init__.py Normal file
View File

@ -0,0 +1,2 @@
from .daemon import Daemon
from .daemon_plugin import DaemonPlugin

40
daemon/daemon.py Normal file
View File

@ -0,0 +1,40 @@
"Daemon class"
import logging
import requests
class Daemon:
"Daemon "
def __init__(self, osd_backend, car_api, messagebus_client):
self.plugins = []
self.osd_backend = osd_backend
self.car_api = car_api
self.messagebus_client = messagebus_client
def register_plugin(self, plugin_class):
"Registers a plugin"
plugin = plugin_class(self)
self.plugins.append(plugin)
def get_data(self):
"Gets data from car api"
return requests.get(self.car_api).json()
def emit(self, event, data):
"Events data to OSD Backend"
json = {
"event": event,
"data": data
}
logging.info("Emitting to OSD Frontend")
logging.debug("%s", json)
return requests.post(self.osd_backend, json=json)
def check_all(self):
"Checks all the plugins"
data = self.get_data()
for plugin in self.plugins:
logging.debug("Checking plugin %s", plugin)
try:
plugin.check(data)
except Exception as error: # pylint: disable=broad-except
logging.error("Exception raised by %s: %s", plugin, error)

30
daemon/daemon_plugin.py Normal file
View File

@ -0,0 +1,30 @@
"defines DaemonPlugin base class"
from abc import ABC, abstractmethod
from mycroft_bus_client import Message
class DaemonPlugin(ABC):
"Abstract class for Plugins to inherit from"
def __init__(self, daemon):
self.daemon = daemon
self.messagebus_client = daemon.messagebus_client
self.initialize()
def initialize(self):
"""
Initialize is called after the plugin object has been created. Add
any handlers for messagebus_client here
"""
def emit(self, event, data):
"Emits a message for OSD frontend"
self.daemon.emit(event, data)
def speak(self, utterance):
"Speaks the given string"
message = Message("speak", {"utterance": utterance})
self.messagebus_client.emit(message)
@abstractmethod
def check(self, data):
"Implement the core checks here"

View File

@ -1,2 +1,2 @@
from . import fuel_check
plugins = [fuel_check]
from .fuel_check import FuelCheck
plugins = [FuelCheck]

28
plugins/air_bags.py Normal file
View File

@ -0,0 +1,28 @@
"AirBags"
import time
from daemon import DaemonPlugin
class AirBags(DaemonPlugin):
"Checks AirBags and sends relevant warnings"
last_message = None
start = None
def initialize(self):
"Initialize plugin"
self.start = time.monotonic()
def check(self, data):
"Checks if the air bags are deployed"
if "AirBags-Deploy" not in data:
return
if data["AirBags-Deploy"]:
if self.last_message is None:
self.emit("switchPlugin", { "plugin": "accident" })
message = ("Airbags were released. Calling ambulance in 20 "
"seconds. Tap screen to cancel.")
self.speak(message)
self.last_message = time.monotonic()
else:
self.last_message = None

View File

@ -1,26 +1,35 @@
"Fuel Check"
import time
start = time.monotonic()
last_message = None
threshold = 5
from daemon import DaemonPlugin
def check(data, emit):
"Checks if the fuel ratio is below a certain threshold"
global last_message
if "FuelRatio" not in data:
return
class FuelCheck(DaemonPlugin):
start = None
last_message = None
threshold = 5
ratio = data["FuelRatio"]
if ratio <= threshold:
if last_message is None:
emit("switchPlugin", {
"plugin": "warning",
"data": {
"title": "Low Fuel",
"description": f"Only {int(ratio)}% fuel left. Please refill the tank."
},
"time": 5000
})
last_message = time.monotonic()
else:
last_message = None
def initialize(self):
"Initialize plugin"
self.start = time.monotonic()
def check(self, data):
"Checks if the fuel ratio is below a certain threshold"
if "FuelRatio" not in data:
return
ratio = data["FuelRatio"]
if ratio <= self.threshold:
if self.last_message is None:
desc = f"Only {int(ratio)}% fuel left. Please refill the tank."
self.speak(desc)
self.emit("switchPlugin", {
"plugin": "warning",
"data": {
"title": "Low Fuel",
"description": desc
},
"time": 5000
})
self.last_message = time.monotonic()
else:
self.last_message = None