mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-21 22:48:16 +01:00
GPIO added
This commit is contained in:
parent
6663a40cef
commit
00c7a465d7
36 changed files with 1129 additions and 1458 deletions
1018
.idea/workspace.xml
1018
.idea/workspace.xml
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@ import logging
|
||||||
from asyncio import Future
|
from asyncio import Future
|
||||||
|
|
||||||
from cbpi_api import *
|
from cbpi_api import *
|
||||||
|
from voluptuous import Schema
|
||||||
|
|
||||||
from core.controller.crud_controller import CRUDController
|
from core.controller.crud_controller import CRUDController
|
||||||
from core.database.model import ActorModel
|
from core.database.model import ActorModel
|
||||||
|
@ -29,23 +30,28 @@ class ActorController(CRUDController):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
await super(ActorController, self).init()
|
await super(ActorController, self).init()
|
||||||
|
|
||||||
for id, value in self.cache.items():
|
for id, value in self.cache.items():
|
||||||
await self._init_actor(value)
|
await self._init_actor(value)
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
return dict(items=self.cache,types=self.types)
|
||||||
|
|
||||||
async def _init_actor(self, actor):
|
async def _init_actor(self, actor):
|
||||||
|
|
||||||
if actor.type in self.types:
|
try:
|
||||||
|
if actor.type in self.types:
|
||||||
|
|
||||||
cfg = actor.config.copy()
|
cfg = actor.config.copy()
|
||||||
cfg.update(dict(cbpi=self.cbpi, id=id, name=actor.name))
|
cfg.update(dict(cbpi=self.cbpi, id=id, name=actor.name))
|
||||||
clazz = self.types[actor.type]["class"];
|
clazz = self.types[actor.type]["class"];
|
||||||
self.cache[actor.id].instance = clazz(**cfg)
|
self.cache[actor.id].instance = clazz(**cfg)
|
||||||
self.cache[actor.id].instance.init()
|
self.cache[actor.id].instance.init()
|
||||||
await self.cbpi.bus.fire(topic="actor/%s/initialized" % actor.id, id=actor.id)
|
await self.cbpi.bus.fire(topic="actor/%s/initialized" % actor.id, id=actor.id)
|
||||||
else:
|
else:
|
||||||
print("NOT FOUND")
|
print("NOT FOUND")
|
||||||
self.logger.error("Actor type '%s' not found (Available Actor Types: %s)" % (actor.type, ', '.join(self.types.keys())))
|
self.logger.error("Actor type '%s' not found (Available Actor Types: %s)" % (actor.type, ', '.join(self.types.keys())))
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error("Failed to init actor %s - Reason %s" % (actor.id, str(e)))
|
||||||
|
|
||||||
async def _stop_actor(self, actor):
|
async def _stop_actor(self, actor):
|
||||||
actor.instance.stop()
|
actor.instance.stop()
|
||||||
|
@ -93,6 +99,7 @@ class ActorController(CRUDController):
|
||||||
else:
|
else:
|
||||||
actor.on()
|
actor.on()
|
||||||
|
|
||||||
|
|
||||||
@on_event(topic="actor/+/off")
|
@on_event(topic="actor/+/off")
|
||||||
async def off(self, actor_id, **kwargs) -> None:
|
async def off(self, actor_id, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -102,7 +109,6 @@ class ActorController(CRUDController):
|
||||||
:param actor_id: the actor actor_id
|
:param actor_id: the actor actor_id
|
||||||
:param kwargs:
|
:param kwargs:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.logger.debug("OFF %s" % actor_id)
|
self.logger.debug("OFF %s" % actor_id)
|
||||||
actor_id = int(actor_id)
|
actor_id = int(actor_id)
|
||||||
|
|
||||||
|
@ -110,6 +116,15 @@ class ActorController(CRUDController):
|
||||||
actor = self.cache[actor_id].instance
|
actor = self.cache[actor_id].instance
|
||||||
actor.off()
|
actor.off()
|
||||||
|
|
||||||
|
@on_event(topic="actor/+/action")
|
||||||
|
async def call_action(self, actor_id, data, **kwargs) -> None:
|
||||||
|
|
||||||
|
schema = Schema({"name":str, "parameter":dict})
|
||||||
|
schema(data)
|
||||||
|
name = data.get("name")
|
||||||
|
parameter = data.get("parameter")
|
||||||
|
actor = self.cache[actor_id].instance.__getattribute__(name)(**parameter)
|
||||||
|
|
||||||
async def _post_add_callback(self, m):
|
async def _post_add_callback(self, m):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ class KettleController(CRUDController):
|
||||||
'''
|
'''
|
||||||
await super(KettleController, self).init()
|
await super(KettleController, self).init()
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
return dict(items=self.cache,types=self.types)
|
||||||
|
|
||||||
async def toggle_automtic(self, id):
|
async def toggle_automtic(self, id):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
|
@ -17,5 +17,6 @@ class NotificationController(object):
|
||||||
|
|
||||||
|
|
||||||
@on_event(topic="notification/#")
|
@on_event(topic="notification/#")
|
||||||
async def _on_event(self, key, message, type, **kwargs):
|
async def _on_event(self, key, message, type=None, **kwargs):
|
||||||
self.cbpi.ws.send("YES")
|
self.cbpi.ws.send(dict(key=message))
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ class SensorController(CRUDController):
|
||||||
for id, value in self.cache.items():
|
for id, value in self.cache.items():
|
||||||
await self.init_sensor(value)
|
await self.init_sensor(value)
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
return dict(items=self.cache,types=self.types)
|
||||||
|
|
||||||
async def init_sensor(self, sensor):
|
async def init_sensor(self, sensor):
|
||||||
if sensor.type in self.types:
|
if sensor.type in self.types:
|
||||||
cfg = sensor.config.copy()
|
cfg = sensor.config.copy()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from cbpi_api import *
|
from cbpi_api import *
|
||||||
|
@ -17,14 +18,17 @@ class StepController(CRUDController):
|
||||||
|
|
||||||
def __init__(self, cbpi):
|
def __init__(self, cbpi):
|
||||||
super(StepController, self).__init__(cbpi)
|
super(StepController, self).__init__(cbpi)
|
||||||
|
self.caching = False
|
||||||
|
self.is_stopping = False
|
||||||
self.cbpi = cbpi
|
self.cbpi = cbpi
|
||||||
self.current_task = None
|
self.current_task = None
|
||||||
|
self.is_next = False
|
||||||
self.types = {}
|
self.types = {}
|
||||||
self.current_step = None
|
self.current_step = None
|
||||||
self.current_job = None
|
self.current_job = None
|
||||||
self.cbpi.register(self)
|
self.cbpi.register(self)
|
||||||
|
self.logger = logging.getLogger(__name__)
|
||||||
|
self.starttime = None
|
||||||
|
|
||||||
async def init(self):
|
async def init(self):
|
||||||
'''
|
'''
|
||||||
|
@ -54,6 +58,8 @@ class StepController(CRUDController):
|
||||||
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), step.name, "step")
|
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), step.name, "step")
|
||||||
|
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
return dict(items=self.get_all(),types=self.types,is_running=self.is_running(),current_step=self.current_step)
|
||||||
|
|
||||||
@on_event("step/action")
|
@on_event("step/action")
|
||||||
async def handle_action(self, action, **kwargs):
|
async def handle_action(self, action, **kwargs):
|
||||||
|
@ -72,7 +78,7 @@ class StepController(CRUDController):
|
||||||
|
|
||||||
|
|
||||||
@on_event("step/next")
|
@on_event("step/next")
|
||||||
async def handle_next(self, **kwargs):
|
async def next(self, **kwargs):
|
||||||
'''
|
'''
|
||||||
Event Handler for "step/next".
|
Event Handler for "step/next".
|
||||||
It start the next step
|
It start the next step
|
||||||
|
@ -80,28 +86,20 @@ class StepController(CRUDController):
|
||||||
:param kwargs:
|
:param kwargs:
|
||||||
:return: None
|
:return: None
|
||||||
'''
|
'''
|
||||||
if self.current_step is not None:
|
print("REQUEST NEXT")
|
||||||
self.current_step.next()
|
self.starttime = time.time()
|
||||||
pass
|
if self.current_step is not None and self.is_next is False:
|
||||||
|
self.logger.info("Request Next Step to start. Stopping current step")
|
||||||
|
self.is_next = True
|
||||||
|
self.current_step.stop()
|
||||||
|
else:
|
||||||
|
self.logger.info("Can Start Next")
|
||||||
|
|
||||||
@on_event("step/reset")
|
|
||||||
async def handle_reset(self, **kwargs):
|
|
||||||
'''
|
|
||||||
Event Handler for "step/reset".
|
|
||||||
Resets the current step
|
|
||||||
|
|
||||||
:param kwargs:
|
|
||||||
:return: None
|
|
||||||
'''
|
|
||||||
if self.current_step is not None:
|
|
||||||
await self.stop()
|
|
||||||
self.is_stopping = True
|
|
||||||
|
|
||||||
await self.model.reset_all_steps()
|
|
||||||
|
|
||||||
|
|
||||||
@on_event("job/step/done")
|
@on_event("job/step/done")
|
||||||
async def handle_step_done(self, topic, **kwargs):
|
async def _step_done(self, topic, **kwargs):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Event Handler for "step/+/done".
|
Event Handler for "step/+/done".
|
||||||
|
@ -112,17 +110,23 @@ class StepController(CRUDController):
|
||||||
:return:
|
:return:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# SHUTDONW DO NOTHING
|
||||||
|
self.logger.info("HANDLE DONE IS SHUTDONW %s IS STOPPING %s IS NEXT %s" % ( self.cbpi.shutdown, self.is_stopping, self.is_next))
|
||||||
|
|
||||||
|
|
||||||
if self.cbpi.shutdown:
|
if self.cbpi.shutdown:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.cache[self.current_step.id].state = "D"
|
if self.is_stopping:
|
||||||
step_id = self.current_step.id
|
self.is_stopping = False
|
||||||
self.current_step = None
|
return
|
||||||
|
self.is_next = False
|
||||||
|
if self.current_step is not None:
|
||||||
|
await self.model.update_state(self.current_step.id, "D", int(time.time()))
|
||||||
|
self.current_step = None
|
||||||
|
await self.start()
|
||||||
|
|
||||||
if self.is_stopping is not True:
|
|
||||||
await self.start()
|
|
||||||
|
|
||||||
self.is_stopping = False
|
|
||||||
|
|
||||||
def _get_manged_fields_as_array(self, type_cfg):
|
def _get_manged_fields_as_array(self, type_cfg):
|
||||||
|
|
||||||
|
@ -139,7 +143,7 @@ class StepController(CRUDController):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@on_event("step/start")
|
@on_event("step/start")
|
||||||
async def start(self, future, **kwargs):
|
async def start(self, **kwargs):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Start the first step
|
Start the first step
|
||||||
|
@ -147,39 +151,58 @@ class StepController(CRUDController):
|
||||||
:return:None
|
:return:None
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if self.current_step is None:
|
if self.is_running() is False:
|
||||||
loop = asyncio.get_event_loop()
|
next_step = await self.model.get_by_state("I")
|
||||||
open_step = False
|
|
||||||
|
|
||||||
inactive = await self.model.get_by_state("I")
|
if next_step is not None:
|
||||||
active = await self.model.get_by_state("A")
|
step_type = self.types[next_step.type]
|
||||||
|
|
||||||
if active is not None:
|
config = dict(cbpi=self.cbpi, id=next_step.id, name=next_step.name, managed_fields=self._get_manged_fields_as_array(step_type))
|
||||||
active.state = 'D'
|
|
||||||
active.end = int(time.time())
|
|
||||||
# self.stop_step()
|
|
||||||
self.current_step = None
|
|
||||||
await self.model.update(**active.__dict__)
|
|
||||||
|
|
||||||
if inactive is not None:
|
|
||||||
step_type = self.types["CustomStepCBPi"]
|
|
||||||
|
|
||||||
config = dict(cbpi=self.cbpi, id=inactive.id, name=inactive.name, managed_fields=self._get_manged_fields_as_array(step_type))
|
|
||||||
self.current_step = step_type["class"](**config)
|
self.current_step = step_type["class"](**config)
|
||||||
|
|
||||||
inactive.state = 'A'
|
next_step.state = 'A'
|
||||||
inactive.stepstate = inactive.config
|
next_step.stepstate = next_step.config
|
||||||
inactive.start = int(time.time())
|
next_step.start = int(time.time())
|
||||||
await self.model.update(**inactive.__dict__)
|
await self.model.update(**next_step.__dict__)
|
||||||
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), inactive.name, "step")
|
if self.starttime is not None:
|
||||||
|
end = time.time()
|
||||||
|
d = end - self.starttime
|
||||||
|
print("DURATION", d)
|
||||||
|
else:
|
||||||
|
print("NORMAL START")
|
||||||
|
self.current_job = await self.cbpi.job.start_job(self.current_step.run(), next_step.name, "step")
|
||||||
|
await self.cbpi.bus.fire("step/%s/started" % self.current_step.id)
|
||||||
else:
|
else:
|
||||||
await self.cbpi.bus.fire("step/berwing/finished")
|
await self.cbpi.bus.fire("step/brewing/finished")
|
||||||
|
else:
|
||||||
future.set_result(True)
|
self.logger.error("Process Already Running")
|
||||||
|
print("----------- END")
|
||||||
|
|
||||||
@on_event("step/stop")
|
@on_event("step/stop")
|
||||||
async def stop(self, **kwargs):
|
async def stop(self, **kwargs):
|
||||||
if self.current_job is not None:
|
|
||||||
|
if self.current_step is not None:
|
||||||
|
self.current_step.stop()
|
||||||
self.is_stopping = True
|
self.is_stopping = True
|
||||||
await self.current_job.close()
|
self.current_step = None
|
||||||
await self.model.reset_all_steps()
|
|
||||||
|
await self.model.reset_all_steps()
|
||||||
|
await self.cbpi.bus.fire("step/brewing/stopped")
|
||||||
|
|
||||||
|
@on_event("step/reset")
|
||||||
|
async def handle_reset(self, **kwargs):
|
||||||
|
'''
|
||||||
|
Event Handler for "step/reset".
|
||||||
|
Resets the current step
|
||||||
|
|
||||||
|
:param kwargs:
|
||||||
|
:return: None
|
||||||
|
'''
|
||||||
|
if self.current_step is not None:
|
||||||
|
|
||||||
|
await self.stop()
|
||||||
|
self.current_step = None
|
||||||
|
self.is_stopping = True
|
||||||
|
|
||||||
|
await self.model.reset_all_steps()
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ from aiojobs.aiohttp import get_scheduler_from_app
|
||||||
|
|
||||||
from cbpi_api import *
|
from cbpi_api import *
|
||||||
|
|
||||||
|
from utils import json_dumps
|
||||||
|
|
||||||
|
|
||||||
class SystemController():
|
class SystemController():
|
||||||
|
|
||||||
|
@ -12,6 +14,16 @@ class SystemController():
|
||||||
self.service = cbpi.actor
|
self.service = cbpi.actor
|
||||||
self.cbpi.register(self, "/system")
|
self.cbpi.register(self, "/system")
|
||||||
|
|
||||||
|
@request_mapping("/state", method="GET", auth_required=False)
|
||||||
|
def state(self, request):
|
||||||
|
# TODO implement restart
|
||||||
|
return web.json_response(data=dict(
|
||||||
|
actor=self.cbpi.actor.get_state(),
|
||||||
|
sensor=self.cbpi.sensor.get_state(),
|
||||||
|
kettle=self.cbpi.kettle.get_state(),
|
||||||
|
step=self.cbpi.step.get_state())
|
||||||
|
, dumps=json_dumps)
|
||||||
|
|
||||||
@request_mapping("/restart", method="POST", name="RestartServer", auth_required=False)
|
@request_mapping("/restart", method="POST", name="RestartServer", auth_required=False)
|
||||||
def restart(self, request):
|
def restart(self, request):
|
||||||
# TODO implement restart
|
# TODO implement restart
|
||||||
|
|
|
@ -35,8 +35,6 @@ from http_endpoints.http_step import StepHttpEndpoints
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@web.middleware
|
@web.middleware
|
||||||
async def error_middleware(request, handler):
|
async def error_middleware(request, handler):
|
||||||
try:
|
try:
|
||||||
|
@ -57,7 +55,6 @@ async def error_middleware(request, handler):
|
||||||
|
|
||||||
class CraftBeerPi():
|
class CraftBeerPi():
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.static_config = load_config(os.path.join(os.path.dirname(__file__), '../config/config.yaml'))
|
self.static_config = load_config(os.path.join(os.path.dirname(__file__), '../config/config.yaml'))
|
||||||
self.database_file = "./craftbeerpi.db"
|
self.database_file = "./craftbeerpi.db"
|
||||||
|
@ -117,7 +114,7 @@ class CraftBeerPi():
|
||||||
'''
|
'''
|
||||||
self.register_http_endpoints(obj, url_prefix, static)
|
self.register_http_endpoints(obj, url_prefix, static)
|
||||||
self.bus.register_object(obj)
|
self.bus.register_object(obj)
|
||||||
self.ws.register_object(obj)
|
#self.ws.register_object(obj)
|
||||||
self.job.register_background_task(obj)
|
self.job.register_background_task(obj)
|
||||||
self.register_on_startup(obj)
|
self.register_on_startup(obj)
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,15 @@ class StepModel(DBModel):
|
||||||
cursor = await db.execute("UPDATE %s SET stepstate = ? WHERE id = ?" % cls.__table_name__, (json.dumps(state), step_id))
|
cursor = await db.execute("UPDATE %s SET stepstate = ? WHERE id = ?" % cls.__table_name__, (json.dumps(state), step_id))
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def update_state(cls, step_id, state, end=None):
|
||||||
|
async with aiosqlite.connect(DATABASE_FILE) as db:
|
||||||
|
if end is not None:
|
||||||
|
await db.execute("UPDATE %s SET state = ?, end = ? WHERE id = ?" % cls.__table_name__, (state, end, step_id))
|
||||||
|
else:
|
||||||
|
await db.execute("UPDATE %s SET state = ? WHERE id = ?" % cls.__table_name__, (state, step_id))
|
||||||
|
await db.commit()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_by_state(cls, state, order=True):
|
async def get_by_state(cls, state, order=True):
|
||||||
|
|
||||||
|
@ -73,6 +82,7 @@ class StepModel(DBModel):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def reset_all_steps(cls):
|
async def reset_all_steps(cls):
|
||||||
|
print("RESET ALL STEPS NOW")
|
||||||
async with aiosqlite.connect(DATABASE_FILE) as db:
|
async with aiosqlite.connect(DATABASE_FILE) as db:
|
||||||
await db.execute("UPDATE %s SET state = 'I', stepstate = NULL , start = NULL, end = NULL " % cls.__table_name__)
|
await db.execute("UPDATE %s SET state = 'I', stepstate = NULL , start = NULL, end = NULL " % cls.__table_name__)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|
|
@ -51,6 +51,7 @@ class CBPiEventBus(object):
|
||||||
if method in self.registry:
|
if method in self.registry:
|
||||||
raise RuntimeError("Method %s already registerd. Please unregister first!" % method.__name__)
|
raise RuntimeError("Method %s already registerd. Please unregister first!" % method.__name__)
|
||||||
self.logger.info("Topic %s", topic)
|
self.logger.info("Topic %s", topic)
|
||||||
|
|
||||||
node = self._root
|
node = self._root
|
||||||
for sym in topic.split('/'):
|
for sym in topic.split('/'):
|
||||||
node = node._children.setdefault(sym, self.Node())
|
node = node._children.setdefault(sym, self.Node())
|
||||||
|
@ -104,7 +105,6 @@ class CBPiEventBus(object):
|
||||||
self.loop = asyncio.get_event_loop()
|
self.loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def sync_fire(self,topic: str,timeout=1, **kwargs):
|
def sync_fire(self,topic: str,timeout=1, **kwargs):
|
||||||
self.loop.create_task(self.fire(topic=topic, timeout=timeout, **kwargs))
|
self.loop.create_task(self.fire(topic=topic, timeout=timeout, **kwargs))
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,90 @@
|
||||||
import logging
|
import logging
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from cbpi_api import *
|
from cbpi_api import *
|
||||||
|
from cbpi_api.exceptions import CBPiException
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
try:
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
except Exception:
|
||||||
|
logger.error("Failed to load RPi.GPIO. Using Mock")
|
||||||
|
MockRPi = MagicMock()
|
||||||
|
modules = {
|
||||||
|
"RPi": MockRPi,
|
||||||
|
"RPi.GPIO": MockRPi.GPIO
|
||||||
|
}
|
||||||
|
patcher = patch.dict("sys.modules", modules)
|
||||||
|
patcher.start()
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
class CustomActor(CBPiActor):
|
class CustomActor(CBPiActor):
|
||||||
|
|
||||||
# Custom property which can be configured by the user
|
# Custom property which can be configured by the user
|
||||||
gpio = Property.Number(label="Test")
|
|
||||||
v1 = Property.Text(label="Test")
|
|
||||||
v2 = Property.Kettle(label="Test")
|
|
||||||
v3 = Property.Sensor(label="Test")
|
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def stop(self):
|
def on(self, power=0):
|
||||||
pass
|
logger.info("ACTOR %s ON" % self.id)
|
||||||
|
self.state = True
|
||||||
|
|
||||||
@action(key="name", parameters={})
|
|
||||||
def myAction(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def state(self):
|
|
||||||
super().state()
|
|
||||||
|
|
||||||
def off(self):
|
def off(self):
|
||||||
|
logger.info("ACTOR %s OFF " % self.id)
|
||||||
print("OFF")
|
|
||||||
# Code to swtich the actor off goes here
|
|
||||||
|
|
||||||
self.state = False
|
self.state = False
|
||||||
|
|
||||||
def on(self, power=100):
|
|
||||||
|
|
||||||
print("ON")
|
|
||||||
# Code to swtich the actor on goes here
|
|
||||||
|
|
||||||
|
|
||||||
|
class GPIOActor(CBPiActor):
|
||||||
|
|
||||||
|
# Custom property which can be configured by the user
|
||||||
|
|
||||||
|
gpio = Property.Select("GPIO", options=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27], description="GPIO to which the actor is connected")
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
try:
|
||||||
|
GPIO.setup(int(self.gpio), GPIO.OUT)
|
||||||
|
GPIO.output(int(self.gpio), 0)
|
||||||
|
except Exception as e:
|
||||||
|
raise CBPiException("FAILD TO INIT ACTOR")
|
||||||
|
|
||||||
|
def on(self, power=0):
|
||||||
|
|
||||||
|
print("GPIO ON %s" % str(self.gpio))
|
||||||
|
GPIO.output(int(self.gpio), 1)
|
||||||
self.state = True
|
self.state = True
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
print("GPIO OFF %s" % str(self.gpio))
|
||||||
|
GPIO.output(int(self.gpio), 0)
|
||||||
|
self.state = False
|
||||||
|
|
||||||
|
class GPIORelayBoardActor(CBPiActor):
|
||||||
|
|
||||||
|
# Custom property which can be configured by the user
|
||||||
|
|
||||||
|
gpio = Property.Select("GPIO", options=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27], description="GPIO to which the actor is connected")
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
try:
|
||||||
|
GPIO.setup(int(self.gpio), GPIO.OUT)
|
||||||
|
GPIO.output(int(self.gpio), 1)
|
||||||
|
except Exception as e:
|
||||||
|
raise CBPiException("FAILD TO INIT ACTOR")
|
||||||
|
|
||||||
|
def on(self, power=0):
|
||||||
|
|
||||||
|
print("GPIO ON %s" % str(self.gpio))
|
||||||
|
GPIO.output(int(self.gpio), 0)
|
||||||
|
self.state = True
|
||||||
|
|
||||||
|
def off(self):
|
||||||
|
print("GPIO OFF %s" % str(self.gpio))
|
||||||
|
GPIO.output(int(self.gpio), 1)
|
||||||
|
self.state = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setup(cbpi):
|
def setup(cbpi):
|
||||||
|
|
|
@ -14,14 +14,12 @@ class CustomStepCBPi(CBPiSimpleStep):
|
||||||
self.name="WOOHOO"
|
self.name="WOOHOO"
|
||||||
|
|
||||||
async def run_cycle(self):
|
async def run_cycle(self):
|
||||||
|
print("RUN", self.name)
|
||||||
|
|
||||||
#await asyncio.sleep(1)
|
|
||||||
self.i = self.i + 1
|
self.i = self.i + 1
|
||||||
self.name="HALLO WELT"
|
if self.i == 5:
|
||||||
if self.i == 20:
|
# print("NEXT")
|
||||||
self.next()
|
self.next()
|
||||||
self.cbpi.notify(key="step", message="HELLO FROM STEP")
|
#self.cbpi.notify(key="step", message="HELLO FROM STEP")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -231,4 +231,39 @@ class ActorHttpEndpoints(HttpCrudEndpoints):
|
||||||
actor_id = int(request.match_info['id'])
|
actor_id = int(request.match_info['id'])
|
||||||
|
|
||||||
await self.cbpi.bus.fire(topic="actor/%s/toggle" % actor_id, actor_id=actor_id)
|
await self.cbpi.bus.fire(topic="actor/%s/toggle" % actor_id, actor_id=actor_id)
|
||||||
|
return web.Response(status=204)
|
||||||
|
|
||||||
|
@request_mapping(path="/{id:\d+}/action", method="POST", auth_required=auth)
|
||||||
|
async def http_action(self, request) -> web.Response:
|
||||||
|
"""
|
||||||
|
|
||||||
|
---
|
||||||
|
description: Toogle an actor on or off
|
||||||
|
tags:
|
||||||
|
- Actor
|
||||||
|
parameters:
|
||||||
|
- name: "id"
|
||||||
|
in: "path"
|
||||||
|
description: "Actor ID"
|
||||||
|
required: true
|
||||||
|
type: "integer"
|
||||||
|
format: "int64"
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: Update an actor
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
config:
|
||||||
|
type: object
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: successful operation
|
||||||
|
"""
|
||||||
|
actor_id = int(request.match_info['id'])
|
||||||
|
|
||||||
|
await self.cbpi.bus.fire(topic="actor/%s/action" % actor_id, actor_id=actor_id, data=await request.json())
|
||||||
return web.Response(status=204)
|
return web.Response(status=204)
|
|
@ -178,12 +178,10 @@ class StepHttpEndpoints(HttpCrudEndpoints):
|
||||||
"""
|
"""
|
||||||
if self.controller.is_running():
|
if self.controller.is_running():
|
||||||
raise CBPiException("Brewing Process Already Running")
|
raise CBPiException("Brewing Process Already Running")
|
||||||
result = await self.cbpi.bus.fire("step/start")
|
print("FIRE START FROM HTTP")
|
||||||
r = result.get("core.controller.step_controller.start")
|
await self.cbpi.bus.fire("step/start")
|
||||||
if r[0] is True:
|
return web.Response(status=204)
|
||||||
return web.Response(status=204)
|
|
||||||
else:
|
|
||||||
raise CBPiException("Failed to start brewing process")
|
|
||||||
|
|
||||||
@request_mapping(path="/reset", auth_required=False)
|
@request_mapping(path="/reset", auth_required=False)
|
||||||
async def http_reset(self, request):
|
async def http_reset(self, request):
|
||||||
|
|
|
@ -2,7 +2,6 @@ from json import JSONEncoder
|
||||||
|
|
||||||
class ComplexEncoder(JSONEncoder):
|
class ComplexEncoder(JSONEncoder):
|
||||||
|
|
||||||
|
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
|
|
||||||
from core.database.orm_framework import DBModel
|
from core.database.orm_framework import DBModel
|
||||||
|
@ -17,7 +16,7 @@ class ComplexEncoder(JSONEncoder):
|
||||||
#elif hasattr(obj, "callback"):
|
#elif hasattr(obj, "callback"):
|
||||||
# return obj()
|
# return obj()
|
||||||
else:
|
else:
|
||||||
return None
|
raise TypeError()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import logging
|
import logging
|
||||||
import weakref
|
import weakref
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import json
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from typing import Iterable, Callable
|
|
||||||
from cbpi_api import *
|
from cbpi_api import *
|
||||||
|
from voluptuous import Schema
|
||||||
|
|
||||||
|
from utils import json_dumps
|
||||||
|
|
||||||
|
|
||||||
class CBPiWebSocket:
|
class CBPiWebSocket:
|
||||||
|
@ -19,60 +21,53 @@ class CBPiWebSocket:
|
||||||
|
|
||||||
@on_event(topic="#")
|
@on_event(topic="#")
|
||||||
async def listen(self, topic, **kwargs):
|
async def listen(self, topic, **kwargs):
|
||||||
from core.utils.encoder import ComplexEncoder
|
data = dict(topic=topic, data=dict(**kwargs))
|
||||||
data = json.dumps(dict(topic=topic, data=dict(**kwargs)),skipkeys=True, check_circular=True, cls=ComplexEncoder)
|
|
||||||
self.logger.info("PUSH %s " % data)
|
self.logger.info("PUSH %s " % data)
|
||||||
self.send(data)
|
self.send(data)
|
||||||
|
|
||||||
def send(self, data):
|
def send(self, data):
|
||||||
|
self.logger.debug("broadcast to ws clients. Data: %s" % data)
|
||||||
for ws in self._clients:
|
for ws in self._clients:
|
||||||
async def send_data(ws, data):
|
async def send_data(ws, data):
|
||||||
await ws.send_str(data)
|
await ws.send_json(data=data, dumps=json_dumps)
|
||||||
self.cbpi.app.loop.create_task(send_data(ws, data))
|
self.cbpi.app.loop.create_task(send_data(ws, data))
|
||||||
|
|
||||||
def add_callback(self, func: Callable, event: str) -> None:
|
|
||||||
self._callbacks[event].add(func)
|
|
||||||
|
|
||||||
def register_object(self, obj):
|
|
||||||
for method in [getattr(obj, f) for f in dir(obj) if callable(getattr(obj, f)) and hasattr(getattr(obj, f), "ws")]:
|
|
||||||
self.add_callback(method, method.__getattribute__("key"))
|
|
||||||
|
|
||||||
async def emit(self, event: str, *args, **kwargs) -> None:
|
|
||||||
for func in self._event_funcs(event):
|
|
||||||
await func(*args, **kwargs)
|
|
||||||
|
|
||||||
def _event_funcs(self, event: str) -> Iterable[Callable]:
|
|
||||||
for func in self._callbacks[event]:
|
|
||||||
yield func
|
|
||||||
|
|
||||||
async def websocket_handler(self, request):
|
async def websocket_handler(self, request):
|
||||||
ws = web.WebSocketResponse()
|
ws = web.WebSocketResponse()
|
||||||
await ws.prepare(request)
|
await ws.prepare(request)
|
||||||
|
|
||||||
self._clients.add(ws)
|
self._clients.add(ws)
|
||||||
|
peername = request.transport.get_extra_info('peername')
|
||||||
|
if peername is not None:
|
||||||
|
host, port = peername
|
||||||
|
else:
|
||||||
|
host, port = "Unknowen"
|
||||||
|
|
||||||
c = len(self._clients) - 1
|
self.logger.info("Client Connected - Host: %s Port: %s - client count: %s " % (host, port, len(self._clients)))
|
||||||
|
|
||||||
self.logger.info(ws)
|
|
||||||
self.logger.info(c)
|
|
||||||
try:
|
try:
|
||||||
|
await ws.send_json(data=dict(topic="connection/success"))
|
||||||
async for msg in ws:
|
async for msg in ws:
|
||||||
if msg.type == aiohttp.WSMsgType.TEXT:
|
if msg.type == aiohttp.WSMsgType.TEXT:
|
||||||
if msg.data == 'close':
|
|
||||||
|
|
||||||
|
msg_obj = msg.json()
|
||||||
|
schema = Schema({"topic": str, "data": dict})
|
||||||
|
schema(msg_obj)
|
||||||
|
|
||||||
|
topic = msg_obj.get("topic")
|
||||||
|
data = msg_obj.get("data")
|
||||||
|
if topic == "close":
|
||||||
await ws.close()
|
await ws.close()
|
||||||
self.logger.info("WS Close")
|
|
||||||
else:
|
else:
|
||||||
msg_obj = msg.json()
|
if data is not None:
|
||||||
|
await self.cbpi.bus.fire(topic=topic, **data)
|
||||||
await self.cbpi.bus.fire(msg_obj["topic"], id=1, power=22)
|
else:
|
||||||
# await self.fire(msg_obj["key"], ws, msg)
|
await self.cbpi.bus.fire(topic=topic)
|
||||||
|
|
||||||
# await ws.send_str(msg.data)
|
|
||||||
elif msg.type == aiohttp.WSMsgType.ERROR:
|
elif msg.type == aiohttp.WSMsgType.ERROR:
|
||||||
self.logger.error('ws connection closed with exception %s' % ws.exception())
|
self.logger.error('ws connection closed with exception %s' % ws.exception())
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error("%s - Received Data %s" % (str(e), msg.data))
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self._clients.discard(ws)
|
self._clients.discard(ws)
|
||||||
|
|
||||||
|
|
BIN
craftbeerpi.db
BIN
craftbeerpi.db
Binary file not shown.
|
@ -230,7 +230,7 @@
|
||||||
</li>
|
</li>
|
||||||
<li><a href="step.html#core.controller.step_controller.StepController.handle_done">handle_done() (core.controller.step_controller.StepController method)</a>
|
<li><a href="step.html#core.controller.step_controller.StepController.handle_done">handle_done() (core.controller.step_controller.StepController method)</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="step.html#core.controller.step_controller.StepController.handle_next">handle_next() (core.controller.step_controller.StepController method)</a>
|
<li><a href="step.html#core.controller.step_controller.StepController.handle_next">next() (core.controller.step_controller.StepController method)</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="step.html#core.controller.step_controller.StepController.handle_reset">handle_reset() (core.controller.step_controller.StepController method)</a>
|
<li><a href="step.html#core.controller.step_controller.StepController.handle_reset">handle_reset() (core.controller.step_controller.StepController method)</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -220,7 +220,7 @@ Starts the next step</p>
|
||||||
|
|
||||||
<dl class="method">
|
<dl class="method">
|
||||||
<dt id="core.controller.step_controller.StepController.handle_next">
|
<dt id="core.controller.step_controller.StepController.handle_next">
|
||||||
<code class="descname">handle_next</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.step_controller.StepController.handle_next" title="Permalink to this definition">¶</a></dt>
|
<code class="descname">next</code><span class="sig-paren">(</span><em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#core.controller.step_controller.StepController.handle_next" title="Permalink to this definition">¶</a></dt>
|
||||||
<dd><p>Event Handler for “step/next”.
|
<dd><p>Event Handler for “step/next”.
|
||||||
It start the next step</p>
|
It start the next step</p>
|
||||||
<table class="docutils field-list" frame="void" rules="none">
|
<table class="docutils field-list" frame="void" rules="none">
|
||||||
|
|
|
@ -1,24 +1,34 @@
|
||||||
2019-01-02 20:34:10,10
|
2019-01-04 00:44:35,10
|
||||||
2019-01-02 20:34:15,10
|
2019-01-04 00:44:40,10
|
||||||
2019-01-02 20:34:20,10
|
2019-01-04 00:44:45,10
|
||||||
2019-01-02 20:34:25,10
|
2019-01-04 00:44:50,10
|
||||||
2019-01-02 20:34:32,10
|
2019-01-04 00:44:55,10
|
||||||
2019-01-02 20:34:37,10
|
2019-01-04 00:45:00,10
|
||||||
2019-01-02 20:34:42,10
|
2019-01-04 00:45:05,10
|
||||||
2019-01-02 20:34:47,10
|
2019-01-04 00:45:10,10
|
||||||
2019-01-02 20:34:52,10
|
2019-01-04 00:45:15,10
|
||||||
2019-01-02 20:34:57,10
|
2019-01-04 00:45:20,10
|
||||||
2019-01-02 20:35:02,10
|
2019-01-04 00:45:25,10
|
||||||
2019-01-02 20:35:07,10
|
2019-01-04 00:45:30,10
|
||||||
2019-01-02 20:35:12,10
|
2019-01-04 00:45:35,10
|
||||||
2019-01-02 20:35:17,10
|
2019-01-04 00:45:40,10
|
||||||
2019-01-02 20:35:22,10
|
2019-01-04 00:45:45,10
|
||||||
2019-01-02 20:35:30,10
|
2019-01-04 00:45:50,10
|
||||||
2019-01-02 20:35:35,10
|
2019-01-04 00:45:55,10
|
||||||
2019-01-02 20:35:40,10
|
2019-01-04 00:46:00,10
|
||||||
2019-01-02 20:35:45,10
|
2019-01-04 00:46:05,10
|
||||||
2019-01-02 20:35:50,10
|
2019-01-04 00:46:10,10
|
||||||
2019-01-02 20:35:55,10
|
2019-01-04 00:46:15,10
|
||||||
2019-01-02 20:36:00,10
|
2019-01-04 00:46:20,10
|
||||||
2019-01-02 20:36:05,10
|
2019-01-04 00:46:31,10
|
||||||
2019-01-02 20:36:10,10
|
2019-01-04 00:46:36,10
|
||||||
|
2019-01-04 00:46:41,10
|
||||||
|
2019-01-04 00:46:46,10
|
||||||
|
2019-01-04 00:46:51,10
|
||||||
|
2019-01-04 00:46:56,10
|
||||||
|
2019-01-04 00:47:01,10
|
||||||
|
2019-01-04 00:47:06,10
|
||||||
|
2019-01-04 00:47:11,10
|
||||||
|
2019-01-04 00:47:16,10
|
||||||
|
2019-01-04 00:47:21,10
|
||||||
|
2019-01-04 00:47:26,10
|
||||||
|
|
|
@ -1,86 +1,86 @@
|
||||||
2019-01-02 20:26:40,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 20:26:45,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 20:26:50,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 20:26:55,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 20:27:00,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 20:27:05,10
|
2019-01-04 00:19:48,10
|
||||||
2019-01-02 20:27:10,10
|
2019-01-04 00:19:53,10
|
||||||
2019-01-02 20:27:15,10
|
2019-01-04 00:20:04,10
|
||||||
2019-01-02 20:27:20,10
|
2019-01-04 00:20:09,10
|
||||||
2019-01-02 20:27:25,10
|
2019-01-04 00:20:14,10
|
||||||
2019-01-02 20:27:30,10
|
2019-01-04 00:20:19,10
|
||||||
2019-01-02 20:27:35,10
|
2019-01-04 00:20:24,10
|
||||||
2019-01-02 20:27:40,10
|
2019-01-04 00:20:29,10
|
||||||
2019-01-02 20:27:45,10
|
2019-01-04 00:20:34,10
|
||||||
2019-01-02 20:27:51,10
|
2019-01-04 00:20:39,10
|
||||||
2019-01-02 20:27:56,10
|
2019-01-04 00:20:44,10
|
||||||
2019-01-02 20:28:01,10
|
2019-01-04 00:20:49,10
|
||||||
2019-01-02 20:28:06,10
|
2019-01-04 00:20:54,10
|
||||||
2019-01-02 20:28:11,10
|
2019-01-04 00:20:59,10
|
||||||
2019-01-02 20:28:16,10
|
2019-01-04 00:38:43,10
|
||||||
2019-01-02 20:28:21,10
|
2019-01-04 00:38:48,10
|
||||||
2019-01-02 20:28:26,10
|
2019-01-04 00:38:53,10
|
||||||
2019-01-02 20:28:31,10
|
2019-01-04 00:38:58,10
|
||||||
2019-01-02 20:28:36,10
|
2019-01-04 00:39:03,10
|
||||||
2019-01-02 20:28:41,10
|
2019-01-04 00:39:08,10
|
||||||
2019-01-02 20:28:46,10
|
2019-01-04 00:39:13,10
|
||||||
2019-01-02 20:28:51,10
|
2019-01-04 00:39:18,10
|
||||||
2019-01-02 20:28:56,10
|
2019-01-04 00:39:23,10
|
||||||
2019-01-02 20:29:01,10
|
2019-01-04 00:39:28,10
|
||||||
2019-01-02 20:29:06,10
|
2019-01-04 00:39:33,10
|
||||||
2019-01-02 20:29:11,10
|
2019-01-04 00:39:38,10
|
||||||
2019-01-02 20:29:16,10
|
2019-01-04 00:39:45,10
|
||||||
2019-01-02 20:29:21,10
|
2019-01-04 00:39:54,10
|
||||||
2019-01-02 20:29:26,10
|
2019-01-04 00:39:59,10
|
||||||
2019-01-02 20:29:31,10
|
2019-01-04 00:40:04,10
|
||||||
2019-01-02 20:29:36,10
|
2019-01-04 00:40:09,10
|
||||||
2019-01-02 20:29:41,10
|
2019-01-04 00:40:14,10
|
||||||
2019-01-02 20:29:46,10
|
2019-01-04 00:40:21,10
|
||||||
2019-01-02 20:29:51,10
|
2019-01-04 00:40:31,10
|
||||||
2019-01-02 20:29:56,10
|
2019-01-04 00:40:36,10
|
||||||
2019-01-02 20:30:01,10
|
2019-01-04 00:40:41,10
|
||||||
2019-01-02 20:30:06,10
|
2019-01-04 00:40:46,10
|
||||||
2019-01-02 20:30:11,10
|
2019-01-04 00:40:51,10
|
||||||
2019-01-02 20:30:16,10
|
2019-01-04 00:40:56,10
|
||||||
2019-01-02 20:30:21,10
|
2019-01-04 00:41:01,10
|
||||||
2019-01-02 20:30:26,10
|
2019-01-04 00:41:06,10
|
||||||
2019-01-02 20:30:31,10
|
2019-01-04 00:41:11,10
|
||||||
2019-01-02 20:30:36,10
|
2019-01-04 00:41:16,10
|
||||||
2019-01-02 20:30:41,10
|
2019-01-04 00:41:21,10
|
||||||
2019-01-02 20:30:46,10
|
2019-01-04 00:41:26,10
|
||||||
2019-01-02 20:30:51,10
|
2019-01-04 00:41:31,10
|
||||||
2019-01-02 20:30:56,10
|
2019-01-04 00:41:36,10
|
||||||
2019-01-02 20:31:01,10
|
2019-01-04 00:41:41,10
|
||||||
2019-01-02 20:31:06,10
|
2019-01-04 00:41:46,10
|
||||||
2019-01-02 20:31:11,10
|
2019-01-04 00:41:51,10
|
||||||
2019-01-02 20:31:16,10
|
2019-01-04 00:41:56,10
|
||||||
2019-01-02 20:31:21,10
|
2019-01-04 00:42:01,10
|
||||||
2019-01-02 20:31:26,10
|
2019-01-04 00:42:06,10
|
||||||
2019-01-02 20:31:31,10
|
2019-01-04 00:42:11,10
|
||||||
2019-01-02 20:31:36,10
|
2019-01-04 00:42:16,10
|
||||||
2019-01-02 20:31:41,10
|
2019-01-04 00:42:21,10
|
||||||
2019-01-02 20:31:46,10
|
2019-01-04 00:42:26,10
|
||||||
2019-01-02 20:31:51,10
|
2019-01-04 00:42:31,10
|
||||||
2019-01-02 20:31:56,10
|
2019-01-04 00:42:36,10
|
||||||
2019-01-02 20:32:01,10
|
2019-01-04 00:42:41,10
|
||||||
2019-01-02 20:32:06,10
|
2019-01-04 00:42:46,10
|
||||||
2019-01-02 20:32:11,10
|
2019-01-04 00:42:51,10
|
||||||
2019-01-02 20:32:16,10
|
2019-01-04 00:42:56,10
|
||||||
2019-01-02 20:32:21,10
|
2019-01-04 00:43:05,10
|
||||||
2019-01-02 20:32:26,10
|
2019-01-04 00:43:10,10
|
||||||
2019-01-02 20:32:31,10
|
2019-01-04 00:43:15,10
|
||||||
2019-01-02 20:32:36,10
|
2019-01-04 00:43:20,10
|
||||||
2019-01-02 20:32:41,10
|
2019-01-04 00:43:25,10
|
||||||
2019-01-02 20:33:05,10
|
2019-01-04 00:43:30,10
|
||||||
2019-01-02 20:33:10,10
|
2019-01-04 00:43:35,10
|
||||||
2019-01-02 20:33:15,10
|
2019-01-04 00:43:40,10
|
||||||
2019-01-02 20:33:20,10
|
2019-01-04 00:43:45,10
|
||||||
2019-01-02 20:33:25,10
|
2019-01-04 00:43:50,10
|
||||||
2019-01-02 20:33:30,10
|
2019-01-04 00:43:55,10
|
||||||
2019-01-02 20:33:35,10
|
2019-01-04 00:44:00,10
|
||||||
2019-01-02 20:33:40,10
|
2019-01-04 00:44:05,10
|
||||||
2019-01-02 20:33:45,10
|
2019-01-04 00:44:10,10
|
||||||
2019-01-02 20:33:50,10
|
2019-01-04 00:44:15,10
|
||||||
2019-01-02 20:33:55,10
|
2019-01-04 00:44:20,10
|
||||||
2019-01-02 20:34:00,10
|
2019-01-04 00:44:25,10
|
||||||
2019-01-02 20:34:05,10
|
2019-01-04 00:44:30,10
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 18:48:13,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 18:48:18,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 18:48:23,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 18:48:28,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 18:48:33,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 18:48:38,10
|
|
||||||
2019-01-02 18:48:43,10
|
|
||||||
2019-01-02 18:48:48,10
|
|
||||||
2019-01-02 18:48:53,10
|
|
||||||
2019-01-02 18:48:58,10
|
|
||||||
2019-01-02 18:49:03,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:07,10
|
|
||||||
2019-01-02 18:49:08,10
|
|
||||||
2019-01-02 18:49:13,10
|
|
||||||
2019-01-02 18:49:18,10
|
|
||||||
2019-01-02 18:49:23,10
|
|
||||||
2019-01-02 18:49:28,10
|
|
||||||
2019-01-02 18:49:33,10
|
|
||||||
2019-01-02 18:49:38,10
|
|
||||||
2019-01-02 18:49:43,10
|
|
||||||
2019-01-02 18:49:48,10
|
|
||||||
2019-01-02 18:49:53,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:49:58,10
|
|
||||||
2019-01-02 18:50:03,10
|
|
||||||
2019-01-02 18:50:08,10
|
|
||||||
2019-01-02 18:50:13,10
|
|
||||||
2019-01-02 18:50:18,10
|
|
||||||
2019-01-02 18:50:23,10
|
|
||||||
2019-01-02 18:50:28,10
|
|
||||||
2019-01-02 18:50:33,10
|
|
||||||
2019-01-02 18:50:38,10
|
|
||||||
2019-01-02 18:50:43,10
|
|
||||||
2019-01-02 18:50:48,10
|
|
||||||
2019-01-02 18:50:53,10
|
|
||||||
2019-01-02 18:50:58,10
|
|
||||||
2019-01-02 18:51:03,10
|
|
||||||
2019-01-02 18:51:08,10
|
|
||||||
2019-01-02 18:51:13,10
|
|
||||||
2019-01-02 18:51:18,10
|
|
||||||
2019-01-02 18:51:23,10
|
|
||||||
2019-01-02 18:51:28,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:29,10
|
|
||||||
2019-01-02 18:51:33,10
|
|
||||||
2019-01-02 18:51:38,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
2019-01-02 18:51:43,10
|
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 19:43:47,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 19:43:52,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 19:43:57,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 19:44:02,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 19:44:07,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 19:44:12,10
|
|
||||||
2019-01-02 19:44:17,10
|
|
||||||
2019-01-02 19:44:22,10
|
|
||||||
2019-01-02 19:44:27,10
|
|
||||||
2019-01-02 19:44:32,10
|
|
||||||
2019-01-02 19:44:37,10
|
|
||||||
2019-01-02 19:44:42,10
|
|
||||||
2019-01-02 19:44:47,10
|
|
||||||
2019-01-02 19:44:52,10
|
|
||||||
2019-01-02 19:44:57,10
|
|
||||||
2019-01-02 19:45:02,10
|
|
||||||
2019-01-02 19:45:07,10
|
|
||||||
2019-01-02 19:45:12,10
|
|
||||||
2019-01-02 19:45:17,10
|
|
||||||
2019-01-02 19:45:22,10
|
|
||||||
2019-01-02 19:45:27,10
|
|
||||||
2019-01-02 20:21:15,10
|
|
||||||
2019-01-02 20:21:20,10
|
|
||||||
2019-01-02 20:21:25,10
|
|
||||||
2019-01-02 20:21:30,10
|
|
||||||
2019-01-02 20:21:35,10
|
|
||||||
2019-01-02 20:21:40,10
|
|
||||||
2019-01-02 20:21:45,10
|
|
||||||
2019-01-02 20:21:50,10
|
|
||||||
2019-01-02 20:21:55,10
|
|
||||||
2019-01-02 20:22:00,10
|
|
||||||
2019-01-02 20:22:05,10
|
|
||||||
2019-01-02 20:22:10,10
|
|
||||||
2019-01-02 20:22:15,10
|
|
||||||
2019-01-02 20:22:20,10
|
|
||||||
2019-01-02 20:22:25,10
|
|
||||||
2019-01-02 20:22:30,10
|
|
||||||
2019-01-02 20:22:35,10
|
|
||||||
2019-01-02 20:22:40,10
|
|
||||||
2019-01-02 20:22:45,10
|
|
||||||
2019-01-02 20:22:50,10
|
|
||||||
2019-01-02 20:22:55,10
|
|
||||||
2019-01-02 20:23:00,10
|
|
||||||
2019-01-02 20:23:05,10
|
|
||||||
2019-01-02 20:23:10,10
|
|
||||||
2019-01-02 20:23:15,10
|
|
||||||
2019-01-02 20:23:20,10
|
|
||||||
2019-01-02 20:23:25,10
|
|
||||||
2019-01-02 20:23:30,10
|
|
||||||
2019-01-02 20:23:35,10
|
|
||||||
2019-01-02 20:23:40,10
|
|
||||||
2019-01-02 20:23:45,10
|
|
||||||
2019-01-02 20:23:50,10
|
|
||||||
2019-01-02 20:23:55,10
|
|
||||||
2019-01-02 20:24:00,10
|
|
||||||
2019-01-02 20:24:05,10
|
|
||||||
2019-01-02 20:24:10,10
|
|
||||||
2019-01-02 20:24:15,10
|
|
||||||
2019-01-02 20:24:20,10
|
|
||||||
2019-01-02 20:24:25,10
|
|
||||||
2019-01-02 20:24:30,10
|
|
||||||
2019-01-02 20:24:35,10
|
|
||||||
2019-01-02 20:24:40,10
|
|
||||||
2019-01-02 20:24:45,10
|
|
||||||
2019-01-02 20:24:50,10
|
|
||||||
2019-01-02 20:24:55,10
|
|
||||||
2019-01-02 20:25:00,10
|
|
||||||
2019-01-02 20:25:05,10
|
|
||||||
2019-01-02 20:25:10,10
|
|
||||||
2019-01-02 20:25:15,10
|
|
||||||
2019-01-02 20:25:20,10
|
|
||||||
2019-01-02 20:25:25,10
|
|
||||||
2019-01-02 20:25:30,10
|
|
||||||
2019-01-02 20:25:35,10
|
|
||||||
2019-01-02 20:25:40,10
|
|
||||||
2019-01-02 20:25:45,10
|
|
||||||
2019-01-02 20:25:50,10
|
|
||||||
2019-01-02 20:25:55,10
|
|
||||||
2019-01-02 20:26:00,10
|
|
||||||
2019-01-02 20:26:05,10
|
|
||||||
2019-01-02 20:26:10,10
|
|
||||||
2019-01-02 20:26:15,10
|
|
||||||
2019-01-02 20:26:20,10
|
|
||||||
2019-01-02 20:26:25,10
|
|
||||||
2019-01-02 20:26:30,10
|
|
||||||
2019-01-02 20:26:35,10
|
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 19:36:04,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 19:36:09,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 19:36:14,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 19:36:19,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 19:36:24,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 19:36:29,10
|
|
||||||
2019-01-02 19:36:34,10
|
|
||||||
2019-01-02 19:36:39,10
|
|
||||||
2019-01-02 19:36:44,10
|
|
||||||
2019-01-02 19:36:49,10
|
|
||||||
2019-01-02 19:36:54,10
|
|
||||||
2019-01-02 19:36:59,10
|
|
||||||
2019-01-02 19:37:04,10
|
|
||||||
2019-01-02 19:37:09,10
|
|
||||||
2019-01-02 19:37:14,10
|
|
||||||
2019-01-02 19:37:19,10
|
|
||||||
2019-01-02 19:37:24,10
|
|
||||||
2019-01-02 19:37:30,10
|
|
||||||
2019-01-02 19:37:35,10
|
|
||||||
2019-01-02 19:37:40,10
|
|
||||||
2019-01-02 19:37:45,10
|
|
||||||
2019-01-02 19:37:50,10
|
|
||||||
2019-01-02 19:37:55,10
|
|
||||||
2019-01-02 19:38:00,10
|
|
||||||
2019-01-02 19:38:05,10
|
|
||||||
2019-01-02 19:38:10,10
|
|
||||||
2019-01-02 19:38:15,10
|
|
||||||
2019-01-02 19:38:20,10
|
|
||||||
2019-01-02 19:38:25,10
|
|
||||||
2019-01-02 19:38:30,10
|
|
||||||
2019-01-02 19:38:35,10
|
|
||||||
2019-01-02 19:38:44,10
|
|
||||||
2019-01-02 19:38:49,10
|
|
||||||
2019-01-02 19:38:54,10
|
|
||||||
2019-01-02 19:38:59,10
|
|
||||||
2019-01-02 19:39:04,10
|
|
||||||
2019-01-02 19:39:09,10
|
|
||||||
2019-01-02 19:39:14,10
|
|
||||||
2019-01-02 19:39:22,10
|
|
||||||
2019-01-02 19:39:27,10
|
|
||||||
2019-01-02 19:39:32,10
|
|
||||||
2019-01-02 19:39:37,10
|
|
||||||
2019-01-02 19:39:42,10
|
|
||||||
2019-01-02 19:39:47,10
|
|
||||||
2019-01-02 19:39:52,10
|
|
||||||
2019-01-02 19:39:58,10
|
|
||||||
2019-01-02 19:40:03,10
|
|
||||||
2019-01-02 19:40:08,10
|
|
||||||
2019-01-02 19:40:13,10
|
|
||||||
2019-01-02 19:40:18,10
|
|
||||||
2019-01-02 19:40:23,10
|
|
||||||
2019-01-02 19:40:28,10
|
|
||||||
2019-01-02 19:40:33,10
|
|
||||||
2019-01-02 19:40:43,10
|
|
||||||
2019-01-02 19:40:48,10
|
|
||||||
2019-01-02 19:40:53,10
|
|
||||||
2019-01-02 19:40:58,10
|
|
||||||
2019-01-02 19:41:03,10
|
|
||||||
2019-01-02 19:41:08,10
|
|
||||||
2019-01-02 19:41:20,10
|
|
||||||
2019-01-02 19:41:25,10
|
|
||||||
2019-01-02 19:41:36,10
|
|
||||||
2019-01-02 19:41:41,10
|
|
||||||
2019-01-02 19:41:46,10
|
|
||||||
2019-01-02 19:41:51,10
|
|
||||||
2019-01-02 19:41:56,10
|
|
||||||
2019-01-02 19:42:01,10
|
|
||||||
2019-01-02 19:42:06,10
|
|
||||||
2019-01-02 19:42:11,10
|
|
||||||
2019-01-02 19:42:16,10
|
|
||||||
2019-01-02 19:42:21,10
|
|
||||||
2019-01-02 19:42:26,10
|
|
||||||
2019-01-02 19:42:31,10
|
|
||||||
2019-01-02 19:42:36,10
|
|
||||||
2019-01-02 19:42:41,10
|
|
||||||
2019-01-02 19:42:46,10
|
|
||||||
2019-01-02 19:42:51,10
|
|
||||||
2019-01-02 19:42:56,10
|
|
||||||
2019-01-02 19:43:01,10
|
|
||||||
2019-01-02 19:43:06,10
|
|
||||||
2019-01-02 19:43:11,10
|
|
||||||
2019-01-02 19:43:22,10
|
|
||||||
2019-01-02 19:43:27,10
|
|
||||||
2019-01-02 19:43:32,10
|
|
||||||
2019-01-02 19:43:37,10
|
|
||||||
2019-01-02 19:43:42,10
|
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 19:28:35,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 19:28:40,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 19:28:47,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 19:28:52,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 19:28:57,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 19:29:02,10
|
|
||||||
2019-01-02 19:29:07,10
|
|
||||||
2019-01-02 19:29:12,10
|
|
||||||
2019-01-02 19:29:17,10
|
|
||||||
2019-01-02 19:29:22,10
|
|
||||||
2019-01-02 19:29:27,10
|
|
||||||
2019-01-02 19:29:32,10
|
|
||||||
2019-01-02 19:29:44,10
|
|
||||||
2019-01-02 19:29:49,10
|
|
||||||
2019-01-02 19:29:54,10
|
|
||||||
2019-01-02 19:29:59,10
|
|
||||||
2019-01-02 19:30:04,10
|
|
||||||
2019-01-02 19:30:09,10
|
|
||||||
2019-01-02 19:30:14,10
|
|
||||||
2019-01-02 19:30:19,10
|
|
||||||
2019-01-02 19:30:24,10
|
|
||||||
2019-01-02 19:30:29,10
|
|
||||||
2019-01-02 19:30:34,10
|
|
||||||
2019-01-02 19:30:39,10
|
|
||||||
2019-01-02 19:30:46,10
|
|
||||||
2019-01-02 19:30:51,10
|
|
||||||
2019-01-02 19:30:56,10
|
|
||||||
2019-01-02 19:31:01,10
|
|
||||||
2019-01-02 19:31:09,10
|
|
||||||
2019-01-02 19:31:14,10
|
|
||||||
2019-01-02 19:31:19,10
|
|
||||||
2019-01-02 19:31:24,10
|
|
||||||
2019-01-02 19:31:29,10
|
|
||||||
2019-01-02 19:31:34,10
|
|
||||||
2019-01-02 19:31:39,10
|
|
||||||
2019-01-02 19:31:44,10
|
|
||||||
2019-01-02 19:31:49,10
|
|
||||||
2019-01-02 19:31:54,10
|
|
||||||
2019-01-02 19:31:59,10
|
|
||||||
2019-01-02 19:32:04,10
|
|
||||||
2019-01-02 19:32:13,10
|
|
||||||
2019-01-02 19:32:18,10
|
|
||||||
2019-01-02 19:32:23,10
|
|
||||||
2019-01-02 19:32:28,10
|
|
||||||
2019-01-02 19:32:33,10
|
|
||||||
2019-01-02 19:32:38,10
|
|
||||||
2019-01-02 19:32:43,10
|
|
||||||
2019-01-02 19:32:48,10
|
|
||||||
2019-01-02 19:32:53,10
|
|
||||||
2019-01-02 19:32:58,10
|
|
||||||
2019-01-02 19:33:03,10
|
|
||||||
2019-01-02 19:33:08,10
|
|
||||||
2019-01-02 19:33:13,10
|
|
||||||
2019-01-02 19:33:18,10
|
|
||||||
2019-01-02 19:33:23,10
|
|
||||||
2019-01-02 19:33:28,10
|
|
||||||
2019-01-02 19:33:33,10
|
|
||||||
2019-01-02 19:33:38,10
|
|
||||||
2019-01-02 19:33:43,10
|
|
||||||
2019-01-02 19:33:48,10
|
|
||||||
2019-01-02 19:33:53,10
|
|
||||||
2019-01-02 19:33:58,10
|
|
||||||
2019-01-02 19:34:03,10
|
|
||||||
2019-01-02 19:34:08,10
|
|
||||||
2019-01-02 19:34:13,10
|
|
||||||
2019-01-02 19:34:18,10
|
|
||||||
2019-01-02 19:34:23,10
|
|
||||||
2019-01-02 19:34:28,10
|
|
||||||
2019-01-02 19:34:33,10
|
|
||||||
2019-01-02 19:34:38,10
|
|
||||||
2019-01-02 19:34:44,10
|
|
||||||
2019-01-02 19:34:49,10
|
|
||||||
2019-01-02 19:34:54,10
|
|
||||||
2019-01-02 19:34:59,10
|
|
||||||
2019-01-02 19:35:04,10
|
|
||||||
2019-01-02 19:35:09,10
|
|
||||||
2019-01-02 19:35:14,10
|
|
||||||
2019-01-02 19:35:19,10
|
|
||||||
2019-01-02 19:35:24,10
|
|
||||||
2019-01-02 19:35:29,10
|
|
||||||
2019-01-02 19:35:34,10
|
|
||||||
2019-01-02 19:35:39,10
|
|
||||||
2019-01-02 19:35:44,10
|
|
||||||
2019-01-02 19:35:49,10
|
|
||||||
2019-01-02 19:35:54,10
|
|
||||||
2019-01-02 19:35:59,10
|
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 19:21:17,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 19:21:22,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 19:21:27,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 19:21:32,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 19:21:37,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 19:21:42,10
|
|
||||||
2019-01-02 19:21:47,10
|
|
||||||
2019-01-02 19:21:52,10
|
|
||||||
2019-01-02 19:21:57,10
|
|
||||||
2019-01-02 19:22:02,10
|
|
||||||
2019-01-02 19:22:07,10
|
|
||||||
2019-01-02 19:22:12,10
|
|
||||||
2019-01-02 19:22:19,10
|
|
||||||
2019-01-02 19:22:24,10
|
|
||||||
2019-01-02 19:22:29,10
|
|
||||||
2019-01-02 19:22:34,10
|
|
||||||
2019-01-02 19:22:39,10
|
|
||||||
2019-01-02 19:22:44,10
|
|
||||||
2019-01-02 19:22:49,10
|
|
||||||
2019-01-02 19:22:54,10
|
|
||||||
2019-01-02 19:22:59,10
|
|
||||||
2019-01-02 19:23:04,10
|
|
||||||
2019-01-02 19:23:09,10
|
|
||||||
2019-01-02 19:23:14,10
|
|
||||||
2019-01-02 19:23:19,10
|
|
||||||
2019-01-02 19:23:24,10
|
|
||||||
2019-01-02 19:23:29,10
|
|
||||||
2019-01-02 19:23:34,10
|
|
||||||
2019-01-02 19:23:39,10
|
|
||||||
2019-01-02 19:23:44,10
|
|
||||||
2019-01-02 19:23:49,10
|
|
||||||
2019-01-02 19:23:54,10
|
|
||||||
2019-01-02 19:24:05,10
|
|
||||||
2019-01-02 19:24:10,10
|
|
||||||
2019-01-02 19:24:15,10
|
|
||||||
2019-01-02 19:24:20,10
|
|
||||||
2019-01-02 19:24:25,10
|
|
||||||
2019-01-02 19:24:30,10
|
|
||||||
2019-01-02 19:24:35,10
|
|
||||||
2019-01-02 19:24:40,10
|
|
||||||
2019-01-02 19:24:45,10
|
|
||||||
2019-01-02 19:24:50,10
|
|
||||||
2019-01-02 19:24:55,10
|
|
||||||
2019-01-02 19:25:00,10
|
|
||||||
2019-01-02 19:25:05,10
|
|
||||||
2019-01-02 19:25:10,10
|
|
||||||
2019-01-02 19:25:15,10
|
|
||||||
2019-01-02 19:25:20,10
|
|
||||||
2019-01-02 19:25:25,10
|
|
||||||
2019-01-02 19:25:30,10
|
|
||||||
2019-01-02 19:25:35,10
|
|
||||||
2019-01-02 19:25:40,10
|
|
||||||
2019-01-02 19:25:45,10
|
|
||||||
2019-01-02 19:25:50,10
|
|
||||||
2019-01-02 19:25:55,10
|
|
||||||
2019-01-02 19:26:00,10
|
|
||||||
2019-01-02 19:26:05,10
|
|
||||||
2019-01-02 19:26:10,10
|
|
||||||
2019-01-02 19:26:15,10
|
|
||||||
2019-01-02 19:26:20,10
|
|
||||||
2019-01-02 19:26:25,10
|
|
||||||
2019-01-02 19:26:30,10
|
|
||||||
2019-01-02 19:26:35,10
|
|
||||||
2019-01-02 19:26:40,10
|
|
||||||
2019-01-02 19:26:45,10
|
|
||||||
2019-01-02 19:26:50,10
|
|
||||||
2019-01-02 19:26:55,10
|
|
||||||
2019-01-02 19:27:00,10
|
|
||||||
2019-01-02 19:27:05,10
|
|
||||||
2019-01-02 19:27:10,10
|
|
||||||
2019-01-02 19:27:15,10
|
|
||||||
2019-01-02 19:27:20,10
|
|
||||||
2019-01-02 19:27:25,10
|
|
||||||
2019-01-02 19:27:30,10
|
|
||||||
2019-01-02 19:27:35,10
|
|
||||||
2019-01-02 19:27:40,10
|
|
||||||
2019-01-02 19:27:45,10
|
|
||||||
2019-01-02 19:27:50,10
|
|
||||||
2019-01-02 19:27:55,10
|
|
||||||
2019-01-02 19:28:00,10
|
|
||||||
2019-01-02 19:28:05,10
|
|
||||||
2019-01-02 19:28:10,10
|
|
||||||
2019-01-02 19:28:15,10
|
|
||||||
2019-01-02 19:28:20,10
|
|
||||||
2019-01-02 19:28:25,10
|
|
||||||
2019-01-02 19:28:30,10
|
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 19:14:06,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 19:14:11,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 19:14:16,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 19:14:21,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 19:14:26,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 19:14:32,10
|
|
||||||
2019-01-02 19:14:37,10
|
|
||||||
2019-01-02 19:14:42,10
|
|
||||||
2019-01-02 19:14:47,10
|
|
||||||
2019-01-02 19:14:52,10
|
|
||||||
2019-01-02 19:14:57,10
|
|
||||||
2019-01-02 19:15:02,10
|
|
||||||
2019-01-02 19:15:07,10
|
|
||||||
2019-01-02 19:15:12,10
|
|
||||||
2019-01-02 19:15:17,10
|
|
||||||
2019-01-02 19:15:22,10
|
|
||||||
2019-01-02 19:15:27,10
|
|
||||||
2019-01-02 19:15:32,10
|
|
||||||
2019-01-02 19:15:37,10
|
|
||||||
2019-01-02 19:15:42,10
|
|
||||||
2019-01-02 19:15:47,10
|
|
||||||
2019-01-02 19:15:52,10
|
|
||||||
2019-01-02 19:15:57,10
|
|
||||||
2019-01-02 19:16:02,10
|
|
||||||
2019-01-02 19:16:07,10
|
|
||||||
2019-01-02 19:16:12,10
|
|
||||||
2019-01-02 19:16:17,10
|
|
||||||
2019-01-02 19:16:22,10
|
|
||||||
2019-01-02 19:16:27,10
|
|
||||||
2019-01-02 19:16:32,10
|
|
||||||
2019-01-02 19:16:37,10
|
|
||||||
2019-01-02 19:16:42,10
|
|
||||||
2019-01-02 19:16:47,10
|
|
||||||
2019-01-02 19:16:52,10
|
|
||||||
2019-01-02 19:16:57,10
|
|
||||||
2019-01-02 19:17:02,10
|
|
||||||
2019-01-02 19:17:07,10
|
|
||||||
2019-01-02 19:17:12,10
|
|
||||||
2019-01-02 19:17:17,10
|
|
||||||
2019-01-02 19:17:22,10
|
|
||||||
2019-01-02 19:17:27,10
|
|
||||||
2019-01-02 19:17:32,10
|
|
||||||
2019-01-02 19:17:37,10
|
|
||||||
2019-01-02 19:17:42,10
|
|
||||||
2019-01-02 19:17:47,10
|
|
||||||
2019-01-02 19:17:52,10
|
|
||||||
2019-01-02 19:17:57,10
|
|
||||||
2019-01-02 19:18:02,10
|
|
||||||
2019-01-02 19:18:07,10
|
|
||||||
2019-01-02 19:18:12,10
|
|
||||||
2019-01-02 19:18:17,10
|
|
||||||
2019-01-02 19:18:22,10
|
|
||||||
2019-01-02 19:18:27,10
|
|
||||||
2019-01-02 19:18:32,10
|
|
||||||
2019-01-02 19:18:37,10
|
|
||||||
2019-01-02 19:18:42,10
|
|
||||||
2019-01-02 19:18:47,10
|
|
||||||
2019-01-02 19:18:52,10
|
|
||||||
2019-01-02 19:18:57,10
|
|
||||||
2019-01-02 19:19:02,10
|
|
||||||
2019-01-02 19:19:07,10
|
|
||||||
2019-01-02 19:19:12,10
|
|
||||||
2019-01-02 19:19:17,10
|
|
||||||
2019-01-02 19:19:22,10
|
|
||||||
2019-01-02 19:19:27,10
|
|
||||||
2019-01-02 19:19:32,10
|
|
||||||
2019-01-02 19:19:37,10
|
|
||||||
2019-01-02 19:19:42,10
|
|
||||||
2019-01-02 19:19:47,10
|
|
||||||
2019-01-02 19:19:52,10
|
|
||||||
2019-01-02 19:19:57,10
|
|
||||||
2019-01-02 19:20:02,10
|
|
||||||
2019-01-02 19:20:07,10
|
|
||||||
2019-01-02 19:20:12,10
|
|
||||||
2019-01-02 19:20:17,10
|
|
||||||
2019-01-02 19:20:22,10
|
|
||||||
2019-01-02 19:20:27,10
|
|
||||||
2019-01-02 19:20:32,10
|
|
||||||
2019-01-02 19:20:37,10
|
|
||||||
2019-01-02 19:20:42,10
|
|
||||||
2019-01-02 19:20:47,10
|
|
||||||
2019-01-02 19:20:52,10
|
|
||||||
2019-01-02 19:20:57,10
|
|
||||||
2019-01-02 19:21:02,10
|
|
||||||
2019-01-02 19:21:07,10
|
|
||||||
2019-01-02 19:21:12,10
|
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 19:02:41,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 19:02:46,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 19:02:51,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 19:02:56,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 19:03:01,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 19:03:06,10
|
|
||||||
2019-01-02 19:03:11,10
|
|
||||||
2019-01-02 19:03:16,10
|
|
||||||
2019-01-02 19:03:21,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:03:33,10
|
|
||||||
2019-01-02 19:08:33,10
|
|
||||||
2019-01-02 19:08:38,10
|
|
||||||
2019-01-02 19:08:43,10
|
|
||||||
2019-01-02 19:08:48,10
|
|
||||||
2019-01-02 19:08:53,10
|
|
||||||
2019-01-02 19:08:58,10
|
|
||||||
2019-01-02 19:09:03,10
|
|
||||||
2019-01-02 19:09:08,10
|
|
||||||
2019-01-02 19:09:16,10
|
|
||||||
2019-01-02 19:09:21,10
|
|
||||||
2019-01-02 19:09:26,10
|
|
||||||
2019-01-02 19:09:31,10
|
|
||||||
2019-01-02 19:09:36,10
|
|
||||||
2019-01-02 19:09:41,10
|
|
||||||
2019-01-02 19:09:46,10
|
|
||||||
2019-01-02 19:09:51,10
|
|
||||||
2019-01-02 19:09:56,10
|
|
||||||
2019-01-02 19:10:01,10
|
|
||||||
2019-01-02 19:10:06,10
|
|
||||||
2019-01-02 19:10:11,10
|
|
||||||
2019-01-02 19:10:16,10
|
|
||||||
2019-01-02 19:10:21,10
|
|
||||||
2019-01-02 19:10:26,10
|
|
||||||
2019-01-02 19:10:31,10
|
|
||||||
2019-01-02 19:10:36,10
|
|
||||||
2019-01-02 19:10:41,10
|
|
||||||
2019-01-02 19:10:46,10
|
|
||||||
2019-01-02 19:10:51,10
|
|
||||||
2019-01-02 19:10:56,10
|
|
||||||
2019-01-02 19:11:01,10
|
|
||||||
2019-01-02 19:11:06,10
|
|
||||||
2019-01-02 19:11:11,10
|
|
||||||
2019-01-02 19:11:16,10
|
|
||||||
2019-01-02 19:11:21,10
|
|
||||||
2019-01-02 19:11:26,10
|
|
||||||
2019-01-02 19:11:31,10
|
|
||||||
2019-01-02 19:11:36,10
|
|
||||||
2019-01-02 19:11:41,10
|
|
||||||
2019-01-02 19:11:46,10
|
|
||||||
2019-01-02 19:11:51,10
|
|
||||||
2019-01-02 19:11:56,10
|
|
||||||
2019-01-02 19:12:01,10
|
|
||||||
2019-01-02 19:12:06,10
|
|
||||||
2019-01-02 19:12:11,10
|
|
||||||
2019-01-02 19:12:16,10
|
|
||||||
2019-01-02 19:12:21,10
|
|
||||||
2019-01-02 19:12:26,10
|
|
||||||
2019-01-02 19:12:31,10
|
|
||||||
2019-01-02 19:12:36,10
|
|
||||||
2019-01-02 19:12:41,10
|
|
||||||
2019-01-02 19:12:46,10
|
|
||||||
2019-01-02 19:12:51,10
|
|
||||||
2019-01-02 19:12:56,10
|
|
||||||
2019-01-02 19:13:01,10
|
|
||||||
2019-01-02 19:13:06,10
|
|
||||||
2019-01-02 19:13:11,10
|
|
||||||
2019-01-02 19:13:16,10
|
|
||||||
2019-01-02 19:13:21,10
|
|
||||||
2019-01-02 19:13:26,10
|
|
||||||
2019-01-02 19:13:31,10
|
|
||||||
2019-01-02 19:13:36,10
|
|
||||||
2019-01-02 19:13:41,10
|
|
||||||
2019-01-02 19:13:46,10
|
|
||||||
2019-01-02 19:13:51,10
|
|
||||||
2019-01-02 19:13:56,10
|
|
||||||
2019-01-02 19:14:01,10
|
|
||||||
|
|
|
@ -1,86 +1,5 @@
|
||||||
2019-01-02 18:51:48,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 18:51:58,10
|
|
||||||
2019-01-02 18:52:03,10
|
|
||||||
2019-01-02 18:52:08,10
|
|
||||||
2019-01-02 18:52:13,10
|
|
||||||
2019-01-02 18:52:18,10
|
|
||||||
2019-01-02 18:52:23,10
|
|
||||||
2019-01-02 18:52:28,10
|
|
||||||
2019-01-02 18:52:33,10
|
|
||||||
2019-01-02 18:52:38,10
|
|
||||||
2019-01-02 18:52:43,10
|
|
||||||
2019-01-02 18:52:48,10
|
|
||||||
2019-01-02 18:52:53,10
|
|
||||||
2019-01-02 18:52:58,10
|
|
||||||
2019-01-02 18:53:03,10
|
|
||||||
2019-01-02 18:53:08,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:13,10
|
|
||||||
2019-01-02 18:53:22,10
|
|
||||||
2019-01-02 18:53:27,10
|
|
||||||
2019-01-02 18:53:32,10
|
|
||||||
2019-01-02 18:53:37,10
|
|
||||||
2019-01-02 18:53:42,10
|
|
||||||
2019-01-02 18:53:47,10
|
|
||||||
2019-01-02 18:53:52,10
|
|
||||||
2019-01-02 18:53:57,10
|
|
||||||
2019-01-02 18:54:02,10
|
|
||||||
2019-01-02 18:54:07,10
|
|
||||||
2019-01-02 18:54:12,10
|
|
||||||
2019-01-02 18:54:17,10
|
|
||||||
2019-01-02 18:54:22,10
|
|
||||||
2019-01-02 18:54:27,10
|
|
||||||
2019-01-02 18:54:32,10
|
|
||||||
2019-01-02 18:54:37,10
|
|
||||||
2019-01-02 18:54:42,10
|
|
||||||
2019-01-02 18:54:47,10
|
|
||||||
2019-01-02 18:54:52,10
|
|
||||||
2019-01-02 18:54:57,10
|
|
||||||
2019-01-02 18:55:02,10
|
|
||||||
2019-01-02 18:55:07,10
|
|
||||||
2019-01-02 18:55:12,10
|
|
||||||
2019-01-02 18:55:17,10
|
|
||||||
2019-01-02 18:55:22,10
|
|
||||||
2019-01-02 18:55:27,10
|
|
||||||
2019-01-02 18:55:32,10
|
|
||||||
2019-01-02 18:55:37,10
|
|
||||||
2019-01-02 18:55:42,10
|
|
||||||
2019-01-02 18:55:47,10
|
|
||||||
2019-01-02 18:55:52,10
|
|
||||||
2019-01-02 18:55:57,10
|
|
||||||
2019-01-02 18:56:02,10
|
|
||||||
2019-01-02 18:56:07,10
|
|
||||||
2019-01-02 18:56:12,10
|
|
||||||
2019-01-02 18:56:17,10
|
|
||||||
2019-01-02 18:56:22,10
|
|
||||||
2019-01-02 18:56:27,10
|
|
||||||
2019-01-02 18:56:32,10
|
|
||||||
2019-01-02 18:56:37,10
|
|
||||||
2019-01-02 18:56:42,10
|
|
||||||
2019-01-02 18:56:47,10
|
|
||||||
2019-01-02 18:56:52,10
|
|
||||||
2019-01-02 18:56:57,10
|
|
||||||
2019-01-02 18:57:02,10
|
|
||||||
2019-01-02 18:57:07,10
|
|
||||||
2019-01-02 18:57:12,10
|
|
||||||
2019-01-02 18:57:17,10
|
|
||||||
2019-01-02 18:57:22,10
|
|
||||||
2019-01-02 18:57:27,10
|
|
||||||
2019-01-02 18:57:32,10
|
|
||||||
2019-01-02 18:57:37,10
|
|
||||||
2019-01-02 19:02:31,10
|
|
||||||
2019-01-02 19:02:36,10
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
2019-01-02 18:51:43,10
|
2019-01-04 00:19:10,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:15,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:20,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:25,10
|
||||||
2019-01-02 18:51:53,10
|
2019-01-04 00:19:30,10
|
||||||
2019-01-02 18:51:53,10
|
|
||||||
2019-01-02 18:51:53,10
|
|
||||||
2019-01-02 18:51:53,10
|
|
||||||
2019-01-02 18:51:53,10
|
|
||||||
|
|
BIN
tests/craftbeerpi.db
Normal file
BIN
tests/craftbeerpi.db
Normal file
Binary file not shown.
|
@ -1,4 +1,5 @@
|
||||||
import aiohttp
|
from unittest import mock
|
||||||
|
|
||||||
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
||||||
|
|
||||||
from core.craftbeerpi import CraftBeerPi
|
from core.craftbeerpi import CraftBeerPi
|
||||||
|
@ -6,14 +7,21 @@ from core.craftbeerpi import CraftBeerPi
|
||||||
|
|
||||||
class ActorTestCase(AioHTTPTestCase):
|
class ActorTestCase(AioHTTPTestCase):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_application(self):
|
async def get_application(self):
|
||||||
self.cbpi = CraftBeerPi()
|
self.cbpi = CraftBeerPi()
|
||||||
await self.cbpi.init_serivces()
|
await self.cbpi.init_serivces()
|
||||||
return self.cbpi.app
|
return self.cbpi.app
|
||||||
|
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_actor_mock(self):
|
||||||
|
with mock.patch.object(self.cbpi.bus, 'fire', wraps=self.cbpi.bus.fire) as mock_obj:
|
||||||
|
# Send HTTP POST
|
||||||
|
resp = await self.client.request("POST", "/actor/1/on")
|
||||||
|
# Check Result
|
||||||
|
assert resp.status == 204
|
||||||
|
# Check if Event are fired
|
||||||
|
assert mock_obj.call_count == 2
|
||||||
|
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_actor_switch(self):
|
async def test_actor_switch(self):
|
||||||
|
@ -92,3 +100,8 @@ class ActorTestCase(AioHTTPTestCase):
|
||||||
# Update not existing actor
|
# Update not existing actor
|
||||||
resp = await self.client.put(path="/actor/%s" % 9999, json=data)
|
resp = await self.client.put(path="/actor/%s" % 9999, json=data)
|
||||||
assert resp.status == 500
|
assert resp.status == 500
|
||||||
|
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_actor_action(self):
|
||||||
|
resp = await self.client.post(path="/actor/1/action", json=dict(name="myAction", parameter=dict(name="Manuel")))
|
||||||
|
assert resp.status == 204
|
||||||
|
|
49
tests/test_gpio.py
Normal file
49
tests/test_gpio.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
try:
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
except Exception:
|
||||||
|
print("Error importing RPi.GPIO!")
|
||||||
|
MockRPi = MagicMock()
|
||||||
|
modules = {
|
||||||
|
"RPi": MockRPi,
|
||||||
|
"RPi.GPIO": MockRPi.GPIO
|
||||||
|
}
|
||||||
|
patcher = patch.dict("sys.modules", modules)
|
||||||
|
patcher.start()
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
|
|
||||||
|
class HelloWorld(object):
|
||||||
|
|
||||||
|
def test(self, a):
|
||||||
|
return a
|
||||||
|
|
||||||
|
|
||||||
|
class TestSwitch(unittest.TestCase):
|
||||||
|
|
||||||
|
GPIO_NUM = 22
|
||||||
|
|
||||||
|
@patch("RPi.GPIO.setup")
|
||||||
|
def test_switch_inits_gpio(self, patched_setup):
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
GPIO.setup(self.GPIO_NUM, GPIO.OUT)
|
||||||
|
patched_setup.assert_called_once_with(self.GPIO_NUM, GPIO.OUT)
|
||||||
|
|
||||||
|
@patch("RPi.GPIO.output")
|
||||||
|
def test_switch_without_scheduler_starts_disabled(self, patched_output):
|
||||||
|
GPIO.output(self.GPIO_NUM, GPIO.LOW)
|
||||||
|
patched_output.assert_called_once_with(self.GPIO_NUM, GPIO.LOW)
|
||||||
|
|
||||||
|
|
||||||
|
def test_hello_world(self):
|
||||||
|
h = HelloWorld()
|
||||||
|
with mock.patch.object(HelloWorld, 'test', wraps=h.test) as fake_increment:
|
||||||
|
#print(h.test("HALLO"))
|
||||||
|
print(h.test("ABC"))
|
||||||
|
print(fake_increment.call_args)
|
||||||
|
print(h.test("HALLO"))
|
||||||
|
print(fake_increment.call_args_list)
|
||||||
|
|
|
@ -18,6 +18,12 @@ class IndexTestCase(AioHTTPTestCase):
|
||||||
resp = await self.client.get(path="/")
|
resp = await self.client.get(path="/")
|
||||||
assert resp.status == 200
|
assert resp.status == 200
|
||||||
|
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_404(self):
|
||||||
|
# Test Index Page
|
||||||
|
resp = await self.client.get(path="/abc")
|
||||||
|
assert resp.status == 200
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_wrong_login(self):
|
async def test_wrong_login(self):
|
||||||
resp = await self.client.post(path="/login", data={"username": "beer", "password": "123"})
|
resp = await self.client.post(path="/login", data={"username": "beer", "password": "123"})
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
||||||
from core.craftbeerpi import CraftBeerPi
|
from core.craftbeerpi import CraftBeerPi
|
||||||
|
|
||||||
|
@ -51,20 +53,46 @@ class StepTestCase(AioHTTPTestCase):
|
||||||
resp = await self.client.delete(path="/step/%s" % sensor_id)
|
resp = await self.client.delete(path="/step/%s" % sensor_id)
|
||||||
assert resp.status == 204
|
assert resp.status == 204
|
||||||
|
|
||||||
|
def create_wait_callback(self, topic):
|
||||||
|
future = self.cbpi.app.loop.create_future()
|
||||||
|
|
||||||
|
async def test(**kwargs):
|
||||||
|
print("GOON")
|
||||||
|
future.set_result("OK")
|
||||||
|
self.cbpi.bus.register(topic, test, once=True)
|
||||||
|
return future
|
||||||
|
|
||||||
|
async def wait(self, future):
|
||||||
|
done, pending = await asyncio.wait({future})
|
||||||
|
|
||||||
|
if future in done:
|
||||||
|
pass
|
||||||
|
|
||||||
@unittest_run_loop
|
@unittest_run_loop
|
||||||
async def test_process(self):
|
async def test_process(self):
|
||||||
resp = await self.client.request("GET", "/step/stop")
|
await self.cbpi.step.stop()
|
||||||
assert resp.status == 204
|
|
||||||
|
|
||||||
resp = await self.client.request("GET", "/step/start")
|
with mock.patch.object(self.cbpi.step, 'start', wraps=self.cbpi.step.start) as mock_obj:
|
||||||
assert resp.status == 204
|
|
||||||
|
|
||||||
resp = await self.client.request("GET", "/step/next")
|
future = self.create_wait_callback("step/+/started")
|
||||||
assert resp.status == 204
|
await self.cbpi.step.start()
|
||||||
|
await self.wait(future)
|
||||||
|
|
||||||
resp = await self.client.request("GET", "/step/stop")
|
future = self.create_wait_callback("step/+/started")
|
||||||
assert resp.status == 204
|
await self.cbpi.step.next()
|
||||||
|
await self.wait(future)
|
||||||
|
|
||||||
|
future = self.create_wait_callback("step/+/started")
|
||||||
|
await self.cbpi.step.next()
|
||||||
|
await self.wait(future)
|
||||||
|
|
||||||
|
future = self.create_wait_callback("step/+/started")
|
||||||
|
await self.cbpi.step.next()
|
||||||
|
await self.wait(future)
|
||||||
|
|
||||||
|
future = self.create_wait_callback("job/step/done")
|
||||||
|
await self.cbpi.step.stop()
|
||||||
|
await self.wait(future)
|
||||||
|
print("COUNT", mock_obj.call_count)
|
||||||
|
print("ARGS", mock_obj.call_args_list)
|
||||||
|
|
||||||
|
|
56
tests/test_ws.py
Normal file
56
tests/test_ws.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
||||||
|
|
||||||
|
from core.craftbeerpi import CraftBeerPi
|
||||||
|
|
||||||
|
|
||||||
|
class WebSocketTestCase(AioHTTPTestCase):
|
||||||
|
|
||||||
|
async def get_application(self):
|
||||||
|
self.cbpi = CraftBeerPi()
|
||||||
|
await self.cbpi.init_serivces()
|
||||||
|
return self.cbpi.app
|
||||||
|
|
||||||
|
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_brewing_process(self):
|
||||||
|
|
||||||
|
count_step_done = 0
|
||||||
|
async with self.client.ws_connect('/ws') as ws:
|
||||||
|
await ws.send_json(data=dict(topic="step/stop"))
|
||||||
|
await ws.send_json(data=dict(topic="step/start"))
|
||||||
|
async for msg in ws:
|
||||||
|
if msg.type == aiohttp.WSMsgType.TEXT:
|
||||||
|
try:
|
||||||
|
msg_obj = msg.json()
|
||||||
|
topic = msg_obj.get("topic")
|
||||||
|
if topic == "job/step/done":
|
||||||
|
count_step_done = count_step_done + 1
|
||||||
|
if topic == "step/brewing/finished":
|
||||||
|
await ws.send_json(data=dict(topic="close"))
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
break
|
||||||
|
elif msg.type == aiohttp.WSMsgType.ERROR:
|
||||||
|
break
|
||||||
|
|
||||||
|
assert count_step_done == 4
|
||||||
|
|
||||||
|
@unittest_run_loop
|
||||||
|
async def test_wrong_format(self):
|
||||||
|
|
||||||
|
async with self.client.ws_connect('/ws') as ws:
|
||||||
|
await ws.send_json(data=dict(a="close"))
|
||||||
|
async for msg in ws:
|
||||||
|
print("MSG TYP", msg.type, msg.data)
|
||||||
|
if msg.type == aiohttp.WSMsgType.TEXT:
|
||||||
|
msg_obj = msg.json()
|
||||||
|
if msg_obj["topic"] != "connection/success":
|
||||||
|
print(msg.data)
|
||||||
|
raise Exception()
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception()
|
||||||
|
|
Loading…
Reference in a new issue