Version 6 (modified by 9 years ago) ( diff ) | ,
---|
Table of Contents
uid device
Introduction
One of my main motivations to write the pKNyX framework was to develop my own client/server, smartphone-oriented, application.
This device is the server part.
Features
All the configuration is done in this device; when the client connects, it first retreives the config, and build the GUI automatically.
Example
First create a pKNyX device as described in the Tutorial.
Then, edit device.py
file as following:
# -*- coding: utf-8 -*- import time import bottle from pknyx.api import Device from pknyx.api import logger import settings from widgets.button import Button, Button2 from widgets.toggle import Toggle from widgets.sunblind import Sunblind from widgets.display import DisplayNumber, DisplayMessage from widgets.heating import Heating from widgets.slider import Slider class Server(Device): FB_001 = dict(cls=Button, name="lumiere_maison", params={"options": {"label": "O", "icon": "Oxygen/22/actions/edit-delete.png", "value": 0}, "label": "Tout"},) FB_002 = dict(cls=Button, name="lumiere_rdc", params={"options": {"label": "O", "value": 0}, "label": "Rdc"}) FB_003 = dict(cls=Button, name="lumiere_etage", params={"options": {"label": "O", "value": 0}, "label": "Étage"}) FB_004 = dict(cls=Toggle, name="lumiere_entree", params={"room": "Entrée", "label": "Appliques & spots"}) FB_005 = dict(cls=Toggle, name="lumiere_sdb", params={"room": "Sdb", "label": "Appliques & spots"}) FB_006 = dict(cls=Toggle, name="lumiere_cuisine", params={"room": "Cuisine", "label": "Appliques & spots"}) FB_007 = dict(cls=Toggle, name="lumiere_sejour", params={"room": "Séjour", "label": "Appliques & suspension"}) FB_008 = dict(cls=Toggle, name="lumiere_salon", params={"room": "Salon", "label": "Appliques"}) FB_009 = dict(cls=Toggle, name="lumiere_ch_1", params={"room": "Chambre 1", "label": "Appliques & spots"}) FB_010 = dict(cls=Toggle, name="lumiere_ch_2", params={"room": "Chambre 2", "label": "Appliques & spots"}) FB_100 = dict(cls=Sunblind, name="bso_maison", params={"label": "Tout"}) FB_101 = dict(cls=Sunblind, name="bso_rdc", params={"label": "Rdc"}) FB_102 = dict(cls=Sunblind, name="bso_etage", params={"label": "Étage"}) FB_103 = dict(cls=Sunblind, name="bso_nord", params={"label": "Nord"}) FB_104 = dict(cls=Sunblind, name="bso_sud", params={"label": "Sud"}) FB_105 = dict(cls=Sunblind, name="bso_est", params={"label": "Est"}) FB_106 = dict(cls=Sunblind, name="bso_ouest", params={"label": "Ouest"}) FB_107 = dict(cls=Sunblind, name="bso_cuisine", params={"room": "Cuisine", "label": "Sud"}) FB_108 = dict(cls=Sunblind, name="bso_sejour", params={"room": "Séjour", "label": "Tout"}) FB_109 = dict(cls=Sunblind, name="bso_sejour_baie", params={"room": "Séjour", "label": "Baie"}) FB_110 = dict(cls=Sunblind, name="bso_sejour_ouest", params={"room": "Séjour", "label": "Ouest"}) FB_111 = dict(cls=Sunblind, name="bso_salon", params={"room": "Salon", "label": "Tout"}) FB_112 = dict(cls=Sunblind, name="bso_salon_sud", params={"room": "Salon", "label": "Sud"}) FB_113 = dict(cls=Sunblind, name="bso_salon_ouest", params={"room": "Salon", "label": "Ouest"}) FB_114 = dict(cls=Sunblind, name="bso_ch_1", params={"room": "Chambre 1", "label": "Ouest"}) FB_115 = dict(cls=Sunblind, name="bso_ch_2", params={"room": "Chambre 2", "label": "Sud"}) FB_200 = dict(cls=DisplayNumber, name="temperature_sdb", params={"room": "Sdb", "label": "Inter", "options": {"postfix": " °C"}}) FB_201 = dict(cls=DisplayNumber, name="temperature_cuisine", params={"room": "Cuisine", "label": "Inter", "options": {"postfix": " °C"}}) FB_202 = dict(cls=DisplayNumber, name="temperature_sejour", params={"room": "Séjour", "label": "Inter", "options": {"postfix": " °C"}}) FB_203 = dict(cls=DisplayNumber, name="temperature_salon", params={"room": "Salon", "label": "Inter", "options": {"postfix": " °C"}}) FB_204 = dict(cls=DisplayNumber, name="temperature_ch_1", params={"room": "Chambre 1", "label": "Inter", "options": {"postfix": " °C"}}) FB_205 = dict(cls=DisplayNumber, name="temperature_ch_2", params={"room": "Chambre 2", "label": "Inter", "options": {"postfix": " °C"}}) FB_206 = dict(cls=DisplayNumber, name="temperature_vmc_air_ext", params={"room": "Local technique", "label": "air extérieur", "options": {"postfix": " °C"}}) FB_207 = dict(cls=DisplayNumber, name="temperature_vmc_air_insuffle", params={"room": "Local technique", "label": "air insufflé", "options": {"postfix": " °C"}}) FB_208 = dict(cls=DisplayNumber, name="temperature_vmc_air_extrait", params={"room": "Local technique", "label": "air extrait", "options": {"postfix": " °C"}}) FB_209 = dict(cls=DisplayNumber, name="temperature_vmc_air_rejete", params={"room": "Local technique", "label": "air rejeté", "options": {"postfix": " °C"}}) FB_210 = dict(cls=DisplayNumber, name="temperature_meteo_air_ext", params={"room": "Extérieur", "label": "air extérieur", "options": {"postfix": " °C"}}) FB_211 = dict(cls=DisplayNumber, name="temperature_meteo_air_int", params={"room": "Global", "label": "air intérieur", "options": {"postfix": " °C"}}) FB_300 = dict(cls=Heating, name="chauffage_sdb_rdc", params={"room": "Sdb", "label": "Consigne"}) FB_301 = dict(cls=Heating, name="chauffage_sejour", params={"room": "Séjour", "label": "Consigne"}) FB_302 = dict(cls=Heating, name="chauffage_etage", params={"room": "Étage", "label": "Consigne"}) LNK_6_0_0 = dict(fb="lumiere_entree", dp="command", gad="6/0/0") LNK_6_1_0 = dict(fb="lumiere_entree", dp="state", gad="6/1/0") LNK_6_0_2 = dict(fb="lumiere_sdb_rdc", dp="command", gad="6/0/2") LNK_6_1_2 = dict(fb="lumiere_sdb_rdc", dp="state", gad="6/1/2") LNK_6_0_5 = dict(fb="lumiere_cuisine", dp="command", gad="6/0/5") LNK_6_1_5 = dict(fb="lumiere_cuisine", dp="state", gad="6/1/5") LNK_6_0_7 = dict(fb="lumiere_sejour", dp="command", gad="6/0/7") LNK_6_1_7 = dict(fb="lumiere_sejour", dp="state", gad="6/1/7") LNK_6_0_9 = dict(fb="lumiere_salon", dp="command", gad="6/0/9") LNK_6_1_9 = dict(fb="lumiere_salon", dp="state", gad="6/1/9") LNK_6_0_51 = dict(fb="lumiere_ch_1", dp="command", gad="6/0/51") LNK_6_1_51 = dict(fb="lumiere_ch_1", dp="state", gad="6/1/51") LNK_6_0_52 = dict(fb="lumiere_ch_2", dp="command", gad="6/0/52") LNK_6_1_52 = dict(fb="lumiere_ch_2", dp="state", gad="6/1/52") LNK_6_0_4 = dict(fb="lumiere_rdc", dp="command", gad="6/0/4") LNK_6_0_54 = dict(fb="lumiere_etage", dp="command", gad="6/0/54") LNK_9_1_30 = dict(fb="bso_cuisine", dp="louvre_step", gad="9/1/30") LNK_9_3_30 = dict(fb="bso_cuisine", dp="louvre_moveto", gad="9/3/30") LNK_9_0_30 = dict(fb="bso_cuisine", dp="blind_updown", gad="9/0/30") LNK_9_1_50 = dict(fb="bso_sejour_baie", dp="louvre_step", gad="9/1/50") LNK_9_3_50 = dict(fb="bso_sejour_baie", dp="louvre_moveto", gad="9/3/50") LNK_9_0_50 = dict(fb="bso_sejour_baie", dp="blind_updown", gad="9/0/50") LNK_9_1_52 = dict(fb="bso_sejour_ouest", dp="louvre_step", gad="9/1/52") LNK_9_3_52 = dict(fb="bso_sejour_ouest", dp="louvre_moveto", gad="9/3/52") LNK_9_0_52 = dict(fb="bso_sejour_ouest", dp="blind_updown", gad="9/0/52") LNK_9_1_59 = dict(fb="bso_sejour", dp="louvre_step", gad="9/1/59") LNK_9_3_59 = dict(fb="bso_sejour", dp="louvre_moveto", gad="9/3/59") LNK_9_0_59 = dict(fb="bso_sejour", dp="blind_updown", gad="9/0/59") LNK_9_1_60 = dict(fb="bso_salon_sud", dp="louvre_step", gad="9/1/60") LNK_9_3_60 = dict(fb="bso_salon_sud", dp="louvre_moveto", gad="9/3/60") LNK_9_0_60 = dict(fb="bso_salon_sud", dp="blind_updown", gad="9/0/60") LNK_9_1_61 = dict(fb="bso_salon_ouest", dp="louvre_step", gad="9/1/61") LNK_9_3_61 = dict(fb="bso_salon_ouest", dp="louvre_moveto", gad="9/3/61") LNK_9_0_61 = dict(fb="bso_salon_ouest", dp="blind_updown", gad="9/0/61") LNK_9_1_79 = dict(fb="bso_salon", dp="louvre_step", gad="9/1/79") LNK_9_3_79 = dict(fb="bso_salon", dp="louvre_moveto", gad="9/3/79") LNK_9_0_79 = dict(fb="bso_salon", dp="blind_updown", gad="9/0/79") LNK_9_1_150 = dict(fb="bso_ch_1", dp="louvre_step", gad="9/1/150") LNK_9_3_150 = dict(fb="bso_ch_1", dp="louvre_moveto", gad="9/3/150") LNK_9_0_150 = dict(fb="bso_ch_1", dp="blind_updown", gad="9/0/150") LNK_9_1_160 = dict(fb="bso_ch_2", dp="louvre_step", gad="9/1/160") LNK_9_3_160 = dict(fb="bso_ch_2", dp="louvre_moveto", gad="9/3/160") LNK_9_0_160 = dict(fb="bso_ch_2", dp="blind_updown", gad="9/0/160") LNK_9_1_240 = dict(fb="bso_maison", dp="louvre_step", gad="9/1/240") LNK_9_3_240 = dict(fb="bso_maison", dp="louvre_moveto", gad="9/3/240") LNK_9_0_240 = dict(fb="bso_maison", dp="blind_updown", gad="9/0/240") LNK_9_1_241 = dict(fb="bso_rdc", dp="louvre_step", gad="9/1/241") LNK_9_3_241 = dict(fb="bso_rdc", dp="louvre_moveto", gad="9/3/241") LNK_9_0_241 = dict(fb="bso_rdc", dp="blind_updown", gad="9/0/241") LNK_9_1_242 = dict(fb="bso_etage", dp="louvre_step", gad="9/1/242") LNK_9_3_242 = dict(fb="bso_etage", dp="louvre_moveto", gad="9/3/242") LNK_9_0_242 = dict(fb="bso_etage", dp="blind_updown", gad="9/0/242") LNK_9_1_243 = dict(fb="bso_nord", dp="louvre_step", gad="9/1/243") LNK_9_3_243 = dict(fb="bso_nord", dp="louvre_moveto", gad="9/3/243") LNK_9_0_243 = dict(fb="bso_nord", dp="blind_updown", gad="9/0/243") LNK_9_1_244 = dict(fb="bso_sud", dp="louvre_step", gad="9/1/244") LNK_9_3_244 = dict(fb="bso_sud", dp="louvre_moveto", gad="9/3/244") LNK_9_0_244 = dict(fb="bso_sud", dp="blind_updown", gad="9/0/244") LNK_9_1_245 = dict(fb="bso_est", dp="louvre_step", gad="9/1/245") LNK_9_3_245 = dict(fb="bso_est", dp="louvre_moveto", gad="9/3/245") LNK_9_0_245 = dict(fb="bso_est", dp="blind_updown", gad="9/0/245") LNK_9_1_246 = dict(fb="bso_ouest", dp="louvre_step", gad="9/1/246") LNK_9_3_246 = dict(fb="bso_ouest", dp="louvre_moveto", gad="9/3/246") LNK_9_0_246 = dict(fb="bso_ouest", dp="blind_updown", gad="9/0/246") LNK_2_0_1 = dict(fb="temperature_sdb", dp="value", gad="2/0/1") LNK_2_0_5 = dict(fb="temperature_cuisine", dp="value", gad="2/0/5") LNK_2_0_7 = dict(fb="temperature_sejour", dp="value", gad="2/0/7") LNK_2_0_4 = dict(fb="temperature_salon", dp="value", gad="2/0/4") LNK_2_0_52 = dict(fb="temperature_ch_1", dp="value", gad="2/0/52") LNK_2_0_53 = dict(fb="temperature_ch_2", dp="value", gad="2/0/53") LNK_3_0_2 = dict(fb="chauffage_sdb", dp="setpoint", gad="3/0/2") LNK_3_2_2 = dict(fb="chauffage_sdb", dp="state", gad="3/2/2") LNK_3_0_7 = dict(fb="chauffage_sejour", dp="setpoint", gad="3/0/7") LNK_3_2_7 = dict(fb="chauffage_sejour", dp="state", gad="3/2/7") LNK_3_0_50 = dict(fb="chauffage_etage", dp="setpoint", gad="3/0/50") LNK_3_2_50 = dict(fb="chauffage_etage", dp="state", gad="3/2/50") LNK_5_0_0 = dict(fb="temperature_vmc_air_ext", dp="value", gad="5/0/0") LNK_5_0_1 = dict(fb="temperature_vmc_air_insuffle", dp="value", gad="5/0/1") LNK_5_0_2 = dict(fb="temperature_vmc_air_extrait", dp="value", gad="5/0/3") LNK_5_0_3 = dict(fb="temperature_vmc_air_rejete", dp="value", gad="5/0/2") DESC = "Server" def init(self): logger.trace("Server.init()") self.createConfig() self.initWebServer() def createConfig(self): """ """ def conf(fb, *args, **kwargs): """ Helper """ return self.fb[fb].getConfig(*args, **kwargs) self._config = { "pages": [ { "title": "Global", "subtitle": "Fonctions globales", "path": "global", "widgets": [ conf("lumiere_maison", group="Éclairages"), conf("lumiere_rdc", group="Éclairages"), conf("lumiere_etage", group="Éclairages"), conf("bso_maison", group="Brise-soleil"), conf("bso_rdc", group="Brise-soleil"), conf("bso_etage", group="Brise-soleil"), conf("bso_nord", group="Brise-soleil"), conf("bso_sud", group="Brise-soleil"), conf("bso_est", group="Brise-soleil"), conf("bso_ouest", group="Brise-soleil"), ] }, { "title": "Éclairages", "subtitle": "Gestion des lumières", "path": "lights", "widgets": [ conf("lumiere_entree"), conf("lumiere_sdb"), conf("lumiere_cuisine"), conf("lumiere_sejour"), conf("lumiere_salon"), conf("lumiere_ch_1"), conf("lumiere_ch_2"), conf("lumiere_maison", group="Global"), conf("lumiere_rdc", group="Global"), conf("lumiere_etage", group="Global"), ] }, { "title": "Brise soleil", "subtitle": "Gestion des BSO", "path": "sunblinds", "widgets": [ conf("bso_cuisine"), conf("bso_sejour"), conf("bso_sejour_baie"), conf("bso_sejour_ouest"), conf("bso_salon"), conf("bso_salon_sud"), conf("bso_salon_ouest"), conf("bso_ch_1"), conf("bso_ch_2"), conf("bso_maison", group="Global"), conf("bso_rdc", group="Global"), conf("bso_etage", group="Global"), conf("bso_nord", group="Orientation"), conf("bso_sud", group="Orientation"), conf("bso_est", group="Orientation"), conf("bso_ouest", group="Orientation"), ] }, { "title": "Chauffage", "subtitle": "Gestion du chauffage", "path": "heating", "widgets": [ conf("temperature_sdb", label="Température"), conf("chauffage_sdb"), conf("temperature_sejour", group="Séjour", label="Température"), conf("chauffage_sejour", group="Séjour"), conf("temperature_ch_1", group="Dégagement", label="Température"), conf("chauffage_etage", group="Dégagement") ] }, { "title": "Températures", "subtitle": "Sondes de température", "path": "temperatures", "widgets": [ conf("temperature_sdb"), conf("temperature_cuisine"), conf("temperature_sejour"), conf("temperature_salon"), conf("temperature_ch_1"), conf("temperature_ch_2"), conf("temperature_vmc_air_ext", group="VMC"), conf("temperature_vmc_air_insuffle", group="VMC"), conf("temperature_vmc_air_extrait", group="VMC"), conf("temperature_vmc_air_rejete", group="VMC"), ] }, { "title": "Ventilation", "subtitle": "Gestion VMC", "path": "vmc", "widgets": [ conf("temperature_vmc_air_ext", group="Sondes de température"), conf("temperature_vmc_air_insuffle", group="Sondes de température"), conf("temperature_vmc_air_extrait", group="Sondes de température"), conf("temperature_vmc_air_rejete", group="Sondes de température"), ] }, { "title": "Pièces", "subtitle": "Fonctions par pièce", "path": "rooms", "pages": [ { "title": "Entrée", "subtitle": "", "path": "entree", "widgets": [ conf("lumiere_entree", group="Éclairages"), conf("temperature_entree", group="Sondes de température"), ] }, { "title": "Sdb", "subtitle": "", "path": "sdb", "widgets": [ conf("lumiere_sdb", group="Éclairages"), conf("temperature_sdb", group="Chauffage", label="Température"), conf("chauffage_sdb", group="Chauffage"), ] }, { "title": "Cuisine", "subtitle": "", "path": "cuisine", "widgets": [ conf("lumiere_cuisine", group="Éclairages"), conf("bso_cuisine", group="Brise-soleil"), conf("temperature_cuisine", group="Sondes de température"), ] }, { "title": "Séjour", "subtitle": "", "path": "sejour", "widgets": [ conf("lumiere_sejour", group="Éclairages"), conf("bso_sejour", group="Brise-soleil", label="Tout"), conf("bso_sejour_baie", group="Brise-soleil"), conf("bso_sejour_ouest", group="Brise-soleil"), conf("chauffage_sejour", group="Chauffage"), ] }, { "title": "Salon", "subtitle": "", "path": "salon", "widgets": [ conf("lumiere_salon", group="Éclairages"), conf("bso_salon", group="Brise-soleil", label="Tout"), conf("bso_salon_sud", group="Brise-soleil"), conf("bso_salon_ouest", group="Brise-soleil"), conf("temperature_salon", group="Sondes de température"), ] }, { "title": "Chambre 1", "subtitle": "", "path": "ch_1", "widgets": [ conf("lumiere_ch_1", group="Éclairages"), conf("bso_ch_1", group="Brise-soleil"), conf("temperature_ch_1", group="Sondes de température"), ] }, { "title": "Chambre 2", "subtitle": "", "path": "ch_2", "widgets": [ conf("lumiere_ch_2", group="Éclairages"), conf("bso_ch_2", group="Brise-soleil"), conf("temperature_ch_2", group="Sondes de température"), ] }, { "title": "Local technique", "subtitle": "", "path": "technique", "widgets": [ conf("temperature_vmc_air_ext", group="VMC"), conf("temperature_vmc_air_insuffle", group="VMC"), conf("temperature_vmc_air_extrait", group="VMC"), conf("temperature_vmc_air_rejete", group="VMC") ] }, { "title": "Maison", "subtitle": "", "path": "maison", "widgets": [ conf("lumiere_maison", group="Éclairage", label="Tout"), conf("bso_maison", group="Brise-soleil", label="Tout"), ] }, { "title": "Rdc", "subtitle": "", "path": "rdc", "widgets": [ conf("lumiere_rdc", group="Éclairages", label="Tout"), conf("bso_rdc", group="Brise-soleil", label="Tout"), ] }, { "title": "Étage", "subtitle": "", "path": "etage", "widgets": [ conf("lumiere_etage", group="Éclairages", label="Tout"), conf("bso_etage", group="Brise-soleil", label="Tout"), ] }, ] } ] } def initWebServer(self): """ """ self.app = bottle.Bottle() loadConfigRoute = bottle.Route(app=self.app, rule='/config', method='GET', callback=self.loadConfig) self.app.add_route(loadConfigRoute) readRoute = bottle.Route(app=self.app, rule="/eib/<ts:int>", method='GET', callback=self.read) self.app.add_route(readRoute) writeRoute = bottle.Route(app=self.app, rule="/eib/<fb>/<dp>", method='PUT', callback=self.write) self.app.add_route(writeRoute) pknyxuiStaticRoute = bottle.Route(app=self.app, rule="/pknyxui/<filename:path>", method='GET', callback=self.pknyxuiStatic) self.app.add_route(pknyxuiStaticRoute) qooxdooStaticRoute = bottle.Route(app=self.app, rule="/qooxdoo-sdk/<filename:path>", method='GET', callback=self.qooxdooStatic) self.app.add_route(qooxdooStaticRoute) self.app.error_handler[404] = self.error404 def mainLoop(self): logger.trace("Server.mainLoop()") self.app.run(server="paste", host=settings.WEB_SERVER, port=settings.WEB_PORT, reloader=False, debug=True) def shutdown(self): logger.trace("Server.shutdown()") self.app.close() def loadConfig(self): logger.trace("Server.loadConfig()") return self._config def read(self, ts): logger.debug("Server.read(): last read ts=%d" % int(ts)) eib = [] while True: for fb in self.fb.values(): result = fb.read(ts) if result: eib.append(result) if ts == 0 or eib: break time.sleep(0.01) ts = int(time.time()) logger.debug("Server.read(): eib=%s" % eib) return dict(eib=eib, ts=ts) def write(self, fb, dp): value = bottle.request.forms.get("value") logger.info("Server.write(): fb=%s, dp=%s, value=%s" % (fb, dp, value)) self.fb[fb].write(dp, value) def pknyxuiStatic(self, filename): return bottle.static_file(filename, root=settings.PKNYXUI_ROOT) def qooxdooStatic(self, filename): return bottle.static_file(filename, root=settings.QOOXDOO_ROOT) def error404(self, error): return "<h2>Tiens, je croyais que Chuck Norris avait retrouvé cette foutue page 404 !!!</h2>" DEVICE = Server
Next, settings.py
:
# -*- coding: utf-8 -*- from pknyx.common import config DEVICE_NAME = "uid" DEVICE_IND_ADDR = "1.1.2" DEVICE_VERSION = "0.1" # Override default logger level config.LOGGER_LEVEL = "info" WEB_SERVER = "my_machine" WEB_PORT = 8081 PKNYXUI_ROOT = "/home/toto/pKNyXui" QOOXDOO_ROOT = "/home/toto/qooxdoo-sdk"
PKNYXUI_ROOT
and QOOXDOO_ROOT
must match your pKNyXui and qooxdoo installation paths. TODO: add link to pKNyXui
Note:
See TracWiki
for help on using the wiki.