Archives du tag : Lua

Xavante : Handler de type fonction WSAPI

Objectif

wsapi

J’ai présenté dans un précédant billet comment mettre en œuvre un serveur web WSAPI-Xavante. L’objectif de ce billet est de présenter plus en détail la mise en œuvre d’une fonction permettant de répondre à une requête de type GET ou POST en s’appuyant sur la librairie WSAPI.

L’intérêt d’utiliser WSAPI est de bénéficier de librairies facilitant l’interprétation de la requête ainsi que la génération et la bufferisation de la sortie.

(suite…)
Publié dans Domotique, Tutoriels, Eloise | Tagué | Laisser un commentaire

WSAPI et Xavante : serveur Web Lua

Introduction

Image23

Contexte

L’objet de ce tutoriel est de détailler l’installation et le fonctionnement d’un serveur web permettant d’héberger un programme Lua : WSAPI-Xavante. La documentation concernant ce serveur web n’est pas très prolixe, pas très pédagogique et pas très francophone, d’où tout l’intérêt de ce tutoriel.

Dans mon cas d’utilisation, je compte héberger « l’intelligence » de ma domotique. C’est parce que celle-ci est développée en Lua que j’ai choisi un serveur web Lua : Xavante basé sur l’API WSAPI

WSAPI

wsapi

WSAPI est une API permettant aux applications Web Lua de s’abstraire du serveur Web. Ainsi, une application codée en utilisant l’API WSAPI peut fonctionner sur n’importe quel serveur supportant cette API (actuellement CGI, FastCGI et Xavante).

WSAPI fournit un ensemble de librairies destinées à faciliter de traitement des requêtes ainsi que la bufferisation des sorties.

Xavante

xavante

Xavante est un serveur Web HTTP 1.1 Lua qui utilise une architecture modulaire basée sur des gestionnaires (handlers) de correspondance d’URI (URI mapped handlers). Xavante implémente des gestionnaires de fichier, des gestionnaires de redirection et des gestionnaires WSAPI. Ces gestionnaires sont respectivement utilisés pour des fichiers, des réécritures d’URI et des fonctions WSAPI. La correspondance d’URI se fait via l’écriture d’expressions régulières au sens Lua du terme.

(suite…)
Publié dans Domotique, Tutoriels, Eloise | Tagué | Laisser un commentaire

Communication entre Vera Lite et IPX800

Vera-IPX800
Problématique

Ce billet propose différentes fonctions qui permette d’utiliser pleinement le contrôleur IPX800 depuis la box Vera Lite. Dans un premier temps, il expose comment consulter ou modifier l’état de l’IPX800. Dans un second temps, il propose un moyen de synchroniser l’état de l’IPX800 avec une structure de donnée dans la Vera Lite afin de bénéficier d’un cache restant synchrone avec les changements d’état de l’IPX800.

Lire un état sur l’IPX800
Connexion à l’IPX800 en Lua :
local socket=require("socket")
 
function josdConnexionIPX800()
  local addresseIP="192.168.0.34"  -- adresseIP de l'IPX
  local port=9870 -- par defaut le port de lIPX est 9870
  local client = assert(socket.connect(addresseIP, port))
  client:send("key=<motdepasse>") -- Si l'interface est protégée par un mot de passe
  client:receive() -- Si l'interface est protégée par un mot de passe
  return (client)
end
</motdepasse>

Attention, à partir du micrologiciel version 3.05.46, si l’interface de l’IPX800 est protégée par un mot de passe, ce dernier doit être envoyé juste après la connexion comme indiqué ci-dessus (remplacer <motDePasse> par le mot de passe).

Fonction interne Lua de lecture d’un état de l’IPX800 :

function josdGetIPX800(indice,commande)
  if (type(indice)=="string") then indice=tonumber(indice) end
  assert(type(indice)=="number" and indice>=1 and indice< =8)
  local client=josdConnexionIPX800()
  commande=commande..tostring(indice)
  client:send(commande)
  local reponse=client:receive()
  assert(client:close())
  local etat=assert(string.match(reponse,'=([0-9]*)$'))
  return tonumber(etat)
end
Fonction Lua de lecture de l’état d’une entrée de l’IPX800 :
function josdGetEntreeIPX800(indice)
  return josdGetIPX800(indice,"GetIn")
end
Fonction Lua de lecture de l’état d’une sortie de l’IPX800 :
function josdGetSortieIPX800(indice)
  return josdGetIPX800(indice,"GetOut")
end
Fonction Lua de lecture de l’état d’un compteur d’impulsion de l’IPX800 :
function josdGetCompteurIPX800(indice)
  return josdGetIPX800(indice,"GetCount")
end
Fonction Lua de lecture de l’état d’une entrée analogique de l’IPX800 :
function josdGetEntreeAnalogiqueIPX800(indice)
  return josdGetIPX800(indice,"GetAn")
end
(suite…)
Publié dans Domotique, Contrôleurs, Tutoriels | Tagué , , , | Laisser un commentaire

Lua : envoyer un courriel avec des images

attachment

Voici une fonction en Lua permettant d’envoyer un courriel avec une ou plusieurs images en pièce jointe à partir de la Vera Lite. Le message et l’objet peuvent contenir des caractères accentués. L’objet est facultatif. Les images sont aussi facultatives, cette fonction peut donc être utilisée pour envoyer un simple courriel à la place de celle présentée dans ce billet. <@_courriel_emetteur>, <@_courriel_destinataire> et <smtp> sont à remplacer par l’adresse électronique et le serveur smtp adéquats.

-- Permet d'envoyer un courriel en passant en paramètres le message, l'objet et des images au format jpeg à attacher en pièces jointes
-- On peut ne donner comme paramètres que (message, objet) voir que (message)
-- message    : le message du courriel (ex : "Voici quelques photos")
-- objet      : l'objet du courriel (ex : "Photos")
-- imagesJPEG : les chemins des images (ex : "/img.jpg" ou encore {"/img1.jpg", "/img2.jpg", "/img3.jpg"} )
function josdEnvoyerCourrielAvecImages(message, objet, imagesJPEG)
  local smtp = require("socket.smtp")
  local mime = require("mime")
  local ltn12 = require("ltn12")
  local emetteur     = "<@_courriel_emetteur>"
  local destinataire = "<@_courriel_destinataire>"
  if (type(objet)=="string") then objet="[Vera]".." "..objet else objet="[Vera]" end
  message="Bonjour, ceci est un courriel envoyé par la VeraLite ("..os.date("%A %B %Y, %H:%M:%S")..
    ")\n\n"..message.."\n\nCordialement, VeraLite"
  local body={}
  body[1] = { headers = { ["content-type"] = "text/plain; charset=utf8" }, body = message }
  if(imagesJPEG~=nil) then
    if(type(imagesJPEG)=="string") then imagesJPEG = { imagesJPEG } end
    for i,v in pairs(imagesJPEG) do
      body[i+1] = { 
        headers = {
          ["content-type"] = 'image/jpeg; name="image'..tostring(i)..'.jpg"',
          ["content-disposition"] = 'attachment; filename="image'..tostring(i)..'.jpg"',
          ["content-description"] = 'Image '..i+1,
          ["content-transfer-encoding"] = "BASE64"
        },
        body = ltn12.source.chain(
          ltn12.source.file(io.open(v, "rb")),
          ltn12.filter.chain(
            mime.encode("base64"),
            mime.wrap()
          )
        )
      }
    end
  end
  local courriel = smtp.message{
    headers = {
      from = emetteur,
      to = destinataire,
      subject = objet
    },
    body=body
  }
  smtp.send{ from=emetteur, rcpt=destinataire, source=courriel, server="<smtp>", port="25" }
end

Attention, capturer des images et les envoyer par courriel peut consommer trop de ressources pour la Vera lite (cf. Vera Lite : Plantage sévère).

Sommaire Domotique sur ce blog

Publié dans Domotique, Surveillance | Tagué , | 12 commentaires

Lua : envoyer un courriel

courriel

Voici une fonction en Lua permettant d’envoyer un courriel à partir de la Vera Lite. Le message et l’objet peuvent contenir des caractères accentués. L’objet est facultatif. <@_courriel_emetteur>, <@_courriel_destinataire> et <smtp> sont à remplacer par l’adresse électronique et le serveur smtp adéquats.

-- Permet d'envoyer un courriel en passant en paramètre le message et l'objet (facultatif)
function josdEnvoyerCourriel(message, objet)
  local smtp = require("socket.smtp")
  local emetteur     = "<@_courriel_emetteur>"
  local destinataire = "<@_courriel_destinataire>"
  if (type(objet)=="string") then objet="[Vera]".." "..objet else objet="[Vera]" end
  message="Bonjour, ceci est un courriel envoyé par la VeraLite ("..os.date("%A %B %Y, %H:%M:%S")..")\n\n"..message.."\n\nCordialement, VeraLite"
  local mesgt = {
    headers = {
      to = destinataire,
      from = emetteur,
      subject = objet,
      ["content-type"] = "text/plain; charset=utf8"
    },
    body = message
  }
  smtp.send{ from=emetteur, rcpt=destinataire, source=smtp.message(mesgt), server="<smtp>", port="25" }
end

Sommaire Domotique sur ce blog

Publié dans Domotique, Tutoriels | Tagué , | Laisser un commentaire

Lua : exécuter une commande système (ping, uptime …)

Exécuter une commande système (os.execute)

Voici une petite fonction permettant d’exécuter une commande système. Cette fonction permet de récupérer la sortie sur stdout de la commande, comme le message d’erreur dans le cas où la commande système échoue.

-- Permet d'exécuter une commande système sur la Vera
-- commande    : la chaîne de caractères contenant la commande
-- Retourne vrai en cas de succès plus le résultat (stdout) de la commande
function josdOsExecute(commande)
  local cmd=commande..' > /tmp/josdOsExecute.log 2>&1'
  local reponse=os.execute(cmd)
  local file=assert(io.open("/tmp/josdOsExecute.log", "r"))
  local stdout=file:read("*all")
  assert(file:close())
  return (reponse==0 or reponse==true), stdout
end

Ping

Voici maintenant une fonction Lua qui permet de tester l’accessibilité d’une autre machine à travers un réseau IP.

-- Permet de faire un ping sur une adresse
function josdPing(adresse)
  local nbPing=3     -- -c CNT : Send only CNT pings
  local nbSecondes=5 -- -w SEC : Seconds until ping exits
  assert(type(adresse)=="string")
  return josdOsExecute("ping -c"..nbPing.." -w"..nbSecondes.." -W"..nbSecondes.." "..adresse)
end

Load Average (uptime)

Le load average est une moyenne de la charge système calculée sur la dernière minute, les cinq dernières minutes et les quinze dernières minutes (3 moyennes en fait). Voici une fonction Lua permettant de retourner la valeur de ces trois moyennes.

-- Permet de connaitre le taux d'occupation du processeur de la VeraLite
-- Retourne la charge système moyenne pour les 1, 5 et 15 dernières minutes.
function josdLoadEverage()
  local succes,message=josdOsExecute("uptime")
  if (succes) then
    local l1,l2,l3=string.match(message, "load average[^0-9.]*([0-9.]*)[^0-9.]*([0-9.]*)[^0-9.]*([0-9.]*)")
    return tonumber(l1),tonumber(l2),tonumber(l3)
  end
end

Voici une fonction Lua permettant de tester si ces trois moyennes sont en dessous d’un seuil passé en paramètre.

-- Vrai si les trois valeurs du taux d'occupation du processeur sont inférieures à la limite
function josdLimiteLoadEverage(limite)
  limite=limite or 0.33 -- Valeur par défaut
  local l1,l2,l3=josdLoadEverage()
  return(l1<limite and l2<limite and l3<limite)
end

Sommaire Domotique sur ce blog

Publié dans Domotique, Tutoriels | Tagué , | 1 commentaire

Lua : vacances, jours chômés et jours fériés

reposFirefox

Indispensable dans une box domotique

Il est souvent utile de savoir si le jour courant est un jour passé à la maison, ou pas, pour planifier la programmation des luminaires ou du thermostat. Ce billet présente un ensemble de fonctions permettant de déterminer si le jour courant est un jours chômé (c’est à dire un jour où au moins un membre de la famille reste à la maison).

Jours chômés

La fonction principale pourrait se résumer à celle-ci :

function josdJourChome()
  local jour=josdGetJourSemaine()
  return jour=="samedi" or jour=="dimanche" or josdJourFerie() or josdJourVacances()
end

Un jour chômé est donc un samedi, un dimanche (à adapter selon votre situation) un jour férié ou un jour de vacances scolaires. Cette fonction fait appel à d’autres fonctions (josdGetJourSemaine(), josdJourFerie() ou josdJourVacances()) que nous détaillerons plus bas.

(suite…)
Publié dans Domotique, Tutoriels | Tagué | Laisser un commentaire

Lua, tour d’horizon

Lua

Sommaire

Présentation
Éléments de syntaxe : Écriture, Commentaires, Chaînes de caractères.
Valeurs, Types, Variables et Fonctions : Typage dynamique, Lua possède 8 types de base, Portée des variables.
Structures de contrôle : Structure conditionnelle, Structures itératives, Structures itératives for générique, Conditions, Bloc d’instructions.
Fonctions particulières, particularités : self et « : », Fonctions sur les chaînes.
Plus d’information, sources

Présentation

Flexible, réflexif, impératif, compact et léger (compilateur, interpréteur et librairies standards n’occupent qu’environ 150 kilo-octets une fois compilés), open-source (distribué sous la licence MIT), Lua est un langage de script extrêmement puissant et rapide (dix à trente fois plus rapide que d’autres langages de scripts tel que TCL, Perl, Python, Ruby ou PHP). Lua est écrit en langage C ANSI strict et donc multiplateforme.

Créé en 1993, Lua (Lune en portugais, prononcer Loua, écrire Lua et pas LUA car ce n’est pas un acronyme) a été développé par Luiz Henrique de Figueiredo, Roberto Ierusalimschy et Waldemar Celes, membres du groupe de recherche TeCGraf, de l’université pontificale catholique de Rio de Janeiro au Brésil.

Voici un programme minimaliste en Lua. En sauvant le code ci-dessous dans le fichier hello.lua, le script s’exécute de la manière suivante : $ lua hello.lua

print("Hello World")

Voici un script Lua plus évolué :

-- Définition d'une fonction factorielle
function fact (n)
  if n == 0 then
    return 1
  else
    return n * fact(n-1)
  end
end
 
print("Saisir un nombre :")
a = io.read("*number") -- read a number
print(fact(a))
(suite…)
Publié dans Enseignement, Domotique, Tutoriels | Tagué | Laisser un commentaire