UPnP : le climatiseur

Un petit descriptif des trames qui passent sur le réseau pour le climatiseur.

Lorsque l’on démarre le climatiseur, on observe tout un tas de requête TCP, parmi lesquelles on a quelques requêtes HTTP de cette forme :

GET /service/power/description.xml HTTP/1.1
User-Agent: Java/1.8.0_31
Host:
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

Le climatiseur à l’air de vouloir mettre à jour ses fichiers de configuration en essayant de télécharger une nouvelle version sur le port 80 de la machine. Ce qui bien sur se solde par un échec :

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /service/power/description.xml was not found on this server.</p>
<hr>
<address>Apache/2.4.10 (Ubuntu) Server at  Port 80</address>
</body></html>

Lorsque l’on démarre la télécommande, elle récupère les informations générales sur le climatiseur via une requête HTTP.

GET /description.xml HTTP/1.1
User-Agent: Java/1.8.0_31
Host: 172.22.206.80:4004
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

Le climatiseur répond avec un fichier xml décrivant l’appareil et donnant la liste des services fournis.
Ici, on a 2 services aux adresses suivantes : /service/power/description.xml et /service/temp/description.xml.

<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
    <specVersion>
        <major>1</major>
        <minor>0</minor>
    </specVersion>
    <URLBase>http://172.22.206.80:4004</URLBase>
    <device>
        <deviceType>urn:schemas-upnp-org:device:aircon:1</deviceType>
        <friendlyName>CyberGarage AirCon Device</friendlyName>
        <manufacturer>CyberGarage</manufacturer>
        <manufacturerURL>http://www.cybergarage.org</manufacturerURL>
        <modelDescription>CyberUPnP AirCon Device</modelDescription>
        <modelName>AirCon</modelName>
        <modelNumber>1.0</modelNumber>
        <modelURL>http://www.cybergarage.org</modelURL>
        <serialNumber>1234567890</serialNumber>
        <UDN>uuid:cybergarageAirConDevice</UDN>
        <UPC>123456789012</UPC>
        <iconList>
            <icon>
                <mimetype>image/gif</mimetype>
                <width>48</width>
                <height>32</height>
                <depth>8</depth>
                <url>icon.gif</url>
            </icon>
        </iconList>
        <serviceList>
            <service>
                <serviceType>urn:schemas-upnp-org:service:power:1</serviceType>
                <serviceId>urn:schemas-upnp-org:serviceId:power:1</serviceId>
                <SCPDURL>/service/power/description.xml</SCPDURL>
                <controlURL>/service/power/control</controlURL>
                <eventSubURL>/service/power/eventSub</eventSubURL>
            </service>
            <service>
                <serviceType>urn:schemas-upnp-org:service:temp:1</serviceType>
                <serviceId>urn:schemas-upnp-org:serviceId:temp:1</serviceId>
                <SCPDURL>/service/temp/description.xml</SCPDURL>
                <controlURL>/service/temp/control</controlURL>
                <eventSubURL>/service/temp/eventSub</eventSubURL>
            </service>
        </serviceList>
        <presentationURL>http://www.cybergarage.org</presentationURL>
    </device>
</root>

Dès que l’on appuie sur un bouton de la télécommande, elle envoie une requête HTTP aux 2 URL précédentes pour récupérer la description des 2 services offerts par le climatiseur.
Le climatiseur répond par des fichiers xml. Le premier pour la description de la fonction on/off, et le second pour la description de la fonction changer la température.

<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
    <specVersion>
        <major>1</major>
        <minor>0</minor>
    </specVersion>
    <actionList>
        <action>
            <name>SetPower</name>
            <argumentList>
                <argument>
                    <name>Power</name>
                    <relatedStateVariable>Power</relatedStateVariable>
                    <direction>in</direction>
                </argument>
                <argument>
                    <name>Result</name>
                    <relatedStateVariable>Result</relatedStateVariable>
                    <direction>out</direction>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetPower</name>
            <argumentList>
                <argument>
                    <name>Power</name>
                    <relatedStateVariable>Power</relatedStateVariable>
                    <direction>out</direction>
                </argument>
            </argumentList>
        </action>
    </actionList>
    <serviceStateTable>
        <stateVariable sendEvents="yes">
            <name>Power</name>
            <dataType>boolean</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>Result</name>
            <dataType>boolean</dataType>
        </stateVariable>
    </serviceStateTable>
</scpd>
<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
    <specVersion>
        <major>1</major>
        <minor>0</minor>
    </specVersion>
    <actionList>
        <action>
            <name>SetTemp</name>
            <argumentList>
                <argument>
                    <name>Temp</name>
                    <relatedStateVariable>Temp</relatedStateVariable>
                    <direction>in</direction>
                </argument>
                <argument>
                    <name>Result</name>
                    <relatedStateVariable>Result</relatedStateVariable>
                    <direction>out</direction>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetTemp</name>
            <argumentList>
                <argument>
                    <name>Temp</name>
                    <relatedStateVariable>Temp</relatedStateVariable>
                    <direction>out</direction>
                </argument>
            </argumentList>
        </action>
    </actionList>
    <serviceStateTable>
        <stateVariable sendEvents="yes">
            <name>Temp</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>Result</name>
            <dataType>boolean</dataType>
        </stateVariable>
    </serviceStateTable>
</scpd>

Maintenant, la phase d’initialisation est terminée.
Tous les messages suivant sont en SOAP (Simple Object Access Protocol).

A chaque fois que l’on augmente ou diminue la température, la télécommande envoie un message avec la fonction SetTemp et la différence de température à appliquer (+1 ou -1).
Le climatiseur répond en renvoyant la nouvelle température.

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:SetTemp xmlns:u="urn:schemas-upnp-org:service:temp:1">
            <Temp>+1</Temp>
        </u:SetTemp>
    </s:Body>
</s:Envelope>

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:SetTempResponse xmlns:u="urn:schemas-upnp-org:service:temp:1">
            <Result>19</Result>
        </u:SetTempResponse>
    </s:Body>
</s:Envelope>

L’allumage et l’extinction du climatiseur se fait toujours en 2 étapes.
D’abord, la télécommande demande au climatiseur son état avec la fonction GetPower, et le climatiseur renvoie son état.

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:GetPower xmlns:u="urn:schemas-upnp-org:service:power:1" />
    </s:Body>
</s:Envelope>

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:GetPowerResponse xmlns:u="urn:schemas-upnp-org:service:power:1">
            <Power>1</Power>
        </u:GetPowerResponse>
    </s:Body>
</s:Envelope>

Puis elle utilise la fonction SetPower pour le mettre dans l’état opposé, et le climatiseur renvoie son nouveau état.

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:SetPower xmlns:u="urn:schemas-upnp-org:service:power:1">
            <Power>0</Power>
        </u:SetPower>
    </s:Body>
</s:Envelope>

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:SetPowerResponse xmlns:u="urn:schemas-upnp-org:service:power:1">
            <Result>0</Result>
        </u:SetPowerResponse>
    </s:Body>
</s:Envelope>

Le fonctionnement de l’allumage/extinction est le même pour la lampe.

Thibault RIVE

Ce contenu a été publié dans L'Internet des Objets, avec comme mot(s)-clé(s) , , . Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *