Aller au contenu

Messages recommandés

Posté(e)

Hello, 

je voulais remettre en place une sonde virtuelle basée sur les infos WEATHER.COM

ça fonctionnait en V3.59.

J'ai importé mon périphérique virtuel avec le code suivant et ça ne fonctionne pas.

Quelqu'un a une idée?

HC2 = Net.FHttp("HTTP://wxdata.weather.com")response = HC2:GET("/wxdata/weather/local/FRXX0076?cc=*&unit=m")
-- enregistrement du retour de l API dans une table
response = json.decode(response)
fibaro:setGlobal("WEATHERTMP", response.tmp)
fibaro:setGlobal("WEATHERHMID", response.hmid)  
Posté(e)

Je switch donc notre conversation ici ;) . Pour résumer:  wxdata.weather.com retourne du xml et pas du json c'est le problème ici.

 

Je regarde un truc simple pour te sortir tmp et hmid sans utiliser un pseudo parser XML...

Posté(e)

Oui pas la peine de faire une usine àgaz :D

local HC2 = Net.FHttp("wxdata.weather.com");
local result, status, errorCode = HC2:GET("/wxdata/weather/local/FRXX0076?cc=*&unit=m");
if tonumber(status) == 200 then
  if (result ~= nil) then
    local temp = tonumber(result:match("<tmp>(.+)</tmp>") or 0);
    local hmid = tonumber(result:match("<hmid>(.+)</hmid>") or 0);
    fibaro:debug(temp.."°C");
    fibaro:debug(hmid.."%");
  end
else
  fibaro:debug("Error Code: " .. errorCode);
end

le debug:

[DEBUG] 23:31:52: 8°C
[DEBUG] 23:31:52: 91%

Tu as des questions ?

Posté(e)

euh... ouais !

D'abord merci, ça fonctionne.

si je veux récupérer aussi des chaines de caractères et stocker tout ça dans des variables globales, ça se passe comment ?

(tu auras compris que je suis une quiche en LUA ! )

Posté(e)

Hum, je suis dans le coin en ce moment, mais pas mal occupé.... normalement dans 2 semaines ça sera calme, je t'en reparle :77:

Sinon y'a Latoupie dans ton coin la semaine prochaine.

 

Bon sinon sérieusement je laisse Krikroff reprendre la main, car ta demande est un peu trop pointue pour moi.

Posté(e)

Re....

 

 

si je veux récupérer aussi des chaines de caractères et stocker tout ça dans des variables globales, ça se passe comment ?

local HC2 = Net.FHttp("wxdata.weather.com");
local result, status, errorCode = HC2:GET("/wxdata/weather/local/FRXX0076?cc=*&unit=m");
if tonumber(status) == 200 then
  if (result ~= nil) then
    local temp = tonumber(result:match("<tmp>(.+)</tmp>") or 0);
    local hmid = tonumber(result:match("<hmid>(.+)</hmid>") or 0);
    fibaro:debug(temp.."°C");
    -- Enregistrement de tmp dans la vg WEATHERTMP
    fibaro:setGlobal("WEATHERTMP", tmp);
    fibaro:debug(hmid.."%");
    -- Enregistrement de hmiddans la vg WEATHERHMID
    fibaro:setGlobal("WEATHERHMID", hmid) 
  end
else
  fibaro:debug("Error Code: " .. errorCode);
end

et pour utiliser la variable globale c'est

local tmp = fibaro:getGlobalValue("WEATHERTMP");
fibaro:debug(tmp);
Posté(e)

Merci, en fait je parlais des retours du XML qui sont des chaines de caractères (cloudy,low,...).

Comme il y a  des instructions tonumber dans le code, je ne pense pas que ça fonctionne... ???

Posté(e)

Soit tu enlèves les tonumber soit tu laisse setGlobal faire tranquillement un CAST et passer la valeur en string, soit tu fais un tostring.... Ce n'est pas les solutions qui manquent

Tu veux que je modifie le code entre midi et deux ?

JC

Envoyé de mon smartphone

Posté(e)

Il faut que tu me dises exactement les valeurs que tu veux et quelles sont les variables globales ;)

Posté(e)

mince j'ai pas vu ton message. :(

Si tu peux me donner un exemple pour "cloudy" à  stocker dans METEO, après j'adapterai.

Merci. 

;)

 

<cc>

<lsup>2/26/15 8:05 AM CET</lsup>
<obst>Paris-Montsouris, 75, FR</obst>
<tmp>7</tmp>
<flik>5</flik>
<t>Cloudy</t>
Posté(e)

Bonjour

pour ma part je récupère des données d'un PHP sur mon serveur

et sur mon Module j'ai ce format qui marchait avant de passer en 3.6 et que j'aimerais également faire marcher en plus de la 3.6 en V4

HC2 = Net.FHttp("xxxx.fr")
response = HC2:GET("/xxxx/agenda-WITHINGS-HIER.php?cal=xxxxxxxxxxxxxxxxxxxxgroup.calendar.google.com/private-xxxxxxxxxxxxxxxx&decode=0&defaut=0,Poids&json=1")  -- 0,NO_DATA,
response = json.decode(response)
fibaro:setGlobal("WITHINGS", response.WITHINGS)
fibaro:setGlobal("WITHINGS_Text", response.WITHINGS_text)
fibaro:log("WITHINGS_ : "..fibaro:getGlobalValue("WITHINGS_Text"))
fibaro:call(206,"setProperty","ui.Label2.value",response.WITHINGS_text)

en message j'obtiens

[ERROR] 09:44:03: line 10: Expected value but found invalid token at character 1

Avez-vous une idée ?

Posté(e)

@Fredo,

 

Je m'excuse pour mon retour très très tardif ... Et pour me faire pardonner je te propose 1 solution plus propre :)  car la récupération de t pose des problèmes en effet il y a 3 ou 4 node t dans le code...

 

Voici un parser XML

---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- LUA XML parser
-- UPDATE: Jean-Christophe Vermandé
-- NOTE: This is a modified version of Alexander Makeev's Lua-only XML parser
-- found here: http://lua-users.org/wiki/LuaXml
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
Parser = function()
    XmlParser = {};
    function XmlParser:ToXmlString(value)
        value = string.gsub(value, "&", "&".."amp;"); -- '&' -> "&"
        value = string.gsub(value, "<", "&".."lt;"); -- '<' -> "<"
        value = string.gsub(value, ">", "&".."gt;"); -- '>' -> ">"
        value = string.gsub(value, "\"", "&".."quot;"); -- '"' -> """
        value = string.gsub(value, "([^%w%&%;%p%\t% ])",
            function(c)
                return string.format("%X;", string.byte(c))
            end);
        return value;
    end

    function XmlParser:FromXmlString(value)
        value = string.gsub(value, "([%x]+)%;",
            function(h)
                return string.char(tonumber(h, 16))
            end);
        value = string.gsub(value, "([0-9]+)%;",
            function(h)
                return string.char(tonumber(h, 10))
            end);
        value = string.gsub(value, "&".."quot;", "\"");
        value = string.gsub(value, "&".."apos;", "'");
        value = string.gsub(value, "&".."gt;", ">");
        value = string.gsub(value, "&".."lt;", "<");
        value = string.gsub(value, "&".."amp;", "&");
        return value;
    end

    function XmlParser:ParseArgs(node, s)
        string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
            node:addProperty(w, self:FromXmlString(a))
        end)
    end

    function XmlParser:ParseXmlText(xmlText)
        local stack = {}
        local top = newNode()
        table.insert(stack, top)
        local ni, c, label, xarg, empty
        local i, j = 1, 1
        while true do
            ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w_:]+)(.-)(%/?)>", i)
            if not ni then break end
      		--fibaro:debug("label: "..label);
      		--fibaro:debug("xarg: "..xarg);
            local text = string.sub(xmlText, i, ni - 1);      		
            if not string.find(text, "^%s*$") then
                local lVal = (top:value() or "") .. self:FromXmlString(text)
        		--fibaro:debug(lVal);
                stack[#stack]:setValue(lVal)
            end
            if empty == "/" then -- empty element tag
                local lNode = newNode(label);        		
                self:ParseArgs(lNode, xarg)
                top:addChild(lNode)
            elseif c == "" then -- start tag
                local lNode = newNode(label);
                self:ParseArgs(lNode, xarg)
                table.insert(stack, lNode)
        		top = lNode
            else -- end tag
                local toclose = table.remove(stack) -- remove top
                top = stack[#stack]
                if #stack < 1 then
                    error("XmlParser: nothing to close with " .. label)
                end
                if toclose:name() ~= label then
                    error("XmlParser: trying to close " .. toclose.name .. " with " .. label)
                end
                top:addChild(toclose)
            end
            i = j + 1
        end
        local text = string.sub(xmlText, i);
        if #stack > 1 then
            error("XmlParser: unclosed " .. stack[#stack]:name())
        end
        return top
    end
    return XmlParser
end

newNode = function(name)
  local node = {}
  node.___value = nil
  node.___name = name
  node.___children = {}
  node.___props = {}
  
  function node:value() return self.___value end
  function node:setValue(val) self.___value = val end
  function node:name() return self.___name end
  function node:setName(name) self.___name = name end
  function node:children() return self.___children end
  function node:numChildren() return #self.___children end
  function node:addChild(child)
    if self[child:name()] ~= nil then
      if type(self[child:name()].name) == "function" then
        local tempTable = {}
        table.insert(tempTable, self[child:name()])
        self[child:name()] = tempTable
      end
      table.insert(self[child:name()], child)
    else
      self[child:name()] = child
    end
    table.insert(self.___children, child)
  end
  
  function node:properties() return self.___props end
  function node:numProperties() return #self.___props end
  function node:addProperty(name, value)
    local lName = "@" .. name
    if self[lName] ~= nil then
      if type(self[lName]) == "string" then
        local tempTable = {}
        table.insert(tempTable, self[lName])
        self[lName] = tempTable
      end
      table.insert(self[lName], value)
    else
      self[lName] = value
    end
    table.insert(self.___props, { name = name, value = self[name] })
  end  
  return node
end

Puis le code pour l'utiliser dans notre cas

local HC2 = Net.FHttp("wxdata.weather.com");
local result, status, errorCode = HC2:GET("/wxdata/weather/local/FRXX0076?cc=*&unit=m");
if tonumber(status) == 200 then
  if (result ~= nil) then
    local xml = Parser();
    local parsedXml = xml:ParseXmlText(result);
    local parsedDIDL = parsedXml['weather'];
    local cnt = 1;
    if parsedDIDL ~= nil then
      local children = parsedDIDL["cc"] or {};
      fibaro:debug(tostring(children.obst:value()));
      fibaro:debug(tostring(children.tmp:value()));
      fibaro:debug(tostring(children.t:value()));
      fibaro:debug(tostring(children.hmid:value()));
    else
      error("Node not created")
    end
  end
else
  fibaro:debug("Error Code: " .. errorCode);
end
  • Upvote 1
Posté(e)

Tu peux remplacer les Fibaro:debug par des setGlobal pour persister les données dans des variables globales.

Envoyé de mon smartphone

Posté(e)

donc j'ai essayé et ça fonctionne.

par contre, si je veux récupérer la pression contenue dans "r" qui est dans une sous-section "bar" de "cc", ça se passe comment?

 

<cc>

<lsup>3/02/15 10:25 PM CET</lsup>
<obst>Paris-Montsouris, 75, FR</obst>
<tmp>6</tmp>
<flik>5</flik>
<t>Clear</t>
<icon>31</icon>
<bar>
<r>1020.32</r>
<d>steady</d>
</bar>
<wind>
<s>8</s>
<gust>N/A</gust>
<d>220</d>
<t>SW</t>
</wind>
<hmid>55</hmid>
<vis>16.1</vis>
<uv>
<i>0</i>
<t>Low</t>
</uv>
<dewp>-2</dewp>
<moon>
<icon>12</icon>
<t>Waxing Gibbous</t>
</moon>
</cc>
×
×
  • Créer...