Changes between Initial Version and Version 1 of uid


Ignore:
Timestamp:
Feb 18, 2016, 2:21:50 PM (9 years ago)
Author:
Frédéric
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • uid

    v1 v1  
     1[[PageOutline(2-5, Table of Contents, floated)]]
     2
     3= uid device =
     4
     5== Introduction ==
     6
     7One of my main motivations to write pKNyX framework was to develop my own client/server, smartphone-oriented, application.
     8
     9This device is the server part.
     10
     11== Features ==
     12
     13All 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.
     14
     15== Example ==
     16
     17First create a pKNyX device as described in the [[Tutorial]].
     18
     19Then, edit you device as following:
     20
     21{{{
     22#!python
     23# -*- coding: utf-8 -*-
     24
     25import time
     26
     27import bottle
     28
     29from pknyx.api import Device
     30from pknyx.api import logger
     31
     32import settings
     33from widgets.button import Button, Button2  # basic
     34from widgets.toggle import Toggle  # basic
     35from widgets.sunblind import Sunblind  # complex
     36from widgets.display import DisplayNumber, DisplayMessage  # basic
     37from widgets.heating import Heating  # complex
     38from widgets.slider import Slider  # basic
     39# TODO: split in basicWidgets (and add more options to set them up) and complexWidgets
     40
     41
     42class Server(Device):
     43    FB_001 = dict(cls=Button, name="lumiere_maison", params={"options": {"label": "O", "icon": "Oxygen/22/actions/edit-delete.png", "value": 0}, "label": "Tout"},)
     44    FB_002 = dict(cls=Button, name="lumiere_rdc", params={"options": {"label": "O", "value": 0}, "label": "Rdc"})
     45    FB_003 = dict(cls=Button, name="lumiere_etage", params={"options": {"label": "O", "value": 0}, "label": "Étage"})
     46    FB_004 = dict(cls=Toggle, name="lumiere_entree", params={"room": "Entrée", "label": "Appliques & spots"})
     47    FB_005 = dict(cls=Toggle, name="lumiere_sdb", params={"room": "Sdb", "label": "Appliques & spots"})
     48    FB_006 = dict(cls=Toggle, name="lumiere_cuisine", params={"room": "Cuisine", "label": "Appliques & spots"})
     49    FB_007 = dict(cls=Toggle, name="lumiere_sejour", params={"room": "Séjour", "label": "Appliques & suspension"})
     50    FB_008 = dict(cls=Toggle, name="lumiere_salon", params={"room": "Salon", "label": "Appliques"})
     51    FB_009 = dict(cls=Toggle, name="lumiere_ch_1", params={"room": "Chambre 1", "label": "Appliques & spots"})
     52    FB_010 = dict(cls=Toggle, name="lumiere_ch_2", params={"room": "Chambre 2", "label": "Appliques & spots"})
     53
     54    FB_100 = dict(cls=Sunblind, name="bso_maison", params={"label": "Tout"})
     55    FB_101 = dict(cls=Sunblind, name="bso_rdc", params={"label": "Rdc"})
     56    FB_102 = dict(cls=Sunblind, name="bso_etage", params={"label": "Étage"})
     57    FB_103 = dict(cls=Sunblind, name="bso_nord", params={"label": "Nord"})
     58    FB_104 = dict(cls=Sunblind, name="bso_sud", params={"label": "Sud"})
     59    FB_105 = dict(cls=Sunblind, name="bso_est", params={"label": "Est"})
     60    FB_106 = dict(cls=Sunblind, name="bso_ouest", params={"label": "Ouest"})
     61    FB_107 = dict(cls=Sunblind, name="bso_cuisine", params={"room": "Cuisine", "label": "Sud"})
     62    FB_108 = dict(cls=Sunblind, name="bso_sejour", params={"room": "Séjour", "label": "Tout"})
     63    FB_109 = dict(cls=Sunblind, name="bso_sejour_baie", params={"room": "Séjour", "label": "Baie"})
     64    FB_110 = dict(cls=Sunblind, name="bso_sejour_ouest", params={"room": "Séjour", "label": "Ouest"})
     65    FB_111 = dict(cls=Sunblind, name="bso_salon", params={"room": "Salon", "label": "Tout"})
     66    FB_112 = dict(cls=Sunblind, name="bso_salon_sud", params={"room": "Salon", "label": "Sud"})
     67    FB_113 = dict(cls=Sunblind, name="bso_salon_ouest", params={"room": "Salon", "label": "Ouest"})
     68    FB_114 = dict(cls=Sunblind, name="bso_ch_1", params={"room": "Chambre 1", "label": "Ouest"})
     69    FB_115 = dict(cls=Sunblind, name="bso_ch_2", params={"room": "Chambre 2", "label": "Sud"})
     70
     71    FB_200 = dict(cls=DisplayNumber, name="temperature_sdb", params={"room": "Sdb", "label": "Inter", "options": {"postfix": " °C"}})
     72    FB_201 = dict(cls=DisplayNumber, name="temperature_cuisine", params={"room": "Cuisine", "label": "Inter", "options": {"postfix": " °C"}})
     73    FB_202 = dict(cls=DisplayNumber, name="temperature_sejour", params={"room": "Séjour", "label": "Inter", "options": {"postfix": " °C"}})
     74    FB_203 = dict(cls=DisplayNumber, name="temperature_salon", params={"room": "Salon", "label": "Inter", "options": {"postfix": " °C"}})
     75    FB_204 = dict(cls=DisplayNumber, name="temperature_ch_1", params={"room": "Chambre 1", "label": "Inter", "options": {"postfix": " °C"}})
     76    FB_205 = dict(cls=DisplayNumber, name="temperature_ch_2", params={"room": "Chambre 2", "label": "Inter", "options": {"postfix": " °C"}})
     77    FB_206 = dict(cls=DisplayNumber, name="temperature_vmc_air_ext", params={"room": "Local technique", "label": "air extérieur", "options": {"postfix": " °C"}})
     78    FB_207 = dict(cls=DisplayNumber, name="temperature_vmc_air_insuffle", params={"room": "Local technique", "label": "air insufflé", "options": {"postfix": " °C"}})
     79    FB_208 = dict(cls=DisplayNumber, name="temperature_vmc_air_extrait", params={"room": "Local technique", "label": "air extrait", "options": {"postfix": " °C"}})
     80    FB_209 = dict(cls=DisplayNumber, name="temperature_vmc_air_rejete", params={"room": "Local technique", "label": "air rejeté", "options": {"postfix": " °C"}})
     81    FB_210 = dict(cls=DisplayNumber, name="temperature_meteo_air_ext", params={"room": "Extérieur", "label": "air extérieur", "options": {"postfix": " °C"}})
     82    FB_211 = dict(cls=DisplayNumber, name="temperature_meteo_air_int", params={"room": "Global", "label": "air intérieur", "options": {"postfix": " °C"}})
     83
     84    FB_300 = dict(cls=Heating, name="chauffage_sdb_rdc", params={"room": "Sdb", "label": "Consigne"})
     85    FB_301 = dict(cls=Heating, name="chauffage_sejour", params={"room": "Séjour", "label": "Consigne"})
     86    FB_302 = dict(cls=Heating, name="chauffage_etage", params={"room": "Étage", "label": "Consigne"})
     87
     88    LNK_6_0_0 = dict(fb="lumiere_entree", dp="command", gad="6/0/0")
     89    LNK_6_1_0 = dict(fb="lumiere_entree", dp="state", gad="6/1/0")
     90    LNK_6_0_2 = dict(fb="lumiere_sdb_rdc", dp="command", gad="6/0/2")
     91    LNK_6_1_2 = dict(fb="lumiere_sdb_rdc", dp="state", gad="6/1/2")
     92    LNK_6_0_5 = dict(fb="lumiere_cuisine", dp="command", gad="6/0/5")
     93    LNK_6_1_5 = dict(fb="lumiere_cuisine", dp="state", gad="6/1/5")
     94    LNK_6_0_7 = dict(fb="lumiere_sejour", dp="command", gad="6/0/7")
     95    LNK_6_1_7 = dict(fb="lumiere_sejour", dp="state", gad="6/1/7")
     96    LNK_6_0_9 = dict(fb="lumiere_salon", dp="command", gad="6/0/9")
     97    LNK_6_1_9 = dict(fb="lumiere_salon", dp="state", gad="6/1/9")
     98    LNK_6_0_51 = dict(fb="lumiere_ch_1", dp="command", gad="6/0/51")
     99    LNK_6_1_51 = dict(fb="lumiere_ch_1", dp="state", gad="6/1/51")
     100    LNK_6_0_52 = dict(fb="lumiere_ch_2", dp="command", gad="6/0/52")
     101    LNK_6_1_52 = dict(fb="lumiere_ch_2", dp="state", gad="6/1/52")
     102    LNK_6_0_4 = dict(fb="lumiere_rdc", dp="command", gad="6/0/4")
     103    LNK_6_0_54 = dict(fb="lumiere_etage", dp="command", gad="6/0/54")
     104
     105    LNK_9_1_30 = dict(fb="bso_cuisine", dp="louvre_step", gad="9/1/30")
     106    LNK_9_3_30 = dict(fb="bso_cuisine", dp="louvre_moveto", gad="9/3/30")
     107    LNK_9_0_30 = dict(fb="bso_cuisine", dp="blind_updown", gad="9/0/30")
     108    LNK_9_1_50 = dict(fb="bso_sejour_baie", dp="louvre_step", gad="9/1/50")
     109    LNK_9_3_50 = dict(fb="bso_sejour_baie", dp="louvre_moveto", gad="9/3/50")
     110    LNK_9_0_50 = dict(fb="bso_sejour_baie", dp="blind_updown", gad="9/0/50")
     111    LNK_9_1_52 = dict(fb="bso_sejour_ouest", dp="louvre_step", gad="9/1/52")
     112    LNK_9_3_52 = dict(fb="bso_sejour_ouest", dp="louvre_moveto", gad="9/3/52")
     113    LNK_9_0_52 = dict(fb="bso_sejour_ouest", dp="blind_updown", gad="9/0/52")
     114    LNK_9_1_59 = dict(fb="bso_sejour", dp="louvre_step", gad="9/1/59")
     115    LNK_9_3_59 = dict(fb="bso_sejour", dp="louvre_moveto", gad="9/3/59")
     116    LNK_9_0_59 = dict(fb="bso_sejour", dp="blind_updown", gad="9/0/59")
     117    LNK_9_1_60 = dict(fb="bso_salon_sud", dp="louvre_step", gad="9/1/60")
     118    LNK_9_3_60 = dict(fb="bso_salon_sud", dp="louvre_moveto", gad="9/3/60")
     119    LNK_9_0_60 = dict(fb="bso_salon_sud", dp="blind_updown", gad="9/0/60")
     120    LNK_9_1_61 = dict(fb="bso_salon_ouest", dp="louvre_step", gad="9/1/61")
     121    LNK_9_3_61 = dict(fb="bso_salon_ouest", dp="louvre_moveto", gad="9/3/61")
     122    LNK_9_0_61 = dict(fb="bso_salon_ouest", dp="blind_updown", gad="9/0/61")
     123    LNK_9_1_79 = dict(fb="bso_salon", dp="louvre_step", gad="9/1/79")
     124    LNK_9_3_79 = dict(fb="bso_salon", dp="louvre_moveto", gad="9/3/79")
     125    LNK_9_0_79 = dict(fb="bso_salon", dp="blind_updown", gad="9/0/79")
     126    LNK_9_1_150 = dict(fb="bso_ch_1", dp="louvre_step", gad="9/1/150")
     127    LNK_9_3_150 = dict(fb="bso_ch_1", dp="louvre_moveto", gad="9/3/150")
     128    LNK_9_0_150 = dict(fb="bso_ch_1", dp="blind_updown", gad="9/0/150")
     129    LNK_9_1_160 = dict(fb="bso_ch_2", dp="louvre_step", gad="9/1/160")
     130    LNK_9_3_160 = dict(fb="bso_ch_2", dp="louvre_moveto", gad="9/3/160")
     131    LNK_9_0_160 = dict(fb="bso_ch_2", dp="blind_updown", gad="9/0/160")
     132    LNK_9_1_240 = dict(fb="bso_maison", dp="louvre_step", gad="9/1/240")
     133    LNK_9_3_240 = dict(fb="bso_maison", dp="louvre_moveto", gad="9/3/240")
     134    LNK_9_0_240 = dict(fb="bso_maison", dp="blind_updown", gad="9/0/240")
     135    LNK_9_1_241 = dict(fb="bso_rdc", dp="louvre_step", gad="9/1/241")
     136    LNK_9_3_241 = dict(fb="bso_rdc", dp="louvre_moveto", gad="9/3/241")
     137    LNK_9_0_241 = dict(fb="bso_rdc", dp="blind_updown", gad="9/0/241")
     138    LNK_9_1_242 = dict(fb="bso_etage", dp="louvre_step", gad="9/1/242")
     139    LNK_9_3_242 = dict(fb="bso_etage", dp="louvre_moveto", gad="9/3/242")
     140    LNK_9_0_242 = dict(fb="bso_etage", dp="blind_updown", gad="9/0/242")
     141    LNK_9_1_243 = dict(fb="bso_nord", dp="louvre_step", gad="9/1/243")
     142    LNK_9_3_243 = dict(fb="bso_nord", dp="louvre_moveto", gad="9/3/243")
     143    LNK_9_0_243 = dict(fb="bso_nord", dp="blind_updown", gad="9/0/243")
     144    LNK_9_1_244 = dict(fb="bso_sud", dp="louvre_step", gad="9/1/244")
     145    LNK_9_3_244 = dict(fb="bso_sud", dp="louvre_moveto", gad="9/3/244")
     146    LNK_9_0_244 = dict(fb="bso_sud", dp="blind_updown", gad="9/0/244")
     147    LNK_9_1_245 = dict(fb="bso_est", dp="louvre_step", gad="9/1/245")
     148    LNK_9_3_245 = dict(fb="bso_est", dp="louvre_moveto", gad="9/3/245")
     149    LNK_9_0_245 = dict(fb="bso_est", dp="blind_updown", gad="9/0/245")
     150    LNK_9_1_246 = dict(fb="bso_ouest", dp="louvre_step", gad="9/1/246")
     151    LNK_9_3_246 = dict(fb="bso_ouest", dp="louvre_moveto", gad="9/3/246")
     152    LNK_9_0_246 = dict(fb="bso_ouest", dp="blind_updown", gad="9/0/246")
     153
     154    LNK_2_0_1 = dict(fb="temperature_sdb", dp="value", gad="2/0/1")
     155    LNK_2_0_5 = dict(fb="temperature_cuisine", dp="value", gad="2/0/5")
     156    LNK_2_0_7 = dict(fb="temperature_sejour", dp="value", gad="2/0/7")
     157    LNK_2_0_4 = dict(fb="temperature_salon", dp="value", gad="2/0/4")
     158    LNK_2_0_52 = dict(fb="temperature_ch_1", dp="value", gad="2/0/52")
     159    LNK_2_0_53 = dict(fb="temperature_ch_2", dp="value", gad="2/0/53")
     160
     161    LNK_3_0_2 = dict(fb="chauffage_sdb", dp="setpoint", gad="3/0/2")
     162    LNK_3_2_2 = dict(fb="chauffage_sdb", dp="state", gad="3/2/2")
     163    LNK_3_0_7 = dict(fb="chauffage_sejour", dp="setpoint", gad="3/0/7")
     164    LNK_3_2_7 = dict(fb="chauffage_sejour", dp="state", gad="3/2/7")
     165    LNK_3_0_50 = dict(fb="chauffage_etage", dp="setpoint", gad="3/0/50")
     166    LNK_3_2_50 = dict(fb="chauffage_etage", dp="state", gad="3/2/50")
     167
     168    LNK_5_0_0 = dict(fb="temperature_vmc_air_ext", dp="value", gad="5/0/0")
     169    LNK_5_0_1 = dict(fb="temperature_vmc_air_insuffle", dp="value", gad="5/0/1")
     170    LNK_5_0_2 = dict(fb="temperature_vmc_air_extrait", dp="value", gad="5/0/3")
     171    LNK_5_0_3 = dict(fb="temperature_vmc_air_rejete", dp="value", gad="5/0/2")
     172
     173    DESC = "Server"
     174
     175    def init(self):
     176        logger.trace("Server.init()")
     177
     178        self.createConfig()
     179        self.initWebServer()
     180
     181    def createConfig(self):
     182        """
     183        """
     184        def conf(fb, *args, **kwargs):
     185            """ Helper
     186            """
     187            return self.fb[fb].getConfig(*args, **kwargs)
     188
     189        self._config = {
     190            "pages": [
     191                {
     192                    "title": "Global", "subtitle": "Fonctions globales", "path": "global",
     193                    "widgets": [
     194                        conf("lumiere_maison", group="Éclairages"),
     195                        conf("lumiere_rdc", group="Éclairages"),
     196                        conf("lumiere_etage", group="Éclairages"),
     197
     198                        conf("bso_maison", group="Brise-soleil"),
     199                        conf("bso_rdc", group="Brise-soleil"),
     200                        conf("bso_etage", group="Brise-soleil"),
     201                        conf("bso_nord", group="Brise-soleil"),
     202                        conf("bso_sud", group="Brise-soleil"),
     203                        conf("bso_est", group="Brise-soleil"),
     204                        conf("bso_ouest", group="Brise-soleil"),
     205                    ]
     206                },
     207
     208                {
     209                    "title": "Éclairages", "subtitle": "Gestion des lumières", "path": "lights",
     210                    "widgets": [
     211                        conf("lumiere_entree"),
     212                        conf("lumiere_sdb"),
     213                        conf("lumiere_cuisine"),
     214                        conf("lumiere_sejour"),
     215                        conf("lumiere_salon"),
     216                        conf("lumiere_ch_1"),
     217                        conf("lumiere_ch_2"),
     218                        conf("lumiere_maison", group="Global"),
     219                        conf("lumiere_rdc", group="Global"),
     220                        conf("lumiere_etage", group="Global"),
     221                    ]
     222                },
     223
     224                {
     225                    "title": "Brise soleil", "subtitle": "Gestion des BSO", "path": "sunblinds",
     226                    "widgets": [
     227                        conf("bso_cuisine"),
     228                        conf("bso_sejour"),
     229                        conf("bso_sejour_baie"),
     230                        conf("bso_sejour_ouest"),
     231                        conf("bso_salon"),
     232                        conf("bso_salon_sud"),
     233                        conf("bso_salon_ouest"),
     234                        conf("bso_ch_1"),
     235                        conf("bso_ch_2"),
     236                        conf("bso_maison", group="Global"),
     237                        conf("bso_rdc", group="Global"),
     238                        conf("bso_etage", group="Global"),
     239                        conf("bso_nord", group="Orientation"),
     240                        conf("bso_sud", group="Orientation"),
     241                        conf("bso_est", group="Orientation"),
     242                        conf("bso_ouest", group="Orientation"),
     243                    ]
     244                },
     245
     246                {
     247                    "title": "Chauffage", "subtitle": "Gestion du chauffage", "path": "heating",
     248                    "widgets": [
     249                        conf("temperature_sdb", label="Température"),
     250                        conf("chauffage_sdb"),
     251                        conf("temperature_sejour", group="Séjour", label="Température"),
     252                        conf("chauffage_sejour", group="Séjour"),
     253                        conf("temperature_ch_1", group="Dégagement", label="Température"),
     254                        conf("chauffage_etage", group="Dégagement")
     255                    ]
     256                },
     257
     258                {
     259                    "title": "Températures", "subtitle": "Sondes de température", "path": "temperatures",
     260                    "widgets": [
     261                        conf("temperature_sdb"),
     262                        conf("temperature_cuisine"),
     263                        conf("temperature_sejour"),
     264                        conf("temperature_salon"),
     265                        conf("temperature_ch_1"),
     266                        conf("temperature_ch_2"),
     267                        conf("temperature_vmc_air_ext", group="VMC"),
     268                        conf("temperature_vmc_air_insuffle", group="VMC"),
     269                        conf("temperature_vmc_air_extrait", group="VMC"),
     270                        conf("temperature_vmc_air_rejete", group="VMC"),
     271                    ]
     272                },
     273
     274                {
     275                    "title": "Ventilation", "subtitle": "Gestion VMC", "path": "vmc",
     276                    "widgets": [
     277                        conf("temperature_vmc_air_ext", group="Sondes de température"),
     278                        conf("temperature_vmc_air_insuffle", group="Sondes de température"),
     279                        conf("temperature_vmc_air_extrait", group="Sondes de température"),
     280                        conf("temperature_vmc_air_rejete", group="Sondes de température"),
     281                        #conf("vmc_auto_manu", group="")
     282                        #conf("vmc_vitesse", group="")
     283                        #conf("vmc_bypass", group="")
     284                    ]
     285                },
     286
     287                {
     288                    "title": "Pièces", "subtitle": "Fonctions par pièce", "path": "rooms",
     289                    "pages": [
     290                        {
     291                            "title": "Entrée", "subtitle": "", "path": "entree",
     292                            "widgets": [
     293                                conf("lumiere_entree", group="Éclairages"),
     294                                conf("temperature_entree", group="Sondes de température"),
     295                            ]
     296                        },
     297                        {
     298                            "title": "Sdb", "subtitle": "", "path": "sdb",
     299                            "widgets": [
     300                                conf("lumiere_sdb", group="Éclairages"),
     301                                conf("temperature_sdb", group="Chauffage", label="Température"),
     302                                conf("chauffage_sdb", group="Chauffage"),
     303                            ]
     304                        },
     305                        {
     306                            "title": "Cuisine", "subtitle": "", "path": "cuisine",
     307                            "widgets": [
     308                                conf("lumiere_cuisine", group="Éclairages"),
     309                                conf("bso_cuisine", group="Brise-soleil"),
     310                                conf("temperature_cuisine", group="Sondes de température"),
     311                            ]
     312                        },
     313                        {
     314                            "title": "Séjour", "subtitle": "", "path": "sejour",
     315                            "widgets": [
     316                                conf("lumiere_sejour", group="Éclairages"),
     317                                conf("bso_sejour", group="Brise-soleil", label="Tout"),
     318                                conf("bso_sejour_baie", group="Brise-soleil"),
     319                                conf("bso_sejour_ouest", group="Brise-soleil"),
     320                                conf("chauffage_sejour", group="Chauffage"),
     321                            ]
     322                        },
     323                        {
     324                            "title": "Salon", "subtitle": "", "path": "salon",
     325                            "widgets": [
     326                                conf("lumiere_salon", group="Éclairages"),
     327                                conf("bso_salon", group="Brise-soleil", label="Tout"),
     328                                conf("bso_salon_sud", group="Brise-soleil"),
     329                                conf("bso_salon_ouest", group="Brise-soleil"),
     330                                conf("temperature_salon", group="Sondes de température"),
     331                            ]
     332                        },
     333                        {
     334                            "title": "Chambre 1", "subtitle": "", "path": "ch_1",
     335                            "widgets": [
     336                                conf("lumiere_ch_1", group="Éclairages"),
     337                                conf("bso_ch_1", group="Brise-soleil"),
     338                                conf("temperature_ch_1", group="Sondes de température"),
     339                            ]
     340                        },
     341                        {
     342                            "title": "Chambre 2", "subtitle": "", "path": "ch_2",
     343                            "widgets": [
     344                                conf("lumiere_ch_2", group="Éclairages"),
     345                                conf("bso_ch_2", group="Brise-soleil"),
     346                                conf("temperature_ch_2", group="Sondes de température"),
     347                            ]
     348                        },
     349                        {
     350                           "title": "Local technique", "subtitle": "", "path": "technique",
     351                           "widgets": [
     352                               conf("temperature_vmc_air_ext", group="VMC"),
     353                               conf("temperature_vmc_air_insuffle", group="VMC"),
     354                               conf("temperature_vmc_air_extrait", group="VMC"),
     355                               conf("temperature_vmc_air_rejete", group="VMC")
     356                               #conf("vmc_auto_manu", group="VMC")
     357                               #conf("vmc_vitesse", group="VMC")
     358                               #conf("vmc_bypass", group="VMC")
     359                           ]
     360                        },
     361                        {
     362                            "title": "Maison", "subtitle": "", "path": "maison",
     363                            "widgets": [
     364                                conf("lumiere_maison", group="Éclairage", label="Tout"),
     365                                conf("bso_maison", group="Brise-soleil", label="Tout"),
     366                            ]
     367                        },
     368                        {
     369                            "title": "Rdc", "subtitle": "", "path": "rdc",
     370                            "widgets": [
     371                                conf("lumiere_rdc", group="Éclairages", label="Tout"),
     372                                conf("bso_rdc", group="Brise-soleil", label="Tout"),
     373                            ]
     374                        },
     375                        {
     376                            "title": "Étage", "subtitle": "", "path": "etage",
     377                            "widgets": [
     378                                conf("lumiere_etage", group="Éclairages", label="Tout"),
     379                                conf("bso_etage", group="Brise-soleil", label="Tout"),
     380                            ]
     381                        },
     382                    ]
     383                }
     384            ]
     385        }
     386
     387    def initWebServer(self):
     388        """
     389        """
     390        self.app = bottle.Bottle()
     391
     392        loadConfigRoute = bottle.Route(app=self.app, rule='/config', method='GET', callback=self.loadConfig)
     393        self.app.add_route(loadConfigRoute)
     394
     395        readRoute = bottle.Route(app=self.app, rule="/eib/<ts:int>", method='GET', callback=self.read)
     396        self.app.add_route(readRoute)
     397
     398        writeRoute = bottle.Route(app=self.app, rule="/eib/<fb>/<dp>", method='PUT', callback=self.write)
     399        self.app.add_route(writeRoute)
     400
     401        pknyxuiStaticRoute = bottle.Route(app=self.app, rule="/pknyxui/<filename:path>", method='GET', callback=self.pknyxuiStatic)
     402        self.app.add_route(pknyxuiStaticRoute)
     403
     404        qooxdooStaticRoute = bottle.Route(app=self.app, rule="/qooxdoo-sdk/<filename:path>", method='GET', callback=self.qooxdooStatic)
     405        self.app.add_route(qooxdooStaticRoute)
     406
     407        self.app.error_handler[404] = self.error404
     408
     409    def mainLoop(self):
     410        logger.trace("Server.mainLoop()")
     411        self.app.run(server="paste", host=settings.WEB_SERVER, port=settings.WEB_PORT, reloader=False, debug=True)
     412
     413    def shutdown(self):
     414        logger.trace("Server.shutdown()")
     415        self.app.close()
     416
     417    def loadConfig(self):
     418        logger.trace("Server.loadConfig()")
     419        return self._config
     420
     421    def read(self, ts):
     422        logger.debug("Server.read(): last read ts=%d" % int(ts))
     423        eib = []
     424        while True:
     425            for fb in self.fb.values():
     426                result = fb.read(ts)
     427                if result:
     428                    eib.append(result)
     429            if ts == 0 or eib:
     430                break
     431            time.sleep(0.01)
     432        ts = int(time.time())
     433        logger.debug("Server.read(): eib=%s" % eib)
     434
     435        return dict(eib=eib, ts=ts)
     436
     437    def write(self, fb, dp):
     438        value = bottle.request.forms.get("value")
     439        logger.info("Server.write(): fb=%s, dp=%s, value=%s" % (fb, dp, value))
     440        self.fb[fb].write(dp, value)
     441
     442    def pknyxuiStatic(self, filename):
     443        return bottle.static_file(filename, root=settings.PKNYXUI_ROOT)
     444
     445    def qooxdooStatic(self, filename):
     446        return bottle.static_file(filename, root=settings.QOOXDOO_ROOT)
     447
     448    def error404(self, error):
     449        return "<h2>Tiens, je croyais que Chuck Norris avait retrouvé cette foutue page 404 !!!</h2>"
     450
     451
     452DEVICE = Server
     453}}}