Compare commits
5 Commits
777d79aec8
...
ff73d81d2d
Author | SHA1 | Date |
---|---|---|
Ceda EI | ff73d81d2d | |
Ceda EI | 8c48beb3b7 | |
Ceda EI | a349a9f133 | |
Ceda EI | 398f432e1a | |
Ceda EI | c55899cd8a |
|
@ -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()
|
25
daemon.py
25
daemon.py
|
@ -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)
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
from .daemon import Daemon
|
||||||
|
from .daemon_plugin import DaemonPlugin
|
|
@ -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)
|
|
@ -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"
|
|
@ -1,2 +1,2 @@
|
||||||
from . import fuel_check
|
from .fuel_check import FuelCheck
|
||||||
plugins = [fuel_check]
|
plugins = [FuelCheck]
|
||||||
|
|
|
@ -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
|
|
@ -1,26 +1,35 @@
|
||||||
|
"Fuel Check"
|
||||||
import time
|
import time
|
||||||
|
|
||||||
start = time.monotonic()
|
from daemon import DaemonPlugin
|
||||||
last_message = None
|
|
||||||
threshold = 5
|
|
||||||
|
|
||||||
def check(data, emit):
|
class FuelCheck(DaemonPlugin):
|
||||||
|
start = None
|
||||||
|
last_message = None
|
||||||
|
threshold = 5
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
"Initialize plugin"
|
||||||
|
self.start = time.monotonic()
|
||||||
|
|
||||||
|
def check(self, data):
|
||||||
"Checks if the fuel ratio is below a certain threshold"
|
"Checks if the fuel ratio is below a certain threshold"
|
||||||
global last_message
|
|
||||||
if "FuelRatio" not in data:
|
if "FuelRatio" not in data:
|
||||||
return
|
return
|
||||||
|
|
||||||
ratio = data["FuelRatio"]
|
ratio = data["FuelRatio"]
|
||||||
if ratio <= threshold:
|
if ratio <= self.threshold:
|
||||||
if last_message is None:
|
if self.last_message is None:
|
||||||
emit("switchPlugin", {
|
desc = f"Only {int(ratio)}% fuel left. Please refill the tank."
|
||||||
|
self.speak(desc)
|
||||||
|
self.emit("switchPlugin", {
|
||||||
"plugin": "warning",
|
"plugin": "warning",
|
||||||
"data": {
|
"data": {
|
||||||
"title": "Low Fuel",
|
"title": "Low Fuel",
|
||||||
"description": f"Only {int(ratio)}% fuel left. Please refill the tank."
|
"description": desc
|
||||||
},
|
},
|
||||||
"time": 5000
|
"time": 5000
|
||||||
})
|
})
|
||||||
last_message = time.monotonic()
|
self.last_message = time.monotonic()
|
||||||
else:
|
else:
|
||||||
last_message = None
|
self.last_message = None
|
||||||
|
|
Loading…
Reference in New Issue