--luasql = require "luasql.sqlite3"

--http = require "socket.http";


--------------------------------
------    USER SETTINGS   ------
--------------------------------

-- domoticz
domoticzIP = '192.168.1.3' --'127.0.0.1'
domoticzPORT = '81'
domoticzUSER = ''   -- nom d'utilisateur
domoticzPSWD = ''   -- mot de pass
domoticzPASSCODE = '' -- pour interrupteur protégés
domoticzURL = 'http://'..domoticzIP..':'..domoticzPORT

-- Ne fonctionne plus
--require "luasql.sqlite3"
--package.preload['luasql.sqlite3']

delai = 300 -- delai avant renvoi consigne
maxVariation = 0.15
radiateurs = {'RadiateurManon','RadiateurTheo','RadiateurChambre','RadiateurBureau','RadiateurCuisine','RadiateurMilieu','RadiateurCheminee', 'RadiateurPorteSalon'}

function updatenum(dev, value1)
    print("NRJ updatenum "..dev.." "..tostring(value1))	
    --local cmd = string.format("%d|0|%d", otherdevices_idx[dev], math.floor(value1))
    local cmd = tostring(otherdevices_idx[dev]).."|0|"..tostring(round(value1, 3))

    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end
function ternary ( cond , T , F )
    if cond then return T else return F end
end
function isempty(s)
  return s == nil or s == ''
end

-- Retourne le jour de la semaine (lundi...dimanche)
josdGetJourSemaineTab={[0]="dimanche",[1]="lundi",[2]="mardi",[3]="mercredi",[4]="jeudi",[5]="vendredi",[6]="samedi"}
function josdGetJourSemaine()
  return josdGetJourSemaineTab[tonumber(os.date("%w"))]
end

-- Retourne le jour de Pâques au format epoch
-- annee : année (Integer) dont on désire connaître le jour de Pâques (ex : 2014)
-- La fonction n'effectue le calcul que si l'année a changée depuis son dernier appel
josdGetJourPaquesAnnee=0      -- Variable globale (année du dernier calcul) pour ne pas recalculer le jour de Pâques à chaque appel
josdGetJourPaquesEpochPaque=0 -- Variable globale (jour de Pâques au format epoch) pour ne pas recalculer le jour de Pâques à chaque appel
function josdGetJourPaques(annee)
  if(josdGetJourPaquesAnnee~=annee or josdGetJourPaquesEpochPaque==0) then
    local a=math.floor(annee/100)
    local b=math.fmod(annee,100)
    local c=math.floor((3*(a+25))/4)
    local d=math.fmod((3*(a+25)),4)
    local e=math.floor((8*(a+11))/25)
    local f=math.fmod((5*a+b),19)
    local g=math.fmod((19*f+c-e),30)
    local h=math.floor((f+11*g)/319)
    local j=math.floor((60*(5-d)+b)/4)
    local k=math.fmod((60*(5-d)+b),4)
    local m=math.fmod((2*j-k-g+h),7)
    local n=math.floor((g-h+m+114)/31)
    local p=math.fmod((g-h+m+114),31)
    local jour=p+1
    local mois=n
    josdGetJourPaquesAnnee=annee
    josdGetJourPaquesEpochPaque=os.time{year=annee,month=mois,day=jour,hour=12,min=0}
  end
  return josdGetJourPaquesEpochPaque
end


-- Retourne true si le jour courant est un jour férié
-- Le calcul des jours férié n'est fait qu'un fois par an (ou si la Vera reboot)
josdJourFerieAnnee=0  -- Variable globale (année du dernier calcul) pour ne pas recalculer le tableau à chaque appel
josdJourFerieTab = {} -- Variable globale (tableau des jours fériés) pour ne pas recalculer le tableau à chaque appel
function josdJourFerie()
  local today=os.date("%m-%d")
  local annee=tonumber(os.date("%Y"))
  if(annee~=josdJourFerieAnnee) then
    josdJourFerieAnnee=annee
    -- Dates fixes
    josdJourFerieTab["01-01"] = true -- 1er janvier
    josdJourFerieTab["05-01"] = true -- Fête du travail
    josdJourFerieTab["05-08"] = true -- Victoire des alliés
    josdJourFerieTab["07-14"] = true -- Fête nationale
    josdJourFerieTab["08-15"] = true -- Assomption
    josdJourFerieTab["11-01"] = true -- Toussaint
    josdJourFerieTab["11-11"] = true -- Armistice
    josdJourFerieTab["12-25"] = true -- Noël
    -- Dates variables
    local epochPaques=josdGetJourPaques(annee)
    josdJourFerieTab[os.date("%m-%d",epochPaques)] = true             -- Pâques
    josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60)] = true    -- Lundi de Pâques = Pâques + 1 jour
    josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60*39)] = true -- Ascension = Pâques + 39 jours
    josdJourFerieTab[os.date("%m-%d",epochPaques+24*60*60*49)] = true -- Pentecôte = Ascension + 49 jours
  end
  return josdJourFerieTab[today] -- (nldr : Both nil and false make a condition false)
end
-- Retourne true si le jour courant est un jour chômé (passé à la maison)
-- Le calcul effectif n'est fait qu'une fois par jour (ou si la Vera reboot)
josdJourChomeToday="NULL" -- Variable globale (date du dernier calcul) pour ne pas recalculer le résultat à chaque appel
josdJourChomeReturn=false -- Variable globale (résulat du dernier calcul) pour ne pas recalculer le résultat à chaque appel
function josdJourChome()
  local today=os.date("%Y-%m-%d")
  if(today~=josdJourChomeToday) then -- Faut-il refaire le calcul ?
    local jour=josdGetJourSemaine()
    josdJourChomeToday=today
    josdJourChomeReturn=(jour=="samedi" or jour=="dimanche" --or jour=="mercredi"
                      or josdJourFerie())
	-- or josdJourVacances())
  end
  return josdJourChomeReturn
end
-- ------------------------------------------------------------------------------
-- transforme une heure en minute
-- ------------------------------------------------------------------------------
function heureEnMinute(t1)

   s1 = split(t1, ":")
   h1 = tonumber(s1[1])
   m1 = tonumber(s1[2])

   return h1 * 60 + m1

end

-- ------------------------------------------------------------------------------
-- compare 2 heures
-- ------------------------------------------------------------------------------
function greater(t1, t2)
  return greater2(t1, t2, 0)
end
-- -------------------------------
-- retourne vrai si t1 > t2 + m
-- -------------------------------
function greater2(t1, t2, m)

   s1 = split(t1, ":")
   s2 = split(t2, ":")

   h1 = tonumber(s1[1])
   h2 = tonumber(s2[1])
   m1 = tonumber(s1[2])
   m2 = tonumber(s2[2])

   if h1 * 60 + m1 > h2 * 60 + m2 + m then return true end
   --if h1 == h2 and m1 > m2 then return true end

   return false

end
-- ------------------------------------------------------------------------------
-- Function sleep n seconds
-- ------------------------------------------------------------------------------
function sleep(n)
  os.execute("sleep " .. tonumber(n))
end

-- ------------------------------------------------------------------------------
-- Truncate number to nb decimal
-- ------------------------------------------------------------------------------
function round(num, idp)
  local mult = 10^(idp or 0)
  return math.floor(num * mult + 0.5) / mult
end

-- ------------------------------------------------------------------------------
-- Get the temperature from a device which contains humidity and pressure too
-- ------------------------------------------------------------------------------
function getTemperatureFromDevice(device)
  return tonumber(split(otherdevices_svalues[device],";")[1])
end
-- ------------------------------------------------------------------------------
-- Get the humidity from a device which contains temperature and pressure too
-- ------------------------------------------------------------------------------
function getHumidityFromDevice(device)
  return tonumber(split(otherdevices_svalues[device],";")[2])
end

-- Test if string is empty or null
function isempty(s)
  return s == nil or s == ''
end

-- ------------------------------------------------------------------------------
-- Permet de couper une chaine de caracteres avec separateur en plusieurs chaines
-- ------------------------------------------------------------------------------
function split(str, pat)
   local t = {}  -- NOTE: use {n = 0} in Lua-5.0
   local fpat = "(.-)" .. pat
   local last_end = 1
   local s, e, cap = str:find(fpat, 1)
   while s do
      if s ~= 1 or cap ~= "" then
	 table.insert(t,cap)
      end
      last_end = e+1
      s, e, cap = str:find(fpat, last_end)
   end
   if last_end <= #str then
      cap = str:sub(last_end)
      table.insert(t, cap)
   end
   return t
end

-- ------------------------------------------------------------------------------
-- Met à jour un switch si nécessaire (déjà à la bonne position)
-- ------------------------------------------------------------------------------
function switchIfNeeded( switch, value )
  if switch == "RadiateurGrenier" then 
    local currentValue = tonumber(otherdevices_svalues["RadiateurGrenier"])

    if value == "On" then
      if (otherdevices[switch] == 'Off') then 
        switchOn(switch) --    commandArray[switch]=value
      end

      switchOnDimmable(switch, currentValue + 1)
    else
      if currentValue <= 1 then
          switchOnDimmable(switch, 0)
      else
        if (otherdevices[switch] ~= 'Off') then
          switchOnDimmable(switch, currentValue - 1)
        end
      end
    end

    print(switch .. ' ' ..value..' current='..currentValue..' '..otherdevices[switch])

  else
    if (otherdevices[switch] == value and not string.match(switch, "Radiateur")) then -- and lastUpdateOfDevice(switch) < 300) then
      debug(switch..' already '..value)	  
    else
      if value == "On" then
        debug(switch..' '..value)
        switchOn(switch) --    commandArray[switch]=value
      else
        switchOff(switch)
        debug(switch..' '..value)
      end
    end
    --sleep(1)
  end
end

-- ------------------------------------------------------------------------------
-- Met à jour un switch si nécessaire (déjà à la bonne position)
-- ------------------------------------------------------------------------------
function switchLightsIfNeeded( value )
  switchIfNeeded('Lampe_Halogene', value)
  sleep(1)
  switchIfNeeded('Lampe_Buffet', value)
  sleep(1)
  switchIfNeeded('Lampe_Tele', value)
  sleep(1)
  switchIfNeeded('Lampe_Led', value)
end

-- ------------------------------------------------------------------------------
-- Function to get result of HTTP request
-- ------------------------------------------------------------------------------
function os.capture(cmd, raw)
  local f = assert(io.popen(cmd, 'r'))
  local s = assert(f:read('*a'))
  f:close()
  if raw then return s end
  s = string.gsub(s, '^%s+', '')
  s = string.gsub(s, '%s+$', '')
  s = string.gsub(s, '[\n\r]+', ' ')
  return s
end
-- ------------------------------------------------------------------------------
-- Function to get the last update of device from now in seconds
-- ------------------------------------------------------------------------------
function lastUpdateOfDevice(switch)
  t1 = os.time()
  s = otherdevices_lastupdate[switch]
  difference = 0
  if (s == nil) then
    debug("Erreur détermination lastUpdate "..switch)
  else
    -- returns a date time like 2013-07-11 17:23:12
    year = string.sub(s, 1, 4)
    month = string.sub(s, 6, 7)
    day = string.sub(s, 9, 10)
    hour = string.sub(s, 12, 13)
    minu = string.sub(s, 15, 16)
    seconds = string.sub(s, 18, 19)

    t2 = os.time{year=year, month=month, day=day, hour=hour, min=minu, sec=seconds}

    difference = (os.difftime (t1, t2))
    --debug(switch..tonumber(difference))
  end

  return difference
end
-- ---------------------------------------------------
-- Function debug
-- ---------------------------------------------------
function debug(string)
  if otherdevices['Debug'] == 'On' and string ~= nil then
    print("DEBUG "..string)
  end
end
-- ---------------------------------------------------
-- Switch off radiateur SIC !
-- ---------------------------------------------------
function switchOffRadiateur(switch)
  debug("Radiateur "..switch.." Off.")
  if (otherdevices[switch] == 'On' or lastUpdateOfDevice(switch) > delai) then
    --commandArray[switch]='Off'
    switchOff(switch)
  end
  --switchIfNeeded(switch, 'Off') -- Inversion pour les radiateurs
end
-- ---------------------------------------------------
-- Switch on radiateur SIC !
-- ---------------------------------------------------
function switchOnRadiateur(switch)
  debug("Radiateur "..switch.." On.")
  if (otherdevices[switch] == 'Off' or lastUpdateOfDevice(switch) > delai) then
    --commandArray[switch]='On'
    switchOn(switch)
  end
  --switchIfNeeded(switch, 'On') -- Inversion pour les radiateurs
end

-- ---------------------------------------------------
-- Get a map of switch values
-- ---------------------------------------------------
function getValuesInTab(switch)
   tmp = otherdevices_svalues[switch]

   debug('temperature lue pour '..switch..' '..tmp)
   tab = split(tmp, ";")

   return tab
 end

-- ---------------------------------------------------
-- Get the last values of a switch (inverse order)
-- ---------------------------------------------------
function getEvolutionFromSwitch(switch)

  env = luasql.sqlite3()
  conn = env:connect("/opt/domoticz/domoticz.db")

  cursor = assert(conn:execute("select temperature,date from temperature,DeviceStatus where DeviceStatus.name = '"..switch.."' and devicerowid = DeviceStatus.id order by date desc limit 10"))
  row = {}
  while cursor:fetch(row) do
      debug(table.concat(row, '|'))
  end

  cursor:close()
  conn:close()

  env:close()
end

-- ---------------------------------------------------
-- Execute a query from domoticz db and returns rows
-- ---------------------------------------------------
function executeQuery( switch, query)

  q = "/usr/bin/sqlite3 -list /opt/domoticz/domoticz.db '" .. query .. "' 2>&1"

  --debug(q)

  --debug("avant execute"..q)
  local rHandle = io.popen( "/usr/bin/sqlite3 -list /opt/domoticz/domoticz.db '" .. query .. "' 2>&1" )
  local aRows = {} ; local aRow = {}; local iRow = 1 ; local iColumn = 1

  --debug("avant while true")
  while true do
    local sResultRow = rHandle:read( '*line' )
    if ( sResultRow == nil ) then break end

   debug(sResultRow)

    for sColumn in sResultRow:gmatch( "([^|]+)" ) do
      aRow[iColumn] = sColumn
      debug(sColumn)
      iColumn = iColumn + 1
    end

    aRows[iRow] = aRow

    iRow = iRow + 1
    iColumn = 1
    aRow = {}
  end
  --debug("Fin while")
  local oReturn = { rHandle:close() }
  if ( tonumber( oReturn[3] ) ~= 0 ) then -- check return code (0 = ok)
    debug( sQuery_, 4 )
    if ( iRow > 1 ) then
      debug( aRows[iRow - 1][1], 4 )
    else
      debug( 'Error while executing query.', 4 )
    end
    return false
  else
    debug( sQuery_, 1 )
    return true, aRows, iRow - 1
  end

  --debug("Fin execute")
end

function executeQueryAndGetValues( switch )
  local bSuccess, aRows, iCount = executeQuery( switch )
  if ( bSuccess ) then
    if ( iCount > 0 ) then
      return table.unpack( aRows[1] )
    else
      return nil
    end
  else
    return false
  end
end

-- --------------------------------------------------------
-- Détermine la variation de température à prendre en compte
-- --------------------------------------------------------
function getVariation( switch )
  local time = 10
  variation = variationTemp(switch)
  debug("Variation 10' ="..tostring(variation))
  if variation == 0 then
      time = 20
     variation = variationTemp2(switch, 20)
     debug("Variation 20' ="..tostring(variation))
  end
  if variation == 0 then
    time = 30
     variation = variationTemp2(switch, 30)
     debug("Variation 30' ="..tostring(variation))
  end
  return variation, time
end

-- --------------------------------------------------------
-- calcul la variation de température depuis n * 5 minutes
-- --------------------------------------------------------
function variationTemp(switch)
  return variationTemp2(switch, 10)
end
function variationTemp2(switch, time)
  local limit = time / 5 + 1

  query = 'select temperature,date from temperature,DeviceStatus where DeviceStatus.Name = "'..switch..'" and devicerowid = DeviceStatus.id order by date desc limit '..tostring(limit)

  --debug("Avant query "..tostring(limit).." "..switch)
  local bSuccess, aRows, iCount = executeQuery(switch, query)

  --debug("Retour executeQuery"..tostring(bSuccess).." icount="..iCount)

  local firstTemp = 0
  local lastTemp = 0
  if (bSuccess and iCount > 0) then
      firstTemp = tonumber(aRows[1][1])
      lastTemp = tonumber(aRows[iCount][1])
      for i = 1, iCount do
        local t = tonumber(aRows[i][1])
        --debug("RETOUR Query"..tostring(aRows[i][1]))
      end
  end

  return firstTemp - lastTemp
end

-- ---------------------------------------------------
-- calcul la variation de pression depuis ?? minutes
-- Basse pression == < à 1013mbar (pluie)
-- Haute pression == > à 1013mbar (beau temps)
-- Diminution rapide ==> vent et mauvais temps
-- superieur à 1020 ==> beau temps calme
-- Tendance
-- Tendance du baromètre   hPa par heure   Évolution du temps
-- montée      0,25 à 0,5    venue d'une haute pression (à long terme)
-- montée      1 à 2     moyenne pression (à court terme)
-- descente    0,25 à 0,5    venue d'une basse pression (à long terme)
-- descente    1 à 2     tempête ; en été, orage.
-- Conversion
-- 10^5 Pa = 1 bar = 1000 mbar = 10,2 mCE (mètres de colonne d'eau) = 0,987 atm.
-- ---------------------------------------------------
function variationPressure(switch, time) -- time en minute
  local limit = time / 5 + 1
  -- SELECT barometer,date FROM temperature where devicerowid =  94 and date like "2016-02-24 %" order by date desc limit 25
  query = 'select barometer,date from temperature,DeviceStatus where DeviceStatus.Name = "'..switch..'" and devicerowid = DeviceStatus.id order by date desc limit '..tostring(limit)

  local bSuccess, aRows, iCount = executeQuery(switch, query)

  debug("Retour executeQuery"..tostring(bSuccess).." icount="..iCount)

  local firstTemp = 0
  local lastTemp = 0
  if (bSuccess and iCount > 0) then
      firstTemp = tonumber(aRows[1][1])
      lastTemp = tonumber(aRows[iCount][1])
      for i = 1, iCount do
        local t = tonumber(aRows[i][1])
        debug("RETOUR Query"..tostring(aRows[i][1]))
      end
  end

  return firstTemp - lastTemp
end


-- -----------------
-- Multiple update
-- -----------------
function update(idx, value1, value2)
    local cmd = string.format("%d|0|%.2f;%.2f", idx, value1, value2)
    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end
function updateCmd(idx, value1)
    local cmd = idx.."|"..value1
    table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end

-- PERF

-- /!\ require Domoticz v3.5776 and after /!\

curl = '/usr/bin/curl -m 3 ' -- don't forgot the final space

domoticzIP = 'localhost'
domoticzPORT = '81'
domoticzURL = 'http://'..domoticzIP..':'..domoticzPORT

-- switch On a device and set level if dimmmable
function switchOnDimmable(device, level)
  print(device..' '..tostring(level))
  os.execute(curl..'"'..domoticzURL..'/json.htm?type=command&param=switchlight&idx='..otherdevices_idx[device]..'&switchcmd=Set%20Level&level='..level..'" &')
end
function switchOn(device)
  if (otherdevices_idx[device] ~= nil) then
    os.execute(curl..'"'..domoticzURL..'/json.htm?type=command&param=switchlight&idx='..otherdevices_idx[device]..'&switchcmd=On" &')
  end
end
-- switch On a devive for x seconds
-- non compatible avec le script sendTwice
function switchOnFor(device, secs)
  if (otherdevices_idx[device] ~= nil) then
    switchOn(device)
    commandArray[device] = "Off AFTER "..secs
  end
end

-- switch Off a device
function switchOff(device)
  if (otherdevices_idx[device] ~= nil) then
     os.execute(curl..'"'..domoticzURL..'/json.htm?type=command&param=switchlight&idx='..otherdevices_idx[device]..'&switchcmd=Off" &')
   end
 end

-- Toggle a device
function switch(device)
  if (otherdevices_idx[device] ~= nil) then
   os.execute(curl..'"'..domoticzURL..'/json.htm?type=command&param=switchlight&idx='..otherdevices_idx[device]..'&switchcmd=Toggle" &')
  end
end

-- switch On a group or scene
function groupOn(device)
  if (otherdevices_idx[device] ~= nil) then
   os.execute(curl..'"'..domoticzURL..'/json.htm?type=command&param=switchscene&idx='..otherdevices_scenesgroups_idx[device]..'&switchcmd=On" &')
  end
end

-- switch Off a group
function groupOff(device)
  if (otherdevices_idx[device] ~= nil) then
   os.execute(curl..'"'..domoticzURL..'/json.htm?type=command&param=switchscene&idx='..otherdevices_scenesgroups_idx[device]..'&switchcmd=Off" &')
  end
end

-- Retourne le nombre de minutes avant la nuit
function whenDark()
  local hour      = tonumber(os.date("%H"));
  local min       = tonumber(os.date("%M"));
  local now       = 60 * hour + min 
  local sunsetMin = heureEnMinute(uservariables["Couche"])

  when_dark = sunsetMin - now
  print("####### Dark in "..tostring(when_dark))

  return when_dark

end

-- Retourne le nombre de minutes avant le jour
function whenLight()
  local hour      = tonumber(os.date("%H"));
  local min       = tonumber(os.date("%M"));
  local now       = 60 * hour + min 
  local sunriseMin = heureEnMinute(uservariables["Lever"])

  when_light = 1440 - (sunriseMin - now)
  debug("####### Light in "..tostring(when_light))

  return when_light

end


function actionSomfy(name, action)
   debug(name..' '..action)
   local url = "mosquitto_pub -h  www.maqiatto.com -u jerome.delacotte@gmail.com -P setaou -I clientId-9FG7vBimhk -t jerome.delacotte@gmail.com/"..name.."/volet -m "..action
   debug(url)
   os.execute(url)
end

-- update an existing variable
function updateVar(name,value)
  local api = '/json.htm?type=command&param=updateuservariable'
  local name = '&vname='..url_encode(name)
  local vtype = '&vtype=2'
  local value = '&vvalue='..url_encode(value)
  api = api..name..vtype..value
  url = curl..'-u '..domoticzUSER..':'..domoticzPSWD..' "'..domoticzURL..api..'" &'
  debug(url)
  os.execute(url)
end
function url_encode(str)
  if (str) then
    str = string.gsub (str, "\n", "\r\n")
    str = string.gsub (str, "([^%w %-%_%.%~])",
        function (c) return string.format ("%%%02X", string.byte(c)) end)
    str = string.gsub (str, " ", "+")
  end
  return str  
end

-- recursive search value in table
function searchValueInTable(value, tbl)
    for k, v in pairs(tbl) do
        if v == value then
            return k -- Retourne la clé si la valeur est trouvée
        elseif type(v) == "table" then
            local result = searchValueInTable(value, v) -- Appel récursif si la valeur est un tableau
            if result then
                return k .. "." .. result -- Retourne la clé trouvée concaténée avec la clé actuelle
            end
        end
    end
    return nil -- Retourne nil si la valeur n'est pas trouvée
end

-- Recursive search key in array
function searchKeyInTable(key, tbl)
    for k, v in pairs(tbl) do
        if k == key then
            return v
        elseif type(v) == "table" then
            local result = searchKeyInTable(key, v)
            if result then
                return result
            end
        end
    end
    
    return nil
end

function printTableAsTree(tbl, indent)
    indent = indent or ""
    for key, value in pairs(tbl) do
        if type(value) == "table" then
            print(indent .. tostring(key) .. ":")
            printTableAsTree(value, indent .. "___")
        else
            print(indent .. tostring(key) .. ": " .. tostring(value))
        end
    end
end

function sendNotification(message)
    commandArray['SendNotification'] = message
end

function getJSONContent(url)
    local cmd = 'curl -s --connect-timeout 2 -m 5 "'..url..'"'
    --local cmd = 'curl "'..url..'"'
    local jsonContent = os.capture(cmd, true)
    return jsonContent
end

function decodeJSON(jsonContent)
    json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()
    return json:decode(jsonContent)
end

function updateDeviceValue(deviceId, svalue)
    local url = domoticzURL..'/json.htm?type=command&param=udevice&idx='..deviceId..'&svalue='..svalue
    print(url)
    result = os.execute(curl..'"'..url..'" &')
    print(result)
end

function getExternalTempRef(device_temp)
  local val
  local val2
  val, val2 = otherdevices_svalues[device_temp]:match("([^;]+);([^;]+)")
  print("Volets "..device_temp.." "..otherdevices["Exterieur_Cellier"].." "..val..
    otherdevices['VoletCuisine'].."  "..otherdevices['VoletSalonTele'].."  "..otherdevices['VoletPorteSalon'])

  return tonumber(val)
end

function convertirAngle(angle)
    local pointsCardinaux = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "N" }
    local index = math.floor(((angle + 22.5) % 360) / 45) + 1
    return pointsCardinaux[index]
end
