Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Веб-интерфейс для кофеварки на Ajenti через HTCPCP

Anna | 15.06.2014 | нет комментариев

Надоело бегать за кофе и жать кнопки на кофеварке? Сделай к ней веб-интерфейс!


Каждый код из статьи доступен на Github.

Подготовка

Скачаем Ajenti c PyPI и распакуем.
Устанавливаем зависимости:

sudo pip install -Ur requirements.txt

Помимо того, потребуется поддерживающая HTCPCP кофеварка, а если ее у вас нет — дозволено воспользоваться простым эмулятором, тот, что поддерживает добавление молока и шоколада!

HTCPCP-заказчик

Сотворим в ajenti/plugins папку htcpcp, а в ней — конструкцию файлов для плагина:

ajenti/plugins/htcpcp
dict>
make run

Сейчас, перейдя в раздел Configure > Plugins, мы видим наш плагин и можем настроить URL.

Интерфейс

Давайте сотворим несколько прекрасных кнопочек!

htcpcp/layout/main.xml:

    <hc>
        <button id="brew" icon="arrow-right" text="Brew" />
        <button id="retrieve" icon="coffee" text="Retrieve" />
        <button id="refresh" icon="refresh" text="Refresh" />
    </hc>

htcpcp/main.py:

from ajenti.api import *
from ajenti.plugins.main.api import SectionPlugin
from ajenti.ui import on
from ajenti.ui.binder import Binder

from client import HTCPCPClient

@plugin
class CoffeePlugin (SectionPlugin):
    """
    A HTCPCP capable coffeepot control plugin
    """

    def init(self):
        self.title = 'Coffeepot'
        self.icon = 'coffee'
        self.category = _('System')
        self.append(self.ui.inflate('htcpcp:main'))  # htcpcp/layout/main.xml
        self.pot = HTCPCPClient.get()

    def on_page_load(self):
        try:
            self.pot.check_connectivity()
        except Exception, e:
            self.context.notify('error', 'Could not access the coffee pot: %s!' % str(e))
            self.context.launch('configure-plugin', plugin=self.pot) # попросим плагин Configure показать окно настроек

    @on('brew', 'click')
    def on_brew(self):
        resp = self.pot.brew()
        if resp.status_code == 200:
            self.context.notify('info', 'Brewing')
        else:
            self.context.notify('error', resp.text)

    @on('refresh', 'click')
    def on_refresh(self):
        # обновим список кофейных добавок
        self.pot.refresh()

    @on('retrieve', 'click')
    def on_retrieve(self):
        resp = self.pot.retrieve()
        if resp.status_code == 200:
            self.context.notify('info', resp.text)
        else:
            self.context.notify('error', resp.text)

Сейчас дозволено жать кнопочки и варить кофе :)

Отображаем данные

Осталось только сделать отображение поддерживаемых кофейных добавок и их выбор. Для этого комфортнее каждого применять связывание данных с UI напрямую, применяя класс Binder.

Добавим в main.xml элементы для отображения списка чекбоксов для добавок:

<vc>
    <body>
        <pad id="pot-root"> <!-- id для стремительного нахождения -->
            <bind:collection bind="additions"> <!-- объединяем список объектов CoffeeAdditions из HTCPCPClient.additions -->
                <vc bind="__items"> <!-- элементы будут помещаться в данный контейнер <vc> -->
                    <label style="bold" text="Available additions:" />
                </vc>
                <bind:template> <!-- образец элемента -->
                    <checkbox bind:value="selected" bind:text="name" /> <!-- объединяем value чекбокса с addition.selected, а text - c addition.name -->
                </bind:template>
            </bind:collection>
        </pad>
    </body>

    <hc>
        <button id="brew" icon="arrow-right" text="Brew" />
        <button id="retrieve" icon="coffee" text="Retrieve" />
        <button id="refresh" icon="refresh" text="Refresh" />
    </hc>
</vc>

А в main.py используем Binder, Дабы наполнить интерфейс данными, а после этого обновить состояние добавок (выбрана либо нет, исходя из состояния чекбоксов):

from ajenti.api import *
from ajenti.plugins.main.api import SectionPlugin
from ajenti.ui import on
from ajenti.ui.binder import Binder

from client import HTCPCPClient

@plugin
class CoffeePlugin (SectionPlugin):
    """
    A HTCPCP capable coffeepot control plugin
    """

    def init(self):
        self.title = 'Coffeepot'
        self.icon = 'coffee'
        self.category = _('System')

        self.append(self.ui.inflate('htcpcp:main'))

        self.pot = HTCPCPClient.get()

        # настраиваем binder для нашего интерфейса (объединяем HTCPCPClient self.pot и элемент с id=pot-root)
        self.binder = Binder(self.pot, self.find('pot-root'))

    def on_page_load(self):
        try:
            self.pot.check_connectivity()
        except Exception, e:
            self.context.notify('error', 'Could not access the coffee pot: %s!' % str(e))
            self.context.launch('configure-plugin', plugin=self.pot)
            return 

        if not self.pot.additions:
            # Если добавки еще не получены, получаем их
            self.pot.refresh()
            # Помещаем данные в UI
            self.binder.populate()

    @on('brew', 'click')
    def on_brew(self):
        # Обновляем данные из UI
        self.binder.update()
        resp = self.pot.brew()
        if resp.status_code == 200:
            self.context.notify('info', 'Brewing')
        else:
            self.context.notify('error', resp.text)

    @on('refresh', 'click')
    def on_refresh(self):
        self.pot.refresh()
        # Помещаем данные в UI
        self.binder.populate()

    @on('retrieve', 'click')
    def on_retrieve(self):
        resp = self.pot.retrieve()
        if resp.status_code == 200:
            self.context.notify('info', resp.text)
        else:
            self.context.notify('error', resp.text)

Готово :)

Напоминаю, что код из статьи доступен на Github, а также не забывайте читать документацию и подглядывать в примеры.

 

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB