{"id":1019,"date":"2011-10-31T22:24:49","date_gmt":"2011-10-31T21:24:49","guid":{"rendered":"http:\/\/blog.guiguiabloc.fr\/?p=1019"},"modified":"2011-11-14T10:24:13","modified_gmt":"2011-11-14T09:24:13","slug":"xpl-et-nut-recuperer-les-donnees-de-votre-onduleur","status":"publish","type":"post","link":"http:\/\/blog.guiguiabloc.fr\/index.php\/2011\/10\/31\/xpl-et-nut-recuperer-les-donnees-de-votre-onduleur\/","title":{"rendered":"xPL et NUT, r\u00e9cup\u00e9rer les donn\u00e9es de votre onduleur"},"content":{"rendered":"<p style=\"text-align: center;\"><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2011\/10\/BeXPL.jpg\"><img loading=\"lazy\" class=\"aligncenter size-full wp-image-1021\" title=\"BeXPL\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2011\/10\/BeXPL.jpg\" alt=\"\" width=\"164\" height=\"200\" \/><\/a><\/p>\n<p>Comme la majorit\u00e9 des passionn\u00e9s qui touche \u00e0 la domotique, j&rsquo;utilise le protocole <a title=\"http:\/\/en.wikipedia.org\/wiki\/XPL_Protocol\" href=\"http:\/\/en.wikipedia.org\/wiki\/XPL_Protocol\" target=\"_blank\">xPL<\/a> pour centraliser les informations de mes \u00e9quipements.<\/p>\n<p>Si vous ne connaissez pas encore le principe, je vous invite \u00e0 lire les excellents billets de <a title=\"http:\/\/www.poulpy.com\/\" href=\"http:\/\/www.poulpy.com\/\" target=\"_blank\">Thibault<\/a> et <a title=\"http:\/\/www.planete-domotique.com\/blog\/\" href=\"http:\/\/www.planete-domotique.com\/blog\/\" target=\"_blank\">Mickael<\/a> \u00e0 ce sujet :<\/p>\n<p><a title=\"http:\/\/www.poulpy.com\/2010\/02\/xpl-one-protocol-to-rule-them-all\/\" href=\"http:\/\/www.poulpy.com\/2010\/02\/xpl-one-protocol-to-rule-them-all\/\" target=\"_blank\">http:\/\/www.poulpy.com\/2010\/02\/xpl-one-protocol-to-rule-them-all\/<\/a><\/p>\n<p><a title=\"http:\/\/www.planete-domotique.com\/blog\/2011\/05\/18\/le-protocole-xpl\/\" href=\"http:\/\/www.planete-domotique.com\/blog\/2011\/05\/18\/le-protocole-xpl\/\" target=\"_blank\">http:\/\/www.planete-domotique.com\/blog\/2011\/05\/18\/le-protocole-xpl\/<\/a><\/p>\n<p>Et bien s\u00fbr, le site du projet lui-m\u00eame :<\/p>\n<p><a title=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Main_Page\" href=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Main_Page\" target=\"_blank\">http:\/\/xplproject.org.uk\/wiki\/index.php?title=Main_Page<\/a><\/p>\n<p>C&rsquo;est un protocole fiable, performant et act\u00e9 par les plus fervents agitateurs de la domotique (par exemple <a title=\"http:\/\/www.domogik.org\/\" href=\"http:\/\/www.domogik.org\/\" target=\"_blank\">Domogik<\/a>, un des projets fran\u00e7ais les plus prometteurs actuellement dans la mise \u00e0 disposition d&rsquo;une solution \u00ab\u00a0tout-en-un\u00a0\u00bb (et libre surtout !) ou <a title=\"http:\/\/www.rfxcom.com\/\" href=\"http:\/\/www.rfxcom.com\/\" target=\"_blank\">RFXCOM<\/a>, un des leaders des \u00e9quipements domotique RF qui int\u00e8gre d\u00e9sormais nativement le xPL dans ses produits).<\/p>\n<p>Moi, comme beaucoup de mes confr\u00e8res passionn\u00e9s, je suis absolument convaincu du fait qu&rsquo;il faille d\u00e9finir un protocole standard pour l&rsquo;interaction des \u00e9quipements de domotique, bien \u00e9videmment, ouvert, et bien \u00e9videmment, xPL r\u00e9pond \u00e0 cette attente.<\/p>\n<p>Jusqu&rsquo;a maintenant, j&rsquo;utilisais beaucoup les scripts de la communaut\u00e9, et surtout ceux de l&rsquo;excellentissime Mark Hindess connu sous le pseudo de beanz et auteur du framework <a title=\"https:\/\/github.com\/beanz\/xpl-perl\" href=\"https:\/\/github.com\/beanz\/xpl-perl\" target=\"_blank\">xpl-perl.<\/a><\/p>\n<p>Et puis vient le moment o\u00f9 l&rsquo;on a un besoin pr\u00e9cis qui n&rsquo;existe pas&#8230;<\/p>\n<p>En l&rsquo;occurence, je voulais r\u00e9cuperer les donn\u00e9es et l&rsquo;\u00e9tat de mon onduleur et bien s\u00fbr en xPL.<\/p>\n<p>Je fais le tour des solutions et il existe xpl-apcups du m\u00eame Mark pr\u00e9-cit\u00e9 mais, mince, fl\u00fbte, sacrebleu, il ne fonctionne qu&rsquo;avec <a title=\"http:\/\/www.apcupsd.org\/\" href=\"http:\/\/www.apcupsd.org\/\" target=\"_blank\">apcupsd<\/a>.<\/p>\n<p>Bon, tant pis, je me dis que je vais revoir le code pour le faire fonctionner et l\u00e0, forc\u00e9ment, je s\u00e8che comme une blonde d\u00e9color\u00e9e aux attributs silicon\u00e9s\u00a0 sur une plage m\u00e9diterran\u00e9enne en plein mois d&rsquo;ao\u00fbt.<\/p>\n<p>Parce que bon, Perl et moi&#8230; Comment dire&#8230; Autant expliquer le principe du cum-swapping \u00e0 une none ayant fait voeu d&rsquo;isolement&#8230; (avouez que vouliez un lien !!!!)<\/p>\n<p>Donc je me dis que je vais tenter de l&rsquo;\u00e9crire moi-m\u00eame mon client, ayant aborder Python du coin de l&rsquo;oeil je regarde ce qu&rsquo;il existe et je trouve un petit exemple de<a title=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Development_Tools#xPL_Toolkit_for_Python\" href=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Development_Tools#xPL_Toolkit_for_Python\" target=\"_blank\"> John Bent sur le site du projet xPL<\/a>.<\/p>\n<p>Quelques litres de caf\u00e9 plus tard (s\/caf\u00e9\/bi\u00e8re\/), je vous propose donc <strong>xpl-nut<\/strong>.<\/p>\n<p>Vous pouvez bien s\u00fbr le t\u00e9l\u00e9charger <a title=\"http:\/\/blog.guiguiabloc.fr\/download\/\" href=\"http:\/\/blog.guiguiabloc.fr\/download\/\" target=\"_blank\">ICI<\/a><br \/>\nOu sur le projet GoogleCode :<br \/>\n<a title=\"http:\/\/code.google.com\/p\/guiguiabloc\/\" href=\"http:\/\/code.google.com\/p\/guiguiabloc\/\" target=\"_blank\">http:\/\/code.google.com\/p\/guiguiabloc\/<\/a><\/p>\n<p>J&rsquo;ai essay\u00e9 de suivre les recommandations du projet xPL.<\/p>\n<p>Les sch\u00e9mas utilis\u00e9s sont <a title=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Schema_-_UPS.BASIC\" href=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Schema_-_UPS.BASIC\" target=\"_blank\">UPS.BASIC<\/a> et <a title=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Schema_-_SENSOR.BASIC\" href=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=Schema_-_SENSOR.BASIC\" target=\"_blank\">SENSOR.BASIC<\/a><\/p>\n<p>Concernant les <a title=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=XPL_Specification_Document#Trigger_messages\" href=\"http:\/\/xplproject.org.uk\/wiki\/index.php?title=XPL_Specification_Document#Trigger_messages\" target=\"_blank\">recommandations TRIGGER<\/a>, il est demand\u00e9 de n&rsquo;\u00e9mettre une trame que lors d&rsquo;un changement d&rsquo;\u00e9tat mais personnellement, j&rsquo;ai pass\u00e9 outre, pr\u00e9f\u00e9rant avoir une remont\u00e9e constante des informations.<\/p>\n<p><strong>EDIT :<\/strong> Suite aux discussions avec l&rsquo;\u00e9quipe Domogik, j&rsquo;ai revu mon code pour \u00eatre \u00ab\u00a0aux normes\u00a0\u00bb et donc le format de message est donc de type STAT d\u00e9sormais et TRIG en cas de changement d&rsquo;\u00e9tat (version 1.1 du script)<\/p>\n<p>Comme donner un script python comme \u00e7a ne sert pas \u00e0 progresser, et comme j&rsquo;ai pris du plaisir \u00e0 l&rsquo;\u00e9crire (et oui :p), je vous propose d&rsquo;en voir les parties int\u00e9ressantes, au cas, o\u00f9, comme moi, vous d\u00e9cidez d&rsquo;\u00e9crire vos propres clients xPL<\/p>\n<pre lang=\"python\">\r\n#############\r\n# variables\r\n#############\r\nupsaddr='127.0.0.1'\r\nupsport=3493\r\npolltime=10\r\nnomups = 'mononduleur'\r\n\r\nxpladdr = (\"255.255.255.255\",3865)\r\nUDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)\r\nUDPSock.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)\r\n<\/pre>\n<p>Ici rien de compliqu\u00e9, on d\u00e9finit les variables essentielles, a savoir :<br \/>\n&#8211; upsaddr : l&rsquo;adresse IP du d\u00e9mon NUT<br \/>\n&#8211; upsport :  le port du d\u00e9mon NUT<br \/>\n&#8211; polltime : la fr\u00e9quence d&rsquo;interrogationdu d\u00e9mon NUT en secondes<br \/>\n&#8211; nomups : le nom de votre onduleur, tel que d\u00e9finit dans votre \/etc\/ups.conf<br \/>\n&#8211; xpladdr :  l&rsquo;adresse et le port de broadcast pour les messages<\/p>\n<p>Le code suivant est la pr\u00e9paration de l&rsquo;ouverture d&rsquo;un socket UDP.<\/p>\n<pre lang=\"python\">\r\netatonduleur = \"get var \"+nomups+\" ups.status\\r\\n\"\r\nvoltage= \"get var \"+nomups+\" input.voltage\\r\\n\"\r\nbatterycharge= \"get var \"+nomups+\" battery.charge\\r\\n\"\r\n<\/pre>\n<p>Ici on d\u00e9finit les requ\u00e8tes que nous allons passer au d\u00e9mon NUT.<br \/>\nSi vous faites un \u00ab\u00a0telnet ip_du_nut_demon 3493\u00a0\u00bb par defaut, vous avez acc\u00e8s a une console qui vous permet d&rsquo;interroger le d\u00e9mon NUT.<br \/>\nHELP donne l&rsquo;aide (nan ????)<br \/>\nGET VAR nomdelonduleur input.voltage donne le voltage en entr\u00e9e<br \/>\netc&#8230;<br \/>\nPour avoir la liste des variables, il vous suffit de taper : upsc nomonduleur.<\/p>\n<p>Voici par exemple ce que cela retourne chez moi :<\/p>\n<pre lang=\"text\">\r\nsrv-guiguiabloc:\/etc\/nut# upsc mgeups\r\nbattery.charge: 100.0\r\nbattery.charge.low: 30\r\nbattery.runtime: 02655\r\nbattery.voltage: 055.2\r\nbattery.voltage.nominal: 048.0\r\ndevice.mfr: MGE UPS SYSTEMS\r\ndevice.model: Pulsar ESV22+\r\ndevice.type: ups\r\ndriver.name: mge-utalk\r\ndriver.parameter.pollinterval: 2\r\ndriver.parameter.port: \/dev\/ttyS0\r\ndriver.version: 2.4.3\r\ndriver.version.internal: 0.89\r\ninput.frequency: 50.00\r\ninput.transfer.boost.high: 212.0\r\ninput.transfer.boost.low: 204.0\r\ninput.transfer.high: 248.0\r\ninput.transfer.low: 204.0\r\ninput.transfer.trim.high: 248.0\r\ninput.transfer.trim.low: 240.0\r\ninput.voltage: 227.0\r\noutput.current: 002.9\r\noutput.voltage: 224.1\r\nups.delay.shutdown: 020\r\nups.delay.start: 001\r\nups.firmware: 2\r\nups.id: Pulsar ESV22+ 2\r\nups.load: 027.0\r\nups.mfr: MGE UPS SYSTEMS\r\nups.model: Pulsar ESV22+\r\nups.status: OL\r\nups.test.interval: 10080\r\n<\/pre>\n<p>A vous de forger les requ\u00e8tes en cons\u00e9quence \ud83d\ude09<\/p>\n<pre lang=\"python\">\r\ns.send(etatonduleur)\r\n    data = s.recv(50)\r\n    resultat = data.split()\r\n    statusbatt = resultat.pop()\r\n    statusbatt = statusbatt.replace('\"','')\r\n    statusbatt = statusbatt.replace('OL','onmains')\r\n    statusbatt = statusbatt.replace('OB','onbattery')\r\n    statusbatt = statusbatt.replace('LB','lowbattery')\r\n    body = 'status=battery\\nevent='+statusbatt\r\n    msg = \"xpl-trig\\n{\\nhop=1\\nsource=guigui-xplnut.\"+hostname+\"\\ntarget=*\\n}\\nups.basic\\n{\\n\" + body + \"\\n}\\n\"\r\n    UDPSock.sendto(msg,xpladdr)\r\n    print msg\r\n<\/pre>\n<p>J&rsquo;envois la requ\u00e8te au d\u00e9mon NUT et je r\u00e9cup\u00e8re le r\u00e9sultat que je traite (salement je l&rsquo;avoue).<br \/>\nJe forge ensuite le message xPL que j&rsquo;envois dans le r\u00e9seau.<\/p>\n<p>Le reste du code est assez basique et vous devriez en comprendre le fonctionnement avec ses quelques explications.<br \/>\nsoyez indulgent, je suppose que mon code n&rsquo;est pas tr\u00e8s propre et si vous \u00eates un pro du python, je suis ouvert \u00e0 vos recommandations ! \ud83d\ude00<\/p>\n<p>En tout cas, cela marche tr\u00e8s bien et pour un premier script xPL j&rsquo;en suis plut\u00f4t fier \ud83d\ude42<\/p>\n<p>Une fois lanc\u00e9, vous devriez voir les remont\u00e9es dans votre bus xPL:<\/p>\n<pre lang=\"text\">\r\n[xpl-trig\/ups.basic: guigui-xplnut.Thanatos -> * - battery onmains]\r\n[xpl-trig\/sensor.basic: guigui-xplnut.Thanatos -> * - mgeups[voltage]=225.7]\r\n[xpl-trig\/sensor.basic: guigui-xplnut.Thanatos -> * - mgeups[battery]=100.0]\r\n<\/pre>\n<p>En esp\u00e9rant que cela vous serve,<\/p>\n<p>Amusez vous bien \ud83d\ude00<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Comme la majorit\u00e9 des passionn\u00e9s qui touche \u00e0 la domotique, j&rsquo;utilise le protocole xPL pour centraliser les informations de mes \u00e9quipements. Si vous ne connaissez pas encore le principe, je vous invite \u00e0 lire les excellents billets de Thibault et &hellip; <a href=\"http:\/\/blog.guiguiabloc.fr\/index.php\/2011\/10\/31\/xpl-et-nut-recuperer-les-donnees-de-votre-onduleur\/\">Read More <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[137],"tags":[169,170,171,168],"_links":{"self":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1019"}],"collection":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/comments?post=1019"}],"version-history":[{"count":22,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1019\/revisions"}],"predecessor-version":[{"id":1040,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1019\/revisions\/1040"}],"wp:attachment":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/media?parent=1019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/categories?post=1019"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/tags?post=1019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}