"notificaton added"

This commit is contained in:
Manuel Fritsch 2021-03-07 22:11:25 +01:00
parent 0371e74b4a
commit 51c8f82834
12 changed files with 135 additions and 34 deletions

View file

@ -1 +1 @@
__version__ = "4.0.0.29"
__version__ = "4.0.0.30"

View file

@ -141,4 +141,13 @@ class Config:
def __str__(self):
return "....name={} value={}".format(self.name, self.value)
def to_dict(self):
return dict(name=self.name, value=self.value, type=self.type.value, description=self.description, options=self.options)
return dict(name=self.name, value=self.value, type=self.type.value, description=self.description, options=self.options)
@dataclass
class NotificationAction:
label: str
method: Any = None
id: str = None
def to_dict(self):
return dict(id=self.id, label=self.label)

View file

@ -117,7 +117,6 @@ class BasicController:
return {"data": list(map(lambda x: x.to_dict(), self.data)), "types":self.get_types()}
async def add(self, item):
print(item)
logging.info("{} Add".format(self.name))
item.id = shortuuid.uuid()
self.data.append(item)

View file

@ -4,6 +4,8 @@ import os
from os import listdir
from os.path import isfile, join
from voluptuous.schema_builder import message
class DashboardController:
@ -29,6 +31,7 @@ class DashboardController:
async def add_content(self, dashboard_id, data):
with open(self.path, 'w') as outfile:
json.dump(data, outfile, indent=4, sort_keys=True)
self.cbpi.notify(title="Dashboard", message="Saved Successfully", type="success")
return {"status": "OK"}
async def delete_content(self, dashboard_id):

View file

@ -0,0 +1,42 @@
import asyncio
import logging
import shortuuid
class NotificationController:
def __init__(self, cbpi):
'''
:param cbpi: craftbeerpi object
'''
self.cbpi = cbpi
self.logger = logging.getLogger(__name__)
self.callback_cache = {}
def notify(self, title, message: str, type: str = "info", action=[]) -> None:
'''
This is a convinience method to send notification to the client
:param key: notification key
:param message: notification message
:param type: notification type (info,warning,danger,successs)
:return:
'''
notifcation_id = shortuuid.uuid()
def prepare_action(item):
item.id = shortuuid.uuid()
return item.to_dict()
actions = list(map(lambda item: prepare_action(item), action))
self.callback_cache[notifcation_id] = action
self.cbpi.ws.send(dict(id=notifcation_id, topic="notifiaction", type=type, title=title, message=message, action=actions))
def notify_callback(self, notification_id, action_id) -> None:
try:
action = next((item for item in self.callback_cache[notification_id] if item.id == action_id), None)
if action.method is not None:
asyncio.create_task(action.method())
del self.callback_cache[notification_id]
except Exception as e:
self.logger.error("Faild to call notificatoin callback")

View file

@ -39,7 +39,7 @@ class RecipeController:
path = os.path.join(".", 'config', "recipes", "{}.yaml".format(name))
with open(path, "w") as file:
yaml.dump(data, file, indent=4, sort_keys=True)
self.cbpi.notify("{} saved".format(data["basic"].get("name")))
async def get_recipes(self):
path = os.path.join(".", 'config', "recipes")
@ -65,7 +65,7 @@ class RecipeController:
async def remove(self, name):
path = os.path.join(".", 'config', "recipes", "{}.yaml".format(name))
os.remove(path)
self.cbpi.notify("{} delted".format(name))
async def brew(self, name):

View file

@ -1,4 +1,5 @@
import asyncio
import cbpi
import copy
import json
import logging
@ -6,7 +7,7 @@ import os.path
from os import listdir
from os.path import isfile, join
import shortuuid
from cbpi.api.dataclasses import Props, Step
from cbpi.api.dataclasses import NotificationAction, Props, Step
from tabulate import tabulate
from ..api.step import StepMove, StepResult, StepState
@ -129,8 +130,7 @@ class StepController:
await self.start_step(step)
await self.save()
return
self.cbpi.notify(message="BREWING COMPLETE")
self.cbpi.notify("Brewing Complete", "Now the yeast will take over",action=[NotificationAction("OK")])
logging.info("BREWING COMPLETE")
async def previous(self):

View file

@ -1,4 +1,5 @@
from cbpi.controller.notification_controller import NotificationController
import logging
from os import urandom
import os
@ -39,7 +40,9 @@ from cbpi.http_endpoints.http_recipe import RecipeHttpEndpoints
from cbpi.http_endpoints.http_plugin import PluginHttpEndpoints
from cbpi.http_endpoints.http_system import SystemHttpEndpoints
from cbpi.http_endpoints.http_log import LogHttpEndpoints
from cbpi.http_endpoints.http_notification import NotificationHttpEndpoints
import shortuuid
logger = logging.getLogger(__name__)
@ -98,9 +101,9 @@ class CraftBeerPi:
self.kettle = KettleController(self)
self.step : StepController = StepController(self)
self.recipe : RecipeController = RecipeController(self)
self.notification : NotificationController = NotificationController(self)
#self.satellite: SatelliteController = SatelliteController(self)
self.dashboard = DashboardController(self)
self.http_step = StepHttpEndpoints(self)
self.http_recipe = RecipeHttpEndpoints(self)
self.http_sensor = SensorHttpEndpoints(self)
@ -111,6 +114,7 @@ class CraftBeerPi:
self.http_plugin = PluginHttpEndpoints(self)
self.http_system = SystemHttpEndpoints(self)
self.http_log = LogHttpEndpoints(self)
self.http_notification = NotificationHttpEndpoints(self)
self.login = Login(self)
def _setup_shutdownhook(self):
@ -208,18 +212,10 @@ class CraftBeerPi:
def notify(self, title: str, message: str, type: str = "info", action=[]) -> None:
self.notification.notify(title, message, type, action)
def notify(self, message: str, type: str = "info") -> None:
'''
This is a convinience method to send notification to the client
:param key: notification key
:param message: notification message
:param type: notification type (info,warning,danger,successs)
:return:
'''
self.ws.send(dict(topic="notifiaction", type=type, message=message))
async def call_initializer(self, app):
self.initializer = sorted(self.initializer, key=lambda k: k['order'])
for i in self.initializer:

View file

@ -1,21 +1,33 @@
from socket import timeout
from typing import KeysView
from voluptuous.schema_builder import message
from cbpi.api.dataclasses import NotificationAction
import logging
from unittest.mock import MagicMock, patch
from datetime import datetime
from cbpi.api import *
logger = logging.getLogger(__name__)
@parameters([])
class DummyActor(CBPiActor):
my_name = ""
# Custom property which can be configured by the user
@action("test", parameters={})
async def action1(self, **kwargs):
self.my_name = kwargs.get("name")
pass
def __init__(self, cbpi, id, props):
super().__init__(cbpi, id, props)
async def yes(self, **kwargs):
print("YES!")
await self.cbpi.step.next()
@action("HELLO WORLD", {})
async def helloWorld(self, **kwargs):
print("HELLO WORLD")
self.cbpi.notify(title="HELLO WORLD", message="DO YOU WANT TO START THE NEXT STEP", action=[NotificationAction("YES", self.yes), NotificationAction("NO")])
async def start(self):
await super().start()

View file

@ -30,12 +30,12 @@ class GPIOActor(CBPiActor):
@action(key="Cusotm Action", parameters=[Property.Number("Value", configurable=True), Property.Kettle("Kettle")])
async def custom_action(self, **kwargs):
print("ACTION", kwargs)
self.cbpi.notify("ACTION CALLED")
@action(key="Cusotm Action2", parameters=[Property.Number("Value", configurable=True)])
async def custom_action2(self, **kwargs):
print("ACTION2")
self.cbpi.notify("ACTION CALLED")
def get_GPIO_state(self, state):
# ON

View file

@ -21,7 +21,7 @@ class MashStep(CBPiStep):
async def custom_action(self, Value, **kwargs):
self.summary = "VALUE FROM ACTION {}".format(Value)
await self.push_update()
self.cbpi.notify("ACTION 2 CALLED".format(Value))
async def on_timer_done(self,timer):
self.summary = ""
@ -60,12 +60,12 @@ class WaitStep(CBPiStep):
@action(key="Custom Step Action", parameters=[])
async def hello(self, **kwargs):
print("ACTION")
self.cbpi.notify("ACTION 1 CALLED")
@action(key="Custom Step Action 2", parameters=[])
async def hello2(self, **kwargs):
print("ACTION2")
self.cbpi.notify("ACTION 2 CALLED")
async def on_timer_done(self,timer):
self.summary = ""
@ -157,7 +157,7 @@ class BoilStep(CBPiStep):
@action("Start Timer", [])
async def star_timer(self):
self.cbpi.notify("Timer started")
self.timer.start()
async def run(self):

View file

@ -0,0 +1,40 @@
from aiohttp import web
from cbpi.api import request_mapping
from cbpi.utils import json_dumps
class NotificationHttpEndpoints:
def __init__(self,cbpi):
self.cbpi = cbpi
self.cbpi.register(self, url_prefix="/notification")
@request_mapping(path="/{id}/action/{action_id}", method="POST", auth_required=False)
async def action(self, request):
"""
---
description: Update an actor
tags:
- Notification
parameters:
- name: "id"
in: "path"
description: "Notification Id"
required: true
type: "string"
- name: "action_id"
in: "path"
description: "Action Id"
required: true
type: "string"
responses:
"200":
description: successful operation
"""
notification_id = request.match_info['id']
action_id = request.match_info['action_id']
print(notification_id, action_id)
self.cbpi.notification.notify_callback(notification_id, action_id)
return web.Response(status=204)