wiki:uid

Version 1 (modified by Frédéric, 9 years ago) ( diff )

--

Table of Contents

  1. Introduction
  2. Features
  3. Example

uid device

Introduction

One of my main motivations to write 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 retreive the config, and build the GUI automatically. So, all you need to create/modify your client, is edit your device, and relaunch it.

Example

First create a pKNyX device as described in the Tutorial.

Then, edit you device 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  # basic
from widgets.toggle import Toggle  # basic
from widgets.sunblind import Sunblind  # complex
from widgets.display import DisplayNumber, DisplayMessage  # basic
from widgets.heating import Heating  # complex
from widgets.slider import Slider  # basic
# TODO: split in basicWidgets (and add more options to set them up) and complexWidgets


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"),
                        #conf("vmc_auto_manu", group="")
                        #conf("vmc_vitesse", group="")
                        #conf("vmc_bypass", group="")
                    ]
                },

                {
                    "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")
                               #conf("vmc_auto_manu", group="VMC")
                               #conf("vmc_vitesse", group="VMC")
                               #conf("vmc_bypass", 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
Note: See TracWiki for help on using the wiki.