Intégration alarme Somfy sur eedomus

Discussion sur la box eedomus

Intégration alarme Somfy sur eedomus

Messagepar slider » 13 Jan 2013 14:21

Bonjour,

N'ayant rien trouvé du coté de Somfy pour s'interfacer avec le monde extérieur, j'ai écrit un petit bout de python qui se connecte à l'interface web de l'alarme pour récupérer son état. Ainsi, je peux l'envoyer à l'eedomus pour gérer des choses.

Par exemple, quand l'alarme se met en route, les volets descendent.

Je tiens à préciser que c'est une solution de secours, ce n'est clairement pas viable. L'idée du script est de se connecter toute les minutes sur l'alarme. Pensez à utiliser une crontab.

Quand est-ce que Somfy proposera un mode push !!!!!!!!!

Code : Tout sélectionner
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
import mechanize

class SomfyException(Exception):
    def __init__(self, value):
        Exception.__init__(self, value)
        self.value = value

    def __str__(self):
        return repr(self.value)

class Somfy:
    def __init__(self, config):
        self.config = config
        self.browser = mechanize.Browser()

    def __enter__(self):
        self.login()
        return self

    def __exit__(self, type, value, traceback):
        self.logout()

    def login(self):
        login_response = self.browser.open(self.config.get('somfy', 'url') + "/m_login.htm")
        login_html = login_response.read()

        login_soup = self._beautiful_it_and_check_error(login_html)
        authentication_code = login_soup.find('form').find('table').findAll('tr')[5].findAll('b')[0].find(text=True)

        self.browser.select_form(nr=0)
        self.browser["password"] = self.config.get('somfy', 'password')
        self.browser["key"] = self.config.get('somfy', 'key_%s' % authentication_code)

        self.browser.submit()

    def logout(self):
        self.browser.open(self.config.get('somfy', 'url') + "/m_logout.htm")

    def set_zone_a(self):
        self.browser.open(self.config.get('somfy', 'url') + "/mu_pilotage.htm")
        self.browser.select_form(nr = 0)
        self.browser.submit()

    def set_zone_b(self):
        self.browser.open(self.config.get('somfy', 'url') + "/mu_pilotage.htm")
        self.browser.select_form(nr = 1)
        self.browser.submit()

    def set_zone_c(self):
        self.browser.open(self.config.get('somfy', 'url') + "/mu_pilotage.htm")
        self.browser.select_form(nr = 2)
        self.browser.submit()

    def set_all_zone(self):
        self.browser.open(self.config.get('somfy', 'url') + "/mu_pilotage.htm")
        self.browser.select_form(nr =3)
        self.browser.submit()

    def unset_all_zone(self):
        self.browser.open(self.config.get('somfy', 'url') + "/mu_pilotage.htm")
        self.browser.select_form(nr =4)
        self.browser.submit()

    def get_state(self):
        state_response = self.browser.open(self.config.get('somfy', 'url') + "/mu_etat.htm")
        state_html = state_response.read()

        state_soup = self._beautiful_it_and_check_error(state_html)
        result = self.get_general_state(state_soup.findAll('table')[0])
        result.update(self.get_zone_state(state_soup.findAll('table')[0]))

        return result

    def get_zone_state(self, state_soup):
        zone_state = state_soup.findAll('table')[2].findAll('tr')

        def get_zone_a():
            return { "zone_a" : zone_state[0].find(text=True) }

        def get_zone_b():
            return { "zone_b" : zone_state[1].find(text=True) }

        def get_zone_c():
            return { "zone_c" : zone_state[2].find(text=True) }

        result = get_zone_a()
        result.update(get_zone_b())
        result.update(get_zone_c())

        return result

    def get_general_state(self, state_soup):
        general_state = state_soup.findAll('table')[1].findAll('tr')

        def get_battery_state():
            return { "battery" : general_state[0].find(text=True) }

        def get_communication_state():
            return { "communication" : general_state[1].find(text=True) }

        def get_door_state():
            return { u"door" : general_state[2].find(text=True) }

        def get_alarm_state():
            return { "alarm" : general_state[4].find(text=True) }

        def get_material_state():
            return { "material" : general_state[6].find(text=True) }

        result = get_battery_state()
        result.update(get_communication_state())
        result.update(get_door_state())
        result.update(get_alarm_state())
        result.update(get_material_state())

        return result

    def _beautiful_it_and_check_error(self, html):
        soup = BeautifulSoup(''.join(html))
        self._check_error(soup)
        return soup

    def _check_error(self, soup):
        if soup.find("div", {"class": "error"}):
            error_code = soup.find('div').findAll('b')[0].find(text=True)
            if '(0x0904)' == error_code:
                raise SomfyException("Nombre d'essais maximum atteint")
            if '(0x1100)' == error_code:
                raise SomfyException("Code errone")
            if '(0x0902)' == error_code:
                raise SomfyException("Session deja ouverte")
            if '(0x0812)' == error_code:
                raise SomfyException("Mauvais login/password")
            if '(0x0903)' == error_code:
                raise SomfyException("Droit d'acces insuffisant")
slider
 
Messages : 48
Inscription : 10 Jan 2012

Re: Intégration alarme somfy sur eedomus

Messagepar slider » 24 Jan 2013 14:23

Bonjour,

Je pensais que beaucoup de personnes avaient se problème... apparemment non.
Pour autant, je continue à publier mes avancés.

La dernière technique avec le script python était loin d'être satisfaisante. Je cherche donc une solution plus pérenne. J'ai découvert que l'alarme répondait à l'url http(s)://ip-de-l'alrame/status.xml

Dedans, il y a ce dont nous avons besoin. Problème de taille, il faut être connecté pour y accéder !

Je cherche donc un moyen de pouvoir taper dessus via l'eedomus sans me loguer !
slider
 
Messages : 48
Inscription : 10 Jan 2012


Retour vers Box eedomus

Qui est en ligne ?

Utilisateurs parcourant ce forum : Google [Bot] et 21 invité(s)