first commit

This commit is contained in:
Souti
2025-03-06 11:09:58 +01:00
commit 11f7d440ff
330 changed files with 38306 additions and 0 deletions

BIN
lua/.AppleDouble/.Parent Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,20 @@
commandArray = {}
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
pid=os.execute('cat /home/pi/motion/motion.pid')
print("Motion pid= "..switch)
------------------------------------------------------------------------
if (pid == 0) then
commandArray['Camera1']='Off'
else
commandArray['Camera1']='On'
end
return commandArray

View File

@@ -0,0 +1,19 @@
require "scripts/lua/functions"
commandArray = {}
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
if (minutes % 1 == 0) then
local f = io.popen("ls /media/WDBlue/motion/ |grep jpg| cut -c 1-2 |uniq| wc -l") -- runs command
local l = f:read("*a") -- read output of command
debug("Nombre de detection "..l)
f:close()
commandArray['PhotoMotion']=tostring(l)
commandArray['UpdateDevice']="1065|"..l
end
return commandArray

View File

@@ -0,0 +1,19 @@
require "scripts/lua/functions"
commandArray = {}
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
if (minutes % 10 == 0) then
local f = io.popen("ls /media/WDBlue/motion/ |grep jpg| cut -c 1-2 |uniq| wc -l") -- runs command
local l = f:read("*a") -- read output of command
debug("Nombre de detection "..l)
f:close()
commandArray['PhotoMotion']=tostring(l)
commandArray['UpdateDevice']="1065|"..l
end
return commandArray

36
lua/Archives/script_time_PC.old Executable file
View File

@@ -0,0 +1,36 @@
--Permet toutes les 15 minutes de renvoyer la commande actuelle sensée etre appliquée aux modules en 433 ( sans retour d'etat )
require "scripts/lua/functions"
commandArray = {}
--recupere les minutes
time=os.time()
jour=tonumber(os.date('%w',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
-- ---------------------------------------------------------------------------------------------------------
-- Toutes les 30 minutes suffisent
-- ---------------------------------------------------------------------------------------------------------
if (minutes == 0 or minutes == 30 ) then
if (otherdevices['Vacances'] == 'On') then
switchIfNeeded['SonoJasper'] = 'Off'
else
if (jour == 0 or jour == 6) then
if (heures >= 08 and heures <= 23) then
switchIfNeeded('SonoJasper', 'On')
else
switchIfNeeded('SonoJasper', 'Off')
end
else
if (heures >= 20 and heures <= 23) then
switchIfNeeded('SonoJasper', 'On')
else
switchIfNeeded('SonoJasper', 'Off')
end
end
end
debug('##### Lancement du check tele chambre '..otherdevices['SonoJasper'] )
end
return commandArray

View File

@@ -0,0 +1,33 @@
require "scripts/lua/functions"
--Permet toutes les 15 minutes de renvoyer la commande actuelle sensée etre appliquée aux modules en 433 ( sans retour d'etat )
commandArray = {}
--recupere les minutes
time=os.time()
jour=tonumber(os.date('%w',time))
--mois=tonumber(os.date('%M',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
if (minutes % 10 == 0) then
debug('####### Lancement du check Presence ' ..heures..'h'..minutes)
if (otherdevices['Vacances'] == 'On') then
switchIfNeeded('Presence','Off')
else
--commandArray['Presence']='Off'
------------------------------------------------------------------------
if (josdJourChome()) then
switchIfNeeded('Presence','On')
else
if (heures > 17 or otherdevices["Zone B"] == 'On') then
switchIfNeeded('Presence','On')
else
switchIfNeeded('Presence','Off')
end
end
end
end
return commandArray

View File

@@ -0,0 +1,108 @@
--Permet toutes les 15 minutes de renvoyer la commande actuelle sensée etre appliquée aux modules en 433 ( sans retour d'etat )
commandArray = {}
--recupere les minutes
time=os.time()
jour=tonumber(os.date('%w',time))
--mois=tonumber(os.date('%M',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
-- 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
print('!*!*!*!*!*!*!*!*!Lancement du check Radiateur Bureau ' ..heures..'h'..minutes)
if (minutes == 0 or minutes == 10 or minutes == 20 or minutes == 30 or minutes == 40 or minutes == 50) then
if (otherdevices['Vacances'] == 'On') then
commandArray['RadiateurBureau']='Off'
print ('CHECK Temperature: Vacances -> ' ..otherdevices_svalues['TemperatureBarometre'])
else
------------------------------------------------------------------------
print ('CHECK Temperature: Travail -> ' ..otherdevices_svalues['TemperatureBarometre'])
if (tonumber(otherdevices_svalues['TemperatureBarometre']) <= 17.0) then
commandArray['RadiateurBureau']='Off'
else
commandArray['RadiateurBureau']='On'
end
end
end
return commandArray

23
lua/Archives/script_time_hc.old Executable file
View File

@@ -0,0 +1,23 @@
--Permet toutes les 15 minutes de renvoyer la commande actuelle sensée etre appliquée aux modules en 433 ( sans retour d'etat )
require "scripts/lua/functions"
commandArray = {}
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
------------------------------------------------------------------------
if (minutes == 0 or minutes == 30) then
print('######### Lancement du check Heures Creuses' ..heures..'h'..minutes)
if ((heures > 21 or (heures == 21 and minutes >= 30)) or (heures < 5 or (heures == 5 and minutes <= 30))) then
switchIfNeeded('HeuresCreuses', 'On')
else
switchIfNeeded('HeuresCreuses', 'Off')
end
end
return commandArray

View File

@@ -0,0 +1,17 @@
commandArray = {}
print("Debut pingVolumio2")
ping_success=os.execute('ping -c1 volumio')
if ping_success then
if ( otherdevices['Volumio2'] == 'Off') then
print("pingVolumio2 success")
commandArray['Volumio2']='On'
end
else
if (otherdevices['Volumio2'] == 'On') then
print("pingVolumio2 fail")
commandArray['Volumio2']='Off'
end
end
print("fin pingVolumio2")
return commandArray

View File

@@ -0,0 +1,78 @@
--Initialise la commande de retour finale
commandArray={}
--Mode deboggage (affichage des messages)
debug=true
--Prefixe pour les sorties de log
prefixe="(PING) "
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
if (minutes == 0 or minutes == 10 or minutes == 20 or minutes == 30 or minutes == 40 or minutes == 50) then
--Tableau des périphériques à "pinguer"
-- Key = adresse ip à pinguer
-- Value = périphérique virtuel à switcher
local ping={}
ping['volumio']='Volumio2'
ping['achille']='Achille'
ping['akhenaton']='Akhenaton'
ping['hackintosh']='Hackintosh'
ping['xbmc']='Xbmc'
ping['akhesa']='Akhesa'
ping['theo']='Theo'
ping['s3-mini']='Moi'
ping['manon']='Manon'
ping['domi1']='Domi1'
ping['domi2']='Domi2'
ping['soutihp']='ImprimanteHp'
ping['192.168.0.17']='Telechambre'
-- Pas de ping de la box ?? == Panne de courant
--ping['192.168.1.1']='PanneCourant'
--ping['192.168.0.20']='Presence Camera Interieure'
--ping['192.168.0.21']='Presence Camera Exterieure'
--ping['192.168.0.100']='Presence Raspberry'
AuMoinsUnPing=false
--pour chaque entree du tableau
for ip, switch in pairs(ping) do
--Le Ping ! : -c1 = Un seul ping , -w1 délai d'une seconde d'attente de réponse
ping_success=os.execute('ping -c1 -w1 '..ip)
--Si le ping à répondu
if ping_success then
AuMoinsUnPing=true
if(debug==true)then
print(prefixe.."ping success "..switch)
end
--si le switch etait sur off on l'allume
if(otherdevices[switch]=='Off') then
commandArray[switch]='On'
end
else
--Si pas de réponse
if(debug==true)then
print(prefixe.."ping fail "..switch)
end
--si le switch etait sur oN on l'eteind
if(otherdevices[switch]=='On') then
commandArray[switch]='Off'
end
end
end
if AuMoinsUnPing then
commandArray['PanneCourant']='Off'
else
commandArray['PanneCourant']='On'
end
end
return commandArray

1743
lua/JSON.lua Normal file

File diff suppressed because it is too large Load Diff

94
lua/ReferenceMeteo.json Executable file
View File

@@ -0,0 +1,94 @@
{
"response": {
"version":"0.1",
"termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"conditions": 1
}
}
, "current_observation": {
"image": {
"url":"http://icons.wxug.com/graphics/wu2/logo_130x80.png",
"title":"Weather Underground",
"link":"http://www.wunderground.com"
},
"display_location": {
"full":"Redon, France",
"city":"Redon",
"state":"35",
"state_name":"France",
"country":"FR",
"country_iso3166":"FR",
"zip":"00000",
"magic":"274",
"wmo":"07217",
"latitude":"47.65000153",
"longitude":"-2.07999992",
"elevation":"25.0"
},
"observation_location": {
"full":"Plessé, Plessé, ",
"city":"Plessé, Plessé",
"state":"",
"country":"FR",
"country_iso3166":"FR",
"latitude":"47.573772",
"longitude":"-1.954625",
"elevation":"0 ft"
},
"estimated": {
},
"station_id":"IPLESS6",
"observation_time":"Last Updated on September 24, 12:08 PM CEST",
"observation_time_rfc822":"Sun, 24 Sep 2017 12:08:56 +0200",
"observation_epoch":"1506247736",
"local_time_rfc822":"Sun, 24 Sep 2017 12:10:00 +0200",
"local_epoch":"1506247800",
"local_tz_short":"CEST",
"local_tz_long":"Europe/Paris",
"local_tz_offset":"+0200",
"weather":"Overcast",
"temperature_string":"62.1 F (16.7 C)",
"temp_f":62.1,
"temp_c":16.7,
"relative_humidity":"94%",
"wind_string":"Calm",
"wind_dir":"SW",
"wind_degrees":232,
"wind_mph":0.6,
"wind_gust_mph":"2.5",
"wind_kph":1.0,
"wind_gust_kph":"4.0",
"pressure_mb":"1019",
"pressure_in":"30.09",
"pressure_trend":"+",
"dewpoint_string":"60 F (16 C)",
"dewpoint_f":60,
"dewpoint_c":16,
"heat_index_string":"NA",
"heat_index_f":"NA",
"heat_index_c":"NA",
"windchill_string":"NA",
"windchill_f":"NA",
"windchill_c":"NA",
"feelslike_string":"62.1 F (16.7 C)",
"feelslike_f":"62.1",
"feelslike_c":"16.7",
"visibility_mi":"6.2",
"visibility_km":"10.0",
"solarradiation":"--",
"UV":"2","precip_1hr_string":"-999.00 in ( 0 mm)",
"precip_1hr_in":"-999.00",
"precip_1hr_metric":" 0",
"precip_today_string":"0.00 in (0 mm)",
"precip_today_in":"0.00",
"precip_today_metric":"0",
"icon":"cloudy",
"icon_url":"http://icons.wxug.com/i/c/k/cloudy.gif",
"forecast_url":"http://www.wunderground.com/global/stations/07217.html",
"history_url":"http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=IPLESS6",
"ob_url":"http://www.wunderground.com/cgi-bin/findweather/getForecast?query=47.573772,-1.954625",
"nowcast":""
}
}

437
lua/XmlParser.lua Normal file
View File

@@ -0,0 +1,437 @@
--- @module Class providing the actual XML parser.
-- Available options are:
-- * stripWS
-- Strip non-significant whitespace (leading/trailing)
-- and do not generate events for empty text elements
--
-- * expandEntities
-- Expand entities (standard entities + single char
-- numeric entities only currently - could be extended
-- at runtime if suitable DTD parser added elements
-- to table (see obj._ENTITIES). May also be possible
-- to expand multibyre entities for UTF-8 only
--
-- * errorHandler
-- Custom error handler function
--
-- NOTE: Boolean options must be set to 'nil' not '0'
---Converts the decimal code of a character to its corresponding char
--if it's a graphical char, otherwise, returns the HTML ISO code
--for that decimal value in the format &#code
--@param code the decimal value to convert to its respective character
local function decimalToHtmlChar(code)
local n = tonumber(code)
if n >= 0 and n < 256 then
return string.char(n)
else
return "&#"..code..";"
end
end
---Converts the hexadecimal code of a character to its corresponding char
--if it's a graphical char, otherwise, returns the HTML ISO code
--for that hexadecimal value in the format &#xCode
--@param code the hexadecimal value to convert to its respective character
local function hexadecimalToHtmlChar(code)
local n = tonumber(code, 16)
if n >= 0 and n < 256 then
return string.char(n)
else
return "&#x"..code..";"
end
end
local XmlParser = {
-- Private attribures/functions
_XML = '^([^<]*)<(%/?)([^>]-)(%/?)>',
_ATTR1 = '([%w-:_]+)%s*=%s*"(.-)"',
_ATTR2 = '([%w-:_]+)%s*=%s*\'(.-)\'',
_CDATA = '<%!%[CDATA%[(.-)%]%]>',
_PI = '<%?(.-)%?>',
_COMMENT = '<!%-%-(.-)%-%->',
_TAG = '^(.-)%s.*',
_LEADINGWS = '^%s+',
_TRAILINGWS = '%s+$',
_WS = '^%s*$',
_DTD1 = '<!DOCTYPE%s+(.-)%s+(SYSTEM)%s+["\'](.-)["\']%s*(%b[])%s*>',
_DTD2 = '<!DOCTYPE%s+(.-)%s+(PUBLIC)%s+["\'](.-)["\']%s+["\'](.-)["\']%s*(%b[])%s*>',
--_DTD3 = '<!DOCTYPE%s+(.-)%s*(%b[])%s*>',
_DTD3 = '<!DOCTYPE%s.->',
_DTD4 = '<!DOCTYPE%s+(.-)%s+(SYSTEM)%s+["\'](.-)["\']%s*>',
_DTD5 = '<!DOCTYPE%s+(.-)%s+(PUBLIC)%s+["\'](.-)["\']%s+["\'](.-)["\']%s*>',
--Matches an attribute with non-closing double quotes (The equal sign is matched non-greedly by using =+?)
_ATTRERR1 = '=+?%s*"[^"]*$',
--Matches an attribute with non-closing single quotes (The equal sign is matched non-greedly by using =+?)
_ATTRERR2 = '=+?%s*\'[^\']*$',
--Matches a closing tag such as </person> or the end of a openning tag such as <person>
_TAGEXT = '(%/?)>',
_errstr = {
xmlErr = "Error Parsing XML",
declErr = "Error Parsing XMLDecl",
declStartErr = "XMLDecl not at start of document",
declAttrErr = "Invalid XMLDecl attributes",
piErr = "Error Parsing Processing Instruction",
commentErr = "Error Parsing Comment",
cdataErr = "Error Parsing CDATA",
dtdErr = "Error Parsing DTD",
endTagErr = "End Tag Attributes Invalid",
unmatchedTagErr = "Unbalanced Tag",
incompleteXmlErr = "Incomplete XML Document",
},
_ENTITIES = {
["&lt;"] = "<",
["&gt;"] = ">",
["&amp;"] = "&",
["&quot;"] = '"',
["&apos;"] = "'",
["&#(%d+);"] = decimalToHtmlChar,
["&#x(%x+);"] = hexadecimalToHtmlChar,
},
}
--- Instantiates a XmlParser object.
--@param _handler Handler module to be used to convert the XML string
-- to another formats. See the available handlers at the handler directory.
-- Usually you get an instance to a handler module using, for instance:
-- local handler = require("xmlhandler/tree").
--@param _options Options for this XmlParser instance.
--@see XmlParser.options
function XmlParser.new(_handler, _options)
local obj = {
handler = _handler,
options = _options,
_stack = {}
}
setmetatable(obj, XmlParser)
obj.__index = XmlParser
return obj;
end
---Checks if a function/field exists in a table or in its metatable
--@param table the table to check if it has a given function
--@param elementName the name of the function/field to check if exists
--@return true if the function/field exists, false otherwise
local function fexists(table, elementName)
if table == nil then
return false
end
if table[elementName] ~= nil then
return true
else
return fexists(getmetatable(table), elementName)
end
end
local function err(self, err, pos)
if self.options.errorHandler then
self.options.errorHandler(err,pos)
end
end
--- Removes whitespaces
local function stripWS(self, s)
if self.options.stripWS then
s = string.gsub(s,'^%s+','')
s = string.gsub(s,'%s+$','')
end
return s
end
local function parseEntities(self, s)
if self.options.expandEntities then
for k,v in pairs(self._ENTITIES) do
s = string.gsub(s,k,v)
end
end
return s
end
--- Parses a string representing a tag.
--@param s String containing tag text
--@return a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
local function parseTag(self, s)
local tag = {
name = string.gsub(s, self._TAG, '%1'),
attrs = {}
}
local parseFunction = function (k, v)
tag.attrs[k] = parseEntities(self, v)
tag.attrs._ = 1
end
string.gsub(s, self._ATTR1, parseFunction)
string.gsub(s, self._ATTR2, parseFunction)
if tag.attrs._ then
tag.attrs._ = nil
else
tag.attrs = nil
end
return tag
end
local function parseXmlDeclaration(self, xml, f)
-- XML Declaration
f.match, f.endMatch, f.text = string.find(xml, self._PI, f.pos)
if not f.match then
err(self, self._errstr.declErr, f.pos)
end
if f.match ~= 1 then
-- Must be at start of doc if present
err(self, self._errstr.declStartErr, f.pos)
end
local tag = parseTag(self, f.text)
-- TODO: Check if attributes are valid
-- Check for version (mandatory)
if tag.attrs and tag.attrs.version == nil then
err(self, self._errstr.declAttrErr, f.pos)
end
if fexists(self.handler, 'decl') then
self.handler:decl(tag, f.match, f.endMatch)
end
return tag
end
local function parseXmlProcessingInstruction(self, xml, f)
local tag = {}
-- XML Processing Instruction (PI)
f.match, f.endMatch, f.text = string.find(xml, self._PI, f.pos)
if not f.match then
err(self, self._errstr.piErr, f.pos)
end
if fexists(self.handler, 'pi') then
-- Parse PI attributes & text
tag = parseTag(self, f.text)
local pi = string.sub(f.text, string.len(tag.name)+1)
if pi ~= "" then
if tag.attrs then
tag.attrs._text = pi
else
tag.attrs = { _text = pi }
end
end
self.handler:pi(tag, f.match, f.endMatch)
end
return tag
end
local function parseComment(self, xml, f)
f.match, f.endMatch, f.text = string.find(xml, self._COMMENT, f.pos)
if not f.match then
err(self, self._errstr.commentErr, f.pos)
end
if fexists(self.handler, 'comment') then
f.text = parseEntities(self, stripWS(self, f.text))
self.handler:comment(f.text, next, f.match, f.endMatch)
end
end
local function _parseDtd(self, xml, pos)
-- match,endMatch,root,type,name,uri,internal
local dtdPatterns = {self._DTD1, self._DTD2, self._DTD3, self._DTD4, self._DTD5}
for i, dtd in pairs(dtdPatterns) do
local m,e,r,t,n,u,i = string.find(xml, dtd, pos)
if m then
return m, e, {_root=r, _type=t, _name=n, _uri=u, _internal=i}
end
end
return nil
end
local function parseDtd(self, xml, f)
f.match, f.endMatch, attrs = _parseDtd(self, xml, f.pos)
if not f.match then
err(self, self._errstr.dtdErr, f.pos)
end
if fexists(self.handler, 'dtd') then
local tag = {name="DOCTYPE", value=string.sub(xml, f.match+10, f.endMatch-1)}
self.handler:dtd(tag, f.match, f.endMatch)
end
end
local function parseCdata(self, xml, f)
f.match, f.endMatch, f.text = string.find(xml, self._CDATA, f.pos)
if not f.match then
err(self, self._errstr.cdataErr, f.pos)
end
if fexists(self.handler, 'cdata') then
self.handler:cdata(f.text, nil, f.match, f.endMatch)
end
end
--- Parse a Normal tag
-- Need check for embedded '>' in attribute value and extend
-- match recursively if necessary eg. <tag attr="123>456">
local function parseNormalTag(self, xml, f)
--Check for errors
while 1 do
--If there isn't an attribute without closing quotes (single or double quotes)
--then breaks to follow the normal processing of the tag.
--Otherwise, try to find where the quotes close.
f.errStart, f.errEnd = string.find(f.tagstr, self._ATTRERR1)
if f.errEnd == nil then
f.errStart, f.errEnd = string.find(f.tagstr, self._ATTRERR2)
if f.errEnd == nil then
break
end
end
f.extStart, f.extEnd, f.endt2 = string.find(xml, self._TAGEXT, f.endMatch+1)
f.tagstr = f.tagstr .. string.sub(xml, f.endMatch, f.extEnd-1)
if not f.match then
err(self, self._errstr.xmlErr, f.pos)
end
f.endMatch = f.extEnd
end
-- Extract tag name and attrs
local tag = parseTag(self, f.tagstr)
if (f.endt1=="/") then
if fexists(self.handler, 'endtag') then
if tag.attrs then
-- Shouldn't have any attributes in endtag
err(self, string.format("%s (/%s)", self._errstr.endTagErr, tag.name), f.pos)
end
if table.remove(self._stack) ~= tag.name then
err(self, string.format("%s (/%s)", self._errstr.unmatchedTagErr, tag.name), f.pos)
end
self.handler:endtag(tag, f.match, f.endMatch)
end
else
table.insert(self._stack, tag.name)
if fexists(self.handler, 'starttag') then
self.handler:starttag(tag, f.match, f.endMatch)
end
--TODO: Tags com fechamento automático estão sendo
--retornadas como uma tabela, o que complica
--para a app NCLua tratar isso. É preciso
--fazer com que seja retornado um campo string vazio.
-- Self-Closing Tag
if (f.endt2=="/") then
table.remove(self._stack)
if fexists(self.handler, 'endtag') then
self.handler:endtag(tag, f.match, f.endMatch)
end
end
end
return tag
end
local function parseTagType(self, xml, f)
-- Test for tag type
if string.find(string.sub(f.tagstr, 1, 5), "?xml%s") then
parseXmlDeclaration(self, xml, f)
elseif string.sub(f.tagstr, 1, 1) == "?" then
parseXmlProcessingInstruction(self, xml, f)
elseif string.sub(f.tagstr, 1, 3) == "!--" then
parseComment(self, xml, f)
elseif string.sub(f.tagstr, 1, 8) == "!DOCTYPE" then
parseDtd(self, xml, f)
elseif string.sub(f.tagstr, 1, 8) == "![CDATA[" then
parseCdata(self, xml, f)
else
parseNormalTag(self, xml, f)
end
end
--- Get next tag (first pass - fix exceptions below).
--@return true if the next tag could be got, false otherwise
local function getNextTag(self, xml, f)
f.match, f.endMatch, f.text, f.endt1, f.tagstr, f.endt2 = string.find(xml, self._XML, f.pos)
if not f.match then
if string.find(xml, self._WS, f.pos) then
-- No more text - check document complete
if #self._stack ~= 0 then
err(self, self._errstr.incompleteXmlErr, f.pos)
else
return false
end
else
-- Unparsable text
err(self, self._errstr.xmlErr, f.pos)
end
end
f.text = f.text or ''
f.tagstr = f.tagstr or ''
f.match = f.match or 0
return f.endMatch ~= nil
end
--Main function which starts the XML parsing process
--@param xml the XML string to parse
--@param parseAttributes indicates if tag attributes should be parsed or not.
-- If omitted, the default value is true.
function XmlParser:parse(xml, parseAttributes)
if type(self) ~= "table" or getmetatable(self) ~= XmlParser then
error("You must call xmlparser:parse(parameters) instead of xmlparser.parse(parameters)")
end
if parseAttributes == nil then
parseAttributes = true
end
self.handler.parseAttributes = parseAttributes
--Stores string.find results and parameters
--and other auxiliar variables
local f = {
--string.find return
match = 0,
endMatch = 0,
-- text, end1, tagstr, end2,
--string.find parameters and auxiliar variables
pos = 1,
-- startText, endText,
-- errStart, errEnd, extStart, extEnd,
}
while f.match do
if not getNextTag(self, xml, f) then
break
end
-- Handle leading text
f.startText = f.match
f.endText = f.match + string.len(f.text) - 1
f.match = f.match + string.len(f.text)
f.text = parseEntities(self, stripWS(self, f.text))
if f.text ~= "" and fexists(self.handler, 'text') then
self.handler:text(f.text, nil, f.match, f.endText)
end
parseTagType(self, xml, f)
f.pos = f.endMatch + 1
end
end
XmlParser.__index = XmlParser
return XmlParser

13
lua/command.txt Normal file
View File

@@ -0,0 +1,13 @@
commandArray['Switch']='On'
commandArray['Scene:Livingroom']='On'
commandArray['Group:Kitchen']='Inactive'
commandArray['Keyfob']='Group On'
commandArray['DimmableDevice']='Set Level 50'
commandArray['Selector']='Set Level: 50'
commandArray['SendNotification']='subject#body#0'
commandArray['SendEmail']='subject#body#your@email.com'
commandArray['OpenURL']='www.yourdomain.com/api/movecamtopreset.cgi'
commandArray['Blinds']='On RANDOM 30'
commandArray['Porch Light']='On FOR 2'
commandArray['Variable:MyVar']='Some value'
commandArray['Variable:MyVar']='Some value AFTER 3'

1053
lua/fonctions2.lua Executable file

File diff suppressed because it is too large Load Diff

145
lua/forecast.lua Normal file
View File

@@ -0,0 +1,145 @@
local cjson = require "cjson"
-- Exemple de JSON
local json_str = [[
{
"cod": "200",
"message": 0,
"cnt": 40,
"list": [
{
"dt": 1718312400,
"main": {
"temp": 12.84,
"feels_like": 12.61,
"temp_min": 12.84,
"temp_max": 13.87,
"pressure": 1010,
"sea_level": 1010,
"grnd_level": 1004,
"humidity": 93,
"temp_kf": -1.03
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "légère pluie",
"icon": "10n"
}
],
"clouds": {
"all": 100
},
"wind": {
"speed": 6.07,
"deg": 200,
"gust": 11.82
},
"visibility": 10000,
"pop": 1,
"rain": {
"3h": 1.17
},
"sys": {
"pod": "n"
},
"dt_txt": "2024-06-13 21:00:00"
},
{
"dt": 1718323200,
"main": {
"temp": 14.27,
"feels_like": 14.21,
"temp_min": 14.27,
"temp_max": 15.25,
"pressure": 1009,
"sea_level": 1009,
"grnd_level": 1002,
"humidity": 94,
"temp_kf": -0.98
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "légère pluie",
"icon": "10n"
}
],
"clouds": {
"all": 100
},
"wind": {
"speed": 5.33,
"deg": 255,
"gust": 9.41
},
"visibility": 10000,
"pop": 1,
"rain": {
"3h": 0.18
},
"sys": {
"pod": "n"
},
"dt_txt": "2024-06-14 00:00:00"
},
{
"dt": 1718334000,
"main": {
"temp": 13.46,
"feels_like": 13.37,
"temp_min": 13.46,
"temp_max": 13.46,
"pressure": 1008,
"sea_level": 1008,
"grnd_level": 1002,
"humidity": 96,
"temp_kf": 0
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "légère pluie",
"icon": "10n"
}
],
"clouds": {
"all": 77
},
"wind": {
"speed": 3.98,
"deg": 240,
"gust": 10.97
},
"visibility": 10000,
"pop": 0.2,
"rain": {
"3h": 0.1
},
"sys": {
"pod": "n"
},
"dt_txt": "2024-06-14 03:00:00"
},
...
]
}
]]
-- Décoder le JSON
local data = cjson.decode(json_str)
-- Extraire les 6 premières valeurs du champ "all"
local cloud_values = {}
for i = 1, math.min(6, #data.list) do
table.insert(cloud_values, data.list[i].clouds.all)
end
-- Afficher les valeurs extraites
for i, value in ipairs(cloud_values) do
print("Cloud coverage for point " .. i .. ": " .. value)
end

724
lua/functions.lua Executable file
View File

@@ -0,0 +1,724 @@
--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

135
lua/iphone.luaTMP Executable file
View File

@@ -0,0 +1,135 @@
-- ==============================
-- Cherche la position iphone sur icloud
-- ==============================
-- Variables
-- 1) User et mot de passe icloud
username = "votre.login@icloud.com"
password = "votre mot de passe icloud"
-- 2) Pour chaque iPhone déclaré : associer le nom du device de présence
devices = {
["iPhone de Georges-David"] = "Presence GD"
-- , ["iPhone de Jean-Michel"] = "Présence JM"
-- , ["iPhone de Pierre-André"] = "Présence PA"
}
-- 3) Pour chaque iPhone déclaré : associer adresse IP et le nom du device de présence
ips= {
["192.168.0.20"] = "moi"
-- , ["xxx.xxx.xxx"] = "Présence JM"
-- , ["xxx.xxx.xxx"] = "Présence PA"
}
-- 4) Position de la maison, "lat, long" as given by google map
coordonneesGoogleDeLaMaison="47.726695, -2.131950"
--(43.693982097361, 0.00010012119960745)
-- 5) Périmètre de considération de la maison
-- NB : 0.001 = 0.111 kilometres soit 111 metres
skew = 0.001
-- ==============================
commandArray = {}
print('Script v01 script_time_localisation.lua')
function debug(m)
print("........ localisation "..m)
end
function Allumer(item)
if otherdevices[item] ~= 'On' then commandArray[item] = 'On' end
end
function Eteindre(item)
if otherdevices[item] ~= 'Off' then commandArray[item] = 'Off' end
end
-- Time to run?
time = os.date("*t")
-- toutes les minutes, on allume si l'adresse IP répond au ping
-- ce mécanisme n'est pas utilisé pour éteindre : contrairement
-- à Android, l'IPhone éteint le wifi quand il est en veille.
for ip, devicePresence in pairs(ips) do
-- local status = os.execute("ping -W 1 -q -c 1 "..ip) !! pas bon, comme as dit papoo
local status = os.execute("ping -W 1 -q -c 4 "..ip)
if status == true then
Allumer(devicePresence)
end
end
-- On vérifie toute les 10 minutes
if time.min % 10 == 2 then
--- Faire un premier appel pour recherche la position
urlCloud1 = ("curl -s -X POST -D - -o /dev/null -L -u '" .. username .. ":" .. password .. "' "
.. "-H 'Content-Type: application/json; charset=utf-8' "
.. "-H 'X-Apple-Find-Api-Ver: 2.0' "
.. "-H 'X-Apple-Authscheme: UserIdGuest' "
.. "-H 'X-Apple-Realm-Support: 1.0' "
.. "-H 'User-agent: Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)' "
.. "-H 'X-Client-Name: iPad' "
.. "-H 'X-Client-UUID: 0cf3dc501ff812adb0b202baed4f37274b210853' "
.. "-H 'Accept-Language: en-us' "
.. "-H 'Connection: keep-alive' https://fmipmobile.icloud.com/fmipservice/device/"
.. username .."/initClient")
-- debug("urlCloud1="..urlCloud1)
local handle = io.popen(urlCloud1)
local result = handle:read("*all")
handle:close()
-- Récupération de la position dans le resultat de la premiere URL
stageServer = string.match(result, "X%-Apple%-MMe%-Host%:%s(.*%.icloud%.com)")
-- Faire la deuxième url en cherchant le nom du tel / ipad ou autre avec jq
urlCloud2 = ("curl -s -X POST -L -u '" .. username .. ":" .. password .. "' "
.. "-H 'Content-Type: application/json; charset=utf-8' "
.. "-H 'X-Apple-Find-Api-Ver: 2.0' "
.. "-H 'X-Apple-Authscheme: UserIdGuest' "
.. "-H 'X-Apple-Realm-Support: 1.0' "
.. "-H 'User-agent: Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)' "
.. "-H 'X-Client-Name: iPad' -H 'X-Client-UUID: 0cf3dc501ff812adb0b202baed4f37274b210853' "
.. "-H 'Accept-Language: en-us' "
.. "-H 'Connection: keep-alive' "
.. "https://" .. stageServer .. "/fmipservice/device/" .. username .."/initClient ")
-- debug("urlCloud2="..urlCloud2)
local handle = io.popen(urlCloud2)
local result = handle:read("*all")
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
local jsonPosition = json:decode(result)
handle:close()
latMaison, lonMaison = string.match(coordonneesGoogleDeLaMaison, "(%d+.%d+), (%d+.%d+)")
for i, iPhone in ipairs(jsonPosition.content) do
devicePresence=devices[iPhone.name]
debug("iPhone.name="..iPhone.name.."; devicePresence="..devicePresence
.."; iPh pos=("..iPhone.location.latitude..", "..iPhone.location.longitude..")")
if devicePresence ~= nil then
-- iPhone connu, on teste la position
distance=math.sqrt((111*(latMaison-iPhone.location.latitude))^2
+ (111*(lonMaison-iPhone.location.longitude))^2)
debug("Distance="..distance
..", TimeStamp="..iPhone.location.timeStamp
..", deltaT="..math.floor(os.time()-iPhone.location.timeStamp/1000).."s")
ici = ((math.abs(latMaison-iPhone.location.latitude) <= skew)
and (math.abs(lonMaison-iPhone.location.longitude) <= skew))
if ici then
Allumer(devicePresence)
debug(iPhone.name.." est ici!")
else
Eteindre(devicePresence)
debug(iPhone.name.." est absent!")
end
end
end
end
--Fin du script
return commandArray

44
lua/meteo.lua Normal file
View File

@@ -0,0 +1,44 @@
-- Chargement de la bibliothèque Lua pour effectuer des requêtes HTTP
local http = require("socket.http")
local json = require("json")
-- Fonction pour effectuer une requête HTTP et renvoyer le contenu JSON en tant que tableau
function getJsonFromUrl(url)
local response = http.request(url) -- Effectue la requête HTTP
return json.decode(response) -- Décode la réponse JSON en tant que tableau
end
-- Fonction récursive pour rechercher une valeur dans un tableau multidimensionnel
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
-- Exemple d'utilisation
local url = "http://api.openweathermap.org/data/2.5/weather?q=La gacilly,fr&APPID=feba3f4d926db3b358a25ec782bd1c8b&lang=FR&units=metric" -- URL à appeler
local jsonData = getJsonFromUrl(url) -- Appel de la fonction pour obtenir le tableau JSON
-- Affichage du contenu du tableau JSON
for k, v in pairs(jsonData) do
print(k, v)
end
-- Recherche d'une valeur spécifique dans le tableau JSON
local searchValue = "valeurRecherchee"
local searchResult = searchValueInTable(searchValue, jsonData)
if searchResult then
print("La valeur", searchValue, "a été trouvée à la clé", searchResult)
else
print("La valeur", searchValue, "n'a pas été trouvée dans le tableau")
end

1035
lua/modules.lua Normal file

File diff suppressed because it is too large Load Diff

481
lua/old/script_device_Energie.old Executable file
View File

@@ -0,0 +1,481 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The print command will output lua print statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do print(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do print(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
require "scripts/lua/functions"
time = os.time()
annee = os.date('%Y',time)
mois = os.date('%m',time)
heures = tonumber(os.date('%H',time))
minutes = tonumber(os.date('%M',time))
secondes = tonumber(os.date('%S',time))
jour = tonumber(os.date('%w',time))
jour_s = os.date('%d',time)
heurmin = heures * 60 + minutes
PUISSANCE_DELESTAGE = 750 -- Watts
function update_meter(device, id, power, energy, index)
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
end
local function round(num, dec)
--print("Round "..tostring(num))
return ( math.floor( tonumber(num) * 10^dec ) / 10^dec )
end
local function updatenum(dev, 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 getConsommationHC(idx)
date=annee..'-'..mois..'-'..jour_s
--date_end=annee..'-'..mois..'-'..math.floor(jour_s + 1)
-- query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
-- .. ' and date like "' .. date ..'%"'
-- .. ' and (date >= "' .. date_deb.. ' 21:29:59" or date <= "'.. date_deb ..' 05:30:00")'
query = 'select sum(hc) from (select max(value) - min(value) as hc from Meter mc where DeviceRowID =' ..idx
.. ' and date like "' .. date ..'%"'
.. ' and (date >= "' .. date.. ' 21:29:59"'
.. ' and date < "' .. date ..' 23:59:59")'
.. ' union all'
.. ' select max(value) - min(value) as hc from Meter mc where DeviceRowID =' .. idx
.. ' and date like "' .. date ..'%"'
.. ' and (date < "' .. date ..' 05:30:00")'
.. ' and (date > "' .. date ..' 00:00:00")'
.. ') as c'
--query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
-- .. ' and date like "' .. date ..'%"'
-- .. ' and not(date > "' .. date.. ' 05:29:59" and date <= "'.. date ..' 21:30:00")'
print("query="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
if aRows[1][1] then
print("Retour executeQuery "..tostring(bSuccess)..' '..aRows[1][1])
return aRows[1][1]
end
print('retour à 0')
return 0
end
function getConsommationHP(idx)
date=annee..'-'..mois..'-'..jour_s
query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
.. ' and date like "' .. date ..'%"'
.. ' and (date > "' .. date.. ' 05:29:59" and date <= "'.. date ..' 21:30:00")'
--print("query="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
--print("Retour executeQuery "..tostring(bSuccess)..' '..aRows[1][1])
return aRows[1][1]
end
function deleteWrongData(idx)
-- delete from MultiMeter where DeviceRowid = 1135 and date >= "2021-06-02 00:00:00"
-- and date like "2021-06-02 00:00%";
date=annee..'-'..mois..'-'..jour_s
query = 'delete from MultiMeter where DeviceRowID =' ..idx
.. ' and date like "' .. date ..' 00:00%"'
.. ' and (date >= "' .. date.. ' 00:00:00")'
print("query delete="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
end
commandArray = {}
-- ==================================================================
-- INTENSITE_GENERALE
-- ==================================================================
if (devicechanged['Oregon_Conso']) then
local tab = getValuesInTab('Oregon_Conso')
print("Conso "..otherdevices['Oregon_Conso'])
values = split(otherdevices['Oregon_Conso'], ";")
if (tonumber(values[1]) < 0) then
if (tonumber(values[1]) == -0.1) then
watt = - tonumber(values[2])
else
watt = tonumber(values[1]) * 100 - tonumber(values[2])
end
else
watt = (tonumber(values[1]) * 100 + tonumber(values[2])) --/ 1.42
end
watt = watt - 80
print("Conso "..tostring(watt))
--print("mesure"..otherdevices['INTENSITE_GENERALE'])
amp = watt / 230 --math.max(0,round(otherdevices['INTENSITE_GENERALE'],3) - 0.54) * 7 / 8
watt_conso = watt --* 0.9459
updatenum('INTENSITE_GENERALE', amp)
print("consommation Amp="..tostring(amp).." conso="..tostring(watt_conso))
updatenum('CONSOMMATION_GENERALE', round(watt_conso,0))
local tab = getValuesInTab('SolaireProduction')
local watt_solaire = tonumber(tab[1])
local watt_solaire_jour = otherdevices_svalues['SolaireProduction']
print("Suivi "..tostring(watt_conso - watt_solaire))
if (minutes%5 == 0) then
date = annee..'-'..mois..'-'..jour_s
counter_conso = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Consommation_Apparente']..' order by Date desc limit 1;"')
counter_conso=tonumber(counter_conso) or 0
print('counter_conso='..counter_conso)
value_conso = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Consommation_Apparente']..' order by Date desc limit 1;"')
value_conso=tonumber(value_conso) or 0
print('value_conso='..value_conso)
counter_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
counter_solar=tonumber(counter_solar) or 0
print('counter_solar='..counter_solar)
value_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
value_solar=tonumber(value_solar) or 0
print('value_solar='..value_solar)
counter_injection = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['INJECTION']..' order by Date desc limit 1;"')
counter_injection=tonumber(counter_injection) or 0
print('counter_injection='..counter_injection)
value_injection = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['INJECTION']..' order by Date desc limit 1;"')
value_injection=tonumber(value_injection) or 0
print('value_injection='..value_injection)
counter_radiateur = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Injection_Radiateur']..' order by Date desc limit 1;"')
counter_radiateur=tonumber(counter_radiateur) or 0
print('counter_radiateur='..counter_radiateur)
value_radiateur = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Injection_Radiateur']..' order by Date desc limit 1;"')
value_radiateur=tonumber(value_radiateur) or 0
print('value_radiateur='..value_radiateur)
cumul_solar = value_solar - counter_solar
cumul_injection = value_injection - counter_injection
consommation = value_conso - counter_conso
cumul_radiateur = value_radiateur - counter_radiateur
print('conso='..consommation)
print('cumul_solar='..cumul_solar)
print('cumul_injection='..cumul_injection)
print('cumul_radiateur='..cumul_radiateur)
if (cumul_solar > 0) then
print("auto consommation="..tostring(
round((100 * (cumul_solar - cumul_injection) / cumul_solar),1))
)
commandArray['AUTO_CONSOMMATION'] = otherdevices_idx['AUTO_CONSOMMATION'] ..'|0|' .. tostring(
round((100 * (cumul_solar - cumul_injection) / cumul_solar),1)
)
updatenum('AUTO_CONSOMMATION', round((100 * (cumul_solar - cumul_injection) / cumul_solar),1)
)
end
if (consommation > 0) then
print("auto production="..tostring(100 * cumul_solar / (cumul_solar + consommation)))
updatenum('AUTO_PRODUCTION', round(100 * cumul_solar / (cumul_solar + consommation),1))
end
updatenum('COUVERTURE', round(100 * value_solar / (value_conso + value_solar),1))
if (cumul_solar > 0) then
updatenum('Consommation_Efficace', round(100 *((cumul_solar - cumul_radiateur) / cumul_solar), 1))
else
updatenum('Consommation_Efficace', 0)
end
end
end
if (devicechanged['Oregon_Solaire']) then
values2 = split(otherdevices['Mesure_Courant'], ";")
print("Solaire production 2"..otherdevices['Mesure_Courant'])
local tab = getValuesInTab('Oregon_Solaire')
print("Solaire "..otherdevices['Oregon_Solaire'])
values = split(otherdevices['Oregon_Solaire'], ";")
if (tonumber(values[1]) < 0) then
if (tonumber(values[1]) == -0.1) then
watt = - tonumber(values[2])
else
watt = tonumber(values[1]) * 100 - tonumber(values[2])
end
else
watt = math.max(0, (tonumber(values[1]) * 100 + tonumber(values[2])))
end
print("Solaire "..tostring(watt))
watt = tonumber(values2[1])
if (watt > 1000) then
watt = 0;
end
--updatenum('SolaireIntensite', round(watt / 230,3))
--updatenum('INTENSITE_GENERALE', round(watt / 230,3))
watt = math.abs(watt) --- 56
--if (watt < 0 or (heures <= 7 or heures >= 21)) then
-- watt = 0
--end
--print("Intensite solaire "..devicechanged['SolaireIntensite'])
amp = math.abs(watt / 230); --math.max(0, round(otherdevices['SolaireIntensite'],3) - 0.54) *1.18
updatenum('SolaireIntensite', amp)
print("# 2 # production amp="..tostring(amp).." watt="..tostring(watt))
updatenum('SolaireProduction', round(watt,1))
watt_solaire = math.abs(watt)
local tab = getValuesInTab('CONSOMMATION_GENERALE')
local watt_conso = tonumber(tab[1])
local tab_r = getValuesInTab('Consommation_Apparente')
local watt_reel = tonumber(tab_r[1])
if (watt_reel > 0) then
if watt_solaire > 0 then
updatenum('COUVERTURE_INSTANTANEE', round(100 * (watt_solaire / (watt_solaire + watt_reel)), 1))
else
updatenum('COUVERTURE_INSTANTANEE', 0)
end
else
updatenum('COUVERTURE_INSTANTANEE', 100)
end
end
if (devicechanged['Oregon_Conso_Reelle']) then
local tab = getValuesInTab('Oregon_Conso_Reelle')
print("Conso réelle "..otherdevices['Oregon_Conso_Reelle'])
values = split(otherdevices['Oregon_Conso_Reelle'], ";")
if (tonumber(values[1]) < 0) then
if (tonumber(values[1]) == -0.1) then
watt = - tonumber(values[2])
else
watt = tonumber(values[1]) * 100 - tonumber(values[2])
end
else
watt = math.max(0, (tonumber(values[1]) * 100 + tonumber(values[2])))
end
watt = 20 + watt * 1.10
print("Conso réelle "..tostring(watt))
updatenum('Consommation_Apparente', round(watt,0))
values = split(otherdevices['SolaireProduction'], ";")
print("Solaire production "..otherdevices['SolaireProduction'])
watt_solaire = values[1]
values2 = split(otherdevices['Mesure_Courant'], ";")
print("Solaire production 2"..otherdevices['Mesure_Courant'])
watt_solaire = values[1] --+ values2[1]
print("Watt solaire "..watt_solaire)
if (watt < 0) then
updatenum('INJECTION', - round(watt,0))
updatenum('TOTAL_INJECTION', - round(watt,0))
--updatenum('Consommation_Apparente', 0)
updatenum('TOTAL_AUTOCONSOMMATION', round(watt_solaire - math.abs(watt), 0))
else
updatenum('INJECTION', 0)
updatenum('TOTAL_INJECTION', 0)
updatenum('TOTAL_AUTOCONSOMMATION', round(watt_solaire,0))
end
-- =========================================================
--Calculate what the house is consuming
-- Get current date & time
t1 = os.time()
local currentDate = os.date("*t"); -- sets up currentDate.[table]
-- (currentDate.year [full], .month [1-12], .day [1-31], .hour [0-23], .min [0-59], .sec [0-59], .wday [0-6 {Sun-Sat}])
sCurrentTime = currentDate.year .. "-" .. currentDate.month .. "-" .. currentDate.day .. " " .. currentDate.hour .. ":" .. currentDate.min .. ":" .. currentDate.sec
counter_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
counter_solar=tonumber(counter_solar) or 0
print('counter_solar='..counter_solar)
value_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
value_solar=tonumber(value_solar) or 0
print('value_solar='..value_solar)
---------------------------------------------------------------------------------------
-- Solaire 2
date = annee..'-'..mois..'-'..jour_s
counter_solar2 = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Mesure_Courant']..
' and date like "' .. date ..'%"'..
' order by Date desc limit 1;"')
counter_solar2=tonumber(counter_solar2) or 0
print('counter_solar2='..counter_solar2)
value_solar2 = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Mesure_Courant']..
' and date like "' .. date ..'%"'..
' order by Date desc limit 1;"')
value_solar2=tonumber(value_solar2) or 0
print('value_solar2='..value_solar2)
--------------------------------------------------------------------------------------
watt_p1 = getConsommationHP(1123) or 0
watt_p2 = getConsommationHC(1123) or 0
local cmd = '1135|0|'
--USAGE1= energy usage meter tariff 1, This is an incrementing counter
--USAGE2= energy usage meter tariff 2, This is an incrementing counter
--RETURN1= energy return meter tariff 1, This is an incrementing counter
--RETURN2= energy return meter tariff 2, This is an incrementing counter
--CONS= actual usage power (Watt)
--PROD= actual return power (Watt)
.. tostring(math.floor(watt_p1)) .. ';'
.. tostring(math.floor(watt_p2)) .. ';'
-- + value_solar2 - counter_solar2
.. tostring(math.floor(value_solar - counter_solar + value_solar2 - counter_solar2)) .. ';'
.. '0;'
.. tostring(math.floor(math.max(0,watt) + watt_solaire)).. ';'
.. tostring(math.floor(watt_solaire)) --math.floor(ConsumoEnergyBalance / 1000)) --round(watt,0))
print('Consommation_Reelle_2 '..cmd)
if heures == 23 and minutes == 59 and secondes >= 45 then
-- ignored
else
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end
if heures == 00 and minutes == 05 and secondes <= 10 then
deleteWrongData(1135)
end
print('when light=' .. tostring(whenLight()))
-- =========================================================
local cmd = '1136|0|'
--USAGE1= energy usage meter tariff 1, This is an incrementing counter
--USAGE2= energy usage meter tariff 2, This is an incrementing counter
--RETURN1= energy return meter tariff 1, This is an incrementing counter
--RETURN2= energy return meter tariff 2, This is an incrementing counter
--CONS= actual usage power (Watt)
--PROD= actual return power (Watt)
.. '0;'
.. '0;'
.. '0;'
.. '0;'
.. tostring(math.floor(math.max(0,watt))).. ';'
.. '0' --math.floor(ConsumoEnergyBalance / 1000)) --round(watt,0))
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
updatenum('Non_Couvert_2', math.floor(math.max(0,watt)))
-- =========================================================
local debut_injection = -20
local fin_injection = 10
if tonumber(watt_solaire) < 50 or uservariables["Dark"] == "True" then
commandArray['Dimmer'] = 'Set Level: 30'
else
if (watt < debut_injection and tonumber(watt_solaire) > 150) then
print("Allumage radiateur pour éviter l'injection " .. tostring(lastUpdateOfDevice('RadiateurBureau')))
if watt < debut_injection then
local quick_value=math.floor(math.abs(watt / (PUISSANCE_DELESTAGE / 100)))
print("quick_value plus="..tostring(quick_value))
os.execute('curl "http://192.168.125.11/plus?value=' .. tostring(quick_value).. '"');
else
commandArray['Dimmer'] = 'Set Level: 40'
end
else
print("Pas de consommation necessaire")
if (watt > 150) then
commandArray['Dimmer'] = 'Set Level: 30'
else
if (watt > fin_injection) then
local quick_value=math.floor(math.abs(watt / (PUISSANCE_DELESTAGE / 100)))
print("quick_value minus="..tostring(quick_value))
os.execute('curl "http://192.168.125.11/minus?value=' .. tostring(quick_value).. '"');
else
commandArray['Dimmer'] = 'Set Level: 50'
end
end
end
end
command = 'curl -s "http://192.168.125.11"|grep "<p>"|awk -F">" \'{print $2}\'|awk -F"<" \'{print $1}\''
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
print("result niveau d'injection= "..result)
updatenum('Injection_Radiateur', tonumber(result) * PUISSANCE_DELESTAGE / 100)
if (tonumber(result) == 1) then
commandArray['Dimmer'] = 'Set Level: 30'
end
end
return commandArray

View File

@@ -0,0 +1,210 @@
require "scripts/lua/functions"
commandArray = {}
--local switch = 'VoletCuisine'
-- ------------------------------------------------------------------------------
--recupere les minutes
-- ------------------------------------------------------------------------------
time=os.time()
minutes=tonumber(os.date('%M',time))
jour=tonumber(os.date('%w',time))
heures=tonumber(os.date('%H',time))
heurmin= heures * 60 + minutes
-- ------------------------------------------------------------------------------
-- Test temperature radiateur chambres
-- ------------------------------------------------------------------------------
function gestionRadiateur( switchTemp, switchRadiateur, consigne)
if (minutes % 10 ~= 5) then
return
end
local last = lastUpdateOfDevice(switchRadiateur)
debug("--------------"..switchRadiateur.."-----------------------------------")
debug("delai="..tostring(delai).." last="..tostring(last)..' Chauffage='..otherdevices[switchRadiateur])
debug("------------------------------------------------------------")
if (last < 600) then
debug("Aucune action. Mise à jour trop récente.".." last="..tostring(last).." temp="..tostring(currentTemp).." / Consigne="..tostring(consigne))
return
end
local delta = 0.2
local currentTemp = tonumber(otherdevices_svalues[switchTemp])
local tempAbsence = tonumber(otherdevices_svalues['ConsigneAbsence'])
local variation = variationTemp2(switchTemp, 10) -- variation des 10 dernières minutes
local variationExt = uservariables['AugmentationTempExterieure']
local augmentation = variation * 60 / 10 --time -- ° par heure
local ecart = consigne - currentTemp
local estimation = 0.0
if (augmentation > 0 and ecart > 0) then
estimation = 60 * ecart / augmentation
end
debug("Retour augmentation="..tostring(augmentation).." ecart="..tostring(ecart)..'°C Estimation='..tostring(estimation).." minutes variationExt="..tostring(variationExt).."°C / heure")
--2016-02-27 20:08:59.864 LUA: delai=180 last=37
--2016-02-27 20:08:59.918 LUA: Retour variation=0.3 switch=RadiateurManon
--2016-02-27 20:08:59.918 LUA: CHECK Temperature Variation=0.3 switch=RadiateurManon currentTemp=18.3 tempAbsence=16 consigne=18.5
debug("Retour variation="..tostring(variation).." switch="..switchRadiateur..' lastUpdate='..tostring(lastUpdateOfDevice(switchRadiateur)))
debug('CHECK Temperature Variation='..tostring(variation)..' switch='..switchRadiateur..' currentTemp='..tostring(currentTemp).. ' tempAbsence='..tostring(tempAbsence)..' consigne='..tostring(consigne))
if otherdevices['ChauffageGeneral'] == 'Off' then
if (minutes%30 == 0) then
switchOffRadiateur(switchRadiateur)
debug("ChauffageGeneral Eteint. Demande extinction.")
else
debug("Radiateur ="..switchRadiateur.." Retour sans rien faire. ChauffageGeneral Eteint.")
end
end
if lastUpdateOfDevice(switchRadiateur) < delai then
debug("Radiateur ="..switchRadiateur.." Retour sans rien faire. Delai non atteint.")
return
end
-- Periode de vacances ou absence ==> hors gel
if (otherdevices['Vacances'] == 'On' or otherdevices['AbsenceFamille'] == 'On') then
if (currentTemp > 14) then
switchOffRadiateur(switchRadiateur)
--commandArray[switchRadiateur]='Off'
else
if variation <= 0 then
--commandArray[switchRadiateur]='On'
switchOnRadiateur(switchRadiateur)
end
end
debug ('CHECK Temperature chambre : Vacances -> ' ..otherdevices_svalues[switchTemp]..' switch='..switchRadiateur)
else
debug ('CHECK Temperature: Presence -> ' ..otherdevices_svalues[switchTemp]..' '..josdGetJourSemaine(jour))
-- Température non atteinte
if (currentTemp < consigne) then
if variation <= 0.0 then
-- commandArray[switchRadiateur]='On'
switchOnRadiateur(switchRadiateur)
debug("Demande chauffe : "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
else
--switchIfNeeded(switchRadiateur, 'On')
-- Dépassement prévu dans le delai on coupe
if (estimation > 0 and estimation <= delai / 60 ) then
--commandArray[switchRadiateur] = 'Off'
switchOffRadiateur(switchRadiateur)
debug("Arrêt chauffage : Température sera atteinte dans le delai "..tostring(estimation).." Minutes")
else
debug("Aucune action. Chauffage en-cours."..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
end
end
-- Température dépassée
else
-- Température supérieure
if (currentTemp >= consigne + delta or (estimation > 0 and estimation <= delai / 60 )) then
if (consigne == consigneAbsence) then
-- rien
switchIfNeeded(switchRadiateur,"Off")
else
if (variation > 0) then
if (variationExt <= 0) then
switchOffRadiateur(switchRadiateur)
debug("Demande arrêt. Température dépassée.")
else
switchIfNeeded(switchRadiateur,"Off")
debug("Aucune action. Augmentation due à température extérieure.")
end
end
end
else
-- Augmentation de la température non due à l'augmentation extérieure
if (variation > 0) then
-- Pas d'augmentation extérieure
if (variationExt <= 0) then
--commandArray[switchRadiateur]='Off'
switchOffRadiateur(switchRadiateur)
debug("Demande arrêt. Température atteinte et continue d'augmenter.")
else
switchIfNeeded(switchRadiateur,"Off")
debug("Aucune action. Augmentation due à température extérieure.")
end
else
-- Températue en baisse pas nécessaire d'envoyer
--switchOffRadiateur(switchRadiateur)
--commandArray[switchRadiateur]='Off'
--switchIfNeeded(switchRadiateur, 'Off')
switchIfNeeded(switchRadiateur,"Off")
debug("Aucune action. Temperature atteinte et pas d'augmentation. "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
end
end
end
end
debug("------------------------------------------------------------")
end
-- ------------------------------------------------------
-- Arrêt tous les radiateurs
-- ------------------------------------------------------
if devicechanged['ChauffageGeneral'] then
if otherdevices['ChauffageGeneral'] == 'Off' then
for i = 1, 7 do
print("Arrêt radiateur="..radiateurs[i])
commandArray[radiateurs[i]]='Off'
end
end
end
-- ------------------------------------------------------
-- Chambre de Manon
-- ------------------------------------------------------
if devicechanged['ChambreManon'] or devicechanged['ConsigneConfortManon'] or devicechanged['ChauffageGeneral'] then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortManon'])
gestionRadiateur('ChambreManon', 'RadiateurManon', consigne)
end
-- ------------------------------------------------------
-- Chambre de Theo
-- ------------------------------------------------------
if devicechanged['ChambreTheo'] or devicechanged['ConsigneConfortTheo'] or devicechanged['ChauffageGeneral'] then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortTheo'])
gestionRadiateur('ChambreTheo', 'RadiateurTheo', consigne)
end
-- ------------------------------------------------------
-- Chambre parents
-- ------------------------------------------------------
if devicechanged['Chambre'] or devicechanged['ConsigneConfortChambre'] or devicechanged['ChauffageGeneral'] then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortChambre'])
gestionRadiateur('Chambre', 'RadiateurChambre', consigne)
end
-- ------------------------------------------------------
-- Radiateur cuisine
-- ------------------------------------------------------
if devicechanged['TemperatureBarometre'] or devicechanged['ConsigneConfortSalon'] or devicechanged['ChauffageGeneral'] then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortSalon'])
gestionRadiateur('TemperatureBarometre', 'RadiateurCuisine', consigne)
end
-- ------------------------------------------------------
-- Radiateur Salon
-- ------------------------------------------------------
if devicechanged['TemperatureBarometre'] or devicechanged['ConsigneConfortSalon'] or devicechanged['ChauffageGeneral'] then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortSalon'])
gestionRadiateur('TemperatureBarometre', 'RadiateurSalon1', consigne)
gestionRadiateur('TemperatureBarometre', 'RadiateurSalon2', consigne)
end
-- ------------------------------------------------------
-- Radiateur Bureau
-- ------------------------------------------------------
if devicechanged['Bureau'] or devicechanged['ConsigneConfortBureau'] or devicechanged['ChauffageGeneral'] then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortBureau'])
gestionRadiateur('Bureau', 'RadiateurBureau', consigne)
--gestionRadiateur('TemperatureBarometre', 'RadiateurSalon2', consigne)
end
return commandArray

39
lua/old/script_device_demo.old Executable file
View File

@@ -0,0 +1,39 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The print command will output lua print statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do print(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do print(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
print('this will end up in the domoticz log')
commandArray = {}
if (devicechanged['MyDeviceName'] == 'On' and otherdevices['MyOtherDeviceName'] == 'Off') then
commandArray['MyOtherDeviceName']='On'
end
return commandArray

143
lua/old/script_time_DewPoint.old Executable file
View File

@@ -0,0 +1,143 @@
--[[
~/domoticz/scripts/lua/script_device_givre.lua
auteur : papoo
MAJ : 28/02/2018
création : 06/05/2016
Principe :
Calculer via les informations température et hygrométrie d'une sonde extérieure
le point de rosée ainsi que le point de givre
puis en comparant ensuite le point de givre et l'a température extérieure, création d'une alerte givre.
http://pon.fr/script-calcul-et-alerte-givre/
http://easydomoticz.com/forum/viewtopic.php?f=21&t=1085&start=10#p17545
https://github.com/papo-o/domoticz_scripts/blob/master/Lua/script_device_givre.lua
--]]
--------------------------------------------
------------ Variables à éditer ------------
--------------------------------------------
require "scripts/lua/functions"
local debugging = true -- true pour voir les logs dans la console log Dz ou false pour ne pas les voir
local temp_ext = 'BarometreLaGacilly' -- nom de la sonde de température/humidité extérieure
local dev_dew_point = 'Point de rosee' -- nom de l'éventuel dummy température point de rosée si vous souhaitez le suivre sinon nil
local dev_freeze_point = 'Point de givre' -- nom de l'éventuel dummy température point de givre si vous souhaitez le suivre sinon nil
local dev_hum_abs_point = nil -- nom de l'éventuel dummy humidité absolue si vous souhaitez le suivre sinon nil
local dev_freeze_alert = 'Alerte givre' -- nom de l'éventuel dummy alert point de givre si vous souhaitez le suivre sinon nil
--------------------------------------------
----------- Fin variables à éditer ---------
--------------------------------------------
local nom_script = 'Point de rosée et point de givrage'
local version = 1.2 -- version du script
commandArray = {}
--------------------------------------------
---------------- Fonctions -----------------
--------------------------------------------
function voir_les_logs (s, debugging)
if (debugging) then
if s ~= nil then
debug ("<font color='#f3031d'>".. tostring(s) .."</font>");
else
debug ("<font color='#f3031d'>aucune valeur affichable</font>");
end
end
end
function round(value, digits)
if not value or not digits then
return nil
end
local precision = 10^digits
return (value >= 0) and
(math.floor(value * precision + 0.5) / precision) or
(math.ceil(value * precision - 0.5) / precision)
end
function dewPoint (T, RH)
local b,c = 17.67, 243.5
--voir_les_logs("--- 1",debugging)
RH = math.max (tonumber(RH), 1e-3)
--voir_les_logs("--- 1",debugging)
local gamma = math.log (tonumber(RH)/100) + b * T / (c + T)
--voir_les_logs("--- 1",debugging)
return c * gamma / (b - gamma)
end
function freezing_point(dp, t)
if not dp or not t or dp > t then
return nil, " La température du point de rosée est supérieure à la température. Puisque la température du point de rosée ne peut être supérieure à la température de l'air , l\'humidité relative a été fixée à nil."
end
T = t + 273.15
Td = dp + 273.15
return (Td + (2671.02 /((2954.61/T) + 2.193665 * math.log(T) - 13.3448))-T)-273.15
end
function hum_abs(t,hr)
-- https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
-- Formule pour calculer l'humidité absolue
-- Dans la formule ci-dessous, la température (T) est exprimée en degrés Celsius, l'humidité relative (hr) est exprimée en%, et e est la base des logarithmes naturels 2.71828 [élevée à la puissance du contenu des crochets]:
-- Humidité absolue (grammes / m3 ) = (6,122 * e^[(17,67 * T) / (T + 243,5)] * rh * 2,1674))/(273,15 + T)
-- Cette formule est précise à 0,1% près, dans la gamme de température de -30 ° C à + 35 ° C
ha = round((6.112 * math.exp((17.67 * t)/(t+243.5)) * hr * 2.1674)/ (273.15 + t),1)
return ha
end
--------------------------------------------
-------------- Fin Fonctions ---------------
--------------------------------------------
time=os.date("*t")
if (time.min%15 == 0) then -- si script_time
--if devicechanged[temp_ext] then -- si script_device
--print("script_device_givre.lua")
print('valeurs '..otherdevices_svalues[temp_ext]);
voir_les_logs("=========== ".. nom_script .." (v".. version ..") ===========",debugging)
Temp, Humidity = otherdevices_svalues[temp_ext]:match("([^;]+);([^;]+)")
voir_les_logs("--- --- --- Température Ext : ".. Temp,debugging)
voir_les_logs("--- --- --- Humidité : ".. Humidity,debugging)
if dev_dew_point ~= nil then
local dew = dewPoint(Temp,Humidity)
voir_les_logs("--- --- --- Dew point calculated : ".. tostring(dew),debugging)
DewPoint = round(dew,2)
voir_les_logs("--- --- --- Point de Rosée : ".. DewPoint,debugging)
commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[dev_dew_point] .. "|0|" .. DewPoint} -- Mise à jour point de rosée
end
--voir_les_logs("--- 1",debugging)
if dev_freeze_point ~= nil then
FreezingPoint = round(freezing_point(DewPoint, tonumber(Temp)),2)
voir_les_logs("--- --- --- Point de Givrage : ".. FreezingPoint,debugging)
commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[dev_freeze_point] .. "|0|" .. FreezingPoint} -- Mise à jour point de givrage
end
--voir_les_logs("--- 2",debugging)
if dev_hum_abs_point ~= nil then
hum_abs_point = hum_abs(Temp, Humidity)
voir_les_logs("--- --- --- Humidité absolue : ".. hum_abs_point,debugging)
commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[dev_hum_abs_point] .. "|0|" .. hum_abs_point} -- Mise à jour humidité absolue
end
--voir_les_logs("--- 3",debugging)
if dev_freeze_alert ~= nil and time.hour == 7 and time.min >= 30 then
if(tonumber(Temp)<=1 and tonumber(FreezingPoint)<=0) then
voir_les_logs("--- --- --- Givre --- --- ---",debugging)
commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[dev_freeze_alert]..'|4|'..FreezingPoint}
commandArray['SendNotification'] = 'Alert#Présence de givre!'
elseif(tonumber(Temp)<=3 and tonumber(FreezingPoint)<=0)then
voir_les_logs("--- --- --- Risque de Givre --- --- ---",debugging)
commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[dev_freeze_alert]..'|2|'..FreezingPoint}
commandArray['SendNotification'] = 'Alert#Risque de givre!'
else
voir_les_logs("--- --- --- Aucun risque de Givre --- --- ---",debugging)
commandArray[#commandArray+1] = {['UpdateDevice'] = otherdevices_idx[dev_freeze_alert]..'|1|'..'Pas de givre'}
end
end
voir_les_logs("========= Fin ".. nom_script .." (v".. version ..") =========",debugging)
end
return commandArray

View File

@@ -0,0 +1,262 @@
--------------------------------------------------------------------------------
-- Probabilite pluie neige
--------------------------------------------------------------------------------
--[[
name : script_time_probabilite_pluie.lua
auteur : papoo
version : 1.11
date de création : 08/08/2016
Date de mise à jour : 10/08/16
Principe : Ce script a pour but d'interroger l'API du site https://www.wunderground.com/ toutes les heures afin de
récuperer les calculs de probabilités de pluie et de neige sur 36 heures pour une ville donnée. Cette API utilise une clé gratuite pour 500 requetes par heure
Il faut donc sinscrire sur weatherunderground pour avoir accès à cette API
URL post : http://easydomoticz.com/forum/viewtopic.php?f=17&t=2301
Ce script utilise Lua-Simple-XML-Parser https://github.com/Cluain/Lua-Simple-XML-Parser
]]--
-- ========================================================================
-- Variables à éditer
-- ========================================================================
local debugging = true -- true pour voir les logs dans la console log Dz ou false pour ne pas les voir
local countryCode="FRANCE" -- Votre countryCode, nécessaire pour l'API
local APIKEY="48a08328a93a18a1" -- Votre Key API Weather Underground de 16 caractères
local ville="Redon" -- Votre ville ou commune nécessaire pour l'API
-- L'api fournie 36 probabilités de pluie, 1 par heure.
local proba_pluie_h = {} -- Ajoutez, modifiez ou supprimez les variables proba_pluie_h[]
-- en changeant le N° entre [] correspondant à l'heure souhaitée pour l'associer au device concerné dans dz
proba_pluie_h[1]=328 -- renseigner l'id du device % probabilité pluie à 1 heure associé, nil si non utilisé
proba_pluie_h[2]=329 -- renseigner l'id du device % probabilité pluie à 2 heures associé, nil si non utilisé
proba_pluie_h[4]=nil -- renseigner l'id du device % probabilité pluie à 4 heures associé, nil si non utilisé
proba_pluie_h[6]=nil -- renseigner l'id du device % probabilité pluie à 6 heures associé, nil si non utilisé
proba_pluie_h[12]=nil -- renseigner l'id du device % probabilité pluie à 12 heures associé, nil si non utilisé
proba_pluie_h[24]=nil -- renseigner l'id du device % probabilité pluie à 24 heures associé, nil si non utilisé
-- L'api fournie 36 probabilités de neige, 1 par heure.
local proba_neige_h={} -- comme pour la pluie Ajoutez, modifiez ou supprimez les variables proba_neige_h[]
-- en changeant le N° entre [] correspondant à l'heure souhaitée pour l'associer au device concerné dans dz
proba_neige_h[1]=nil -- renseigner l'id du device % probabilité neige à 1 heure associé, nil si non utilisé
proba_neige_h[3]=nil -- renseigner l'id du device % probabilité neige à 2 heures associé, nil si non utilisé
proba_neige_h[6]=nil -- renseigner l'id du device % probabilité neige à 4 heures associé, nil si non utilisé
proba_neige_h[12]=nil -- renseigner l'id du device % probabilité neige à 6 heures associé, nil si non utilisé
proba_neige_h[24]=nil -- renseigner l'id du device % probabilité neige à 12 heures associé, nil si non utilisé
proba_neige_h[36]=nil -- renseigner l'id du device % probabilité neige à 24 heures associé, nil si non utilisé
local seuil_notification=80 -- pourcentage au delà duquel vous souhaitez être notifié, nil si non utilisé
-- ========================================================================
-- Fin Variables à éditer
-- ========================================================================
local pluie = nil
local neige = nil
local indexArray=0
---------------------------------------------------------------------------
--Fonctions
---------------------------------------------------------------------------
function voir_les_logs (s,debugging)
if (debugging) then
if s ~= nil then
print ("<font color='#f3031d'>--- --- --- ".. s .." --- --- ---</font>");
else
print ("<font color='#f3031d'>aucune valeur affichable</font>");
end
end
end
---------------------------------------------------------------------------------
-- Lua-Simple-XML-Parser
---------------------------------------------------------------------------------
XmlParser = {};
self = {};
function XmlParser:ToXmlString(value)
value = string.gsub(value, "&", "&amp;"); -- '&' -> "&amp;"
value = string.gsub(value, "<", "&lt;"); -- '<' -> "&lt;"
value = string.gsub(value, ">", "&gt;"); -- '>' -> "&gt;"
value = string.gsub(value, "\"", "&quot;"); -- '"' -> "&quot;"
value = string.gsub(value, "([^%w%&%;%p%\t% ])",
function(c)
return string.format("&#x%X;", string.byte(c))
end);
return value;
end
function XmlParser:FromXmlString(value)
value = string.gsub(value, "&#x([%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
local text = string.sub(xmlText, i, ni - 1);
if not string.find(text, "^%s*$") then
local lVal = (top:value() or "") .. self:FromXmlString(text)
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
function XmlParser:loadFile(xmlFilename, base)
if not base then
base = system.ResourceDirectory
end
local path = system.pathForFile(xmlFilename, base)
local hFile, err = io.open(path, "r");
if hFile and not err then
local xmlText = hFile:read("*a"); -- read file content
io.close(hFile);
return self:ParseXmlText(xmlText), nil;
else
print(err)
return nil
end
end
function newNode(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
---------------------------------------------------------------------------
-- Fin Fonctions
---------------------------------------------------------------------------
commandArray = {}
now=os.date("*t")
if now.min == 15
and ((now.hour >= 11 and now.hour <= 13) or (now.hour >= 17 and now.hour <= 20))
then -- éxécution du script toutes les heures
voir_les_logs("script_time_probabilite_pluie.lua",debugging)
local fname ="/tmp/weather"..ville.."1.out"
os.execute("wget -q -O " .. fname .. " http://api.wunderground.com/api/"..APIKEY.."/hourly/lang:FR/q/"..countryCode.."/"..ville..".xml")
--voir_les_logs("Fichier local : " ..fname,debugging)
local f = io.open(fname, "r")
if f == nil then
voir_les_logs("Error opening file '" .. fname .. "'.",debugging)
os.exit(1)
end
local testXml = f:read("*all")
f:close()
local parsedXml = XmlParser:ParseXmlText(testXml)
if (parsedXml) then local abr = parsedXml.response.hourly_forecast
for i in pairs(abr:children()) do
if proba_pluie_h[i] ~= nil then
pluie = tonumber(abr:children()[i]:children()[19]:value())
voir_les_logs("Probabilite de pluie a ".. i .."h => " .. pluie,debugging)
commandArray[indexArray] = {['UpdateDevice'] = proba_pluie_h[i]..'|0|'.. pluie}
indexArray=indexArray+1
if seuil_notification ~= nil and pluie > seuil_notification then
commandArray[indexArray] = {['SendNotification'] = 'Alerte : '.. pluie ..' % de probabilité de pluie dans '.. i ..'heure(s)'}
indexArray=indexArray+1
end
end
if proba_neige_h[i] ~=nil then
neige = tonumber(abr:children()[i]:children()[18]:children()[2]:value())
voir_les_logs("probabilite de neige a ".. i .."h => " .. neige,debugging)
commandArray[indexArray] = {['UpdateDevice'] = proba_neige_h[i]..'|0|'.. neige}
indexArray=indexArray+1
if seuil_notification ~= nil and neige > seuil_notification then
commandArray[indexArray] = {['SendNotification'] = 'Alerte : '.. neige ..' % de probabilité de neige dans '.. i ..'heure(s)'}
indexArray=indexArray+1
end
end
end
end
end -- if now
return commandArray

View File

@@ -0,0 +1,237 @@
--[[ Virtual Lux sensor and other real-time solar data
~/domoticz/scripts/lua/script_time_SolarSensor.lua
-- http://www.domoticz.com/wiki/Real-time_solar_data_without_any_hardware_sensor_:_azimuth,_Altitude,_Lux_sensor...#Installation_instructions
-- Autors ----------------------------------------------------------------
V1.0 - Sébastien Joly - Great original work
V1.1 - Neutrino - Adaptation to Domoticz
V1.2 - Jmleglise - An acceptable approximation of the lux below 1° altitude for Dawn and dusk + translation + several changes to be more userfriendly.
V1.3 - Jmleglise - No update of the Lux data when <=0 to get the sunset and sunrise with lastUpdate
V1.4 - use the API instead of updateDevice to update the data of the virtual sensor to be able of using devicechanged['Lux'] in our scripts. (Due to a bug in Domoticz that doesn't catch the devicechanged event of the virtual sensor)
]]--
-- Variables to customize ------------------------------------------------
local localhost = '127.0.0.1:81' -- Set your port. (Not the universal IP).
local city = "Redon" -- Your city for Wunderground API
local countryCode = "FR" -- Your country code for Wunderground API
local idxLux ='653' -- Your virtual Lux Device ID
local idxSolarAzimuth ='321' -- Your virtual Azimuth Device ID
local idxSolarAltitude ='322' -- Your virtual Solar Altitude Device ID
local idxUserVarOcta='31' -- Your user variable ID , named octa
local wuAPIkey = "48a08328a93a18a1" -- Your Weather Underground API Key
local latitude = 47.726872 -- your home
local longitude = -2.131937 -- your home
local altitude = 19 -- Your home altitude : run once in debug = 1 to found your altitude in Log and write it here
local WMOID = '07130' --Rennes -- Your nearest SYNOP Station for ogimet. Very important ! http://www.ogimet.com/
local DEBUG = 0
if (otherdevices['Debug'] == 'On') then
DEBUG = 1 -- 0 , 1 for domoticz log , 2 for file log
end
-- and customize the URL of api.wunderground around line 104 according to your country.
-- Below , edit at your own risk ------------------------------------------
function leapYear(year)
return year%4==0 and (year%100~=0 or year%400==0)
end
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
function pow(num, dec)
return num^dec
end
function round(num, dec)
if num == 0 then
return 0
else
local mult = 10^(dec or 0)
return math.floor(num * mult + 0.5) / mult
end
end
commandArray = {}
time = os.date("*t")
if ((time.min % 10)==0) then -- Run every n minutes. Check the wundergroud API limitation before changing this
json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")() -- For Linux
--json = (loadfile "D:\\Domoticz\\scripts\\lua\\json.lua")() -- For Windows
local arbitraryTwilightLux=6.32 -- W/m² egal 800 Lux (the theoritical value is 4.74 but I have more accurate result with 6.32...)
local constantSolarRadiation = 1361 -- Solar Constant W/m²
if (uservariables['octa'] == nil) then print("Error : Did you create the Uservariable octa ?") end
-- API Wunderground
local url_json = 'curl http://api.wunderground.com/api/'..wuAPIkey..'/conditions/q/'..countryCode..'/'..city..'.json'
print('url_json='..url_json)
--local config=assert(io.popen('curl http://api.wunderground.com/api/'..wuAPIkey..'/conditions/q/'..countryCode..'/'..city..'.json'))
--local location = config:read('*all')
--config:close()
--local jsonLocation = json:decode(location)
--if( DEBUG == 1) then
-- local latitude = jsonLocation.current_observation.display_location.latitude
-- local longitude = jsonLocation.current_observation.display_location.longitude
-- local altitude = jsonLocation.current_observation.display_location.elevation
-- print('Lat: '..latitude..'Long: '..longitude..'Alt: '..altitude)
-- end
--relativePressure = jsonLocation.current_observation.pressure_mb -- if you have an another way to get the Pressure, (local barometer ...) then you may optimize the script and avoid the call to api.wunderground)
----------------------------------
print("valeurs"..otherdevices_svalues['BarometreLaGacilly'])
local tab = split(otherdevices_svalues['BarometreLaGacilly'], ";")
print("Pressure="..tostring(tab[4]))
relativePressure = tonumber(tab[4])
local year = os.date("%Y")
local numOfDay = os.date("%j")
if leapYear(year) == true then
nbDaysInYear = 366 -- How many days in the year ?
else
nbDaysInYear = 365
end
angularSpeed = 360/365.25
local Declinaison = math.deg(math.asin(0.3978 * math.sin(math.rad(angularSpeed) *(numOfDay - (81 - 2 * math.sin((math.rad(angularSpeed) * (numOfDay - 2))))))))
timeDecimal = (os.date("!%H") + os.date("!%M") / 60) -- Coordinated Universal Time (UTC)
solarHour = timeDecimal + (4 * longitude / 60 ) -- The solar Hour
hourlyAngle = 15 * ( 12 - solarHour ) -- hourly Angle of the sun
sunAltitude = math.deg(math.asin(math.sin(math.rad(latitude))* math.sin(math.rad(Declinaison)) + math.cos(math.rad(latitude)) * math.cos(math.rad(Declinaison)) * math.cos(math.rad(hourlyAngle))))-- the height of the sun in degree, compared with the horizon
local azimuth = math.acos((math.sin(math.rad(Declinaison)) - math.sin(math.rad(latitude)) * math.sin(math.rad(sunAltitude))) / (math.cos(math.rad(latitude)) * math.cos(math.rad(sunAltitude) ))) * 180 / math.pi -- deviation of the sun from the North, in degree
local sinAzimuth = (math.cos(math.rad(Declinaison)) * math.sin(math.rad(hourlyAngle))) / math.cos(math.rad(sunAltitude))
if(sinAzimuth<0) then azimuth=360-azimuth end
sunstrokeDuration = math.deg(2/15 * math.acos(- math.tan(math.rad(latitude)) * math.tan(math.rad(Declinaison)))) -- duration of sunstroke in the day . Not used in this calculation.
RadiationAtm = constantSolarRadiation * (1 +0.034 * math.cos( math.rad( 360 * numOfDay / nbDaysInYear ))) -- Sun radiation (in W/m²) in the entrance of atmosphere.
-- Coefficient of mitigation M
absolutePressure = relativePressure - round((altitude/ 8.3),1) -- hPa
sinusSunAltitude = math.sin(math.rad(sunAltitude))
if (DEBUG == 1) then
print('<b style="color:Blue"============== SUN LOG ==================</b>')
print(os.date("%Y-%m-%d %H:%M:%S", os.time()))
print(city .. ", latitude:" .. latitude .. ", longitude:" .. longitude)
print("Home altitude = " .. tostring(altitude) .. " m")
print("number Of Day = " .. numOfDay)
if nbDaysInYear==366 then
print(year .." is a leap year !")
else
print(year.." is not a leap year")
end
print("Angular Speed = " .. angularSpeed .. " per day")
print("Declinaison = " .. Declinaison .. "°")
print("Universel Coordinated Time (UTC)".. timeDecimal .." H.dd")
print("Solar Hour ".. solarHour .." H.dd")
print("Altitude of the sun = " .. sunAltitude .. "°")
print("Angular hourly = ".. hourlyAngle .. "°")
print("Azimuth of the sun = " .. azimuth .. "°")
print("Duration of the sunstroke of the day = " .. round(sunstrokeDuration,2) .." H.dd") -- not used
print("Radiation max in atmosphere = " .. round(RadiationAtm,2) .. " W/m²")
print("Local relative pressure = " .. relativePressure .. " hPa")
print("Absolute pressure in atmosphere = " .. absolutePressure .. " hPa")
end
local sun = 614 * sinusSunAltitude * 614 * sinusSunAltitude
M0 = math.sqrt(1229 + sun) - 614 * sinusSunAltitude
M = M0 * relativePressure/absolutePressure
print("Coefficient of mitigation M = " .. M .." M0:"..M0)
-- Get SYNOP message from Ogimet web site
hourUTCminus1 = math.floor(os.date("!%H")-1)
print("hourUTCminus1 = " .. tostring(hourUTCminus1))
if string.len(hourUTCminus1) == 1 then
hourUTCminus1 = "0" .. hourUTCminus1
print("hourUTCminus1 = " .. tostring(hourUTCminus1))
end
UTC = os.date("%Y%m%d").. hourUTCminus1.."00" -- os.date("!%M")
-- if (DEBUG == 1) then
-- local WMOID = jsonLocation.current_observation.display_location.wmo
-- end
cmd='curl "http://www.ogimet.com/cgi-bin/getsynop?block='..WMOID..'&begin='..UTC..'"'
print(cmd)
local ogimet=assert(io.popen(cmd))
local synop = ogimet:read('*all')
ogimet:close()
if( DEBUG == 1) then print('ogimet:'..synop) end
if string.find(synop,"Status: 500") == nil
then
rslt = split(synop,",")
CodeStation = rslt[1]
rslt = split(synop, " "..CodeStation.. " ")
Trame = string.gsub(rslt[2], "=", "")
Trame = CodeStation .." ".. Trame
rslt = split(Trame, " ")
Octa = string.sub(rslt[3], 1, 1) -- 3rd char is the cloud layer. 0=no cloud , 1-8= cloudy from 1 to 8 max , 9 =Fog , / = no data
if Octa == "/" then -- not defined ? take the previous value
Octa = uservariables['octa']
elseif Octa == "9" then
Octa = 8
end
else
Octa = uservariables['octa']
end
--os.execute('curl "http://127.0.0.1:8081/json.htm?type=command&param=updateuservariable&idx='..idxUserVarOcta..'&vname=octa&vtype=0&vvalue='..tostring(Octa)..'"')
commandArray[#commandArray + 1] = {['Variable:octa'] = tostring(Octa)}
Kc=1-0.75*pow(Octa/8,3.4) -- Factor of mitigation for the cloud layer
if sunAltitude > 1 then -- Below 1° of Altitude , the formulae reach their limit of precision.
directRadiation = RadiationAtm * pow(0.6,M) * sinusSunAltitude
scatteredRadiation = RadiationAtm * (0.271 - 0.294 * pow(0.6,M)) * sinusSunAltitude
totalRadiation = scatteredRadiation + directRadiation
Lux = totalRadiation / 0.0079 -- Radiation in Lux. 1 Lux = 0,0079 W/m²
weightedLux = Lux * Kc -- radiation of the Sun with the cloud layer
elseif sunAltitude <= 1 and sunAltitude >= -7 then -- apply theoretical Lux of twilight
directRadiation = 0
scatteredRadiation = 0
arbitraryTwilightLux=arbitraryTwilightLux-(1-sunAltitude)/8*arbitraryTwilightLux
totalRadiation = scatteredRadiation + directRadiation + arbitraryTwilightLux
Lux = totalRadiation / 0.0079 -- Radiation in Lux. 1 Lux = 0,0079 W/m²
weightedLux = Lux * Kc -- radiation of the Sun with the cloud layer
elseif sunAltitude < -7 then -- no management of nautical and astronomical twilight...
directRadiation = 0
scatteredRadiation = 0
totalRadiation = 0
Lux = 0
weightedLux = 0 -- should be around 3,2 Lux for the nautic twilight. Nevertheless.
end
if (DEBUG == 1) then
print("Station SYNOP = " .. WMOID)
print( Octa .. " Octa")
print("Kc = " .. Kc)
print("Direct Radiation = ".. round(directRadiation,2) .." W/m²")
print("Scattered Radiation = ".. round(scatteredRadiation,2) .." W/m²")
print("Total radiation = " .. round(totalRadiation,2) .." W/m²")
print("Total Radiation in lux = ".. round(Lux,2).." Lux")
print("and at last, Total weighted lux = ".. round(weightedLux,2).." Lux")
end
if tonumber(otherdevices_svalues['Lux'])+round(weightedLux,0)>0 -- No update if Lux is already 0. So lastUpdate of the Lux sensor will keep the time when Lux has reached 0. (Kind of timeofday['SunsetInMinutes'])
then
-- commandArray[#commandArray + 1] = {['UpdateDevice'] = idxLux..'|0|'..tostring(round(weightedLux,0))} -- THis form is not recommended. due to limitation of the eventsystem of Domoticz
commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command&param=udevice&idx="..idxLux.."&nvalue=0&svalue="..tostring(round(weightedLux,0)) }
end
-- commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAzimuth..'|0|'..tostring(round(azimuth,0))}
commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command&param=udevice&idx="..idxSolarAzimuth.."&nvalue=0&svalue="..tostring(round(azimuth,0)) }
-- commandArray[#commandArray + 1] = {['UpdateDevice'] = idxSolarAltitude..'|0|'..tostring(round(sunAltitude,0))}
commandArray[#commandArray + 1]={['OpenURL']="http://"..localhost.."/json.htm?type=command&param=udevice&idx="..idxSolarAltitude.."&nvalue=0&svalue="..tostring(round(sunAltitude,0)) }
if (DEBUG == 2) then
logDebug=os.date("%Y-%m-%d %H:%M:%S",os.time())
logDebug=logDebug.." Azimuth:" .. azimuth .. " Height:" .. sunAltitude
logDebug=logDebug.." Octa:" .. Octa.." KC:".. Kc
logDebug=logDebug.." Direct:"..directRadiation.." inDirect:"..scatteredRadiation.." TotalRadiation:"..totalRadiation.." LuxCloud:".. round(weightedLux,2)
os.execute('echo '..logDebug..' >>logSun.txt') -- compatible Linux & Windows
end
end
return commandArray

View File

@@ -0,0 +1,51 @@
--curl http://domogeek.entropialux.com/vigilance/56/
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
commandArray = {}
-- Function to update a switch
function updateVigilance(zone, idx)
local cmd = "curl -y 1 http://domogeek.entropialux.com/vigilance/"..zone.."/color"
local vac = os.capture(cmd, true)
local level = 0
if (vac == "rouge") then level = 4 end
if (vac == "orange") then level = 3 end
if (vac == "jaune") then level = 2 end
if (vac == "vert") then level = 1 end
if (level >= 3 or (level == 2 and heures == 18)) then
--local html = os.capture("curl \"http://vigilance.meteofrance.com/Bulletin_sans.html?a=dept44&b=2&c=\"", true)
commandArray['SendNotification']='Alerte Vigilance '..vac..'#Attention alerte vigilance '..vac..' sur le '..zone..' \nhttp://vigilance.meteofrance.com/\n#0'
end
debug("Sunset" .. cmd .. ": "..vac..' Level '..level)
commandArray['UpdateDevice']=idx..'|'..level..'|Niveau de vigilance '..vac..' Departement '..zone
end
time = os.date("*t")
-- local cmd = "curl http://domogeek.entropialux.com/vigilance/56/all"
-- local vac = os.capture(cmd, true)
-- print(vac)
-- Trigger at 0:03 every day
if (time.hour == 0 or time.hour == 6 or time.hour == 12 or time.hour == 18) then
if time.min == 1 then
updateVigilance("56", "185")
end
if time.min == 2 then
updateVigilance("44", "315")
end
if time.min == 3 then
updateVigilance("35", "314")
end
end
return commandArray

View File

@@ -0,0 +1,146 @@
require "scripts/lua/functions"
-- URL du fichier JSON
local url = "http://api.openweathermap.org/data/2.5/weather?q=La%20gacilly,fr&APPID=feba3f4d926db3b358a25ec782bd1c8b&lang=FR&units=metric"
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
function updateBarometerDevice(deviceId, temperature, humidity, pressure, cloud)
local svalue = string.format("%.1f;%d;%d;%d;%d;", temperature, humidity, humidity, pressure, cloud)
--local svalue = "TEMP;HUM;HUM_STAT;BAR;BAR_FOR"
url = domoticzURL..'/json.htm?type=command&param=udevice&idx='..deviceId..'&svalue='..svalue
print(url)
result = os.execute(curl..'"'..url..'" &')
print(result)
end
commandArray = {}
if minutes == 00 and heures == 08 then
if mois == 2 and jour == 01 then
commandArray['SendNotification']='Changement d\'anglet#Passer l\'angle des pannneaux à 60°!'
end
if mois == 3 and jour == 01 then
commandArray['SendNotification']='Changement d\'anglet#Passer l\'angle des pannneaux à 45!'
end
if mois == 4 and jour == 24 then
commandArray['SendNotification']='Changement d\'anglet#Passer l\'angle des pannneaux à 30°!'
end
if mois == 8 and jour == 19 then
commandArray['SendNotification']='Changement d\'anglet#Passer l\'angle des pannneaux à 45!'
end
if mois == 10 and jour == 13 then
commandArray['SendNotification']='Changement d\'anglet#Passer l\'angle des pannneaux à 60°!'
end
end
if minutes%15 == 0 then
local cmd = 'curl "'..url..'"'
local jsonContent = os.capture(cmd, true)
-- jsonContent = '{"coord":{"lon":-2.1322,"lat":47.7656},"weather":[{"id":803,"main":"Clouds","description":"nuageux","icon":"04d"}],"base":"stations","main":{"temp":22.33,"feels_like":22.21,"temp_min":21.14,"temp_max":23.77,"pressure":1012,"humidity":61,"sea_level":1012,"grnd_level":1010},"visibility":10000,"wind":{"speed":4.87,"deg":265,"gust":5.72},"clouds":{"all":58},"dt":1686396178,"sys":{"type":2,"id":2007485,"country":"FR","sunrise":1686370227,"sunset":1686427534},"timezone":7200,"id":3009239,"name":"La Gacilly","cod":200}'
print(cmd)
-- Appel de la fonction pour récupérer le contenu JSON de l'URL
-- local jsonContent = getJSON(url)
json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()
local devices = json:decode(jsonContent)
printTableAsTree(devices)
-- local jsonTable = domoticz.utils.fromJSON(jsonContent)
-- Vérification si la récupération du JSON a réussi
if jsonContent then
print("Contenu JSON récupéré avec succès:")
--print(jsonContent)
else
print("Erreur lors de la récupération du JSON")
end
-- Conversion du contenu JSON en une table Lua
-- local devices = json.decode(jsonContent)
--local devices = domoticz.utils.fromJSON(jsonContent)
--for k, v in pairs(devices) do
--print(k .. ' '.. v)
--end
pluie_1h = 0
local main = searchKeyInTable("main", devices['weather'])
print('main='..main)
forecast = 0
if main == "Clouds" then
nuage = searchKeyInTable("all", devices)
if (tonumber(nuage) > 50) then
forecast = 3
else
forecast = 2
end
print("Nuage " .. nuage)
elseif main == "Rain" then
forecast = 4
pluie_1h = searchKeyInTable("1h", devices)
elseif main == "Clear" then
nuage = searchKeyInTable("all", devices)
forecast = 1
end
print("pluie " .. pluie_1h)
deviceId = 1159
-- /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=RAINRATE;RAINCOUNTER
local svalue = string.format(";%d", pluie_1h)
url = domoticzURL..'/json.htm?type=command&param=udevice&idx='..deviceId..'&svalue='..svalue
print(url)
result = os.execute(curl..'"'..url..'" &')
print(result)
deviceId = 1160
-- /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=RAINRATE;RAINCOUNTER
local svalue = string.format("%d", nuage)
url = domoticzURL..'/json.htm?type=command&param=udevice&idx='..deviceId..'&svalue='..svalue
print(url)
result = os.execute(curl..'"'..url..'" &')
print(result)
local temp_min = searchKeyInTable("temp", devices)
local humidity = searchKeyInTable("humidity", devices)
local grnd_level = searchKeyInTable("pressure", devices)
local cloud = searchKeyInTable("all", devices)
updateBarometerDevice(1157, temp_min, humidity, grnd_level, forecast)
local temp = searchKeyInTable("temp", devices)
local feels_like = searchKeyInTable("feels_like", devices)
local deg = searchKeyInTable("pressure", devices)
local speed = searchKeyInTable("speed", devices) * 10
local gust = searchKeyInTable("gust", devices) * 10
deviceId = 1158
local svalue = string.format("%d;;%.1f;%.1f;%.1f;%.1f", deg, speed, gust, temp, feels_like)
--local svalue = "TEMP;HUM;HUM_STAT;BAR;BAR_FOR"
url = domoticzURL..'/json.htm?type=command&param=udevice&idx='..deviceId..'&svalue='..svalue
print(url)
result = os.execute(curl..'"'..url..'" &')
print(result)
end
return commandArray

245
lua/old/script_time_general.old Executable file
View File

@@ -0,0 +1,245 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- -----------------------------------------------------------------------
-- Test la dernière réception d'un switch et déclenche une alerte
-- Il faut une variable de la forme PILE_nowswitch pour mettre à jour le
-- témoin de notification envoyée
-- -----------------------------------------------------------------------
function levelBattery( switch )
if (lastUpdateOfDevice(switch) > 3600 ) then
if (uservariables['Variable:PILE_'..switch] == 'Normal') then
commandArray['SendNotification']='Alerte niveau pile#Attention plus de réception de température depuis '..switch..'#0'
commandArray['Variable:PILE_'..switch]='Plus de réception'
end
else
commandArray['Variable:PILE_'..switch]='Normal'
end
end
-- -----------------------------------------------------------------------
-- Test le nombre d'erreur dans le log toutes les heures
-- -----------------------------------------------------------------------
if (minutes == 0) then
local var = os.capture("grep Error /var/log/syslog |wc -l")
--print(var)
if (tonumber(var) > 0 and tonumber(uservariables['Variable:Erreurs']) == 0) then
commandArray['SendNotification']='Alerte Erreur '..var..'#Attention Il y a des erreurs dans domoticz #0'
end
commandArray['Variable:Erreurs']=var
end
-- -----------------------------------------------------------------------
-- Vérifie le nombre de sequences capturées par motion
-- -----------------------------------------------------------------------
if (minutes % 10 == 0) then
local f = io.popen("ls /home/pi/motion/ |grep avi| cut -c 1-2 |uniq| wc -l") -- runs command
local l = f:read("*a") -- read output of command
debug("Nombre de detection "..l)
f:close()
commandArray['PhotoMotion']=tostring(l)
commandArray['UpdateDevice']="136|0|"..l
end
-- -----------------------------------------------------------------------
--recupere les minutes
-- -----------------------------------------------------------------------
if (minutes % 10 == 0) then
debug('####### Lancement du check Presence ' ..heures..'h'..minutes)
if (otherdevices['Vacances'] == 'On') then
switchIfNeeded('Presence','Off')
else
--commandArray['Presence']='Off'
------------------------------------------------------------------------
if (josdJourChome() or otherdevices['PresenceForcee'] == 'On') then
debug(' Jour Chômé / Presence normale à la maison')
switchIfNeeded('Presence','On')
else
local jourS=josdGetJourSemaine()
debug("jour "..jourS)
if otherdevices['AbsenceFamille'] == 'Off' then
if ((jourS == "mercredi" and (heures >= 13 or (heures == 12 and minutes >= 30)))
or heures >= 17 or heures < 8
or (heures == 8 and minutes <= 30)
or otherdevices["Zone B"] == 'On' ) then
debug(' Jour non Chômé pas de vacances '..tostring(heures))
switchIfNeeded('Presence','On')
else
switchIfNeeded('Presence','Off')
end
else
if (((heures == 8 and minutes <= 15) or heures < 8) or heures >= 20 or otherdevices['moi'] == 'On' or otherdevices['Akhenaton'] == 'On') then
switchIfNeeded('Presence','On')
else
switchIfNeeded('Presence','Off')
end
end
end
end
end
-- --------------------------------------------------------------------------------
-- Vérification des dernières mises à jour des températures
-- --------------------------------------------------------------------------------
if (minutes%10== 0) then
levelBattery('Bureau')
levelBattery('ChambreManon')
levelBattery('ChambreTheo')
levelBattery('Chambre')
--levelBattery('ATMEGA_TEMP_1')
levelBattery('TemperatureBarometre')
end
-- --------------------------------------------------------------------------------
-- Function to update a switch
-- --------------------------------------------------------------------------------
function updateSunset(zone)
local cmd = "curl http://domogeek.entropialux.com/sun/" .. zone .. "/sunset/now"
local vac = os.capture(cmd, true)
debug("Sunset" .. cmd .. ": " .. vac)
commandArray['Variable:Couche']=vac
local cmd = "curl http://domogeek.entropialux.com/sun/" .. zone .. "/sunrise/now"
local vac = os.capture(cmd, true)
debug("Sunrise" .. cmd .. ": " .. vac)
commandArray['Variable:Lever']=vac
end
-- --------------------------------------------------------------------------------
-- Trigger at 0:03 every day
-- --------------------------------------------------------------------------------
if (minutes == 3 and (heures == 0 or heures == 8)) then
updateSunset("redon")
end
-- -------------------------------------------------------------------
-- Performance ping
-- -------------------------------------------------------------------
if (minutes % 10 == 0 ) then
local f = io.popen("ping -c 5 192.168.0.1 2>/dev/null |grep rtt |awk -F = '{print $2}'|awk -F / '{print $2}'") -- runs command
local l = f:read("*a") -- read output of command
debug("##### Perf ping : temps de ping "..l)
f:close()
-- Perf Reseau
commandArray['UpdateDevice']="145|0|"..l
end
-- ------------------------------------------------------------------------------
-- Lampes eteinte après 22 heures 30 / 23 heures si pas d'activite depuis 10 minutes
-- ------------------------------------------------------------------------------
-- Pas de traitement en cas d'alerte fumée
if otherdevices['DétecteurFuméeCuisine'] == "Normal"
-- Pas de traitement si lampe allumée il y a moins d'une heure
and (lastUpdateOfDevice('Lampe_Buffet') > 3600 and otherdevices['Lampe_Buffet'] == 'On')
then
if ((heures >= 23 or (heures == 22 and minutes >= 30)) and (minutes%5==0)) then
t1 = os.time()
s = uservariables_lastupdate['DerniereDetection'] --otherdevices_lastupdate['Detecteur Salon']
-- 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("Eteindre les lumieres, DerniereDetection="..tostring(difference))
if (difference > 300 or heures >= 23) then
switchIfNeeded('Salon_Halogene', 'Off')
switchIfNeeded('Lampe_Buffet', 'Off')
switchIfNeeded('LumiereTele', 'Off')
switchIfNeeded('SonoJasper', 'Off')
end
end
end
-- Variation de pression
if minutes%10 == 0 then
local pressure = otherdevices_svalues['Pression']
local variationPressure = variationPressure('Barometre',60)
print("variationPressure="..tostring(variationPressure)..' Pression='..tostring(pressure))
end
-- ---------------------------------
-- Réglage des consigne temperature
-- ---------------------------------
if minutes%10 == 0 then
debug('####### Lancement du calcul consigne ' ..heures..'h'..minutes)
--commandArray['UpdateDevice'] = '214|0|25.00'
if (otherdevices['Vacances'] == 'On') then
commandArray['UpdateDevice'] = "213|0|16.5" -- Chambre
commandArray['UpdateDevice'] = "211|0|16.5" -- ChambreTheo
commandArray['UpdateDevice'] = "212|0|16.5" -- ChambreManon
commandArray['UpdateDevice'] = "214|0|16.5" -- Bureau
else
--commandArray['Presence']='Off'
------------------------------------------------------------------------
if (josdJourChome() or otherdevices['PresenceForcee'] == 'On') then
debug(' Jour Chômé / consigne temperature présence')
commandArray['UpdateDevice'] = "213|0|18" -- Chambre
commandArray['UpdateDevice'] = "211|0|18.5" -- ChambreTheo
commandArray['UpdateDevice'] = "212|0|18.5" -- ChambreManon
commandArray['UpdateDevice'] = "214|0|18" -- Bureau
else
local jourS=josdGetJourSemaine()
debug("jour "..jourS)
if otherdevices['AbsenceFamille'] == 'Off' then
if ((jourS == "mercredi" and (heures >= 13 or (heures == 12 and minutes >= 30)))
or heures >= 17 or heures < 8
or (heures == 8 and minutes <= 30)
or otherdevices["Zone B"] == 'On' ) then
debug(' Jour non Chômé pas de vacances '..tostring(heures))
commandArray['UpdateDevice'] = "213|0|18" -- Chambre
commandArray['UpdateDevice'] = "211|0|18.5" -- ChambreTheo
commandArray['UpdateDevice'] = "212|0|18.5" -- ChambreManon
commandArray['UpdateDevice'] = "214|0|18" -- Bureau
else
commandArray['UpdateDevice'] = "213|0|16.5" -- Chambre
commandArray['UpdateDevice'] = "211|0|16.5" -- ChambreTheo
commandArray['UpdateDevice'] = "212|0|16.5" -- ChambreManon
commandArray['UpdateDevice'] = "214|0|16.5" -- Bureau
end
else
if (((heures == 8 and minutes <= 15) or heures < 8) or heures >= 20 or otherdevices['moi'] == 'On'
or otherdevices['Akhenaton'] == 'On') then
commandArray['UpdateDevice'] = "213|0|18" -- Chambre
commandArray['UpdateDevice'] = "211|0|18.5" -- ChambreTheo
commandArray['UpdateDevice'] = "212|0|18.5" -- ChambreManon
commandArray['UpdateDevice'] = "214|0|18" -- Bureau
else
commandArray['UpdateDevice'] = "213|0|16.5" -- Chambre
commandArray['UpdateDevice'] = "211|0|16.5" -- ChambreTheo
commandArray['UpdateDevice'] = "212|0|16.5" -- ChambreManon
commandArray['UpdateDevice'] = "214|0|16.5" -- Bureau
end
end
end
end
end
-- return commandArray

5
lua/old/script_time_list.old Executable file
View File

@@ -0,0 +1,5 @@
print('Liste des capteurs : ')
commandArray = {}
for i, v in pairs(otherdevices) do print(i, v) end
return commandArray

95
lua/old/script_time_livebox.old Executable file
View File

@@ -0,0 +1,95 @@
---------------------------------
-- Script de détection de présence via livebox
-- Auteur : Sopalin
-- Date : 22 Juillet 2016
-- Nécessite un switch classique
-- source :
---------------------------------
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
commandArray={}
function testActive(name, active)
if active then
--commandArray[name]='On'
switchIfNeeded(name, 'On')
else
switchIfNeeded(name, 'Off')
--commandArray[name]='Off'
end
debug("### Test active Name : "..name.." active "..tostring(active))
end
--time = os.date("*t")
if (minutes % 10 == 7) then
--import des fontions pour lire le JSON
json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()
--Récupération des informations sur la livebox
--Utilisation d'un script VBS sous windows
--Utilisation d'un script bash pour extraire les données
----------------------------------------------------------------
--Lecture des données
local f = assert(io.open("/tmp/getHosts.txt","r"))
local livebox = f:read('*all')
f:close()
--Décodage ud fichier
local jsonLivebox = json:decode(livebox)
--debug("DEBUG")
--debug(timedifference(otherdevices_lastupdate['Presence Thomas']))
--commandArray['Theo']='Off'
--commandArray['Moi']='Off'
--commandArray['Manon']='Off'
devices = jsonLivebox['result']['status']
--Parcours du fichier pour vérifier la présence d'un téléphone
for result,status in pairs(devices) do
local name = status['hostName']
debug("Name : "..name.." IP : "..status['ipAddress'].." "..tostring(status['active']))
if (name == "Windows-Phone" or name == "Akhesa" or name == "Playstation3") then
--commandArray['Theo']='On'
testActive('Theo', status['active'])
end
if (name == "iPhone-de-Jerome") then
--commandArray['moi']='On'
testActive("Moi", status['active'])
end
if (name == "Akhenaton-1" or name == "Akhenaton") then
testActive("Akhenaton", status['active'])
end
if (name == "Manon" or name == "AcerManon") then
--commandArray['Manon']='On'
testActive("Manon", status['active'])
end
if (name == "TeleChambre" or name == "AcerManon"
or name == "Volumio" or name == "LibreELEC" or name == "Akhesa"
or name == "SoutiHP" or name == "Hackintosh"
or name == "Akhenaton"
or name == "Domi" or name == "DomiPro" or name == "Octoprint"
or name == "Recovery" or name == "orangepizero" or name == "orangepizero-1") then
testActive(name, status['active'])
end
if (name == "RadiateurManon" or name == "RadiateurTheo" or name == "RadiateurBureau"
or name == "RadiateurChambre") then
if status['active'] then
-- nothing
else
-- commandArray['SendNotification']='Alerte radiateur '..name..'#Alerte radiateur ne repond pas au ping '..name
end
end
end
end
return commandArray

View File

@@ -0,0 +1,36 @@
require "scripts/lua/functions"
commandArray = {}
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
if (minutes % 10 == 0 ) then
local f = io.popen("ping -c 5 192.168.0.1 2>/dev/null |grep rtt |awk -F = '{print $2}'|awk -F / '{print $2}'") -- runs command
local l = f:read("*a") -- read output of command
debug("##### Perf ping : temps de ping "..l)
f:close()
-- Perf Reseau
commandArray['UpdateDevice']="145|0|"..l
end
if (minutes % 30 == 0 ) then
local f = io.popen("ping -c 4 -n www.free.fr|grep packet|awk -F ' ' '{print $1}'") -- runs command
local l = f:read("*a") -- read output of command
debug("##### Nombre de ping: "..l)
f:close()
if (l == "4") then
debug("##### Internet fonctionne correctement")
switchIfNeeded('Internet','On')
else
debug("##### Internet ne répond pas")
switchIfNeeded('Internet','Off')
end
end
return commandArray

30
lua/old/script_time_soleil.lua Executable file
View File

@@ -0,0 +1,30 @@
---------------------------------
-- Script de collecte de quelques indicateurs solaire
-- Auteur : Sébastien Joly
-- Adapté pour Domoticz par Neutrino
-- Date : 29 août 2015
-- Eléments de calculs :
-- http://www.plevenon-meteo.info/technique/theorie/enso/ensoleillement.html
-- http://herve.silve.pagesperso-orange.fr/solaire.htm
-- http://www.domotique-info.fr/2015/09/ou-est-le-soleil-pour-votre-homecenter-2/
---------------------------------
require "scripts/lua/functions"
commandArray = {}
time = os.date("*t")
local idxLux="320"
if ((time.min % 5)==0) then
if (timeofday['Nighttime']) then
--il fait nuit
LuxPondere = 0
--mise a jour du dispositif
commandArray[1] = {['UpdateDevice'] = idxLux..'|0|' .. tostring(LuxPondere)}
else
os.execute("lua /opt/domoticz/scripts/lua/soleil.lua "..uservariables['octa'].." &")
end
end
return commandArray

89
lua/old/script_time_tele.old Executable file
View File

@@ -0,0 +1,89 @@
require "scripts/lua/functions"
--Initialise la commande de retour finale
commandArray={}
--Prefixe pour les sorties de log
prefixe="(PING) "
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
if (heures >= 22 and (minutes % 10 == 0)) then
-- ------------------------------
--Tableau des périphérique"pinguer"
-- Key = adresse ip pinguer
-- Value = périphérique virtueswitcher
-- ------------------------------
local ping={}
ping['192.168.0.17']='TeleChambre'
ping['akhenaton']='Akhenaton'
AuMoinsUnPing=false
-- ------------------------------
--pour chaque entree du tableau
-- ------------------------------
for ip, switch in pairs(ping) do
--Le Ping ! : -c1 = Un seul ping , -w1 délai d'une seconde d'attente de réponse
ping_success=os.execute('ping -c1 -w1 '..ip)
-- ------------------------------
--Si le ping a répondu
-- ------------------------------
if ping_success then
AuMoinsUnPing=true
debug(prefixe.."ping success "..switch)
-- ------------------------------
--si le switch etait sur off on l'allume
-- ------------------------------
switchIfNeeded(switch, 'On')
--if(otherdevices[switch]=='Off') then
-- commandArray[switch]='On'
--end
else
-- ------------------------------
--Si pas de réponse
-- ------------------------------
debug(prefixe.."ping sans reponse "..switch)
-- ------------------------------
--si le switch etait sur oN on l'eteint
-- ------------------------------
switchIfNeeded(switch, 'Off')
--if(otherdevices[switch]=='On') then
-- commandArray[switch]='Off'
--end
end
end
if AuMoinsUnPing then
else
-- ------------------------------
-- Extinction halogene
-- ------------------------------
debug("Tout le monde est couché")
-- if(otherdevices["Salon_Halogene"]=='On')
switchIfNeeded("Salon_Halogene",'Off')
switchIfNeeded("LumiereTele",'Off')
switchIfNeeded("Lampe_Buffet",'Off')
-- end
if(otherdevices["Volet droit"]=='On') then
debug("Attention le volet droit est ouvert")
end
if(otherdevices["Volet gauche"]=='On') then
debug("Attention le volet gauche est ouvert")
end
end
end
return commandArray

601
lua/old/script_time_vmc.old Executable file
View File

@@ -0,0 +1,601 @@
-- http://easydomoticz.com/forum/viewtopic.php?f=17&t=2869&hilit=vmc
require "scripts/lua/fonctions2"
commandArray = {}
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
--jour=tonumber(os.date('%w',time))
heures=tonumber(os.date('%H',time))
if minutes%10 == 6 then
INTERVAL_MESURE = 2 -- Nombre d'intervals de mesure entre deux cycles d'analyse de l'humidité (en nombre de cycles = nombre de minutes)
SEUIL_DECLENCHEMENT_VMC = 2 -- Augmentation en % au-delà de laquelle on déclenche la GV de la VMC
NbCycles_Max_GV_VMC = 5 -- Nombre de cycles maximum durant lequel la GV de la VMC peut rester ON
-- à partir du moment où il n'y a plus d'augmentation de l'humidité entre deux mesures
Anticipation_Arret= 1 -- l'arrêt de la grande vitesse se fera à l'humidité avant déclenchement de la GV plus cette valeur
-- ce qui permet d'anticiper l'arrêt de la grande vitesse avant d'atteindre la valeur initiale
NOM_INTERRUPTEUR_PILOTAGE_VMC = 'VMC'
NOM_INTERRUPTEUR_OnOff_VMC = 'VMC-OnOff'
NOM_INTERRUPTEUR_GV_VMC = 'VMC-GV'
NOM_CAPTEUR_HUMIDITE1 = 'TemperatureSDB'
NOM_CAPTEUR_HUMIDITE2 = 'TemperatureCuisine'
NOM_INTERRUPTEUR_DEBUG = 'Debug'
NOM_INTERRUPTEUR_TEST = 'Test-GV-SDB'
--NOM_CAPTEUR_VIRTUEL_HYGRO_MOYENNE= 'Hygro_Maison_Moyenne'
VALEUR_TEST_HUMIDITE1 = 'VMC_TST_HUM_SDB1' -- valeur de test pour l'umidité positionné dans les variables domoticz
VALEUR_TEST_HUMIDITE2 = 'VMC_TST_HUM_SDB2' -- valeur de test pour l'umidité positionné dans les variables domoticz
-- ---------------------------------------------------------------------
-- Récupération de paramètres de Domoticz passés par les interrupteurs
-- ---------------------------------------------------------------------
if(otherdevices[NOM_INTERRUPTEUR_DEBUG]=='On') then -- Si le mode debug est activé dans Domoticz (inter debug sur on)
MODE_DEBUGG= true
else
MODE_DEBUGG= false
end
if(otherdevices[NOM_INTERRUPTEUR_TEST]=='On') then -- Si le mode test est activé dans Domoticz (inter Test sur on)
MODE_TEST=true
else
MODE_TEST=false
end
-- MODE_TEST=true
if MODE_DEBUGG== true then
print(' ')
print('>>>>>>>>>>>>>> Script de controle de la VMC v1.0 <<<<<<<<<<<<<<<<<<<<<')
end
-- ----------------------------------------------------------------------------------
-- --Récupération de toutes les variables Domoticz servant au script et remise à 0 --
-- ----------------------------------------------------------------------------------
VMC_VAR_Compteur_Cycles = tonumber(uservariables['VMC_VAR_Compteur_Cycles']) -- compteur de cycles
VMC_VAR_Histo_Hum1_SDB1 = tonumber(uservariables['VMC_VAR_Histo_Hum1_SDB1']) -- mesure la plus récente SDB1
VMC_VAR_Histo_Hum1_SDB2 = tonumber(uservariables['VMC_VAR_Histo_Hum1_SDB2']) -- mesure la plus récente SDB2
VMC_VAR_Histo_Hum2_SDB1 = tonumber(uservariables['VMC_VAR_Histo_Hum2_SDB1']) -- mesure la plus ancienne SDB1
VMC_VAR_Histo_Hum2_SDB2 = tonumber(uservariables['VMC_VAR_Histo_Hum2_SDB2']) -- mesure la plus ancienne SDB2
VMC_VAR_Cible_Hum_GV_Off_SDB1 = tonumber(uservariables['VMC_VAR_Cible_Hum_GV_Off_SDB1']) -- Cible à atteindre pour arrêter la deshumidification SDB1 lorsqu'elle est active
VMC_VAR_Cible_Hum_GV_Off_SDB2 = tonumber(uservariables['VMC_VAR_Cible_Hum_GV_Off_SDB2']) -- Cible à atteindre pour arrêter la deshumidification SDB2 lorsqu'elle est active
VMC_VAR_TimerSecuriteArret_SDB1 = tonumber(uservariables['VMC_VAR_TimerSecuriteArret_SDB1']) -- Nb de cycles restants avant l'arrête automatique de sécurité de la SDB1
VMC_VAR_TimerSecuriteArret_SDB2 = tonumber(uservariables['VMC_VAR_TimerSecuriteArret_SDB2']) -- Nb de cycles restants avant l'arrête automatique de sécurité de la SDB2
VMC_VAR_Deshumidification_On_SDB1 = tonumber(uservariables['VMC_VAR_Deshumidification_On_SDB1']) -- Vaut 1 si la deshumidification est en cours dans la SDB1, 0 sinon
VMC_VAR_Deshumidification_On_SDB2 = tonumber(uservariables['VMC_VAR_Deshumidification_On_SDB2']) -- Vaut 1 si la deshumidification est en cours dans la SDB2, 0 sinon
Cible_Humidite_SDB1 = 0 -- Variable servant à calculer la cible d'humidité lorsuqe la déshumidification s'active pour la SDB1
Cible_Humidite_SDB2 = 0 -- Variable servant à calculer la cible d'humidité lorsuqe la déshumidification s'active pour la SDB2
Humidite_Actuelle_EXT = tonumber(otherdevices_humidity["BarometreLaGacilly"])
Temperature_Actuelle_EXt = tonumber(otherdevices_temperature["BarometreLaGacilly"])
-- ********************************************************************
-- SI L'UTILISATEUR A ACTIVé LA VMC DE MANIERE MANUELLE ON N'EXECUTE --
-- PAS LE SCRIPT ET ON POSITIONNE LA VMC A LA BONNNE VALEUR
-- ********************************************************************
Etat_Pilotage_VMC = tonumber(otherdevices_svalues[NOM_INTERRUPTEUR_PILOTAGE_VMC]) -- récupération de l'état de l'inter 4 positions de pilotage de la VMC
print('Etat_Pilotage_VMC='..tostring(Etat_Pilotage_VMC))
if Etat_Pilotage_VMC < 30 then -- Si inter sur mode différent d'automatique (qui vaut 30)
if Etat_Pilotage_VMC == 0 then -- Si inter sur VMC Off
print('VMC arretee manuellement via l interrupteur. Sortie du script')
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'Off'
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'Off'
end
if Etat_Pilotage_VMC == 10 then -- Si inter sur VMC petite vitesse
print('VMC positionnee en marche / petite vitesse via l interrupteur. Sortie du script')
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'On'
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'Off'
end
if Etat_Pilotage_VMC == 20 then -- si inter sur VMC grande vitesse
print('VMC positionnee en marche / grande vitesse via l interrupteur. Sortie du script')
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'On'
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'On'
end
print('NOM_CAPTEUR_HUMIDITE1 '..tostring(tonumber(otherdevices_humidity[NOM_CAPTEUR_HUMIDITE1])))
-- On n'est plus en mode automatique donc on sort du script après l'avoir remis à 0 (réinitialisation de toutes les variables)
commandArray['Variable:VMC_VAR_Compteur_Cycles'] = '0'
commandArray['Variable:VMC_VAR_Histo_Hum2_SDB1'] = tostring(math.floor(tonumber(otherdevices_humidity[NOM_CAPTEUR_HUMIDITE1])))
commandArray['Variable:VMC_VAR_Histo_Hum1_SDB1'] = tostring(math.floor(tonumber(otherdevices_humidity[NOM_CAPTEUR_HUMIDITE1])))
commandArray['Variable:VMC_VAR_Cible_Hum_GV_Off_SDB1'] = '0'
commandArray['Variable:VMC_VAR_TimerSecuriteArret_SDB1'] = '0'
commandArray['Variable:VMC_VAR_Deshumidification_On_SDB1'] = '0'
commandArray['Variable:VMC_VAR_Histo_Hum2_SDB2'] = tostring(math.floor(tonumber(otherdevices_humidity[NOM_CAPTEUR_HUMIDITE2])))
commandArray['Variable:VMC_VAR_Histo_Hum1_SDB2'] = tostring(math.floor(tonumber(otherdevices_humidity[NOM_CAPTEUR_HUMIDITE2])))
commandArray['Variable:VMC_VAR_Cible_Hum_GV_Off_SDB2'] = '0'
commandArray['Variable:VMC_VAR_TimerSecuriteArret_SDB2'] = '0'
commandArray['Variable:VMC_VAR_Deshumidification_On_SDB2'] = '0'
return commandArray
end
print('mode automatique')
-- **************************************
-- Recuperation des valeurs d'humidite
-- **************************************
if (MODE_TEST) then
-- Si on est en mode test, on prends les valeurs fixées dans les variables DOMOTICZ
Humidite_Actuelle_SDB1 = tonumber(uservariables['VMC_TST_HUM_SDB1'])
Humidite_Actuelle_SDB2 = tonumber(uservariables['VMC_TST_HUM_SDB2'])
Hygro_Moyenne_Maison = tonumber(uservariables['VMC_TST_HUM_MOYENNE_MAISON'])
else
-- Si on est en mode normal, on prends les valeurs remontées par les capteurs
Humidite_Actuelle_SDB1 = otherdevices_humidity[NOM_CAPTEUR_HUMIDITE1]
Humidite_Actuelle_SDB2 = otherdevices_humidity[NOM_CAPTEUR_HUMIDITE2]
Humidite_Actuelle_CELLIER = otherdevices_humidity["TemperatureCellier"]
Hygro_Moyenne_Maison = math.max(Humidite_Actuelle_SDB1, Humidite_Actuelle_CELLIER) -- otherdevices_humidity[NOM_CAPTEUR_VIRTUEL_HYGRO_MOYENNE]
end
print('Hygro_Moyenne_Maison='..tostring(Hygro_Moyenne_Maison))
-- L'humidité maximum acceptable dans la salle de bain est le maximum de la valeur moyenne humidité
-- en cours dans la maison et de la valeur fixées
-- Cette humidité max permet de maintenir la VMC en petite vitesse même si l'humidité de la salle de
-- bain est redescendue après un pic
Maximum_Humidite_Acceptable_SDB = math.max(tonumber(uservariables['Hygro_Max_SDB']), Hygro_Moyenne_Maison)
-- ******************************************************************************
-- Sortie du script si les valeurs d'humidité récupérées ne sont pas exploitables
-- *******************************************************************************
if (Humidite_Actuelle_SDB1 == 0 or Humidite_Actuelle_SDB1 == nil) then
print('Pas de signal du capteur ' .. NOM_CAPTEUR_HUMIDITE1 .. '. Sortie du script')
return commandArray
end
if (Humidite_Actuelle_SDB2 == 0 or Humidite_Actuelle_SDB2 == nil) then
print('Pas de signal du capteur ' .. NOM_CAPTEUR_HUMIDITE2 .. '. Sortie du script')
return commandArray
end
if (Hygro_Moyenne_Maison== 0 or Hygro_Moyenne_Maison== nil) then
print('Pas de signal du capteur virtuel d humidite moyenne de la maison, Sortie du script')
return commandArray
end
print('Les capteurs sont ok ')
-- ************************************************************************************
-- Le script est executé toutes les minutes, on augmente la valeur du compteur de cycle
-- ************************************************************************************
VMC_VAR_Compteur_Cycles = VMC_VAR_Compteur_Cycles + 1
-- ***************************************************************************************************
-- On commence par traiter l'humidité globale de la maison pour savoir si la VMC doit être activée ou non
-- ***************************************************************************************************
local humidite_ext = humiditeAbsolue(Temperature_Actuelle_EXt, Humidite_Actuelle_EXT)
local humidite_sdb = humiditeAbsolue(tonumber(otherdevices_temperature["TemperatureSDB"]),
tonumber(otherdevices_humidity["TemperatureSDB"]))
if humidite_ext > humidite_sdb then
print("L'humidité extérieure est trop élevée. Arret VMC")
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'Off'
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'Off'
return commandArray
else
if Hygro_Moyenne_Maison > uservariables['Hygro_Max_Maison'] then
Hygro_Max_Depassee = 1 -- L'humidité de la maison est trop importante on active la VMC
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'On'
else -- L'humidité de la maison est correcte
Hygro_Max_Depassee = 0
if VMC_VAR_Deshumidification_On_SDB1 == 0 and VMC_VAR_Deshumidification_On_SDB2 == 0 then
if Humidite_Actuelle_SDB1 <= Maximum_Humidite_Acceptable_SDB and
Humidite_Actuelle_SDB2 <= Maximum_Humidite_Acceptable_SDB
then
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'Off' -- on arrête la VMC si aucune des salles de bains n'est utilisée et que l'humidité des salles de bain est acceptable
else
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'On' -- on allume la VMC si aucune des salles de bains n'est utilisée mais que l'humidité des salles de bain n'est pas acceptable
end
end
end
end
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('***************')
print('ETAT ACTUEL : ')
print('***************')
if Hygro_Moyenne_Maison <= uservariables['Hygro_Max_Maison']
and VMC_VAR_Deshumidification_On_SDB1 ==0
and VMC_VAR_Deshumidification_On_SDB2 == 0
then
if Humidite_Actuelle_SDB1 <= Maximum_Humidite_Acceptable_SDB and Humidite_Actuelle_SDB2 <= Maximum_Humidite_Acceptable_SDB then
print('[Hygro Maison] - Hygrometrie correcte (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max) et aucune salle de bain en cours d utilisation, desactivation de la vmc')
else
print('[Hygro Maison] - Hygrometrie correcte (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max), aucune salle de bain en cours d utilisation mais humidite SDB toujours trop elevee, VMC laissee active en petite vitesse')
end
else
if VMC_VAR_Deshumidification_On_SDB1 ==0 and VMC_VAR_Deshumidification_On_SDB2 == 0 then
print('[Hygro Maison] - Hygrometrie incorrect (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max), maintien de la VMC meme si aucune salle de bain en cours d utilisation')
end
end
if VMC_VAR_Deshumidification_On_SDB1 == 0 then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Deshumidification OFF - actuelle : ' .. Humidite_Actuelle_SDB1 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB1 .. '% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB1 .. '%')
else
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Deshumidification ON - actuelle : ' .. Humidite_Actuelle_SDB1 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB1 ..'% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB1 .. '% / Cible arret : ' .. VMC_VAR_Cible_Hum_GV_Off_SDB1 .. '% / arret de securite dans ' .. VMC_VAR_TimerSecuriteArret_SDB1 .. ' cycle(s)')
end
if VMC_VAR_Deshumidification_On_SDB2 == 0 then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Deshumidification OFF - actuelle : ' .. Humidite_Actuelle_SDB2 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB2 .. '% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB2 .. '%')
else
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Deshumidification ON - actuelle : ' .. Humidite_Actuelle_SDB2 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB2 ..'% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB2 .. '% / Cible arret : ' .. VMC_VAR_Cible_Hum_GV_Off_SDB2 .. '% / arret de securite dans ' .. VMC_VAR_TimerSecuriteArret_SDB2 .. ' cycle(s)')
end
end
if (VMC_VAR_Compteur_Cycles >= INTERVAL_MESURE) then
-- *************************************************************************************
-- Si le nombre de cycles a atteint l'interval de mesure fixé on commence l'analyse pour
-- identifier les besoins d'activation ou désactivation de la grande vitesse de la VMC
-- *************************************************************************************
VMC_VAR_Compteur_Cycles = 0 -- remise à 0 du compteur de cycle
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print(' ')
print('***************')
print('ANALYSE : ')
print('***************')
print('Nombre de cycles atteint (' .. VMC_VAR_Compteur_Cycles .. '/' .. INTERVAL_MESURE .. '), realisation des tests pour adapter la vitesse VMC')
end
-- ***************************************************************************
-- Initialisation des historiques s'ils ne contiennent aucune information. On
-- positionne alors dans les deux historiques les valeurs d'hulidité actuelles
-- ***************************************************************************
if (VMC_VAR_Histo_Hum1_SDB1 == 0) then
-- Initialisation des valeurs historiques
VMC_VAR_Histo_Hum1_SDB1 = Humidite_Actuelle_SDB1
VMC_VAR_Histo_Hum2_SDB1 = Humidite_Actuelle_SDB1
end
if (VMC_VAR_Histo_Hum1_SDB2 == 0) then
-- Initialisation des valeurs historiques
VMC_VAR_Histo_Hum1_SDB2 = Humidite_Actuelle_SDB2
VMC_VAR_Histo_Hum2_SDB2 = Humidite_Actuelle_SDB2
end
-- ********************************************************************
-- Calcul des écarts maximum d'humidité constatés dans chacune des SDB
-- ********************************************************************
Ecart_Max_Humidite_SDB1 = Humidite_Actuelle_SDB1 - math.min(VMC_VAR_Histo_Hum2_SDB1, VMC_VAR_Histo_Hum1_SDB1)
Ecart_Max_Humidite_SDB2 = Humidite_Actuelle_SDB2 - math.min(VMC_VAR_Histo_Hum2_SDB2, VMC_VAR_Histo_Hum1_SDB2)
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Ecart max d humidite constate sur les dernieres periodes : ' .. Ecart_Max_Humidite_SDB1)
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Ecart max d humidite constate sur les dernieres periodes : ' .. Ecart_Max_Humidite_SDB2)
end
-- ********************************************************************************************************
-- Identification de la cible humidité à atteindre si la grande vitesse de la VMC est activée. Il s'agira
-- de redescendre à la plus basse des valeurs d'humidité de l'historique + un % défini dans "Anticipation_Arret"
-- ********************************************************************************************************
Cible_Humidite_SDB1 = math.min(VMC_VAR_Histo_Hum2_SDB1, VMC_VAR_Histo_Hum1_SDB1) + Anticipation_Arret
Cible_Humidite_SDB2 = math.min(VMC_VAR_Histo_Hum2_SDB2, VMC_VAR_Histo_Hum1_SDB2) + Anticipation_Arret
-- *****************************************************************************
-- Sauvegarde dans l'historique des mesures précédentes et de la mesure actuelle
-- *****************************************************************************
VMC_VAR_Histo_Hum2_SDB1 = VMC_VAR_Histo_Hum1_SDB1 -- L'historique le plus ancien reçoit l'historique plus récent de l'humidité
VMC_VAR_Histo_Hum2_SDB2 = VMC_VAR_Histo_Hum1_SDB2
VMC_VAR_Histo_Hum1_SDB1 = Humidite_Actuelle_SDB1 -- L'historique plus récent reçoit la valeur actuelle d'humidité
VMC_VAR_Histo_Hum1_SDB2 = Humidite_Actuelle_SDB2
-- ********************************************************************************************************
-- Remise à 0 des indicateurs précisant s'il y a eu un déclenchement de la GV pour une des SDB lors
-- de l'execution du script en cours. Pour l'instant aucune mise en route n'a été décidée/effectuée
-- ********************************************************************************************************
Declenchement_SDB1 = 0
Declenchement_SDB2 = 0
-- *****************************************************************************
-- Si le ventilateur est off alors qu'un des deux programmes est en route, on
-- force l'arrêt des programmes de déshumidification (arrêt manuel extérieur)
-- *****************************************************************************
if (otherdevices[NOM_INTERRUPTEUR_GV_VMC]=='Off')
and (VMC_VAR_Deshumidification_On_SDB1 == 1 or VMC_VAR_Deshumidification_On_SDB2 ==1)
then
VMC_VAR_Deshumidification_On_SDB1 = 0
VMC_VAR_Deshumidification_On_SDB2 = 0
end
-- *****************************************************************************************
-- Si la VMC n'est pas en grande vitesse ou si une des deux SDB n'est pas en grande vitesse
-- on identifie s'il est nécessaire de mettre en route la marche forcée pour une des SDBs
-- *****************************************************************************************
if otherdevices[NOM_INTERRUPTEUR_GV_VMC]=='Off'
or VMC_VAR_Deshumidification_On_SDB1 == 0
or VMC_VAR_Deshumidification_On_SDB2 == 0
then
-- **************************************************************************
-- Identification du besoin éventuel de déclenchement de la VMC pour la SDB1
-- Besoin identifié si humidité > au seuil de déclenchement et que le programme
-- de déshumidification n'est pas déjà activé pour cette SDB
-- **************************************************************************
if Ecart_Max_Humidite_SDB1 >= SEUIL_DECLENCHEMENT_VMC and VMC_VAR_Deshumidification_On_SDB1 == 0 then
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'On'
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'On'
VMC_VAR_Deshumidification_On_SDB1 = 1
VMC_VAR_Cible_Hum_GV_Off_SDB1 = Cible_Humidite_SDB1
VMC_VAR_TimerSecuriteArret_SDB1 = NbCycles_Max_GV_VMC
Declenchement_SDB1 = 1
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Augmentation soudaine de l humidite. Activation de la VMC en grande vitesse. Ecart d humidite observe: ' .. Ecart_Max_Humidite_SDB1)
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Cible a atteindre pour l extinction du ventilateur : ' ..VMC_VAR_Cible_Hum_GV_Off_SDB1)
end
else
if MODE_DEBUGG== true and Ecart_Max_Humidite_SDB2 >= SEUIL_DECLENCHEMENT_VMC and VMC_VAR_Deshumidification_On_SDB1 == 0 then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Ecart non significatif, pas de mise en route du programme de deshumidification')
end
end
-- **************************************************************************
-- Identification du besoin éventuel de déclenchement de la VMC pour la SDB2
-- Besoin identifié si humidité > au seuil de déclenchement et que le programme
-- de déshumidification n'est pas déjà activé pour cette SDB
-- **************************************************************************
if Ecart_Max_Humidite_SDB2 >= SEUIL_DECLENCHEMENT_VMC and VMC_VAR_Deshumidification_On_SDB2 == 0 then
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'On'
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'On'
VMC_VAR_Deshumidification_On_SDB2 = 1
VMC_VAR_Cible_Hum_GV_Off_SDB2 = Cible_Humidite_SDB2
VMC_VAR_TimerSecuriteArret_SDB2 = NbCycles_Max_GV_VMC
Declenchement_SDB2 = 1
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Augmentation soudaine de l humidite. Activation de la VMC en grande vitesse. Ecart d humidite observe: ' .. Ecart_Max_Humidite_SDB2)
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Cible a atteindre pour l extinction du ventilateur : ' ..VMC_VAR_Cible_Hum_GV_Off_SDB2)
end
else
if MODE_DEBUGG== true and Ecart_Max_Humidite_SDB1 >= SEUIL_DECLENCHEMENT_VMC and VMC_VAR_Deshumidification_On_SDB2 == 0 then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Ecart non significatif, pas de mise en route du programme de deshumidification')
end
end
end
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if Ecart_Max_Humidite_SDB1 < SEUIL_DECLENCHEMENT_VMC
and Ecart_Max_Humidite_SDB2 < SEUIL_DECLENCHEMENT_VMC
then
if MODE_DEBUGG== true then
print('Ecarts non significatif sur les deux SDB, pas de mise en route du programme de deshumidification')
end
end
-- *****************************************************************************************
-- Si la VMC est en grande vitesse après l'analyse du besoin effectuée ci-dessus
-- *****************************************************************************************
if (otherdevices[NOM_INTERRUPTEUR_GV_VMC]=='On') or VMC_VAR_Deshumidification_On_SDB1 == 1 or VMC_VAR_Deshumidification_On_SDB2 == 1 then
if (VMC_VAR_TimerSecuriteArret_SDB1 > 0) then -- Si le déshumidification est en courspour la SDB1 on diminue
VMC_VAR_TimerSecuriteArret_SDB1 = VMC_VAR_TimerSecuriteArret_SDB1 - 1 -- la valeur du timer de sécurité pour l'arrêt automatique
end
if (VMC_VAR_TimerSecuriteArret_SDB2 > 0) then -- Si le déshumidification est en courspour la SDB2 on diminue
VMC_VAR_TimerSecuriteArret_SDB2 = VMC_VAR_TimerSecuriteArret_SDB2 - 1 -- la valeur du timer de sécurité pour l'arrêt automatique
end
end
-- *****************************************************************************************
-- Si la VMC est en grande vitesse pour la SDB1 et que l'humidité continue d'augmenter
-- *****************************************************************************************
if (VMC_VAR_Deshumidification_On_SDB1 == 1) then
if (Ecart_Max_Humidite_SDB1 >= SEUIL_DECLENCHEMENT_VMC and Declenchement_SDB1 == 0) then
-- S'il y a encore un écart d'humidité constaté sur la dernière période (augmentation humidité toujours en cours) et qu'il n'y a pas
-- eu de déclenchement dans ce cycle, on considère qu'on n'a pas encore atteint l'humidité max et on remet à 0 la VMC_VAR_TimerSecuriteArret_SDB1
VMC_VAR_TimerSecuriteArret_SDB1 = NbCycles_Max_GV_VMC
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - L humidite est toujours en augmentation, remise a 0 de la Securite Arret. Ecart constate sur la derniere periode : ' .. Ecart_Max_Humidite_SDB1)
end
end
end
-- *****************************************************************************************
-- Si la VMC est en grande vitesse pour la SDB2 et que l'humidité continue d'augmenter
-- *****************************************************************************************
if (VMC_VAR_Deshumidification_On_SDB2 == 1) then
if (Ecart_Max_Humidite_SDB2 >= SEUIL_DECLENCHEMENT_VMC and Declenchement_SDB2 == 0) then
-- S'il y a encore un écart d'humidité constaté sur la dernière période (augmentation humidité toujours en cours) et qu'il n'y a pas
-- eu de déclenchement dans ce cycle, on considère qu'on n'a pas encore atteint l'humidité max et on remet à 0 la VMC_VAR_TimerSecuriteArret_SDB2
VMC_VAR_TimerSecuriteArret_SDB2 = NbCycles_Max_GV_VMC
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - L humidite est toujours en augmentation, remise a 0 de la Securite Arret. Ecart constate sur la derniere periode : ' .. Ecart_Max_Humidite_SDB2)
end
end
end
-- *************************************************************************************************************
-- Analyse pour identifier si la grande vitesse peut être arrêtée si elle a été activée auparavant.
-- Si les Timers de sécurité sont atteints ou que l'humidité est redescendu pour les deux SDB on
-- arrête la grande vitesse et on regarde si on peut arrêter complètement la VMC (si l'humidité globale est Ok)
-- *************************************************************************************************************
if (VMC_VAR_TimerSecuriteArret_SDB1 == 0 or Humidite_Actuelle_SDB1 <= VMC_VAR_Cible_Hum_GV_Off_SDB1) and (VMC_VAR_TimerSecuriteArret_SDB2 == 0 or Humidite_Actuelle_SDB2 <= VMC_VAR_Cible_Hum_GV_Off_SDB2) then
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'Off'
if Hygro_Max_Depassee == 0 then -- Si l'humidité maximum globale de la maison n'est pas atteinte
if Humidite_Actuelle_SDB1<= uservariables['Hygro_Max_SDB'] and Humidite_Actuelle_SDB2<= uservariables['Hygro_Max_SDB'] then -- Si l'humidité des deux SDB est inférieure à l'humidité maximum acceptable dans une SDB
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'Off' -- on arrête complètement la VMC
if MODE_DEBUGG== true then
print('[Hygro Maison] - Hygrometrie correcte (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max) et aucune salle de bain en cours d utilisation, desactivation de la vmc')
end
else
-- sinon (hygro maison Ok, mais humidité d'une des deux SDB dépasse la valeur maximum acceptable), on active la VMC en petite vitesse
commandArray[NOM_INTERRUPTEUR_OnOff_VMC] = 'On'
if MODE_DEBUGG== true then
print('[Hygro Maison] - Hygrometrie correcte (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max), aucune salle de bain en cours d utilisation mais humidite SDB toujours trop elevee, VMC laissee active en petite vitesse')
end
end
end
end
-- *************************************************************************************************************
-- Analyse pour identifier s'il faut arrêter la grande vitesse suite à atteinte du timer de sécurité sur la SDB1
-- *************************************************************************************************************
if (VMC_VAR_TimerSecuriteArret_SDB1 == 0 and Humidite_Actuelle_SDB1 > VMC_VAR_Cible_Hum_GV_Off_SDB1 and VMC_VAR_Deshumidification_On_SDB1 == 1) then
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - L humidite n est pas redescendue a sa valeur initiale (avant activation de la grande vitesse) mais le TimeOut de securite pour l arret est atteint. Arret de la grande vitesse de la VMC pour ' .. NOM_CAPTEUR_HUMIDITE1)
end
-- Si on a atteint le timer de sécurité on réinitialise l'historique avec la valeur d'hulidité actuelle ainsi que les variables de la SDB1
VMC_VAR_Histo_Hum2_SDB1 = VMC_VAR_Histo_Hum1_SDB1
VMC_VAR_Deshumidification_On_SDB1 = 0
VMC_VAR_Cible_Hum_GV_Off_SDB1 = 0
VMC_VAR_TimerSecuriteArret_SDB1 = 0
VMC_VAR_Deshumidification_On_SDB1 = 0
end
-- *************************************************************************************************************
-- Analyse pour identifier s'il faut arrêter la grande vitesse suite à retour à au taux d'humidité initial sur la SDB1
-- *************************************************************************************************************
if (VMC_VAR_TimerSecuriteArret_SDB1 > 0 and Humidite_Actuelle_SDB1 <= VMC_VAR_Cible_Hum_GV_Off_SDB1 and VMC_VAR_Deshumidification_On_SDB1 == 1) then
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - L humidite est redescendue a une valeur proche de sa valeur initiale ('.. VMC_VAR_Cible_Hum_GV_Off_SDB1 ..'%). Arret de la grande vitesse de la VMC pour ' .. NOM_CAPTEUR_HUMIDITE1)
end
-- On réinitialise l'historique avec la valeur d'hulidité actuelle ainsi que les variables de la SDB1
VMC_VAR_Histo_Hum2_SDB1 = VMC_VAR_Histo_Hum1_SDB1
VMC_VAR_Deshumidification_On_SDB1 = 0
VMC_VAR_Cible_Hum_GV_Off_SDB1 = 0
VMC_VAR_TimerSecuriteArret_SDB1 = 0
VMC_VAR_Deshumidification_On_SDB1 = 0
end
-- *************************************************************************************************************
-- Analyse pour identifier s'il faut arrêter la grande vitesse suite à atteinte du timer de sécurité sur la SDB2
-- *************************************************************************************************************
if (VMC_VAR_TimerSecuriteArret_SDB2 == 0 and Humidite_Actuelle_SDB2 > VMC_VAR_Cible_Hum_GV_Off_SDB2 and VMC_VAR_Deshumidification_On_SDB2 == 1) then
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - L humidite n est pas redescendue a sa valeur initiale (avant activation de la grande vitesse) mais le TimeOut de securite pour l arret est atteint. Arret de la grande vitesse de la VMC pour ' .. NOM_CAPTEUR_HUMIDITE2)
end
-- Si on a atteint le timer de sécurité on réinitialise l'historique avec la valeur d'hulidité actuelle ainsi que les variables de la SDB2
VMC_VAR_Deshumidification_On_SDB2 = 0
VMC_VAR_Cible_Hum_GV_Off_SDB2 = 0
VMC_VAR_TimerSecuriteArret_SDB2 = 0
VMC_VAR_Deshumidification_On_SDB2 = 0
VMC_VAR_Histo_Hum2_SDB2 = VMC_VAR_Histo_Hum1_SDB2
end
-- *************************************************************************************************************
-- Analyse pour identifier s'il faut arrêter la grande vitesse suite à retour à au taux d'humidité initial sur la SDB2
-- *************************************************************************************************************
if (VMC_VAR_TimerSecuriteArret_SDB2 > 0 and Humidite_Actuelle_SDB2 <= VMC_VAR_Cible_Hum_GV_Off_SDB2 and VMC_VAR_Deshumidification_On_SDB2 == 1) then
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - L humidite est redescendue a une valeur proche de sa valeur initiale ('.. VMC_VAR_Cible_Hum_GV_Off_SDB2 ..'%). Arret de la grande vitesse de la VMC pour ' .. NOM_CAPTEUR_HUMIDITE2)
end
-- On réinitialise l'historique avec la valeur d'hulidité actuelle ainsi que les variables de la SDB2
VMC_VAR_Deshumidification_On_SDB2 = 0
VMC_VAR_Cible_Hum_GV_Off_SDB2 = 0
VMC_VAR_TimerSecuriteArret_SDB2 = 0
VMC_VAR_Deshumidification_On_SDB2 = 0
VMC_VAR_Histo_Hum2_SDB2 = VMC_VAR_Histo_Hum1_SDB2
end
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
if (Humidite_Actuelle_SDB1 > VMC_VAR_Cible_Hum_GV_Off_SDB1 and VMC_VAR_TimerSecuriteArret_SDB1 > 0 and Declenchement_SDB1 == 0) then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Deshumidification toujours en cours, humidite actuelle = ' .. Humidite_Actuelle_SDB1.. '% ,cible = ' .. VMC_VAR_Cible_Hum_GV_Off_SDB1 .. '% ,TimerSecurite= ' .. VMC_VAR_TimerSecuriteArret_SDB1)
end
if (Humidite_Actuelle_SDB2 > VMC_VAR_Cible_Hum_GV_Off_SDB2 and VMC_VAR_TimerSecuriteArret_SDB2 > 0 and Declenchement_SDB2 == 0) then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Deshumidification toujours en cours, humidite actuelle = ' .. Humidite_Actuelle_SDB2.. '% ,cible = ' .. VMC_VAR_Cible_Hum_GV_Off_SDB2 .. '% ,TimerSecurite= ' .. VMC_VAR_TimerSecuriteArret_SDB2)
end
end
else
-- -----------------------------------
-- Affichage des infos en mode debug
-- -----------------------------------
if MODE_DEBUGG== true then
print('Nombre de cycles avant la realisation des tests d adaptation de la vitesse VMC non atteint (' .. VMC_VAR_Compteur_Cycles .. '/' .. INTERVAL_MESURE .. ')')
end
end
-- *******************************************************
-- Si la VMC est arrêtée on arrête aussi la grande vitesse
-- *******************************************************
if commandArray[NOM_INTERRUPTEUR_OnOff_VMC] == 'Off' then
commandArray[NOM_INTERRUPTEUR_GV_VMC] = 'Off'
end
if MODE_DEBUGG== true then
print(' ')
print('***************')
print('ETAT EN SORTIE : ')
print('***************')
if VMC_VAR_Deshumidification_On_SDB1 == 0 then
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Deshumidification OFF - actuelle : ' .. Humidite_Actuelle_SDB1 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB1 .. '% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB1 .. '%')
else
print('[' .. NOM_CAPTEUR_HUMIDITE1 .. '] - Deshumidification ON - actuelle : ' .. Humidite_Actuelle_SDB1 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB1 ..'% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB1 .. '% / Cible arret : ' .. VMC_VAR_Cible_Hum_GV_Off_SDB1 .. '% / arret de securite dans ' .. VMC_VAR_TimerSecuriteArret_SDB1 .. ' cycle(s)')
end
if VMC_VAR_Deshumidification_On_SDB2 == 0 then
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Deshumidification OFF - actuelle : ' .. Humidite_Actuelle_SDB2 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB2 .. '% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB2 .. '%')
else
print('[' .. NOM_CAPTEUR_HUMIDITE2 .. '] - Deshumidification ON - actuelle : ' .. Humidite_Actuelle_SDB2 .. '% / Precedente : ' .. VMC_VAR_Histo_Hum1_SDB2 ..'% / Cycle -2 : ' .. VMC_VAR_Histo_Hum2_SDB2 .. '% / Cible arret : ' .. VMC_VAR_Cible_Hum_GV_Off_SDB2 .. '% / arret de securite dans ' .. VMC_VAR_TimerSecuriteArret_SDB2 .. ' cycle(s)')
end
if Hygro_Moyenne_Maison <= uservariables['Hygro_Max_Maison'] and VMC_VAR_Deshumidification_On_SDB1 ==0 and VMC_VAR_Deshumidification_On_SDB2 == 0 then
if Humidite_Actuelle_SDB1 <= Maximum_Humidite_Acceptable_SDB and Humidite_Actuelle_SDB2 <= Maximum_Humidite_Acceptable_SDB then
print('[Hygro Maison] - Hygrometrie correcte (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max) et aucune salle de bain en cours d utilisation, VMC desactivee')
else
print('[Hygro Maison] - Hygrometrie correcte (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max), aucune salle de bain en cours d utilisation mais humidite SDB toujours trop elevee, VMC laissee active en petite vitesse')
end
else
if Hygro_Moyenne_Maison > uservariables['Hygro_Max_Maison'] then
print('[Hygro Maison] - Hygrometrie incorrecte (' .. Hygro_Moyenne_Maison .. '% vs ' .. uservariables['Hygro_Max_Maison'] ..'% max), VMC activee')
end
end
end
-- Sauvegarde des variables
commandArray['Variable:VMC_VAR_Compteur_Cycles'] = tostring(VMC_VAR_Compteur_Cycles)
commandArray['Variable:VMC_VAR_Histo_Hum2_SDB1'] = tostring(math.floor(tonumber(VMC_VAR_Histo_Hum2_SDB1)))
commandArray['Variable:VMC_VAR_Histo_Hum1_SDB1'] = tostring(math.floor(tonumber(VMC_VAR_Histo_Hum1_SDB1)))
commandArray['Variable:VMC_VAR_Cible_Hum_GV_Off_SDB1'] = tostring(VMC_VAR_Cible_Hum_GV_Off_SDB1)
commandArray['Variable:VMC_VAR_TimerSecuriteArret_SDB1'] = tostring(VMC_VAR_TimerSecuriteArret_SDB1)
commandArray['Variable:VMC_VAR_Deshumidification_On_SDB1'] = tostring(VMC_VAR_Deshumidification_On_SDB1)
commandArray['Variable:VMC_VAR_Histo_Hum2_SDB2'] = tostring(math.floor(tonumber(VMC_VAR_Histo_Hum2_SDB2)))
commandArray['Variable:VMC_VAR_Histo_Hum1_SDB2'] = tostring(math.floor(tonumber(VMC_VAR_Histo_Hum1_SDB2)))
commandArray['Variable:VMC_VAR_Cible_Hum_GV_Off_SDB2'] = tostring(VMC_VAR_Cible_Hum_GV_Off_SDB2)
commandArray['Variable:VMC_VAR_TimerSecuriteArret_SDB2'] = tostring(VMC_VAR_TimerSecuriteArret_SDB2)
commandArray['Variable:VMC_VAR_Deshumidification_On_SDB2'] = tostring(VMC_VAR_Deshumidification_On_SDB2)
end
return commandArray

205
lua/old/script_time_volets.old Executable file
View File

@@ -0,0 +1,205 @@
require "scripts/lua/functions"
commandArray = {}
local HEURE_DEB = 9
local HEURE_FIN = 17
local TEMP_MAX = 24
local TEMP_MAX_2 = 28
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
--jour=tonumber(os.date('%w',time))
heures=tonumber(os.date('%H',time))
local saison = uservariables["Saison"]
local jourS = josdGetJourSemaine()
-- -------------------------------------------------------------------
-- Verification des volets ouverts si température trop basse
-- -------------------------------------------------------------------
if (minutes == 0 or minutes == 30 ) then
debug('########## Lancement du check fermeture velux du grenier ' ..heures..'h'..minutes)
tab = getValuesInTab('BarometreLaGacilly')
local tmp = tonumber(tab[1])
debug('########## Lancement du check fermeture velux du grenier ' ..heures..'h'..minutes..' tmp='..tostring(tmp))
if (tmp < 14.0 and (otherdevices['Velux droit'] == 'Open' or otherdevices['Velux gauche'] == 'Open')) then
commandArray['notification']="Volet ouvert#Un des volets du grenier est reste ouvert #0"
end
end
-- -----------------------
-- Fermeture volet central
-- -----------------------
if minutes%30 == 0
and (saison ~= "Ete")
and (heures >= 22) -- or uservariables['Dark'] == "True")
then
debug('------------------------------------------------------')
debug(' Test fermeture volet Central '..otherdevices['VoletPorteSalon'])
debug('------------------------------------------------------')
if (otherdevices['VoletPorteSalon'] ~= 'Closed') then
commandArray['VoletPorteSalon']='On'
end
end
-- ---------------------------------------------------------------------------------------
-- Fermeture des volets en fonction de la temperature exterieure Pas l'ETE
-- ---------------------------------------------------------------------------------------
--print("DARK=="..tostring(uservariables['Dark'] == "True"))
if minutes%9 == 0 and
(saison ~= "Ete")
and (otherdevices['VoletCuisine'] == 'Open' or otherdevices['VoletSalonTele'] == 'Open')
and (heures >= 18 or
(
heures >= 17 and (
uservariables['Dark'] == "True")
or (tonumber(otherdevices['Lux']) < tonumber(uservariables["LuxMini"]))
)
)
then
debug('------------------------------------------------------')
debug(' Test fermeture volet ')
debug('------------------------------------------------------')
debug('####### Comparaison heure vs Couche du soleil ========>'..uservariables["Heure"].." "..uservariables["Couche"])
debug('####### Lancement du check test ' ..heures..'h'..minutes..' volet cuisine '..otherdevices['BarometreLaGacilly']..' svalues='..otherdevices_svalues['BarometreLaGacilly']..' VoletCuisine='..otherdevices['VoletCuisine'])
tmp = otherdevices_svalues['BarometreLaGacilly']
tab = split(tmp, ";")
debug("######### Check fermeture : temperature lue par BarometreLaGacilly "..tab[1])
temp = tonumber(tab[1])
if (
(
(
(temp < 6.0 and whenDark() <= 30)
or (temp < 8 and whenDark() <= 15)
or (temp < 10 and whenDark() <= 0)
)
)
or (
uservariables['Dark'] == "True"
)
)
then
debug("######### Dans temperature")
if (otherdevices['VoletCuisine'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20) ) then
commandArray['VoletCuisine']='On'
end
if (otherdevices['VoletSalonTele'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20)) then
commandArray['VoletSalonTele']='On'
end
else
debug("############ PAS DANS LE IF")
end
end
-- ------------------------------------------------------------------------------
-- Ouverture des volets en fonction de la temperature exterieure Hiver et Automne
-- ------------------------------------------------------------------------------
if minutes%5 == 0
and heures <= HEURE_DEB
and ((heures >= 9 and josdJourChome()) or (heures > 6 and not josdJourChome()))
and (saison == "Hiver" or saison == "Automne")
and (greater2(uservariables["Heure"],uservariables["Lever"], - 30)) -- heures >= 20
and (otherdevices['VoletCuisine'] == 'Closed'
or otherdevices['VoletSalonTele'] == 'Closed'
or otherdevices['VoletPorteSalon'] == 'Closed'
)
then
debug('------------------------------------------------------')
debug(' Test ouverture volet ')
debug('------------------------------------------------------')
debug('####### Comparaison heure vs Lever du soleil ========>'..uservariables["Heure"]..
" "..uservariables["Lever"])
debug('####### Lancement du check test ' ..heures..'h'..minutes..' volet cuisine '
..otherdevices['BarometreLaGacilly']..' svalues='..otherdevices_svalues['BarometreLaGacilly']..' VoletCuisine='..otherdevices['VoletCuisine'])
tmp = otherdevices_svalues['BarometreLaGacilly']
tab = split(tmp, ";")
debug("######### Check Ouverture : temperature lue par BarometreLaGacilly "..tab[1])
temp = tonumber(tab[1])
if (temp > 12.0 or (heures >=9 and minutes >= 30)) then
if (otherdevices['VoletCuisine'] == 'Closed' or (minutes % 10 == 0 and heures == 9)) then
commandArray['VoletCuisine']='Off'
end
if (otherdevices['VoletSalonTele'] == 'Closed' or (minutes % 10 == 0 and heures == 9)) then
commandArray['VoletSalonTele']='Off'
end
if (otherdevices['VoletPorteSalon'] == 'Closed' or (minutes % 10 == 0 and heures == 9)) then
commandArray['VoletPorteSalon']='Off'
end
end
end
-- ------------------------------------------------------------------------------
-- fermeture des volets en fonction de la temperature interieure en ete
-- ------------------------------------------------------------------------------
if minutes%5 == 0 --and uservariables['Dark'] == "False"
and (heures > HEURE_DEB and heures <= HEURE_FIN)
--and (saison == "ete")
--and (greater(uservariables["Heure"] , uservariables["Lever"])) -- heures >= 20
--and (otherdevices['VoletCuisine'] == 'Open' or otherdevices['VoletSalonTele'] == 'Open' or otherdevices['VoletPorteSalon'] == 'Open')
then
debug('------------------------------------------------------')
debug(' Test fermeture volet Ete')
debug('------------------------------------------------------')
debug('####### Lancement du check test ' ..heures..'h'..minutes..' volet cuisine '..otherdevices['BarometreLaGacilly']..' svalues='..otherdevices_svalues['BarometreLaGacilly']..' VoletCuisine='..otherdevices['VoletCuisine'])
local val
local val2
val, val2 = otherdevices_svalues['BarometreLaGacilly']:match("([^;]+);([^;]+)")
debug("BarometreLaGacilly"..otherdevices["BarometreLaGacilly"]..val.." "..val2..otherdevices['VoletCuisine'].." "..otherdevices['VoletSalonTele'].." "..otherdevices['VoletPorteSalon'])
local temp = tonumber(val)
if temp >= TEMP_MAX and (otherdevices['VoletCuisine'] == 'Open' and otherdevices['VoletSalonTele'] == 'Open'
and otherdevices['VoletPorteSalon'] == 'Open') then
debug("fermeture volets : temp élevée")
if temp >= TEMP_MAX_2 then
os.execute("/opt/domoticz/scripts/volets2.sh On &")
else
os.execute("/opt/domoticz/scripts/volets.sh On &")
end
end
end
-- ------------------------------------------------------------------------------
-- Réouverture après la vague de chaleur ETE
-- ------------------------------------------------------------------------------
if minutes%5 == 0
and (heures > HEURE_FIN and heures <= 19)
and (saison == "ete" )
then
local val
local val2
val, val2 = otherdevices_svalues['BarometreLaGacilly']:match("([^;]+);([^;]+)")
print("BarometreLaGacilly"..otherdevices["BarometreLaGacilly"].." "..val.." "..val2..otherdevices['VoletCuisine'].." "..otherdevices['VoletSalonTele'].." "..otherdevices['VoletPorteSalon'])
local temp = tonumber(val)
if ((temp <= 24 or (temp <= TEMP_MAX and heures >= 18))
and (otherdevices['VoletCuisine'] == 'Closed' and
otherdevices['VoletSalonTele'] == 'Closed' and
otherdevices['VoletPorteSalon'] == 'Closed'))
then
debug("Ouverture volets : temp en baisse")
os.execute("/opt/domoticz/scripts/volets.sh Off &")
end
end
return commandArray

238
lua/old/soleil.lua Executable file
View File

@@ -0,0 +1,238 @@
--Variables à éditer--------------
local Ville = "pws:ILAGACIL2" --Ville de référence
local idxLux = '320' --Capteur virtuel de Luminosité
local idxOcta = '5' -- idx de la variable Utilisateur
local wuAPIkey = "48a08328a93a18a1"
local DEBUG = 'OUI'
--import des fontions pour lire le JSON
json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()
-- Fonction déterminant si année bissextile
function AnneeBissextile(annee)
return annee%4==0 and (annee%100~=0 or annee%400==0)
end
---------------------------------
-- Fonction spliter
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
---------------------------------
-- Fonction Arrondir
function arrondir(num, dec)
if num == 0 then
return 0
else
local mult = 10^(dec or 0)
return math.floor(num * mult + 0.5) / mult
end
end
---------------------------------
-- Procedure principale
---------------------------------
---------------------------------
-- Meteo API Wunderground
local config=assert(io.popen('curl http://api.wunderground.com/api/'..wuAPIkey..'/conditions/q/FR/'..Ville..'.json'))
local location = config:read('*all')
config:close()
local jsonLocation = json:decode(location)
local Latitude = jsonLocation.current_observation.display_location.latitude
local Longitude = jsonLocation.current_observation.display_location.longitude
local Altitude = jsonLocation.current_observation.display_location.elevation
PressionRelative = jsonLocation.current_observation.pressure_mb
----------------------------------
local An = os.date("%Y")
local NiemeJourDeLAnnee = os.date("%j")
---------------------------------
DateHeure = os.date("%Y-%m-%d %H:%M:%S", os.time())
-- Début debug
if( DEBUG == 'OUI') then
print("=====================================")
print(os.date("%Y-%m-%d %H:%M:%S", os.time()))
print(Ville .. ", " .. Latitude .. ", " .. Longitude)
print("Altitude = " .. tostring(Altitude) .. " m")
print("NiemeJourDeLAnnee = " .. NiemeJourDeLAnnee)
end
---------------------------------
--calcul de l'année bissextile
if AnneeBissextile(An) == true then
if( DEBUG == 'OUI') then
print( An .. " est bissextile.")
end
JourDansLAnnee = 366
else
if( DEBUG == 'OUI') then
print( An .. " n'est pas bissextile.")
end
JourDansLAnnee = 365
end
---------------------------------
-- Vitesse angulaire = Combien de degrés par jour
VitesseAngulaire = 360/365.25 ----JourDansLAnnee -- ou approximativement 365.25
if( DEBUG == 'OUI') then
print("Vitesse angulaire = " .. VitesseAngulaire .. " par jour")
end
---------------------------------
-- Formule Declinaison = ArcSin(0,3978 x Sin(Va x (j - (81 - 2 x Sin(Va� x (j - 2))))))
local Declinaison = math.deg(math.asin(0.3978 * math.sin(math.rad(VitesseAngulaire) *(NiemeJourDeLAnnee - (81 - 2 * math.sin((math.rad(VitesseAngulaire) * (NiemeJourDeLAnnee - 2))))))))
if( DEBUG == 'OUI') then
print("La déclinaison = " .. Declinaison .. "°")
end
---------------------------------
-- Temps universel décimal (UTC)
TempsDecimal = (os.date("!%H") + os.date("!%M") / 60)
if( DEBUG == 'OUI') then
print("Temps universel decimal (UTC)".. TempsDecimal .." H.dd")
end
---------------------------------
-- Temps solaire
HeureSolaire = TempsDecimal + (4 * Longitude / 60 )
if( DEBUG == 'OUI') then
print("Temps solaire ".. HeureSolaire .." H.dd")
end
---------------------------------
-- Angle horaire du soleil
AngleHoraire = 15 * ( 12 - HeureSolaire )
if( DEBUG == 'OUI') then
print("Angle Horaire = ".. AngleHoraire .. "°")
end
---------------------------------
-- La hauteur du soleil (Elévation ou altitude)
HauteurSoleil = math.deg(math.asin(math.sin(math.rad(Latitude))* math.sin(math.rad(Declinaison)) + math.cos(math.rad(Latitude)) * math.cos(math.rad(Declinaison)) * math.cos(math.rad(AngleHoraire))))
if( DEBUG == 'OUI') then
print("Hauteur du soleil = " .. HauteurSoleil .. "°")
end
local Azimut = math.acos((math.sin(math.rad(Declinaison)) - math.sin(math.rad(Latitude)) * math.sin(math.rad(HauteurSoleil))) / (math.cos(math.rad(Latitude)) * math.cos(math.rad(HauteurSoleil) ))) * 180 / math.pi
local SinAzimut = (math.cos(math.rad(Declinaison)) * math.sin(math.rad(AngleHoraire))) / math.cos(math.rad(HauteurSoleil))
if(SinAzimut<0) then
Azimut=360-Azimut
end
if( DEBUG == 'OUI') then
print("Azimut du soleil = " .. Azimut .. "°")
end
---------------------------------
-- La durée d'insolation journalière - non stockée en VG
DureeInsolation = math.deg(2/15 * math.acos(- math.tan(math.rad(Latitude)) * math.tan(math.rad(Declinaison))))
DureeInsolation = arrondir(DureeInsolation,2)
if( DEBUG == 'OUI') then
print("La durée d'insolation journalière = " .. DureeInsolation .." H.dd")
end
---------------------------------
-- Constantes Solaire
ConstanteRatiationSolaire = 1361 -- W/m²
ConstanteRadiationLux = 200000 -- Lux
---------------------------------
-- Rayonnement solaire (en W/m²) présent à l'entrée de l'atmosphère.
RadiationAtm = ConstanteRatiationSolaire * (1 +0.034 * math.cos( math.rad( 360 * NiemeJourDeLAnnee / JourDansLAnnee )))
if( DEBUG == 'OUI') then
print("Radiation max en atmosphère = " .. arrondir(RadiationAtm,2) .. " W/m²")
end
---------------------------------
-- Coefficient d'attenuation M
PressionAbsolue = PressionRelative - arrondir((Altitude/ 8.3),1) -- hPa
SinusHauteurSoleil = math.sin(math.rad(HauteurSoleil))
M0 = math.sqrt(1229 + math.pow(614 * SinusHauteurSoleil,2)) - 614 * SinusHauteurSoleil
M = M0 * PressionRelative/PressionAbsolue
if( DEBUG == 'OUI') then
print("Pression relative locale = " .. PressionRelative .. " hPa")
print("Pression absolue atmosphère = " .. PressionAbsolue .. " hPa")
print("Coefficient d'attenuation = " .. M )
end
---------------------------------
-- Récupérer message SYNOP sur le site Ogimet
heureUTCmoins1 = os.date("!%H")-1
if string.len(heureUTCmoins1) == 1 then
heureUTCmoins1 = "0" .. heureUTCmoins1
end
UTC = os.date("%Y%m%d").. heureUTCmoins1.."00" -- os.date("!%M")
local WMOID = jsonLocation.current_observation.display_location.wmo
print("WMOID="..WMOID)
local ogimet=assert(io.popen('curl "http://www.ogimet.com/cgi-bin/getsynop?block='..WMOID..'&begin='..UTC..'"'))
local synop = ogimet:read('*all')
ogimet:close()
rslt = split(synop,",")
CodeStation = rslt[1]
rslt = split(synop, " "..CodeStation.. " ")
Trame = string.gsub(rslt[2], "=", "")
Trame = CodeStation .." ".. Trame
rslt = split(Trame, " ")
if( DEBUG == 'OUI') then
print("Horodatage UTC = " .. UTC)
print("Station SYNOP = " .. WMOID)
end
---------------------------------
-- Récupérer le premier caractere du 3eme mot = Nebulosité en Octa
Octa = string.sub(rslt[3], 1, 1)
--print(rslt[3])
-- 0 Pas de couverture nuageuse
-- 1-8 Huitième
-- 9 Brouillard
-- / Couverture indiscernable
-- cas particulier si valeur indéterminé un slash est renvoyé.
if Octa == "/" then
-- si la couverture est indiscernable, on reprend l'ancienne valeur
-- cela evite les violentes cassures dans la courbe
--Octa = uservariables['octa']
Octa = arg[1]
elseif Octa == "9" then
Octa = 8
end
if( DEBUG == 'OUI') then
print( Octa .. " Octa")
end
-- stockage de la variable octa
--commandArray['Variable:octa']=tostring(Octa)
os.execute('/usr/bin/curl "http://127.0.0.1:8080/json.htm?type=command&param=updateuservariable&idx='..idxOcta..'&vname=octa&vtype=0&vvalue='..tostring(Octa)..'"')
---------------------------------
-- Facteur d'atténuation des couches nuageuses Kc
-- Kc=1-(0.75*((OCTA)**(3.4))
Kc=1-0.75*(math.pow(Octa/8,3.4))
if( DEBUG == 'OUI') then
print("Kc = " .. Kc)
end
---------------------------------
-- Au lever/coucher du soleil, on atteind les limites de précisions de ces calculs.
-- J'interrompts donc le calcul de radiation dès 1°.
if HauteurSoleil > 1 then
-- Radiation directe
RadiationDirecte = RadiationAtm * math.pow(0.6,M) * SinusHauteurSoleil
-- Radiation Diffuse
RadiationDiffuse = RadiationAtm * (0.271 - 0.294 * math.pow(0.6,M)) * SinusHauteurSoleil
-- Radiation totale
RadiationTotale = RadiationDiffuse + RadiationDirecte
-- Radiation en Lux : -- 1 Lux = 0,0079 W/m²
Lux = RadiationTotale / 0.0079
--Lux = ConstanteRadiationLux / ConstanteRatiationSolaire * RadiationTotale
-- Le rayonnement solaire avec ciel nuageux
RTOTC = RadiationTotale * Kc
-- Radiation en Lux pondéré
-- LuxPondere = ConstanteRadiationLux / ConstanteRatiationSolaire * RTOTC
LuxPondere = RTOTC / 0.0079
print("Radiation totale en lux pondéré = ".. arrondir(LuxPondere,2).." Lux")
if( DEBUG == 'OUI') then
print("RadiationDirecte = ".. arrondir(RadiationDirecte,2) .." W/m²")
print("Radiation Diffuse = ".. arrondir(RadiationDiffuse,2) .." W/m²")
print("Radiation totale = " .. arrondir(RadiationTotale,2) .." W/m²")
print("Radiation totale en lux = ".. arrondir(Lux,2).." Lux")
print("Le rayonnement solaire avec pondération = " .. arrondir(RTOTC,2))
end
else
--le soleil est trop bas
RTOTC = 0
LuxPondere = 0
end
--mise à jour du dispositif
os.execute('/usr/bin/curl "http://127.0.0.1:8080/json.htm?type=command&param=udevice&idx='..idxLux..'&svalue="'..tostring(LuxPondere)..' -s -o /dev/null')

74
lua/script_device_Cameras.lua Executable file
View File

@@ -0,0 +1,74 @@
require "scripts/lua/functions"
commandArray = {}
-- ------------------------------------------------------------------------------
--recupere les minutes
-- ------------------------------------------------------------------------------
time=os.time()
minutes=tonumber(os.date('%M',time))
jour=tonumber(os.date('%w',time))
heures=tonumber(os.date('%H',time))
heurmin= heures * 60 + minutes
-- ------------------------------------------------------------------------------
-- Determination de l'augmentation de la temperature exterieure
-- ------------------------------------------------------------------------------
if devicechanged['DETECTION_CAMERA1'] then
print("--------------Detection camera 1--------------------------------")
-- if (otherdevices['Presence'] == 'Off' or otherdevices['Vacances'] == 'On'
-- or heures <= 11 or heures >= 21
--) then
commandArray['SendNotification']='Alerte intrusion '..tostring(heures)..':'..tostring(minutes)..' #Attention Detection intrusion par camera 1#0'
-- end
-- print("------------------------------------------------------------------")
end
-- ------------------------------------------------------------------------------
-- Detecteur de fumée, on allume les lumières et on ouvre les volets
-- ------------------------------------------------------------------------------
if devicechanged['DétecteurFuméeCuisine'] then
debug("--------------Detecteur fumée --------------------------------")
if (otherdevices['Presence'] == 'Off' or otherdevices['Vacances'] == 'On') then
commandArray['SendNotification']='Alerte détection de fumée '..tostring(heures)..':'..tostring(minutes)..' #Attention Detection fumée#0'
else
if uservariables['Dark'] == "True" then
commandArray['VoletsSalon'] = 'Off'
commandArray['LumieresSalon'] = 'On'
end
end
debug("------------------------------------------------------------------")
end
-- ------------------------------------------------------------------------------
-- Réglage volume
-- ------------------------------------------------------------------------------
if devicechanged['VolumeSonoJasper'] then
print("--------------Volume Sono Jasper --------------------------------")
local slash = '\\'
--local val = os.capture(cmd2)
-- print(tostring(val))
local cmd = "/opt/domoticz/scripts/changevol.sh "
os.execute('/opt/domoticz/scripts/changevol.sh &')
print("Réglage volume " .. cmd)
print("------------------------------------------------------------------")
end
--debug("temperature lue par otherdevice "..otherdevices_svalues['Bureau'])
--debug(round(timeofday['SunsetInMinutes'] / 60, 0)..'H'..timeofday['SunsetInMinutes'] % 60)
--debug(round(timeofday['SunriseInMinutes'] / 60, 0)..'H'..timeofday['SunriseInMinutes'] % 60)
--debug("################################# SUNSET "..uservariables['Couche'])
return commandArray

162
lua/script_device_Detection.lua Executable file
View File

@@ -0,0 +1,162 @@
require "scripts/lua/functions"
commandArray = {}
-- ------------------------------------------------------------------------------
--recupere les minutes
-- ------------------------------------------------------------------------------
time=os.time()
minutes=tonumber(os.date('%M',time))
jour=tonumber(os.date('%w',time))
day=tonumber(os.date('%d',time))
heures=tonumber(os.date('%H',time))
heurmin= heures * 60 + minutes
mois=tonumber(os.date('%m',time))
extinction = uservariables['HEURE_EXTINCTION_FEUX']
-- ------------------------------------------------------------------------------
-- Derniere détection
-- ------------------------------------------------------------------------------
if devicechanged['Detecteur Salon'] or devicechanged['Detecteur Bureau'] then
commandArray['Variable:DerniereDetection'] = tostring(heures)..":"..tostring(minutes)
debug("DerniereDetection"..tostring(heures)..":"..tostring(minutes))
end
-- Quelqu'un est reveillé on ouvre les volets
if devicechanged['Detecteur Bureau'] or devicechanged['Detecteur Salon'] then
if ((heures >= 6) and (heures <= 9))
and otherdevices['VoletPorteSalon'] == 'Closed'
and lastUpdateOfDevice('VoletPorteSalon') > 120
then
os.execute("/opt/domoticz/scripts/volets3.sh Off &")
end
if (heures >= 23)
and otherdevices['VoletPorteSalon'] == 'Open'
then
-- os.execute("/opt/domoticz/scripts/volets2.sh On &")
end
end
-- Volets
-- ------------------------------------------------------------------------------
-- Lampes allumees si presence détéctée
-- ------------------------------------------------------------------------------
if devicechanged['Detecteur Bureau'] or devicechanged['Detecteur Salon']
--or devicechanged['Lux']
or devicechanged['Presence'] or
devicechanged['Philae'] or devicechanged['Akhesa'] or
devicechanged['Moi'] or devicechanged['Domi'] or
devicechanged['Theo'] or devicechanged['Manon'] or
devicechanged['DetectionCamera1']
--or true
then
print("LAMPE : test allumage lampes")
local sunriseMin = heureEnMinute(uservariables["Lever"])
local now = 60 * heures + minutes
if (otherdevices['Vacances'] == 'On' or otherdevices['Presence'] == 'Off'
or ((mois >= 6 and mois <= 7) or (mois == 8 and day < 15))) then
print("LAMPE : desactivation"..tostring(mois)..' '..tostring(day))
switchLightsIfNeeded('Off')
elseif (otherdevices['Vacances'] == 'Off' and otherdevices['Presence'] == 'On') then
if (whenDark() <= 15) then -- and otherdevices['VoletPorteSalon'] == 'Open') then
if (
(heures >= 7 and heures <= 10 and not josdJourChome())
or (heures >= 14 and
(
(heures < 22) --or (heures == 22 and minutes < 30)
)
)
) then
print("LAMPE Allumer les lampes")
switchLightsIfNeeded('On')
else
if (heures > 22) or heures < 7 then
switchLightsIfNeeded('Off')
print("LAMPE Eteindre les lampes")
end
end
else
if (now > sunriseMin) then -- and lum > luxMini) then
switchLightsIfNeeded('Off')
print("LAMPE Eteindre les lampes")
elseif (heures >= 22) or heures < 7 then
switchLightsIfNeeded('Off')
print("LAMPE Eteindre les lampes")
end
end
else
print("LAMPE Dans le else "..tostring(heures))
end
end
--end
-- ------------------------------------------------------------------------------
-- Envoi de notification si detection en absence
-- ------------------------------------------------------------------------------
-- Vacances
if devicechanged['Detecteur Salon'] and (otherdevices['Vacances'] == 'On' or otherdevices['Presence'] == 'Off') then
debug("Detection en absence")
commandArray['SendNotification']='Mode absence#Une presence a ete detectee pres de la tele.#0'
end
-- Vacances
if devicechanged['Detecteur Bureau'] and (otherdevices['Vacances'] == 'On' or otherdevices['Presence'] == 'Off') then
debug("Detection en absence")
commandArray['SendNotification']='Mode absence#Une presence a ete detectee dans le bureau.#0'
end
-- ------------------------------------------------------------------------------
-- Derniere détection
-- ------------------------------------------------------------------------------
if devicechanged['Detecteur Salon'] or devicechanged['Detecteur Bureau'] then
commandArray['Variable:DerniereDetection'] = tostring(heures)..":"..tostring(minutes)
debug("DerniereDetection"..tostring(heures)..":"..tostring(minutes))
end
-- Quelqu'un est reveillé on ouvre les volets
if false and devicechanged['Detection_Tennis'] then
value = tonumber(otherdevices['Detection_Tennis'])
print("nombre de Detection_Tennis="..tostring(value).." jour="..jour)
heure_debut = 21
heure_fin = 8
if jour == 1 then
heure_debut = 8
end
if jour == 2 then
heure_debut = 21
end
-- Jour 3 = Mercredi
if jour == 3 then
heure_debut = 23
end
if jour == 4 then
heure_debut = 20
end
if jour == 5 then
heure_debut = 20
end
if jour == 6 then
heure_debut = 19
end
if jour == 7 then
heure_debut = 20
end
if (((heures >= heure_debut) or (heures <= 8)) and value > 0)
then
commandArray['SendNotification']='Detection présence au tennis club après 23h#Une presence a ete detectee dans le bureau http://souti56.ddns.net:8081/.#0'
end
end
return commandArray

628
lua/script_device_Energie.SAVE Executable file
View File

@@ -0,0 +1,628 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The debug command will output lua debug statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do debug(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do debug(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
require "scripts/lua/functions"
time = os.time()
annee = os.date('%Y',time)
mois = os.date('%m',time)
heures = tonumber(os.date('%H',time))
minutes = tonumber(os.date('%M',time))
secondes = tonumber(os.date('%S',time))
jour = tonumber(os.date('%w',time))
jour_s = os.date('%d',time)
jour_y = tonumber(os.date('%j',time))
heurmin = heures * 60 + minutes
PUISSANCE_DELESTAGE = 750 -- Watts
disable_radiateur = false
function callExternal(command)
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
--debug("Commande = "..command.." "..result)
return result
end
function update_meter(device, id, power, energy, index)
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
end
local function round(num, dec)
--debug("Round "..tostring(num))
return ( math.floor( tonumber(num) * 10^dec ) / 10^dec )
end
local 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 getConsommationHC(idx)
date=annee..'-'..mois..'-'..jour_s
--date_end=annee..'-'..mois..'-'..math.floor(jour_s + 1)
-- query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
-- .. ' and date like "' .. date ..'%"'
-- .. ' and (date >= "' .. date_deb.. ' 21:29:59" or date <= "'.. date_deb ..' 05:30:00")'
query = 'select sum(hc) from (select max(value) - min(value) as hc from Meter mc where DeviceRowID =' ..idx
.. ' and date like "' .. date ..'%"'
.. ' and (date >= "' .. date.. ' 21:29:59"'
.. ' and date < "' .. date ..' 23:59:59")'
.. ' union all'
.. ' select max(value) - min(value) as hc from Meter mc where DeviceRowID =' .. idx
.. ' and date like "' .. date ..'%"'
.. ' and (date < "' .. date ..' 05:30:00")'
.. ' and (date > "' .. date ..' 00:00:00")'
.. ') as c'
--query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
-- .. ' and date like "' .. date ..'%"'
-- .. ' and not(date > "' .. date.. ' 05:29:59" and date <= "'.. date ..' 21:30:00")'
debug("query="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
if aRows[1][1] then
debug("Retour executeQuery "..tostring(bSuccess)..' '..aRows[1][1])
return aRows[1][1]
end
debug('retour à 0')
return 0
end
function getConsommationHP(idx)
date=annee..'-'..mois..'-'..jour_s
query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
.. ' and date like "' .. date ..'%"'
.. ' and (date > "' .. date.. ' 05:29:59" and date <= "'.. date ..' 21:30:00")'
--debug("query="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
--debug("Retour executeQuery "..tostring(bSuccess)..' '..aRows[1][1])
return aRows[1][1]
end
function deleteWrongData(idx)
-- delete from MultiMeter where DeviceRowid = 1135 and date >= "2021-06-02 00:00:00"
-- and date like "2021-06-02 00:00%";
date=annee..'-'..mois..'-'..jour_s
query = 'delete from MultiMeter where DeviceRowID =' ..idx
.. ' and date like "' .. date ..' 00:00%"'
.. ' and (date >= "' .. date.. ' 00:00:00")'
debug("query delete="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
end
commandArray = {}
if devicechanged['RadiateurGrenier'] then
print("Dimmer Radiateur "..otherdevices_svalues['RadiateurGrenier']..tostring(otherdevices['RadiateurGrenier']))
local consigne = tonumber(otherdevices_svalues['RadiateurGrenier'])
print("Dimmer Radiateur grenier="..tostring(consigne))
if consigne <= 0 or otherdevices['RadiateurGrenier'] == "Off" then
-- command = 'curl -m 3 "http://192.168.177.240/stop"'
command = 'curl -m 3 "http://192.168.197.193/stop"'
else
-- command = 'curl -m 3 "http://192.168.177.240/exact?value=' .. tostring(consigne * 7).. '"'
command = 'curl -m 3 "http://192.168.197.193/exact?value=' .. tostring(consigne * 3.5).. '"'
end
callExternal(command)
end
-- ==================================================================
-- INTENSITE_GENERALE
-- ==================================================================
--if (devicechanged['CONSOMMATION_GENERALE']) then
function calcul()
--local tab = getValuesInTab('Oregon_Conso')
--debug("Conso "..otherdevices['Oregon_Conso'])
--values = split(otherdevices['Oregon_Conso'], ";")
--if (tonumber(values[1]) < 0) then
-- if (tonumber(values[1]) == -0.1) then
-- watt = - tonumber(values[2])
-- else
-- watt = tonumber(values[1]) * 100 - tonumber(values[2])
-- end
--else
-- watt = (tonumber(values[1]) * 100 + tonumber(values[2])) --/ 1.42
--end
values2 = split(otherdevices['CONSOMMATION_GENERALE'], ";")
print("NRJ Solaire CONSOMMATION_GENERALE tabs "..otherdevices['CONSOMMATION_GENERALE'])
watt = tonumber(values2[1])
for deviceName,deviceValue in pairs(devicechanged) do
if deviceName=="CONSOMMATION_GENERALE_Utility" then
watt = deviceValue
end
debug ("Device based event fired on '"..deviceName.."', value '"..tostring(deviceValue).."'");
end
debug("Conso "..tostring(watt))
--debug("mesure"..otherdevices['INTENSITE_GENERALE'])
amp = watt / 230 --math.max(0,round(otherdevices['INTENSITE_GENERALE'],3) - 0.54) * 7 / 8
watt_conso = watt --* 0.9459
updatenum('INTENSITE_GENERALE', amp)
debug("consommation Amp="..tostring(amp).." conso="..tostring(watt_conso))
--updatenum('CONSOMMATION_GENERALE', round(watt_conso,0))
local tab = getValuesInTab('SolaireProduction')
local watt_solaire = tonumber(tab[1])
local watt_solaire_jour = otherdevices_svalues['SolaireProduction']
if watt_solaire == nil then
watt_solaire = 0
end
debug("Suivi "..tostring(watt_conso - watt_solaire))
if (minutes%5 == 0 and secondes < 8) then
date = annee..'-'..mois..'-'..jour_s
counter_conso = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Consommation_Apparente']..' order by Date desc limit 1;"')
counter_conso=tonumber(counter_conso) or 0
debug('counter_conso='..counter_conso)
value_conso = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Consommation_Apparente']..' order by Date desc limit 1;"')
value_conso=tonumber(value_conso) or 0
debug('value_conso='..value_conso)
counter_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
counter_solar=tonumber(counter_solar) or 0
debug('counter_solar='..counter_solar)
value_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
value_solar=tonumber(value_solar) or 0
debug('value_solar='..value_solar)
counter_injection = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['INJECTION']..' order by Date desc limit 1;"')
counter_injection=tonumber(counter_injection) or 0
debug('counter_injection='..counter_injection)
value_injection = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['INJECTION']..' order by Date desc limit 1;"')
value_injection=tonumber(value_injection) or 0
debug('value_injection='..value_injection)
counter_radiateur = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Injection_Radiateur']..' order by Date desc limit 1;"')
counter_radiateur=tonumber(counter_radiateur) or 0
debug('counter_radiateur='..counter_radiateur)
value_radiateur = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Injection_Radiateur']..' order by Date desc limit 1;"')
value_radiateur=tonumber(value_radiateur) or 0
debug('value_radiateur='..value_radiateur)
cumul_solar = value_solar - counter_solar
cumul_injection = value_injection - counter_injection
consommation = value_conso - counter_conso
cumul_radiateur = value_radiateur - counter_radiateur
debug('conso='..consommation)
debug('cumul_solar='..cumul_solar)
debug('cumul_injection='..cumul_injection)
debug('cumul_radiateur='..cumul_radiateur)
if (cumul_solar > 0) then
debug("auto consommation="..tostring(
round((100 * (cumul_solar - cumul_injection) / cumul_solar),1))
)
commandArray['AUTO_CONSOMMATION'] = otherdevices_idx['AUTO_CONSOMMATION'] ..'|0|' .. tostring(
round((100 * (cumul_solar - cumul_injection) / cumul_solar),1)
)
updatenum('AUTO_CONSOMMATION', round((100 * (cumul_solar - cumul_injection) / cumul_solar),1) )
end
if (consommation > 0) then
debug("auto production="..tostring(100 * cumul_solar / (cumul_solar + consommation)))
updatenum('AUTO_PRODUCTION', round(100 * cumul_solar / (cumul_solar + consommation),1))
end
updatenum('COUVERTURE', round(100 * value_solar / (value_conso + value_solar),1))
if (cumul_solar > 0) then
updatenum('Consommation_Efficace', round(100 *((cumul_solar - cumul_radiateur - cumul_injection) / cumul_solar), 1))
else
updatenum('Consommation_Efficace', 0)
end
end
end
if (devicechanged['Mesure_Courant']) then
print('NRJ Mesure_Courant '..otherdevices['Mesure_Courant'])
values2 = split(otherdevices['Mesure_Courant'], ";")
debug("Solaire Mesure courant tabs ") --..otherdevices['Mesure_Courant'])
watt = tonumber(values2[1])
if (watt > 1600) then
watt = 0;
end
for deviceName,deviceValue in pairs(devicechanged) do
if deviceName=="Mesure_Courant_Utility" then
watt = deviceValue
end
debug ("Device based event fired on '"..deviceName.."', value '"..tostring(deviceValue).."'");
end
print("NRJ Solaire Mesure courant "..tostring(watt))
--updatenum('SolaireIntensite', round(watt / 230,3))
--updatenum('INTENSITE_GENERALE', round(watt / 230,3))
watt = math.abs(watt) --- 56
--if (watt < 0 or (heures <= 7 or heures >= 21)) then
-- watt = 0
--end
--debug("Intensite solaire "..devicechanged['SolaireIntensite'])
amp = math.abs(watt / 230); --math.max(0, round(otherdevices['SolaireIntensite'],3) - 0.54) *1.18
updatenum('SolaireIntensite', amp)
print("NRJ # 2 # production amp="..tostring(amp).." watt="..tostring(watt))
--debug("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN")
if (watt == nil or watt == "NAN") then
watt = 0
end
updatenum('SolaireProduction', round(watt,1))
watt_solaire = math.abs(watt)
local tab = getValuesInTab('CONSOMMATION_GENERALE')
local watt_conso = tonumber(tab[1])
local tab_r = getValuesInTab('Consommation_Apparente')
local watt_reel = tonumber(tab_r[1])
if (watt_reel > 0) then
updatenum('CONSOMMATION_GENERALE', watt_reel)
if watt_solaire > 0 then
updatenum('COUVERTURE_INSTANTANEE', round(100 * (watt_solaire / (watt_solaire + watt_reel)), 1))
else
updatenum('COUVERTURE_INSTANTANEE', 0)
end
else
updatenum('COUVERTURE_INSTANTANEE', 100)
updatenum('CONSOMMATION_GENERALE', 0)
end
calcul()
end
if (devicechanged['Consommation_Apparente']) then
print("NRJ Consommation_Apparente ================================================")
values2 = split(otherdevices['Consommation_Apparente'], ";")
watt = tonumber(values2[1])
for deviceName,deviceValue in pairs(devicechanged) do
if deviceName=="Consommation_Apparente_Utility" then
-- watt = deviceValue
watt = round(deviceValue, 2)
debug ("Device based event fired on '"..deviceName.."', value "..tostring(round(deviceValue, 2)));
end
-- debug ("Device based event fired on '"..deviceName.."', value "..tostring(tonumber(deviceValue)));
end
debug("Solaire Consommation_Apparente "..tostring(watt))
values = split(otherdevices['SolaireProduction'], ";")
--debug("Solaire production "..otherdevices['SolaireProduction'])
watt_solaire = values[1]
values2 = split(otherdevices['Mesure_Courant'], ";")
--debug("Solaire production mesure courant "..otherdevices['Mesure_Courant'])
watt_solaire = values[1] --+ values2[1]
if watt_solaire == "NAN" then
watt_solaire = "0"
end
injection = split(otherdevices['INJECTION'], ";")
debug(injection[1])
local debut_injection = -14
local fin_injection = 14
local currentTemp = getTemperatureFromDevice('Bureau')
debug("Solaire production temperature Exterieur_Cellier "..tostring(currentTemp).." "..tostring(watt_solaire))
if disable_radiateur == false then
command = 'curl -s -m 3 "http://192.168.125.11"|grep "<p>"|awk -F">" \'{print $2}\'|awk -F"<" \'{print $1}\''
--local handle = io.popen(command)
--local result = handle:read("*a")
--handle:close()
result = callExternal(command)
print("quick_value result niveau d'injection= "..result)
if --tonumber(watt_solaire) < 50 or
uservariables["Dark"] == "True" or (currentTemp >= 24 and (jour_y > 150 and jour_y < 260)) then
-- commandArray['Dimmer'] = 'Set Level: 30'
else
if result == 0 or result == "" or result == nil or result == "NAN" then
result = 0
end
--if (tonumber(watt_solaire) < result * (PUISSANCE_DELESTAGE / 100) and tonumber(watt) > 0 ) or tonumber(watt) > fin_injection then
-- debug("Solaire quick_value stop")
-- command = 'curl -m 3 "http://192.168.125.11/stop"'
-- callExternal(command)
--else
if (watt < debut_injection) then
local to_inject = math.abs(watt) -- + tonumber(result) * (PUISSANCE_DELESTAGE / 100)
local quick_value = math.floor(to_inject / (PUISSANCE_DELESTAGE / 100))
--print("Solaire PLUS quick_value="..tostring(quick_value).." to_inject="..tostring(to_inject))
--local quick_value = math.floor(math.abs(watt / (PUISSANCE_DELESTAGE / 100)) - tonumber(result)) --/ 2
print("Solaire quick_value plus="..tostring(quick_value).." watt="..tostring(watt))
if (quick_value > 0) then
command = 'curl -m 3 "http://192.168.125.11/plus?value=' .. tostring(quick_value).. '"'
callExternal(command)
end
else
if (watt > fin_injection) then
local to_inject = watt --tonumber(result) * (PUISSANCE_DELESTAGE / 100) - watt
local quick_value = math.abs(math.floor(to_inject / (PUISSANCE_DELESTAGE / 100)))
--local quick_value = math.floor(tonumber(result) - math.abs((watt) / (PUISSANCE_DELESTAGE / 100)) )
--print("Solaire MINUS quick_value="..tostring(quick_value).." to_inject="..tostring(to_inject))
print("Solaire quick_value minus="..tostring(quick_value).." watt="..tostring(watt))
command = 'curl -m 3 "http://192.168.125.11/minus?value=' .. tostring(quick_value).. '"'
callExternal(command)
end
end
--end
end
end
if result == 0 or result == "" or result == nil or result == "NAN" then
print("result nil value")
updatenum('TOTAL_AUTOCONSOMMATION', 0)
else
if (tonumber(result) == 1) then
commandArray['Dimmer'] = 'Set Level: 30'
result=0
end
local injection_radiateur = tonumber(result) * PUISSANCE_DELESTAGE / 100
updatenum('Injection_Radiateur', injection_radiateur)
updatenum('TOTAL_AUTOCONSOMMATION', round(watt_solaire - injection[1] - math.abs(injection_radiateur), 0))
end
-- ========================================================================
if false then
if tonumber(watt_solaire) < 50 or uservariables["Dark"] == "True" then
commandArray['Dimmer'] = 'Set Level: 30'
else
if (watt < debut_injection and tonumber(watt_solaire) > 150) then
debug("Allumage radiateur pour éviter l'injection " .. tostring(lastUpdateOfDevice('RadiateurBureau')))
if watt < debut_injection then
local quick_value = math.floor(math.abs(watt / (PUISSANCE_DELESTAGE / 100)))
debug("quick_value plus="..tostring(quick_value))
command = 'curl -m 3 "http://192.168.125.11/plus?value=' .. tostring(quick_value).. '"'
callExternal(command)
--os.execute('curl -m 3 "http://192.168.125.11/plus?value=' .. tostring(quick_value).. '"');
else
commandArray['Dimmer'] = 'Set Level: 40'
end
else
debug("Pas de consommation necessaire")
if (watt > 150) then
commandArray['Dimmer'] = 'Set Level: 30'
else
if (watt > fin_injection) then
local quick_value=math.floor(math.abs(watt / (PUISSANCE_DELESTAGE / 100)))
debug("quick_value minus="..tostring(quick_value))
command = 'curl -m 3 "http://192.168.125.11/minus?value=' .. tostring(quick_value).. '"'
callExternal(command)
--os.execute('curl -m 3 "http://192.168.125.11/minus?value=' .. tostring(quick_value).. '"');
else
commandArray['Dimmer'] = 'Set Level: 50'
end
end
end
end
command = 'curl -s -m 3 "http://192.168.125.11"|grep "<p>"|awk -F">" \'{print $2}\'|awk -F"<" \'{print $1}\''
--local handle = io.popen(command)
--local result = handle:read("*a")
--handle:close()
result = callExternal(command)
debug("result niveau d'injection= "..result)
if result == nil then
else
if (tonumber(result) == 1) then
commandArray['Dimmer'] = 'Set Level: 30'
result=0
end
local injection_radiateur = tonumber(result) * PUISSANCE_DELESTAGE / 100
updatenum('Injection_Radiateur', injection_radiateur)
updatenum('TOTAL_AUTOCONSOMMATION', round(watt_solaire - math.abs(injection_radiateur), 0))
end
else
end
-- ========================================================================
if (watt < 0) then
debug("Watt injection "..watt)
updatenum('INJECTION', - round(watt,0))
updatenum('TOTAL_INJECTION', - round(watt,0))
else
updatenum('INJECTION', 0)
updatenum('TOTAL_INJECTION', 0)
end
-- =========================================================
--Calculate what the house is consuming
-- Get current date & time
t1 = os.time()
local currentDate = os.date("*t"); -- sets up currentDate.[table]
-- (currentDate.year [full], .month [1-12], .day [1-31], .hour [0-23], .min [0-59], .sec [0-59], .wday [0-6 {Sun-Sat}])
sCurrentTime = currentDate.year .. "-" .. currentDate.month .. "-" .. currentDate.day .. " " .. currentDate.hour .. ":" .. currentDate.min .. ":" .. currentDate.sec
counter_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
counter_solar=tonumber(counter_solar) or 0
debug('counter_solar='..counter_solar)
value_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
value_solar=tonumber(value_solar) or 0
debug('value_solar='..value_solar)
---------------------------------------------------------------------------------------
-- Solaire 2
date = annee..'-'..mois..'-'..jour_s
counter_solar2 = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Mesure_Courant']..
' and date like "' .. date ..'%"'..
' order by Date desc limit 1;"')
counter_solar2=tonumber(counter_solar2) or 0
debug('counter_solar2='..counter_solar2)
value_solar2 = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Mesure_Courant']..
' and date like "' .. date ..'%"'..
' order by Date desc limit 1;"')
value_solar2=tonumber(value_solar2) or 0
debug('value_solar2='..value_solar2)
--------------------------------------------------------------------------------------
watt_p1 = getConsommationHP(1123) or 0
watt_p2 = getConsommationHC(1123) or 0
local cmd = '1135|0|'
--USAGE1= energy usage meter tariff 1, This is an incrementing counter
--USAGE2= energy usage meter tariff 2, This is an incrementing counter
--RETURN1= energy return meter tariff 1, This is an incrementing counter
--RETURN2= energy return meter tariff 2, This is an incrementing counter
--CONS= actual usage power (Watt)
--PROD= actual return power (Watt)
.. tostring(math.floor(watt_p1)) .. ';'
.. tostring(math.floor(watt_p2)) .. ';'
-- + value_solar2 - counter_solar2
.. tostring(math.floor(value_solar - counter_solar + value_solar2 - counter_solar2)) .. ';'
.. '0;'
.. tostring(math.floor(math.max(0,watt) + watt_solaire)).. ';'
.. tostring(math.floor(watt_solaire)) --math.floor(ConsumoEnergyBalance / 1000)) --round(watt,0))
debug('Consommation_Reelle_2 '..cmd)
if heures == 23 and minutes == 59 and secondes >= 45 then
-- ignored
else
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end
if heures == 00 and minutes == 05 and secondes <= 10 then
deleteWrongData(1135)
end
debug('when light=' .. tostring(whenLight()))
-- =========================================================
local cmd = '1136|0|'
--USAGE1= energy usage meter tariff 1, This is an incrementing counter
--USAGE2= energy usage meter tariff 2, This is an incrementing counter
--RETURN1= energy return meter tariff 1, This is an incrementing counter
--RETURN2= energy return meter tariff 2, This is an incrementing counter
--CONS= actual usage power (Watt)
--PROD= actual return power (Watt)
.. '0;'
.. '0;'
.. '0;'
.. '0;'
.. tostring(math.floor(math.max(0,watt))).. ';'
.. '0' --math.floor(ConsumoEnergyBalance / 1000)) --round(watt,0))
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
updatenum('Non_Couvert_2', math.floor(math.max(0,watt)))
-- =========================================================
end
capacite=76 * 12 --Wh
charge=200 --Wh
decharge=50 --Wh
tension_charge_max_off=13.3
tension_charge_max_on=13.8
tension_injection_min=11.2
tension_force_charge=10.8
--Initialise la commande de retour finale
commandArray={}
return commandArray

680
lua/script_device_Energie.lua Executable file
View File

@@ -0,0 +1,680 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The debug command will output lua debug statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do debug(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do debug(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
require "scripts/lua/functions"
time = os.time()
annee = os.date('%Y',time)
mois = os.date('%m',time)
heures = tonumber(os.date('%H',time))
minutes = tonumber(os.date('%M',time))
secondes = tonumber(os.date('%S',time))
jour = tonumber(os.date('%w',time))
jour_s = os.date('%d',time)
jour_y = tonumber(os.date('%j',time))
heurmin = heures * 60 + minutes
PUISSANCE_DELESTAGE = 750 -- Watts
disable_radiateur = true
function callExternal(command)
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
--debug("Commande = "..command.." "..result)
return result
end
function update_meter(device, id, power, energy, index)
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
end
local function round(num, dec)
--debug("Round "..tostring(num))
if (num and dec) then
return ( math.floor( tonumber(num) * 10^dec ) / 10^dec )
end
return 0
end
function getConsommationHC(idx)
date=annee..'-'..mois..'-'..jour_s
--date_end=annee..'-'..mois..'-'..math.floor(jour_s + 1)
-- query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
-- .. ' and date like "' .. date ..'%"'
-- .. ' and (date >= "' .. date_deb.. ' 21:29:59" or date <= "'.. date_deb ..' 05:30:00")'
query = 'select sum(hc) from (select max(value) - min(value) as hc from Meter mc where DeviceRowID =' ..idx
.. ' and date like "' .. date ..'%"'
.. ' and (date >= "' .. date.. ' 21:29:59"'
.. ' and date < "' .. date ..' 23:59:59")'
.. ' union all'
.. ' select max(value) - min(value) as hc from Meter mc where DeviceRowID =' .. idx
.. ' and date like "' .. date ..'%"'
.. ' and (date < "' .. date ..' 05:30:00")'
.. ' and (date > "' .. date ..' 00:00:00")'
.. ') as c'
--query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
-- .. ' and date like "' .. date ..'%"'
-- .. ' and not(date > "' .. date.. ' 05:29:59" and date <= "'.. date ..' 21:30:00")'
debug("query="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
if aRows[1][1] then
debug("Retour executeQuery "..tostring(bSuccess)..' '..aRows[1][1])
return aRows[1][1]
end
debug('retour à 0')
return 0
end
function getConsommationHP(idx)
date=annee..'-'..mois..'-'..jour_s
query = 'select max(value) - min(value) from Meter mc where DeviceRowID =' ..idx
.. ' and date like "' .. date ..'%"'
.. ' and (date > "' .. date.. ' 05:29:59" and date <= "'.. date ..' 21:30:00")'
--debug("query="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
--debug("Retour executeQuery "..tostring(bSuccess)..' '..aRows[1][1])
return aRows[1][1]
end
function deleteWrongData(idx)
-- delete from MultiMeter where DeviceRowid = 1135 and date >= "2021-06-02 00:00:00"
-- and date like "2021-06-02 00:00%";
date=annee..'-'..mois..'-'..jour_s
query = 'delete from MultiMeter where DeviceRowID =' ..idx
.. ' and date like "' .. date ..' 00:00%"'
.. ' and (date >= "' .. date.. ' 00:00:00")'
debug("query delete="..query)
local bSuccess, aRows, iCount = executeQuery(idx, query)
end
-- ----------------------------------
-- Gestion des batteries automatique
-- ---------------------------------
function gestionBatterie(ip_controller)
local attente_radiateur = false
local capacite=100 * 24 --Wh
local charge=390 --W
local decharge=270 --210 --W
local tension_charge_max_off=29.6
local tension_charge_max_on=29.6
local tension_injection_min_off=25.2
local tension_injection_min_on=24.8
local tension_force_charge=24.6
local fact = 2 --2.43
local regul = false
-- Tension repos V Conso charge W
-- 11.35 330
-- 12.35 270
-- 12.8 233
-- 12.67 190
-- 13.33 66
url = "http://"..ip_controller.."/getData"
--result = os.execute(curl..'"'..url..'"')
local jsonContent = getJSONContent(url)
--print(cmd)
local statuses = decodeJSON(jsonContent)
--printTableAsTree(statuses)
--updatenum("BatterieCharge", 0)
--updatenum("BatterieInjection", 0)
--local charge_theorique = (13.796 - tension) / 0.01213 -- -127.57 * tension + 1796.82
if isempty(statuses) then -- or tension <= 0 then
print("BAT ERROR getData")
--switchOff('Batterie')
return 0 --commandArray
end
local tension = round(tonumber(statuses['V']) / 1000,2) -- tonumber(otherdevices['BatterieTension'])
if tension <= 10 then
print("BAT ERROR tension fausse")
--switchOff('Batterie')
return 0 --commandArray
end
if (otherdevices['ForceChargeBatterie'] == 'On' and
((tonumber(lastUpdateOfDevice('ForceChargeBatterie')) > 3 * 3600) or tension > tension_charge_max_on))
then
commandArray['ForceChargeBatterie'] = "Off"
switchOff("ForceChargeBatterie")
end
if (statuses['CS'] == '3' and tonumber(statuses['PPV']) > 450 or (statuses['CS'] == '4' or statuses['CS'] == '5')) then
print("Radiateur solaire Actif CS="..statuses['CS'].." PPV="..statuses['PPV'])
disable_radiateur = false
else
print("Radiateur solaire Inactif CS="..statuses['CS'].." PPV="..statuses['PPV'])
disable_radiateur = true
command = 'curl -m 3 "http://192.168.125.11/stop"'
callExternal(command)
updatenum("Injection_Radiateur", 0)
end
local decharge_theorique = 63.29 * tension - 697.5
--decharge=150 --decharge_theorique
--charge=220 --charge_theorique
--print("BAT Power theorique "..tostring(charge_theorique))
local temperature = round(tonumber(statuses['XY_T']) / 10,1) -- tonumber(otherdevices['BatterieTension'])
updatenum("BatterieTension", tension)
updatenum("BatterieCharge", tonumber(statuses['PPV']))
local decharge_tmp = tonumber(statuses['V']) * tonumber(statuses['IL']) / 1000000
if decharge_tmp > 0 then
decharge = decharge_tmp
end
updatenum("BatterieInjection", tonumber(statuses['V']) * tonumber(statuses['IL']) / 1000000)
updatenum("TemperatureBatterie", temperature)
--commandArray['UpdateDevice'] = "1195|0|"..tostring(tension)
--commandArray['UpdateDevice'] = "1196|0|"..tostring(temperature)
--commandArray['Batterie'] = ternary(statuses['PIN_POWER'] == 0, 'On', 'Off')
--commandArray['InjectionBatterie'] = ternary(statuses['PIN_INJECTION'] == 0, 'On', 'Off')
--commandArray['ChargeBatterie'] = ternary(statuses['PIN_CHARGE'] == 0, 'On', 'Off')
local production = tonumber(split(otherdevices['SolaireProduction'], ";")[1])
local injection = tonumber(split(otherdevices['Injection_Radiateur'], ";")[1])
local injection_reseau = tonumber(split(otherdevices['INJECTION'], ";")[1])
local chauffe = tonumber(split(otherdevices['Chauffe_Eau'], ";")[1])
local conso = tonumber(split(otherdevices['Consommation_Apparente'], ";")[1])
local nuages = tonumber(otherdevices['CouvertureNuageusePrevisionnelle'])
updatenum("Surplus", injection + injection_reseau)
print("BAT injection="..tostring(injection)
..' solaire='..tostring(production)
..' chauffe='..tostring(chauffe)
..' charge='..statuses['PPV']
..' decharge='..tostring(tonumber(statuses['V']) * tonumber(statuses['IL']) / 1000000)
..' conso='..tostring(conso)
..' tension='..tostring(tension)
..' temperature='..tostring(temperature)
)
if isempty(statuses) then -- or tension <= 0 then
print("BAT ERROR getData")
--switchOff('Batterie')
return 0 --commandArray
end
print("BAT PIN_CHARGE="..statuses['PIN_CHARGE'].." PIN_INJECTION="..statuses['PIN_INJECTION'])
-- status 1 = ON / 0 = OFF
if (uservariables['Dark'] == "True" and tonumber(statuses['PPV']) > 100) then
--switchOff('LUMIERE_PLANTE')
end
return tonumber(statuses['PPV'])
end -- GestionBatterie
commandArray = {}
if devicechanged['RadiateurGrenier'] then
print("Dimmer Radiateur "..otherdevices_svalues['RadiateurGrenier']..tostring(otherdevices['RadiateurGrenier']))
local consigne = tonumber(otherdevices_svalues['RadiateurGrenier'])
print("Dimmer Radiateur grenier="..tostring(consigne))
if consigne <= 0 or otherdevices['RadiateurGrenier'] == "Off" then
-- command = 'curl -m 3 "http://192.168.177.240/stop"'
command = 'curl -m 3 "http://192.168.197.193/stop"'
else
-- command = 'curl -m 3 "http://192.168.177.240/exact?value=' .. tostring(consigne * 7).. '"'
command = 'curl -m 3 "http://192.168.197.193/exact?value=' .. tostring(consigne * 3.5).. '"'
end
callExternal(command)
end
-- ==================================================================
-- INTENSITE_GENERALE
-- ==================================================================
--if (devicechanged['CONSOMMATION_GENERALE']) then
function calcul()
--local tab = getValuesInTab('Oregon_Conso')
--debug("Conso "..otherdevices['Oregon_Conso'])
--values = split(otherdevices['Oregon_Conso'], ";")
--if (tonumber(values[1]) < 0) then
-- if (tonumber(values[1]) == -0.1) then
-- watt = - tonumber(values[2])
-- else
-- watt = tonumber(values[1]) * 100 - tonumber(values[2])
-- end
--else
-- watt = (tonumber(values[1]) * 100 + tonumber(values[2])) --/ 1.42
--end
values2 = split(otherdevices['CONSOMMATION_GENERALE'], ";")
print("NRJ Solaire CONSOMMATION_GENERALE tabs "..otherdevices['CONSOMMATION_GENERALE'])
watt = tonumber(values2[1])
for deviceName,deviceValue in pairs(devicechanged) do
if deviceName=="CONSOMMATION_GENERALE_Utility" then
watt = deviceValue
end
debug ("Device based event fired on '"..deviceName.."', value '"..tostring(deviceValue).."'");
end
debug("Conso "..tostring(watt))
--debug("mesure"..otherdevices['INTENSITE_GENERALE'])
amp = watt / 230 --math.max(0,round(otherdevices['INTENSITE_GENERALE'],3) - 0.54) * 7 / 8
watt_conso = watt --* 0.9459
updatenum('INTENSITE_GENERALE', amp)
debug("consommation Amp="..tostring(amp).." conso="..tostring(watt_conso))
--updatenum('CONSOMMATION_GENERALE', round(watt_conso,0))
local tab = getValuesInTab('SolaireProduction')
local watt_solaire = tonumber(tab[1])
local watt_solaire_jour = otherdevices_svalues['SolaireProduction']
if watt_solaire == nil then
watt_solaire = 0
end
debug("Suivi "..tostring(watt_conso - watt_solaire))
if (minutes%5 == 0 and secondes < 8) then
date = annee..'-'..mois..'-'..jour_s
counter_conso = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Consommation_Apparente']..' order by Date desc limit 1;"')
counter_conso=tonumber(counter_conso) or 0
debug('counter_conso='..counter_conso)
value_conso = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Consommation_Apparente']..' order by Date desc limit 1;"')
value_conso=tonumber(value_conso) or 0
debug('value_conso='..value_conso)
counter_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
counter_solar=tonumber(counter_solar) or 0
debug('counter_solar='..counter_solar)
value_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
value_solar=tonumber(value_solar) or 0
debug('value_solar='..value_solar)
counter_injection = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['INJECTION']..' order by Date desc limit 1;"')
counter_injection=tonumber(counter_injection) or 0
debug('counter_injection='..counter_injection)
value_injection = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['INJECTION']..' order by Date desc limit 1;"')
value_injection=tonumber(value_injection) or 0
debug('value_injection='..value_injection)
counter_radiateur = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Injection_Radiateur']..' order by Date desc limit 1;"')
counter_radiateur=tonumber(counter_radiateur) or 0
debug('counter_radiateur='..counter_radiateur)
value_radiateur = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Injection_Radiateur']..' order by Date desc limit 1;"')
value_radiateur=tonumber(value_radiateur) or 0
debug('value_radiateur='..value_radiateur)
cumul_solar = value_solar - counter_solar
cumul_injection = value_injection - counter_injection
consommation = value_conso - counter_conso
cumul_radiateur = value_radiateur - counter_radiateur
debug('conso='..consommation)
debug('cumul_solar='..cumul_solar)
debug('cumul_injection='..cumul_injection)
debug('cumul_radiateur='..cumul_radiateur)
if (cumul_solar > 0) then
debug("auto consommation="..tostring(
round((100 * (cumul_solar - cumul_injection) / cumul_solar),1))
)
commandArray['AUTO_CONSOMMATION'] = otherdevices_idx['AUTO_CONSOMMATION'] ..'|0|' .. tostring(
round((100 * (cumul_solar - cumul_injection) / cumul_solar),1)
)
updatenum('AUTO_CONSOMMATION', round((100 * (cumul_solar - cumul_injection) / cumul_solar),1) )
end
if (consommation > 0) then
debug("auto production="..tostring(100 * cumul_solar / (cumul_solar + consommation)))
updatenum('AUTO_PRODUCTION', round(100 * cumul_solar / (cumul_solar + consommation),1))
end
updatenum('COUVERTURE', round(100 * value_solar / (value_conso + value_solar),1))
if (cumul_solar > 0) then
updatenum('Consommation_Efficace', round(100 *((cumul_solar - cumul_radiateur - cumul_injection) / cumul_solar), 1))
else
updatenum('Consommation_Efficace', 0)
end
end
end
if (devicechanged['Mesure_Courant']) then
print('NRJ Mesure_Courant '..otherdevices['Mesure_Courant'])
values2 = split(otherdevices['Mesure_Courant'], ";")
debug("Solaire Mesure courant tabs ") --..otherdevices['Mesure_Courant'])
watt = tonumber(values2[1])
if (watt > 1600) then
watt = 0;
end
for deviceName,deviceValue in pairs(devicechanged) do
if deviceName=="Mesure_Courant_Utility" then
watt = deviceValue
end
debug ("Device based event fired on '"..deviceName.."', value '"..tostring(deviceValue).."'");
end
print("NRJ Solaire Mesure courant "..tostring(watt))
--updatenum('SolaireIntensite', round(watt / 230,3))
--updatenum('INTENSITE_GENERALE', round(watt / 230,3))
watt = math.abs(watt) --- 56
--if (watt < 0 or (heures <= 7 or heures >= 21)) then
-- watt = 0
--end
--debug("Intensite solaire "..devicechanged['SolaireIntensite'])
amp = math.abs(watt / 230); --math.max(0, round(otherdevices['SolaireIntensite'],3) - 0.54) *1.18
updatenum('SolaireIntensite', amp)
print("NRJ # 2 # production amp="..tostring(amp).." watt="..tostring(watt))
--debug("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN")
if (watt == nil or watt == "NAN") then
watt = 0
end
updatenum('SolaireProduction', round(watt,1))
watt_solaire = math.abs(watt)
local tab = getValuesInTab('CONSOMMATION_GENERALE')
local watt_conso = tonumber(tab[1])
local tab_r = getValuesInTab('Consommation_Apparente')
local watt_reel = tonumber(tab_r[1])
if (watt_reel > 0) then
updatenum('CONSOMMATION_GENERALE', watt_reel)
if watt_solaire > 0 then
updatenum('COUVERTURE_INSTANTANEE', round(100 * (watt_solaire / (watt_solaire + watt_reel)), 1))
else
updatenum('COUVERTURE_INSTANTANEE', 0)
end
else
updatenum('COUVERTURE_INSTANTANEE', 100)
updatenum('CONSOMMATION_GENERALE', 0)
end
calcul()
end
if (devicechanged['SolaireProduction']) then
end
if (devicechanged['Consommation_Apparente']) then
print("NRJ Consommation_Apparente ================================================")
values2 = split(otherdevices['Consommation_Apparente'], ";")
watt = tonumber(values2[1])
for deviceName,deviceValue in pairs(devicechanged) do
if deviceName=="Consommation_Apparente_Utility" then
-- watt = deviceValue
watt = round(deviceValue, 2)
debug ("Device based event fired on '"..deviceName.."', value "..tostring(round(deviceValue, 2)));
end
-- debug ("Device based event fired on '"..deviceName.."', value "..tostring(tonumber(deviceValue)));
end
debug("Solaire Consommation_Apparente "..tostring(watt))
values = split(otherdevices['SolaireProduction'], ";")
--debug("Solaire production "..otherdevices['SolaireProduction'])
watt_solaire = values[1]
values2 = split(otherdevices['Mesure_Courant'], ";")
--debug("Solaire production mesure courant "..otherdevices['Mesure_Courant'])
watt_solaire = values[1] --+ values2[1]
if watt_solaire == "NAN" then
watt_solaire = "0"
end
injection = split(otherdevices['INJECTION'], ";")
debug(injection[1])
local debut_injection = - 7
local fin_injection = 7
local currentTemp = getTemperatureFromDevice('Bureau')
-- --------------------------------------------------------
-- Gestion batterie
-- --------------------------------------------------------
local watt_a_enlever = gestionBatterie("batterie")
--watt = watt - watt_a_enlever -- Charge batterie
-- -------------------------------------------------------
debug("Solaire production temperature Exterieur_Cellier "..tostring(currentTemp).." "..tostring(watt_solaire))
if disable_radiateur == false then
command = 'curl -s -m 3 "http://192.168.125.11"|grep "<p>"|awk -F">" \'{print $2}\'|awk -F"<" \'{print $1}\''
result = callExternal(command)
local radiateur = tonumber(result) * (PUISSANCE_DELESTAGE / 100)
local to_inject = math.abs(watt) -- watt_a_enlever -- tonumber(result) * (PUISSANCE_DELESTAGE / 100)
local quick_value = math.floor(0.5 * to_inject / (PUISSANCE_DELESTAGE / 100))
print("quick_value result niveau d'injection= "..radiateur ..' to inject='..tostring(to_inject)..' quick='..tostring(quick_value)..' watt='..tostring(watt)..' a_enlever='..tostring(watt_a_enlever))
--if (otherdevices['InjectionBatterie'] == 'On') then
-- command = 'curl -m 3 "http://192.168.125.11/stop"'
-- callExternal(command)
-- updatenum("Injection_Radiateur", 0)
--else
if result == 0 or result == "" or result == nil or result == "NAN" then
result = 0
end
if (watt < debut_injection) then
print("quick_value plus="..tostring(quick_value).." conso="..tostring(watt))
if (quick_value > 0) then
command = 'curl -m 3 "http://192.168.125.11/plus?value=' .. tostring(quick_value).. '"'
callExternal(command)
updatenum("Injection_Radiateur", radiateur + to_inject)
else
print("quick_value reset radiateur")
--command = 'curl -m 3 "http://192.168.125.11/stop"'
--callExternal(command)
--updatenum("Injection_Radiateur", 0)
end
else
if (watt > fin_injection) then
print("quick_value minus="..tostring(quick_value).." conso="..tostring(watt))
command = 'curl -m 3 "http://192.168.125.11/minus?value=' .. tostring(quick_value).. '"'
callExternal(command)
updatenum("Injection_Radiateur", radiateur - to_inject)
end
end
--end
else
updatenum("Injection_Radiateur", 0)
end
if result == 0 or result == "" or result == nil or result == "NAN" then
print("result nil value")
updatenum('TOTAL_AUTOCONSOMMATION', 0)
else
if (tonumber(result) == 1) then
commandArray['Dimmer'] = 'Set Level: 30'
result=0
end
local injection_radiateur = tonumber(result) * PUISSANCE_DELESTAGE / 100
updatenum('Injection_Radiateur', injection_radiateur)
updatenum('TOTAL_AUTOCONSOMMATION', round(watt_solaire - injection[1] - math.abs(injection_radiateur), 0))
end
-- ========================================================================
if (watt < 0) then
debug("Watt injection "..watt)
updatenum('INJECTION', - round(watt,0))
updatenum('TOTAL_INJECTION', - round(watt,0))
else
updatenum('INJECTION', 0)
updatenum('TOTAL_INJECTION', 0)
end
-- =========================================================
--Calculate what the house is consuming
-- Get current date & time
t1 = os.time()
local currentDate = os.date("*t"); -- sets up currentDate.[table]
-- (currentDate.year [full], .month [1-12], .day [1-31], .hour [0-23], .min [0-59], .sec [0-59], .wday [0-6 {Sun-Sat}])
sCurrentTime = currentDate.year .. "-" .. currentDate.month .. "-" .. currentDate.day .. " " .. currentDate.hour .. ":" .. currentDate.min .. ":" .. currentDate.sec
counter_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
counter_solar=tonumber(counter_solar) or 0
debug('counter_solar='..counter_solar)
value_solar = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['SolaireProduction']..' order by Date desc limit 1;"')
value_solar=tonumber(value_solar) or 0
debug('value_solar='..value_solar)
---------------------------------------------------------------------------------------
-- Solaire 2
date = annee..'-'..mois..'-'..jour_s
counter_solar2 = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select counter from Meter_Calendar where DeviceRowID='..
otherdevices_idx['Mesure_Courant']..
' and date like "' .. date ..'%"'..
' order by Date desc limit 1;"')
counter_solar2=tonumber(counter_solar2) or 0
debug('counter_solar2='..counter_solar2)
value_solar2 = os.capture('sqlite3 '..'/opt/domoticz/domoticz.db'..' " select Value from Meter where DeviceRowID=='..
otherdevices_idx['Mesure_Courant']..
' and date like "' .. date ..'%"'..
' order by Date desc limit 1;"')
value_solar2=tonumber(value_solar2) or 0
debug('value_solar2='..value_solar2)
--------------------------------------------------------------------------------------
watt_p1 = getConsommationHP(1123) or 0
watt_p2 = getConsommationHC(1123) or 0
values_batterie = split(otherdevices['BatterieInjection'], ";")
print('BatterieInjection='..otherdevices['BatterieInjection']..' '..values_batterie[1]..' '..tostring(watt_solaire))
local cmd = '1135|0|'
--USAGE1= energy usage meter tariff 1, This is an incrementing counter
--USAGE2= energy usage meter tariff 2, This is an incrementing counter
--RETURN1= energy return meter tariff 1, This is an incrementing counter
--RETURN2= energy return meter tariff 2, This is an incrementing counter
--CONS= actual usage power (Watt)
--PROD= actual return power (Watt)
.. tostring(math.floor(watt_p1)) .. ';'
.. tostring(math.floor(watt_p2)) .. ';'
-- + value_solar2 - counter_solar2
.. tostring(math.floor(value_solar - counter_solar + value_solar2 - counter_solar2)) .. ';'
.. '0;'
.. tostring(math.floor(math.max(0,watt)) + watt_solaire + tonumber(values_batterie[1])).. ';'
.. tostring(math.floor(watt_solaire + tonumber(values_batterie[1]))) --math.floor(ConsumoEnergyBalance / 1000)) --round(watt,0))
debug('Consommation_Reelle_2 '..cmd)
if heures == 23 and minutes == 59 and secondes >= 45 then
-- ignored
else
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
end
if heures == 00 and minutes == 05 and secondes <= 10 then
deleteWrongData(1135)
end
debug('when light=' .. tostring(whenLight()))
-- =========================================================
local cmd = '1136|0|'
--USAGE1= energy usage meter tariff 1, This is an incrementing counter
--USAGE2= energy usage meter tariff 2, This is an incrementing counter
--RETURN1= energy return meter tariff 1, This is an incrementing counter
--RETURN2= energy return meter tariff 2, This is an incrementing counter
--CONS= actual usage power (Watt)
--PROD= actual return power (Watt)
.. '0;'
.. '0;'
.. '0;'
.. '0;'
.. tostring(math.floor(math.max(0,watt))).. ';'
.. '0' --math.floor(ConsumoEnergyBalance / 1000)) --round(watt,0))
table.insert (commandArray, { ['UpdateDevice'] = cmd } )
updatenum('Non_Couvert_2', math.floor(math.max(0,watt)))
-- =========================================================
end
--
return commandArray

229
lua/script_device_General.lua Executable file
View File

@@ -0,0 +1,229 @@
require "scripts/lua/functions"
commandArray = {}
-- ------------------------------------------------------------------------------
--recupere les minutes
-- ------------------------------------------------------------------------------
time=os.time()
minutes=tonumber(os.date('%M',time))
jour=tonumber(os.date('%w',time))
quantieme=tonumber(os.date('%j',time))
heures=tonumber(os.date('%H',time))
heurmin= heures * 60 + minutes
extinction = uservariables['HEURE_EXTINCTION_FEUX']
-- ------------------------------------------------------------------------------
-- Test check
-- ------------------------------------------------------------------------------
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do debug(i..' '..v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do debug('svalues '..i..' '..v) end
-- ------------------------------------------------------------------------------
-- Pollens tous les lundis
-- ------------------------------------------------------------------------------
if (jour == 1 and devicechanged['Pollens']) then
debug("Nouveau bulletin pollens")
commandArray['SendNotification']='Pollens#Nouveau bulletin pollen http://www.pollens.fr/docs/vigilance.html#0'
end
-- ------------------------------------------------------------------------------
-- Derniere détection
-- ------------------------------------------------------------------------------
if devicechanged['Detecteur Salon'] or devicechanged['Detecteur Bureau'] then
commandArray['Variable:DerniereDetection'] = tostring(heures)..":"..tostring(minutes)
debug("DerniereDetection"..tostring(heures)..":"..tostring(minutes))
end
-- ------------------------------------------------------------------------------
-- Température extérieure a changé, mise à jour du chauffage central
-- ------------------------------------------------------------------------------
if devicechanged['BarometreLaGacilly'] then
local variation = variationTemp('BarometreLaGacilly')
--if (minutes%30==0) then
--local variationBarometer = variationPressure('BarometreLaGacilly', 30)
--print("variationBarometer="..tostring(variationBarometer))
local tempExt = getTemperatureFromDevice('BarometreLaGacilly')
local humidityExt = getHumidityFromDevice('BarometreLaGacilly')
--print(split(otherdevices_svalues['BarometreLaGacilly'],";")[1]);
local consigne = 13 -- tonumber(otherdevices_svalues['ConsigneChauffageGeneral'])
debug (otherdevices_svalues['BarometreLaGacilly']..' Consigne='..otherdevices_svalues['ConsigneChauffageGeneral']..' TempExt='..tostring(tempExt)..' humidityExt='..tostring(humidityExt))
if heures == 23 and minutes == 00 then
if tempExt < consigne and (quantieme < 92 or quantieme > 275) then
switchIfNeeded('ChauffageGeneral','On')
end
if tempExt >= consigne then
switchIfNeeded('ChauffageGeneral','Off')
end
end
if humidityExt > 65 then
switchIfNeeded('Deshumidificateur','On')
else
if humidityExt < 60 then
switchIfNeeded('Deshumidificateur','Off')
end
end
debug("Retour variation="..tostring(variation).." switch="..'BarometreLaGacilly tempExt='..tostring(tempExt))
--end
end
-- ------------------------------------------------------------------------------
-- Test suivi consommation électrique
-- ------------------------------------------------------------------------------
--debug(otherdevices['ConsoCapteurHC'])
--debug("ConsocapteurHP="..otherdevices_svalues['ConsoCapteurHP'])
if devicechanged['Capteur électricité'] then
debug("Electricité a changé")
local val
local val2
val, val2 = otherdevices_svalues['Capteur électricité']:match("([^;]+);([^;]+)")
val = tonumber(val)
debug(val)
--debug('#### HC '..otherdevices['ConsoCapteurHC'])
--debug('#### HP '..otherdevices['ConsoCapteurHP'])
if val > 2200 or val == nil then
debug("Reception de données incohérentes pour la consommation électrique "..tostring(val))
else
val = val - 50
if uservariables['HeuresCreuses'] == 'On' then
-- Recuperation des valeurs du compteur global
local consoCumule
local consoInstant
consoInstant, consoCumule = otherdevices_svalues['ConsoCapteurHC']:match("([^;]+);([^;]+)")
consoInstant = tonumber(consoInstant)
consoCumule = tonumber(consoCumule)
debug('Conso Instant = '..tostring(consoInstant)..' / Conso Cumule = '..tostring(consoCumule)..' ')
local timeLast = lastUpdateOfDevice('ConsoCapteurHC')
local joules = val * timeLast -- Puissance en W * second = Joule
local wattH = joules / 3600
if (consoCumule == nil) then consoCumule = 0 end
if (val < 0) then wattH = 0 end
commandArray['UpdateDevice'] = '197|0|'..tostring(wattH)..';'..tostring(consoCumule + wattH)
debug("Ajout en heures creuses wattH "..tostring(wattH)..'; total '..tostring(consoCumule + wattH))
else
-- Recuperation des valeurs du compteur global
local consoCumule
local consoInstant
consoInstant, consoCumule = otherdevices_svalues['ConsoCapteurHP']:match("([^;]+);([^;]+)")
consoInstant = tonumber(consoInstant)
consoCumule = tonumber(consoCumule)
debug('Conso Instant = '..tostring(consoInstant)..' / Conso Cumule = '..tostring(consoCumule)..' ')
--local current = tonumber(otherdevices_svalues['ConsoCapteurHP'])
--if current == nil then current = 0 end
local timeLast = lastUpdateOfDevice('ConsoCapteurHP')
local joules = val * timeLast -- Puissance en W * second = Joule
local wattH = joules / 3600
if (val < 0) then wattH = 0 end
commandArray['UpdateDevice'] = '196|0|'..tostring(wattH)..';'..tostring(consoCumule + wattH)
debug("Ajout en heures pleines wattH "..tostring(wattH)..'; total '..tostring(consoCumule + wattH))
end
end
end
-- ------------------------------------------------------------------------------
-- Mode vacances
-- ------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------
-- Envoi de notification
-- ------------------------------------------------------------------------------
-- Vacances
if devicechanged['Vacances'] then
debug("Mode vacances a change")
commandArray['SendNotification']='Mode vacances#Le mode vacances a ete modifie#0'
if otherdevices['Vacances'] == 'On' then
-- non on conserve internet switchIfNeeded('PriseInternet', 'Off')
switchIfNeeded('Lampe_Halogene', 'Off')
switchIfNeeded('Lampe_Buffet', 'Off')
switchIfNeeded('Lampe_Tele', 'Off')
switchIfNeeded('SonoJasper', 'Off')
switchOffRadiateur('RadiateurManon')
switchOffRadiateur('RadiateurTheo')
switchOffRadiateur('RadiateurBureau')
switchOffRadiateur('RadiateurChambre')
switchOffRadiateur('RadiateurCuisine')
switchOffRadiateur('RadiateurMilieu')
switchOffRadiateur('RadiateurCheminee')
end
end
-- ------------------------------------------------------------------------------
-- Plus d'internet on redémarre
-- ------------------------------------------------------------------------------
if --otherdevices['Vacances'] == 'Off' and
devicechanged['Internet'] and otherdevices['Internet'] == 'Off' then
commandArray['PriseInternet'] = 'Off'
sleep(10)
commandArray['PriseInternet'] = 'On'
end
-- ------------------------------------------------------------------------------
-- Absence famille mais présence moi
-- ------------------------------------------------------------------------------
if otherdevices['Vacances'] == 'Off' and devicechanged['AbsenceFamille'] then
if otherdevices['AbsenceFamille'] == 'Off' then
switchOffRadiateur('RadiateurTheo')
switchOffRadiateur('RadiateurChambre')
else
switchOnRadiateur('RadiateurTheo')
switchOnRadiateur('RadiateurChambre')
end
end
-- ------------------------------------------------------------------------------
-- Determination de l'augmentation de la temperature exterieure
-- ------------------------------------------------------------------------------
if devicechanged['BarometreLaGacilly'] then
print("--------------TemperatureLaGacilly--------------------------------")
local variation, time = getVariation('BarometreLaGacilly')
local augmentation = variation * 60 / time -- ° par heure
print("Retour augmentation="..tostring(augmentation))
commandArray['Variable:AugmentationTempExterieure'] = tostring(augmentation)
print("------------------------------------------------------------------")
--local currentTemp = tonumber(otherdevices_svalues['Bureau']
local tempExt = getTemperatureFromDevice('BarometreLaGacilly')
debug("-------------- Ventilo Bureau------------------- "..tostring(tempExt))
if (tempExt < 8.5) then
switchOn('VentilateurBureau')
else
switchOff('VentilateurBureau')
end
end
return commandArray

37
lua/script_device_Presence.lua Executable file
View File

@@ -0,0 +1,37 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The print command will output lua print statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do print(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do print(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
commandArray = {}
if (devicechanged['Presence Forcee'] == 'On' and otherdevices['Presence'] == 'Off') then
commandArray['Presence']='On'
end
return commandArray

485
lua/script_device_Radiateur.lua Executable file
View File

@@ -0,0 +1,485 @@
require "scripts/lua/functions"
commandArray = {}
--local switch = 'VoletCuisine'
-- ------------------------------------------------------------------------------
--recupere les minutes
-- ------------------------------------------------------------------------------
time = os.time()
minutes = tonumber(os.date('%M',time))
jour = tonumber(os.date('%w',time))
heures = tonumber(os.date('%H',time))
heurmin = heures * 60 + minutes
function callExternal(command)
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
--debug("Commande = "..command.." "..result)
return result
end
-- ------------------------------------------------------------------------------
-- Test temperature radiateur chambres
-- ------------------------------------------------------------------------------
function gestionRadiateurInv( switchTemp, switchRadiateur, consigne)
local intervalle = tonumber(uservariables['Intervalle_Chauffe'])
--if (minutes % intervalle ~= 0) then
--return
--end
local last = lastUpdateOfDevice(switchRadiateur)
local local_delai = delai
debug("--------------"..switchRadiateur.."-----------------------------------")
debug(tostring(switchRadiateur).." local_delai="..tostring(local_delai).." last="..tostring(last)..' Chauffage='..otherdevices[switchRadiateur])
debug("------------------------------------------------------------")
local currentTemp = tonumber(otherdevices_svalues[switchTemp])
local delta = 0.2
local tempAbsence = tonumber(otherdevices_svalues['ConsigneAbsence'])
local variation = variationTemp2(switchTemp, 10) -- variation des 10 dernières minutes
local variationExt = uservariables['AugmentationTempExterieure']
local augmentation = variation * 60 / 10 --time -- ° par heure
local ecart = consigne - currentTemp
local estimation = 0.0
if (augmentation > 0 and ecart > 0) then
estimation = 60 * ecart / augmentation
end
print("GR Retour augmentation="..tostring(augmentation).." ecart="..tostring(ecart)..'°C Estimation='..tostring(estimation).." minutes variationExt="..tostring(variationExt).."°C / heure")
--2016-02-27 20:08:59.864 LUA: local_delai=180 last=37
--2016-02-27 20:08:59.918 LUA: Retour variation=0.3 switch=RadiateurManon
--2016-02-27 20:08:59.918 LUA: CHECK Temperature Variation=0.3 switch=RadiateurManon currentTemp=18.3 tempAbsence=16 consigne=18.5
print("GR Retour variation="..tostring(variation).." switch="..switchRadiateur..' lastUpdate='..tostring(last))
debug('CHECK Temperature Variation='..tostring(variation)..' switch='..switchRadiateur..' currentTemp='..tostring(currentTemp).. ' tempAbsence='..tostring(tempAbsence)..' consigne='..tostring(consigne))
-- if otherdevices['ChauffageGeneral'] == 'Off' then
-- if (minutes%5 == 0) then
-- if (currentTemp >= consigne + delta) then
-- switchOn(switchRadiateur)
-- end
-- debug("Radiateur ="..switchRadiateur.." Retour sans rien faire. ChauffageGeneral Eteint.")
-- end
-- return
-- end
if last < local_delai then
debug("Radiateur ="..switchRadiateur.." Retour sans rien faire. local_delai non atteint.")
return
end
-- Periode de vacances ou absence ==> hors gel
if (otherdevices['Vacances'] == 'On' or otherdevices['AbsenceFamille'] == 'On') then
if (currentTemp > 14) then
switchIfNeeded(switchRadiateur,"On")
--commandArray[switchRadiateur]='Off'
else
if variation <= 0 then
--commandArray[switchRadiateur]='On'
switchIfNeeded(switchRadiateur,"Off")
end
end
print("GR "..tostring(switchRadiateur)..' Temperature chambre : Vacances -> ' ..otherdevices_svalues[switchTemp]..' switch='..switchRadiateur)
else
print("GR "..tostring(switchRadiateur)..' Temperature: Presence -> ' ..otherdevices_svalues[switchTemp]..' '..josdGetJourSemaine(jour))
-- Température non atteinte
if (currentTemp < consigne) then
if variation <= 0.0 then
switchIfNeeded(switchRadiateur,"Off")
debug("Demande chauffe : "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
else
-- Dépassement prévu dans le local_delai on coupe
if (estimation > 0 and estimation <= local_delai / 60 ) then
switchIfNeeded(switchRadiateur,"On")
debug("Arrêt chauffage : Température sera atteinte dans le local_delai "..tostring(estimation).." Minutes")
else
if estimation > 60 then
switchIfNeeded(switchRadiateur,"Off")
debug("Demande chauffe dela trop long : "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
else
debug("Aucune action. Chauffage en-cours."..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
end
end
end
-- Température dépassée
else
-- Température supérieure
if (currentTemp >= consigne + delta or (estimation > 0 and estimation <= local_delai / 60 )) then
if (consigne == consigneAbsence) then
-- rien
if (variation > 0) then
switchIfNeeded(switchRadiateur,"On")
debug("Demande arrêt. Température dépassée et augmente.")
else
debug("Aucune consigne. Température dépassée et diminue.")
end
else
if (variation > 0) then
if (variationExt <= 0) then
switchIfNeeded(switchRadiateur,"On")
debug("Demande arrêt. Température dépassée.")
else
switchIfNeeded(switchRadiateur,"On")
debug("Aucune action. Augmentation due à température extérieure.")
end
else
-- switchIfNeeded(switchRadiateur,"On")
end
end
else
-- Augmentation de la température non due à l'augmentation extérieure
if (variation > 0) then
-- Pas d'augmentation extérieure
if (variationExt <= 0) then
switchIfNeeded(switchRadiateur,"On")
debug("Demande arrêt. Température atteinte et continue d'augmenter.")
else
switchIfNeeded(switchRadiateur,"On")
debug("Aucune action. Augmentation due à température extérieure.")
end
else
-- Températue en baisse pas nécessaire d'envoyer
switchIfNeeded(switchRadiateur,"On")
debug("Aucune action. Temperature atteinte et pas d'augmentation. "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
end
end
end
end
debug("------------------------------------------------------------")
end
-- ------------------------------------------------------------------------------
-- Test temperature radiateur chambres
-- ------------------------------------------------------------------------------
function gestionRadiateur( switchTemp, switchRadiateur, consigne)
local intervalle = tonumber(uservariables['Intervalle_Chauffe'])
-- if (minutes % intervalle ~= 0) or switchRadiateur == "RadiateurGrenier" then
-- return
-- end
local chauffe_eau = tonumber(split(otherdevices['Chauffe_Eau'], ";")[1])
local currentTemp = getTemperatureFromDevice(switchTemp)
local last = lastUpdateOfDevice(switchRadiateur)
local local_delai = delai
if switchRadiateur == "RadiateurGrenier" then
local_delai = 60
end
print("GR --------------"..switchRadiateur.."-----------------------------------")
values2 = split(otherdevices['CONSOMMATION_GENERALE'], ";")
print("GR Dans Radiateur CONSOMMATION_GENERALE tabs "..otherdevices['CONSOMMATION_GENERALE'])
print("GR "..tostring(switchRadiateur).." local_delai="..tostring(local_delai).." last="..tostring(last)..' Chauffage='..otherdevices[switchRadiateur] .. " currentTemp="..tostring(currentTemp) )
if last < local_delai then
print("GR Radiateur ="..switchRadiateur.." Retour sans rien faire. local_delai non atteint.")
return
end
watt = tonumber(values2[1])
if watt > 8000 then
if otherdevices["RadiateurBureau"] == 'On' then
print("GR "..tostring(switchRadiateur).." Dans Radiateur Haute consommation arrêt bureau")
switchOffRadiateur("RadiateurBureau")
elseif otherdevices["RadiateurBureau"] == 'On' then
print("GR "..tostring(switchRadiateur).." Dans Radiateur Haute consommation arrêt porte salon")
switchOffRadiateur("RadiateurPorteSalon")
elseif otherdevices["RadiateurCuisine"] == 'On' then
print("GR "..tostring(switchRadiateur).." Dans Radiateur Haute consommation arrêt cuisine")
switchOffRadiateur("RadiateurCuisine")
elseif otherdevices["RadiateurCheminee"] == 'On' then
print("GR "..tostring(switchRadiateur).." Dans Radiateur Haute consommation arrêt Cheminee")
switchOffRadiateur("RadiateurCheminee")
elseif otherdevices["RadiateurMilieu"] == 'On' then
print("GR "..tostring(switchRadiateur).." Dans Radiateur Haute consommation arrêt milieu")
switchOffRadiateur("RadiateurMilieu")
end
end
--print("GR ------------------------------------------------------------")
--debug(getTemperatureFromDevice(switchTemp));
--local currentTemp = tonumber(otherdevices_svalues[switchTemp])
local time_variation = 30
local delta = 0.2
local tempAbsence = tonumber(otherdevices_svalues['ConsigneAbsence'])
local variation = variationTemp2(switchTemp, time_variation) -- variation des 10 dernières minutes
local variationExt = uservariables['AugmentationTempExterieure']
local augmentation = variation * 60 / time_variation --time -- ° par heure
local ecart = consigne - currentTemp
local estimation = 0.0
if (augmentation > 0 and ecart > 0) then
estimation = 60 * ecart / augmentation
end
--if (switchRadiateur=="RadiateurCheminee" and augmentation > 1) then
-- arretRadiateursSalon('ChauffageGeneral')
--end
print("GR "..tostring(switchRadiateur).." Retour augmentation="..tostring(augmentation).." ecart="..tostring(ecart)..'°C Estimation='..tostring(estimation).." minutes variationExt="..tostring(variationExt).."°C / heure")
--2016-02-27 20:08:59.864 LUA: local_delai=180 last=37
--2016-02-27 20:08:59.918 LUA: Retour variation=0.3 switch=RadiateurManon
--2016-02-27 20:08:59.918 LUA: CHECK Temperature Variation=0.3 switch=RadiateurManon currentTemp=18.3 tempAbsence=16 consigne=18.5
print("GR "..tostring(switchRadiateur).." Retour variation="..tostring(variation).." switch="..switchRadiateur..' lastUpdate='..tostring(last))
print("GR "..tostring(switchRadiateur).." Temperature Variation="..tostring(variation)..' switch='..switchRadiateur..' currentTemp='..tostring(currentTemp).. ' tempAbsence='..tostring(tempAbsence)..' consigne='..tostring(consigne))
if otherdevices['ChauffageGeneral'] == 'Off' then
if (minutes%5 == 0) then
if (currentTemp >= consigne + delta) then
switchOff(switchRadiateur)
end
debug("ChauffageGeneral Eteint. Demande extinction.")
else
debug("Radiateur ="..switchRadiateur.." Retour sans rien faire. ChauffageGeneral Eteint.")
end
return
end
if (currentTemp >= consigne + 2 * delta) then
print("GR Radiateur ="..switchRadiateur.." arret immediat température > consigne + 2 * delta.")
switchIfNeeded(switchRadiateur,"Off")
return
end
-- Periode de vacances ou absence ==> hors gel
if (otherdevices['Vacances'] == 'On' or otherdevices['AbsenceFamille'] == 'On') then
if (currentTemp > 14) then
switchIfNeeded(switchRadiateur,"Off")
--commandArray[switchRadiateur]='Off'
else
if variation <= 0 then
--commandArray[switchRadiateur]='On'
switchIfNeeded(switchRadiateur,"On")
end
end
print("GR "..tostring(switchRadiateur)..' Temperature chambre : Vacances -> ' ..otherdevices_svalues[switchTemp]..' switch='..switchRadiateur)
else
print("GR "..tostring(switchRadiateur)..' Temperature: Presence -> ' ..otherdevices_svalues[switchTemp]..' '..josdGetJourSemaine(jour))
-- Température non atteinte
if (currentTemp < consigne - delta) then
debug('Temperature non atteinte')
if variation <= 0.0 then
-- commandArray[switchRadiateur]='On'
switchIfNeeded(switchRadiateur,"On")
print("GR "..tostring(switchRadiateur).."Demande chauffe : "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
else
--switchIfNeeded(switchRadiateur, 'On')
-- Dépassement prévu dans le local_delai on coupe
if (estimation > 0 and estimation <= local_delai / 60 ) then
--commandArray[switchRadiateur] = 'Off'
switchIfNeeded(switchRadiateur,"Off")
print("GR "..tostring(switchRadiateur).." Arrêt chauffage : Température sera atteinte dans le local_delai "..tostring(estimation).." Minutes")
else
if estimation > 60 then
switchIfNeeded(switchRadiateur,"On")
debug("Demande chauffe dela trop long : "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
else
debug("Aucune action. Chauffage en-cours."..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
end
end
end
-- Température dépassée
else
debug('Temperature supérieure')
-- Température supérieure
if (currentTemp >= consigne + delta or (estimation > 0 and estimation <= local_delai / 60 )) then
if (consigne == consigneAbsence) then
switchIfNeeded(switchRadiateur,"Off")
else
if (variation > 0) then
if (variationExt <= 0) then
switchIfNeeded(switchRadiateur,"Off")
debug("Demande arrêt. Température dépassée.")
else
switchIfNeeded(switchRadiateur,"Off")
debug("Aucune action. Augmentation due à température extérieure.")
end
else
debug('Aucune variation')
switchIfNeeded(switchRadiateur,"Off")
end
end
else if (currentTemp <= consigne - delta) then
-- Augmentation de la température non due à l'augmentation extérieure
if (variation > 0) then
-- Pas d'augmentation extérieure
if (variationExt <= 0) then
switchIfNeeded(switchRadiateur,"Off")
debug("Demande arrêt. Température atteinte et continue d'augmenter.")
else
switchIfNeeded(switchRadiateur,"Off")
debug("Aucune action. Augmentation due à température extérieure.")
end
else
-- Températue en baisse pas nécessaire d'envoyer
switchIfNeeded(switchRadiateur,"Off")
debug("Aucune action. Temperature atteinte et pas d'augmentation. "..tostring(currentTemp).." / "..tostring(consigne).." Variation="..tostring(variation))
end
end
end
end
end
debug("------------------------------------------------------------")
end
-- ------------------------------------------------------------------------------
-- Test temperature radiateur salon et cuisine
-- ------------------------------------------------------------------------------
function gestionRadiateurSalon( switchTemp, switchRadiateur, consigne)
local currentTemp = tonumber(otherdevices_svalues[switchTemp])
local tempAbsence = tonumber(otherdevices_svalues['ConsigneAbsence'])
if otherdevices['ChauffageGeneral'] == 'Off' then
if (minutes%30 == 0) then
switchOffRadiateur(switchRadiateur)
else
debug("Radiateur ="..switchRadiateur.." Retour sans rien faire. ChauffageGeneral Eteint.")
end
end
-- Periode de vacances ou absence ==> hors gel
if (otherdevices['Vacances'] == 'On' or otherdevices['Presence'] == 'Off') then
if (currentTemp > tempAbsence) then
switchOffRadiateur(switchRadiateur)
else
switchOnRadiateur(switchRadiateur)
end
print("GR "..tostring(switchRadiateur)..' Temperature Salon: Vacances -> ' ..otherdevices_svalues[switchTemp]..' switch='..switchRadiateur)
else
-- Samedi Dimanche ou jour férié ou mercredi
if (jour == 0 or jour == 6 or josdJourChome() or jour == 3) then
print("GR "..tostring(switchRadiateur)..' Temperature: Presence -> ' ..otherdevices_svalues[switchTemp]..' '..josdGetJourSemaine(jour))
if (currentTemp < tempAbsence
or (currentTemp <= consigne and heures >= 08 and heures <= 24)) then
switchOnRadiateur(switchRadiateur)
else
switchOffRadiateur(switchRadiateur)
end
else
print("GR "..tostring(switchRadiateur)..' Temperature: Travail -> ' ..otherdevices_svalues[switchTemp]..' '..josdGetJourSemaine(jour))
if (currentTemp < tempAbsence
or (currentTemp <= (consigne - 1) and heures >= 17)
or (currentTemp <= consigne and heures >= 19 and heures < 23)) then
switchOnRadiateur(switchRadiateur)
else
switchOffRadiateur(switchRadiateur)
end
end
end
end
-- ------------------------------------------------------
-- Arrêt tous les radiateurs
-- ------------------------------------------------------
if devicechanged['ChauffageGeneral'] then
print("Chauffage General "..otherdevices['ChauffageGeneral'])
if otherdevices['ChauffageGeneral'] == 'Off' then
-- for i = 1, 7 do
for i,radiateur in ipairs(radiateurs) do
print("Chauffage General Arrêt radiateur="..radiateur)
commandArray[radiateur]='Off'
end
end
end
local saison = uservariables["Saison"]
if otherdevices['ChauffageGeneral'] == 'On' then
-- ----------------------------------------------------
-- Chambre de Manon
-- ------------------------------------------------------
if devicechanged['ChambreManon'] or devicechanged['ConsigneConfortManon'] or devicechanged['ChauffageGeneral']
then --or tonumber(lastUpdateOfDevice('ChambreManon')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortManon'])
gestionRadiateur('ChambreManon', 'RadiateurManon', consigne)
end
-- ------------------------------------------------------
-- Chambre de Theo
-- ------------------------------------------------------
if devicechanged['ChambreTheo'] or devicechanged['ConsigneConfortTheo'] or devicechanged['ChauffageGeneral']
then -- or tonumber(lastUpdateOfDevice('ChambreTheo')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortTheo'])
gestionRadiateur('ChambreTheo', 'RadiateurTheo', consigne)
end
-- ------------------------------------------------------
-- Chambre parents
-- ------------------------------------------------------
if devicechanged['Chambre'] or devicechanged['ConsigneConfortChambre'] or devicechanged['ChauffageGeneral']
then --or tonumber(lastUpdateOfDevice('Chambre')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortChambre'])
gestionRadiateur('Chambre', 'RadiateurChambre', consigne)
end
-- ------------------------------------------------------
-- Radiateur cuisine
-- ------------------------------------------------------
if devicechanged['TemperatureCuisine'] or devicechanged['ConsigneConfortSalon'] or devicechanged['ChauffageGeneral']
then -- or tonumber(lastUpdateOfDevice('TemperatureCuisine')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortSalon'])
gestionRadiateur('TemperatureCuisine', 'RadiateurCuisine', consigne)
end
-- ------------------------------------------------------
-- Radiateur Cheminee
-- ------------------------------------------------------
if devicechanged['Cheminee'] or devicechanged['ConsigneConfortSalon'] or devicechanged['ChauffageGeneral']
then -- or tonumber(lastUpdateOfDevice('Cheminee')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortSalon']) - 1 --0.2
gestionRadiateur('Cheminee', 'RadiateurCheminee', consigne)
end
-- ------------------------------------------------------
-- Radiateur Salon
-- ------------------------------------------------------
if devicechanged['TemperatureSalon'] or devicechanged['ConsigneConfortSalon'] or devicechanged['ChauffageGeneral']
then -- or tonumber(lastUpdateOfDevice('TemperatureSalon')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortSalon'])
gestionRadiateur('TemperatureSalon', 'RadiateurPorteSalon', consigne)
gestionRadiateur('TemperatureSalon', 'RadiateurMilieu', consigne)
end
-- ------------------------------------------------------
-- Radiateur Bureau
-- ------------------------------------------------------
if devicechanged['Bureau'] or devicechanged['ConsigneConfortBureau'] or devicechanged['ChauffageGeneral']
then -- or tonumber(lastUpdateOfDevice('Bureau')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortBureau'])
gestionRadiateur('Bureau', 'RadiateurBureau', consigne)
--gestionRadiateur('TemperatureBarometre', 'RadiateurCheminee', consigne)
end
-- ------------------------------------------------------
-- Radiateur Grenier
-- ------------------------------------------------------
if (devicechanged['TemperatureGrenier'] or devicechanged['ConsigneConfortGrenier'] or devicechanged['ChauffageGeneral'] or devicechanged['Force_Grenier'])
then -- or tonumber(lastUpdateOfDevice('TemperatureGrenier')) > 2 * delai then
local consigne = tonumber(otherdevices_svalues['ConsigneConfortGrenier'])
gestionRadiateur('TemperatureGrenier', 'RadiateurGrenierAcova', consigne)
--gestionRadiateur('TemperatureBarometre', 'RadiateurCheminee', consigne)
end
end
return commandArray

64
lua/script_device_Vacances.lua Executable file
View File

@@ -0,0 +1,64 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The print command will output lua print statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do print(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do print(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
commandArray = {}
--if (minutes == 0 or minutes == 30) then
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
commandArray = {}
if (minutes == 0 or minutes == 30) then
if (devicechanged['Vacances']) then
if otherdevices['Vacances'] == 'On' then
print('Depart en vacances : Actions')
print(' Actions : Arret Volumio et Raspbmc')
print(' Actions : Activation script vacances ')
print(' Actions : Arret chauffage ')
else
print('Retour de vacances : Actions')
print(' Actions : Arret script vacances ')
print(' Actions : Demarrage chauffage ')
end
end
end
return commandArray

View File

@@ -0,0 +1,112 @@
-- script domoticz/scripts/lua/script_device_compteurHC-HP.lua
-- Initialisation des variables locales
local capteurGlobal = uservariables['Capteur électricité']
local capteurCptHP = uservariables['ConsoCapteurHP']
local capteurCptHC = uservariables['ConsoCapteurHC']
local idxCptHP = uservariables['IdxCptHP']
local idxCptHC = uservariables['IdxCptHC']
local flagHC = uservariables['FlagHC']
local flagHP = uservariables['FlagHP']
local lastValueCptElecGlobal = uservariables['LastValueCptElecGlobal']
-- Mode debug Oui / Non
local debug = uservariables['debug']
-- Fonction de mise à jour
function update(device, id, power, energy, index)
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
return
end
commandArray = {}
-- On prend en compte a chaque changement de valeur du compteur global
if (devicechanged[capteurGlobal]) then
if (debug == 'OUI') then
print('-- Calcul Compteurs HC / HP --')
print('CapteurGlobal = '..capteurGlobal)
print('CapteurCptHP = '..capteurCptHP)
print('CapteurCptHC = '..capteurCptHC)
print('idxCptHP = '..tostring(idxCptHP))
print('idxCptHC = '..tostring(idxCptHC))
print('flagHP = '..tostring(flagHP))
print('flagHC = '..tostring(flagHC))
print('LastValueCptElecGlobal = '..tostring(lastValueCptElecGlobal))
end
-- Recuperation des valeurs du compteur global
local consoCumule
local consoInstant
consoInstant, consoCumule = otherdevices_svalues[capteurGlobal]:match("([^;]+);([^;]+)")
consoInstant = tonumber(consoInstant)
consoCumule = tonumber(consoCumule)
if (debug == 'OUI') then
print('Conso Instant = '..tostring(consoInstant)..' / Conso Cumule = '..tostring(consoCumule)..' ')
end
-- Calcul de l'ecart avec le dernier envoi de donnees
lastValueCptElecGlobal = tonumber(lastValueCptElecGlobal)
local consoDelta = consoCumule - lastValueCptElecGlobal
if (debug == 'OUI') then
print('Delta conso = '..tostring(consoDelta))
end
local consoCumuleCible
local consoInstantCible
if (otherdevices[flagHC] == 'On') then
-- Periode heures creuse
-- Recuperation des valeurs du compteur global
consoInstantCible, consoCumuleCible = otherdevices_svalues[capteurCptHC]:match("([^;]+);([^;]+)")
-- Seul le cumule du compteur nous interesse pour calculer la nouvelle valeur
consoCumuleCible = tonumber(consoCumuleCible)
if (debug == 'OUI') then
print('Compteur cible = HC')
print('Valeur precedente = '..tostring(consoCumuleCible))
print('Valeur ajustee = '..tostring(consoCumuleCible + consoDelta))
end
consoCumuleCible = consoCumuleCible + consoDelta
-- Mise à jour du compteur
update(capteurCptHC, idxCptHC, consoInstant, consoCumuleCible, 1)
-- Mise à 0 de la conso intantanee du compteur HP
consoInstantHP, consoCumuleHP = otherdevices_svalues[capteurCptHP]:match("([^;]+);([^;]+)")
consoInstantHP = 0
update(capteurCptHP, idxCptHP, consoInstantHP, consoCumuleHP, 2)
else
-- Periode heures pleines
-- Recuperation des valeurs du compteur global
consoInstantCible, consoCumuleCible = otherdevices_svalues[capteurCptHP]:match("([^;]+);([^;]+)")
-- Seul le cumule du compteur nous interesse pour calculer la nouvelle valeur
consoCumuleCible = tonumber(consoCumuleCible)
if (debug == 'OUI') then
print('Compteur cible = HP')
print('Valeur precedente = '..tostring(consoCumuleCible))
print('Valeur ajustee = '..tostring(consoCumuleCible + consoDelta))
end
consoCumuleCible = consoCumuleCible + consoDelta
-- Mise à jour du compteur
update(capteurCptHP, idxCptHP, consoInstant, consoCumuleCible, 3)
-- Mise à 0 de la conso intantanee du compteur HC
consoInstantHC, consoCumuleHC = otherdevices_svalues[capteurCptHC]:match("([^;]+);([^;]+)")
consoInstantHC = 0
update(capteurCptHC, idxCptHC, consoInstantHC, consoCumuleHC, 4)
end
-- Sauvegarde de la valeur du compteur global pour prochain calcul
commandArray['Variable:LastValueCptElecGlobal'] = tostring(consoCumule)
if (debug == 'OUI') then
print('-- Fin Calcul Compteur HC / HP --')
end
end
return commandArray

View File

@@ -0,0 +1,39 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The print command will output lua print statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do print(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do print(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
print('this will end up in the domoticz log')
commandArray = {}
if (devicechanged['MyDeviceName'] == 'On' and otherdevices['MyOtherDeviceName'] == 'Off') then
commandArray['MyOtherDeviceName']='On'
end
return commandArray

49
lua/script_time_ESP8266.lua Executable file
View File

@@ -0,0 +1,49 @@
-- demo device script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: devicechanged, otherdevices,otherdevices_svalues
--
-- device changed contains state and svalues for the device that changed.
-- devicechanged['yourdevicename']=state
-- devicechanged['svalues']=svalues string
--
-- otherdevices and otherdevices_svalues are arrays for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for the state of the changed device.
-- If you would only specify commandArray['AnotherDevice']='On', every device trigger will switch AnotherDevice on, which will trigger a device event, which will switch AnotherDevice on, etc.
--
-- The print command will output lua print statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do print(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do print(i, v) end
--
-- TBD: nice time example, for instance get temp from svalue string, if time is past 22.00 and before 00:00 and temp is bloody hot turn on fan.
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
commandArray = {}
--if (minutes == 0 or minutes == 30) then
if (minutes%5 == 0) then
if otherdevices['ESP8266_31_2'] == 'On' then
-- commandArray['ESP8266_31_2']='Off'
else
-- commandArray['ESP8266_31_2']='On'
end
end
--end
return commandArray

28
lua/script_time_Frigo.lua Executable file
View File

@@ -0,0 +1,28 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- ------------------------------------------------------------------------------
-- Porte Frigo ouverte
-- ------------------------------------------------------------------------------
debug('Porte Frigo ' .. otherdevices['Porte Frigo'] .. ' temps ' .. lastUpdateOfDevice('Porte Frigo'))
-- Pas de traitement en cas d'alerte fumée
if otherdevices['Porte Frigo'] ~= 'Closed'
-- Porte ouverte depuis trop longtemps
and (lastUpdateOfDevice('Porte Frigo')) > 300 then
-- commandArray['SendNotification']='Frigo alerte#La porte du frigo est ouverte depuis trop longtemps !'
end
return commandArray

View File

@@ -0,0 +1,21 @@
-- script_time_garagedoor.lua
t1 = os.time()
s = otherdevices_lastupdate['Garagedeur']
-- 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)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
commandArray = {}
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = (os.difftime (t1, t2))
if (otherdevices['Garagedeur'] == 'Open' and difference > 600 and difference < 700) then
commandArray['SendNotification']='Garage door alert#The garage door has been open for more than 10 minutes!'
end
return commandArray

52
lua/script_time_IP.lua Executable file
View File

@@ -0,0 +1,52 @@
--curl http://domogeek.entropialux.com/vigilance/56/
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
commandArray = {}
-- Function to update a switch
function updateIP()
local idx = 1144
local cmd = "curl -k -y 1 https://api4.my-ip.io/ip"
local vac = os.capture(cmd, true)
print("IP actuelle"..vac)
local level = 0
local old_ip = otherdevices_svalues['Mon_IP']
if old_ip ~= vac then
commandArray['SendNotification']='Changement IP '..vac..'#Attention changement IP '..vac..' #0'
print("Recherche ip publique " .. cmd .. ": "..vac)
commandArray['UpdateDevice']=idx..'|'..level..'|'..vac
commandArray['SendEmail']='Changement IP#'..ip..'#souti@free.fr'
return vac
else
print("Pas de changement IP : "..vac..' '..old_ip)
commandArray['UpdateDevice']=idx..'|'..level..'|'..vac
return vac
end
end
time = os.date("*t")
if heures%3 == 0 and minutes % 10 == 8 then
local old_ip = otherdevices_svalues['Mon_IP']
local cmd = "curl -s -m 5 \"http://".. old_ip ..":81/name.txt\""
print("Cmd="..cmd)
local ok = os.capture(cmd, true)
print("Ok="..ok .." IP="..old_ip)
if ok ~= "Akhenaton" then
print("updateIP")
ip = updateIP()
--commandArray['SendEmail']='Changement IP#'..ip..'#souti@free.fr'
end
end
return commandArray

92
lua/script_time_Lumieres.lua Executable file
View File

@@ -0,0 +1,92 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- -----------------------------------------------------------------------
-- Test le nombre d'erreur dans le log toutes les heures
-- -----------------------------------------------------------------------
if (false and minutes == 0) then
local var = os.capture("grep Error /var/log/domoticz.log |wc -l")
--print(var)
if (tonumber(var) > 0 and tonumber(uservariables['Variable:Erreurs']) == 0) then
commandArray['SendNotification']='Alerte Erreur '..var..'#Attention Il y a des erreurs dans domoticz #0'
end
commandArray['Variable:Erreurs']=var
end
-- -----------------------------------------------------------------------
-- Vérifie le nombre de sequences capturées par motion
-- -----------------------------------------------------------------------
if (minutes % 10 == 1) then
local f = io.popen("ls /media/WDBlue/motion/CAM21/*.avi |grep avi |uniq| wc -l") -- runs command
local l = f:read("*a") -- read output of command
debug("Nombre de detection "..l)
f:close()
commandArray['PhotoMotion']=tostring(l)
commandArray['UpdateDevice']="136|0|"..l
end
-- ------------------------------------------------------------------------------
-- Lampes eteinte après 22 heures 30 / 23 heures si pas d'activite depuis n minutes
-- ------------------------------------------------------------------------------
-- Pas de traitement en cas d'alerte fumée
if (minutes%1==0)
and otherdevices['DétecteurFuméeCuisine'] == "Normal"
-- Pas de traitement si lampe allumée il y a moins d'une 1/2 heure
--and (lastUpdateOfDevice('Lampe_Buffet') > 1800) -- and otherdevices['Lampe_Buffet'] == 'On')
then
debug('Test extinction lumieres')
if (
(
(heures == 22 and minutes >= 0) or
(heures >= 23 and heures <= 5) or
(heures >= 09 and heures <= 10 ) or
(otherdevices['Presence'] == 'Off')
)
) then
t1 = os.time()
s = uservariables_lastupdate['DerniereDetection'] --otherdevices_lastupdate['Detecteur Salon']
-- 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("Eteindre les lumieres, DerniereDetection="..tostring(difference)..' heures='..tostring(heures))
if (difference > 300 and (
(heures >= 22 and (minutes >= 0))
or (heures >= 23)
or (heures <= 5)
)
)
then
debug("Extinction des lumieres")
switchIfNeeded('Lampe_Halogene', 'Off')
sleep(1)
switchIfNeeded('Lampe_Buffet', 'Off')
sleep(1)
switchIfNeeded('Lampe_Tele', 'Off')
--switchIfNeeded('SonoJasper', 'Off')
end
end
end
return commandArray

View File

@@ -0,0 +1,80 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- -----------------------------------------------------------------------
--recupere les minutes
-- -----------------------------------------------------------------------
if (true or minutes % 10 == 5) then
debug('####### Lancement du check Presence ' ..heures..'h'..minutes)
if (otherdevices['Vacances'] == 'On') then
switchIfNeeded('Presence','Off')
else
if otherdevices['Domi'] == 'On'
or otherdevices['Moi'] == 'On'
or otherdevices['Theo'] == 'On'
or otherdevices['Manon'] == 'On'
then
debug(' Presence détectée par téléphone à la maison')
switchIfNeeded('Presence','On')
elseif (true) then
switchIfNeeded('Presence','Off')
elseif (
(josdJourChome() or otherdevices['PresenceForcee'] == 'On')
and otherdevices['AbsenceFamille'] == 'Off')
then
debug(' Jour Chômé / Presence normale à la maison')
switchIfNeeded('Presence','On')
else
local jourS=josdGetJourSemaine()
debug("jour "..jourS)
if otherdevices['AbsenceFamille'] == 'Off' then
if (
--(jourS == "mercredi" and (heures >= 13 or (heures == 12 and minutes >= 30)))
(heures >= 18 or (heures == 17 and minutes >= 30))
or (heures < 8 or (heures == 8 and minutes <= 10))
or otherdevices["Zone B"] == 'On'
) then
debug(' Jour non Chômé pas de vacances '..tostring(heures))
switchIfNeeded('Presence','On')
else
switchIfNeeded('Presence','Off')
end
else
if (
(
(heures == 8 and minutes <= 15) or heures < 8)
or heures >= 20
or otherdevices['Moi'] == 'On'
-- or otherdevices['Akhenaton'] == 'On'
or otherdevices['Philae'] == 'On'
) then
switchIfNeeded('Presence','On')
else
switchIfNeeded('Presence','Off')
end
end
end
end
end
-- http://cellier.home:8081/0/detection/start
-- http://192.168.1.3:8080/0/detection/pause
-- http://cellier.home:8081/0/detection/start
-- http://192.168.1.3:8080/0/detection/start
return commandArray

38
lua/script_time_Solaire.lua Executable file
View File

@@ -0,0 +1,38 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- ------------------------------------------------------------------------------
-- Gestion de la production solaire
-- ------------------------------------------------------------------------------
--if (minutes %1 == 0) then
local tab1 = split(otherdevices['CONSOMMATION_GENERALE'], ";")
local watt_consomme = tonumber(tab1[1])
--print("Time Consommation générale "..watt_consomme)
local tab = getValuesInTab('SolaireProduction')
print("Time Production Solaire "..tab[1])
local watt_solaire = tonumber(tab[1])
if watt_solaire ~= nil and watt_solaire > 100 then
if watt_consomme < 80 then
print("Consommation devient faible => routage solaire")
else
print("Consommation encore importante solaire 100% injecté")
end
end
--end
return commandArray

35
lua/script_time_Sunset.lua Executable file
View File

@@ -0,0 +1,35 @@
-- School Holiday Status Request from Domogeek API
-- http://api.domogeek.fr/static/doc/index.html#api-Domogeek-GetSchoolHoliday
-- Prerequis: 3 switch On/Off: "Zone A", "Zone B", "Zone C"
--curl http://domogeek.entropialux.com/sun/brest/all/now
--{"dayduration": "9:51", "sunset": "18:28", "zenith": "13:32", "sunrise": "8:37"}
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
commandArray = {}
time = os.date("*t")
-- Trigger at 0:03 every day
if (time.min == 3 and (time.hour == 0 or time.hour == 8)) then
-- retourne l'heure du lever de soleil ex: "06:41"
leverSoleil = string.sub(os.date("!%X",60*timeofday['SunriseInMinutes']), 1, 5)
-- retourne l'heure du coucher de soleil ex: "22:15"
coucherSoleil = string.sub(os.date("!%X",60*timeofday['SunsetInMinutes']), 1, 5)
print("Lever/Coucher "..leverSoleil..'-'..coucherSoleil)
commandArray['Variable:Couche']=coucherSoleil
commandArray['Variable:Lever']=leverSoleil
--updateSunset("redon")
end
return commandArray

68
lua/script_time_Vacances.lua Executable file
View File

@@ -0,0 +1,68 @@
require "scripts/lua/functions"
commandArray = {}
-- School Holiday Status Request from Domogeek API
-- http://api.domogeek.fr/static/doc/index.html#api-Domogeek-GetSchoolHoliday
-- Prerequis: 3 switch On/Off: "Zone A", "Zone B", "Zone C"
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
-- Path to curl
-- Windows: curl = 'C:\\bin\\curl.exe'
curl = "curl"
-- Devices (Switch On/Off on virtual hardware)
--switchA = "Zone A"
switchB = "Zone B"
--switchC = "Zone C"
-- 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 update a switch
function updateZoneSwitch(zone, switch)
local cmd = curl .. " -y 2 http://domogeek.entropialux.com/schoolholiday/" .. zone .. "/now"
local vac = os.capture(cmd, true)
print("School Holiday Status: " .. cmd .. ": " .. tostring(vac))
if (vac == "False") then
--if (otherdevices[switch] == "On") then
--commandArray[switch] = "Off";
--end
else
if (vac ~= "") then
--commandArray[switch] = "On";
end
end
end
-- Trigger at 0:02 every day
if ((minutes == 5 and heures == 2)) then
-- Zone A
-- updateZoneSwitch("A", switchA)
-- Zone B
updateZoneSwitch("B", "Zone B")
-- Zone C
-- updateZoneSwitch("C", switchC)
end
return commandArray

120
lua/script_time_angle.lua Normal file
View File

@@ -0,0 +1,120 @@
require "scripts/lua/functions"
-- URL du fichier JSON
local weather_url = "http://api.openweathermap.org/data/2.5/weather?q=La%20gacilly,fr&APPID=feba3f4d926db3b358a25ec782bd1c8b&lang=FR&units=metric"
local forecast_url = "http://api.openweathermap.org/data/2.5/forecast?q=La%20gacilly,fr&APPID=feba3f4d926db3b358a25ec782bd1c8b&lang=FR&units=metric"
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
local function forecast(pressure)
-- pressureForecast = tonumber(forecast)
if (pressure == 0) then
pressureForecast = 0
elseif (pressure > 1030) then
pressureForecast = 1
elseif ((pressure > 1010) and (pressure <= 1030)) then
pressureForecast = 2
elseif ((pressure > 990) and (pressure <= 1010)) then
pressureForecast = 3
elseif ((pressure > 970) and (pressure <= 990)) then
pressureForecast = 4
end
return pressureForecast
end
local function updateBarometerDevice(deviceId, temperature, humidity, pressure, cloud)
local svalue = string.format("%.1f;%d;%d;%d;%d;", temperature, humidity, humidity, pressure, cloud)
local url = domoticzURL..'/json.htm?type=command&param=udevice&idx='..deviceId..'&svalue='..svalue
print(url)
result = os.execute(curl..'"'..url..'" &')
print(result)
end
commandArray = {}
if minutes == 0 and heures == 8 then
if mois == 2 and jour == 1 then
sendNotification('Changement d\'angle#Passer l\'angle des panneaux à 60°!')
end
if mois == 3 and jour == 1 then
sendNotification('Changement d\'angle#Passer l\'angle des panneaux à 45°!')
end
if mois == 4 and jour == 24 then
sendNotification('Changement d\'angle#Passer l\'angle des panneaux à 30°!')
end
if mois == 8 and jour == 19 then
sendNotification('Changement d\'angle#Passer l\'angle des panneaux à 45°!')
end
if mois == 10 and jour == 13 then
sendNotification('Changement d\'angle#Passer l\'angle des panneaux à 60°!')
end
end
if minutes % 10 == 0 then
local jsonContent = getJSONContent(weather_url)
local devices = decodeJSON(jsonContent)
printTableAsTree(devices)
local nuage = 0
local pluie_1h = 0
local main = searchKeyInTable("main", devices['weather'])
print('main='..main)
local nuage = searchKeyInTable("all", devices['clouds'])
print("pluie " .. pluie_1h)
print("Nuage " .. nuage)
updateDeviceValue(1159, ';'..pluie_1h)
updateDeviceValue(1160, nuage)
local temp_min = searchKeyInTable("temp", devices)
local humidity = searchKeyInTable("humidity", devices)
local pressure = searchKeyInTable("pressure", devices)
local cloud = searchKeyInTable("all", devices)
local forecast = forecast(pressure)
updateBarometerDevice(1157, temp_min, humidity, pressure, forecast)
local temp = searchKeyInTable("temp", devices)
local feels_like = searchKeyInTable("feels_like", devices)
local deg = searchKeyInTable("deg", devices)
local speed = searchKeyInTable("speed", devices) * 10
local gust = searchKeyInTable("gust", devices) * 10
local angle = searchKeyInTable("deg", devices['wind'])
local compass = convertirAngle(angle)
-- print("deg"..tostring(deg))
updateDeviceValue(1158, string.format("%d;%s;%.1f;%.1f;%.1f;%.1f", deg, compass, speed, gust, temp, feels_like))
end
if heures % 3 == 0 and minutes == 26 then
local jsonContent = getJSONContent(forecast_url)
--print(jsonContent)
local data = decodeJSON(jsonContent)
-- Extraire les 6 premières valeurs du champ "all"
local cloud_values = {}
for i = 1, math.min(6, #data.list) do
table.insert(cloud_values, data.list[i].clouds.all)
end
-- Afficher les valeurs extraites
local somme = 0
for i, value in ipairs(cloud_values) do
print("Cloud coverage for point " .. i .. ": " .. value)
somme = somme + tonumber(value)
end
local moyenne = somme / 6
print("Cloud coverage average".. tostring(moyenne))
updateDeviceValue(1199, tostring(moyenne))
end
return commandArray

40
lua/script_time_cam.lua Normal file
View File

@@ -0,0 +1,40 @@
-- demo time script
-- script names have three name components: script_trigger_name.lua
-- trigger can be 'time' or 'device', name can be any string
-- domoticz will execute all time and device triggers when the relevant trigger occurs
--
-- copy this script and change the "name" part, all scripts named "demo" are ignored.
--
-- Make sure the encoding is UTF8 of the file
--
-- ingests tables: otherdevices,otherdevices_svalues
--
-- otherdevices and otherdevices_svalues are two item array for all devices:
-- otherdevices['yourotherdevicename']="On"
-- otherdevices_svalues['yourotherthermometer'] = string of svalues
--
-- Based on your logic, fill the commandArray with device commands. Device name is case sensitive.
--
-- Always, and I repeat ALWAYS start by checking for a state.
-- If you would only specify commandArray['AnotherDevice']='On', every time trigger (e.g. every minute) will switch AnotherDevice on.
--
-- The print command will output lua print statements to the domoticz log for debugging.
-- List all otherdevices states for debugging:
-- for i, v in pairs(otherdevices) do print(i, v) end
-- List all otherdevices svalues for debugging:
-- for i, v in pairs(otherdevices_svalues) do print(i, v) end
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
commandArray = {}
if heures ==23 and minute == 00 then
end
return commandArray

345
lua/script_time_consigne.lua Executable file
View File

@@ -0,0 +1,345 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- ---------------------------------
-- Réglage des consigne temperature
-- ---------------------------------
function callDomoticz(device, svalue)
local idx = otherdevices_idx[device]
if (svalue == nil) then
print("CONSIGNE Call Domoticz Update canceled null value"..tostring(idx).." "..svalue)
end
print("CONSIGNE Call Domoticz IDx="..idx.." device="..device.." value="..tostring(svalue))
--commandArray['SetSetpoint:'..idx]=svalue
--local cmd ='curl -y 1 "http://localhost:81/json.htm?type=command&param=udevice&idx='..idx..'&nvalue=0&svalue='..svalue..'"'
--local vac = os.capture(cmd, true)
--os.execute(cmd)
--debug("Domoticz called pour consige " .. cmd .. ": ") -- .. vac)
print("CONSIGNE Consigne "..otherdevices_svalues[device].." svalue="..svalue.." idx="..tostring(idx).." "..device)
if tonumber(otherdevices_svalues[device]) ~= tonumber(svalue) then
update(idx,tonumber(svalue),tonumber(svalue))
print("CONSIGNE Update "..tostring(idx).." "..svalue)
else
print("CONSIGNE Update inutile "..tostring(idx).." "..svalue)
end
--sleep(1)
end
--print("CONSIGNE ++++++++++++PRESENCE MANON "..otherdevices['Manon'])
if minutes%1 == 0
--and otherdevices['ChauffageGeneral'] == 'Off'
then
print('CONSIGNE ####### Lancement du calcul consigne ' ..heures..'h'..minutes)
local temp_ext = getExternalTempRef("BarometreLaGacilly")
local heureCreuse = (uservariables['HeuresCreuses'] == 'On')
local delta = -0.5
if (heureCreuse) then
delta = 0.5
end
-- Pas d'heure creuse
delta = 0
local jourS=josdGetJourSemaine()
local consigneConfortGrenier = 18
local consigneAbsence = otherdevices['ConsigneAbsence'] + delta
local consigneConfort = otherdevices['ConsigneChauffageGeneral'] + delta
local consigneConfortSalon = uservariables['ConfortSalon'] + delta
local consigneConfortCuisine = uservariables['ConfortCuisine'] + delta
local consigneConfortBureau = uservariables["ConfortBureau"] + delta
local consigneConfortManon = uservariables["ConfortManon"] + delta
local consigneConfortTheo = uservariables["ConfortTheo"] + delta
local consigneConfortChambre = uservariables["ConfortChambre"] + delta
--local consigneConfortSalon = 17.5 + delta
local consigneHorsGel = 14
-- Cheminee allumée
local currentTempCheminee = tonumber(otherdevices_svalues["Cheminee"])
local variation = variationTemp2("Cheminee", 120) -- variation des 120 dernières minutes
local coucheManon = 17
local coucheTheo = 17
local reveilManon = uservariables["HeureLeveManon"]
local reveilTheo = uservariables["HeureLeveTheo"]
local reveilManonEcole = uservariables["HeureLeveEcoleManon"]
local reveilTheoEcole = uservariables["HeureLeveEcoleTheo"]
local presenceManon = (
otherdevices['Manon'] == "On" or uservariables['Detection_Manon_20H'] == 1
or otherdevices["Zone B"] == 'On'
or (((jourS == "vendredi" and heures >= 18) or jourS == "samedi" or
(jourS == "dimanche" and heures <= 18)
)
-- or otherdevices["Manon"] == 'On'
-- )
-- and uservariables['Detection_Manon_20H'] == "1"
)
)
and otherdevices['AbsenceFamille'] == 'Off'
local presenceTheo = (
otherdevices['Theo'] == "On" or uservariables['Detection_Theo_20H'] == 1
or otherdevices["Zone B"] == 'On'
or (
--(jourS == "jeudi" and heures >= 18) or
(jourS == "vendredi" and heures >= 18) or
jourS == "samedi" or
(jourS == "dimanche" and uservariables['Detection_Theo_20H'] == 1) )
--and uservariables['Detection_Theo_20H'] == "1")
-- or otherdevices["Theo"] == 'On'
-- )
-- )
)
and otherdevices['AbsenceFamille'] == 'Off'
local presenceMoi = (otherdevices['Moi'] == "On" )
or (
(jourS == "lundi" or jourS == "mardi" or jourS == "mercredi" or jourS == "jeudi" or jourS == "vendredi") and (heures >= 8 and heures <= 18) and otherdevices['jerome'] == "On"
)
local presenceDomi = (otherdevices['Domi'] == "On" or jourS == "samedi" or jourS == "dimanche")
and otherdevices['AbsenceFamille'] == 'Off'
local yaPersonne = not (presenceManon or presenceTheo or presenceMoi or presenceDomi or otherdevices['PresenceForcee'] == 'On')
if not yaPersonne then
if (heures >= 7 and heures <= 9) or (heures >= 11 and heures <= 14) or (heures >= 19 and heures <= 21) then
consigneConfortCuisine = uservariables['ConfortCuisine'] + delta
else
consigneConfortCuisine = uservariables['ConfortCuisine'] - 1
end
end
print("CONSIGNE Cheminee variation"..tostring(variation))
local cheminee_allumee = false
if (currentTempCheminee > 21.5 or (variation > 0 and currentTempCheminee >= 20)) then
cheminee_allumee = true;
print('CONSIGNE Cheminee fonctionne : arrêt radiateurs')
if (heures > 11) then
consigneConfortSalon = consigneHorsGel
end
if (heures > 11 and heures < 20) then
consigneConfortManon = consigneAbsence
consigneConfortTheo = consigneAbsence
consigneConfortChambre = consigneAbsence
end
if ((not presenceMoi or otherdevices['jerome'] == 'Off') and otherdevices['Akhesa'] == 'Off') then
consigneConfortBureau = consigneHorsGel
end
end
--if ((not presenceMoi or otherdevices['jerome'] == 'Off' or josdJourChome())) then
-- consigneConfortBureau = consigneHorsGel
--end
print("CONSIGNE Presence Manon "..tostring(presenceManon));
print("CONSIGNE Presence Theo "..tostring(presenceTheo));
print("CONSIGNE Presence moi "..tostring(presenceMoi));
if (otherdevices['Manon'] == 'On' and heures >= 17) then
coucheManon = heures
end
if (otherdevices['Vacances'] == 'On') then
print("CONSIGNE Vacances");
callDomoticz('ConsigneConfortCuisine',consigneHorsGel) -- Chambre
callDomoticz('ConsigneConfortChambre',consigneHorsGel) -- Chambre
callDomoticz('ConsigneConfortTheo',consigneHorsGel) -- ChconsigneConfortambreTheo
callDomoticz('ConsigneConfortManon', consigneHorsGel) -- ChambreManon
callDomoticz('ConsigneConfortBureau',consigneHorsGel) -- Bureau
callDomoticz('ConsigneConfortSalon',consigneHorsGel) -- Salon
callDomoticz('ConsigneConfortGrenier',consigneHorsGel) -- Salon
else
if otherdevices['Force_Grenier'] == "On" then
callDomoticz('ConsigneConfortGrenier',consigneConfortGrenier)
elseif heures > 18 or heures < 8 or josdJourChome() or otherdevices['Domi_Work'] == "Off" then
callDomoticz('ConsigneConfortGrenier', 6) --consigneHorsGel)
elseif otherdevices['Domi_Work'] == "On" then
callDomoticz('ConsigneConfortGrenier',consigneConfortGrenier)
end
--commandArray['Presence']='Off
-- Presence à la maison
------------------------------------------------------------------------
if (josdJourChome() or otherdevices['PresenceForcee'] == 'On') then
print('CONSIGNE Jour Chômé / consigne temperature présence')
-- callDomoticz('ConsigneConfortBureau',consigneConfortBureau) -- Bureau
if (heures >= 21 or heures < 11 or yaPersonne) then
callDomoticz('ConsigneConfortCuisine',consigneAbsence) -- Salon
else
callDomoticz('ConsigneConfortCuisine',consigneConfortCuisine) -- Salon
end
if (heures >= 22 or heures < 8 or yaPersonne --or temp_ext < 3
or cheminee_allumee)
then
callDomoticz('ConsigneConfortSalon',consigneAbsence) -- Salon
else
callDomoticz('ConsigneConfortSalon',consigneConfortSalon) -- Salon
end
if (heures >= 20 or heures < 8) then
callDomoticz('ConsigneConfortChambre',consigneConfortChambre) -- Chambre
else
callDomoticz('ConsigneConfortChambre',consigneAbsence) -- Chambre
end
if (
(otherdevices['Akhesa'] == 'On' or otherdevices['jerome'] == 'On')
and (heures > 7 and heures < 21)
) then
callDomoticz('ConsigneConfortBureau',consigneConfortBureau) -- Bureau
else
callDomoticz('ConsigneConfortBureau',consigneHorsGel) -- Bureau
end
-- Heure Manon en vacances
if --(heures >= coucheManon or heures <= reveilManon) and
presenceManon then
callDomoticz('ConsigneConfortManon', consigneConfortManon) -- ChambreManon
else
callDomoticz('ConsigneConfortManon', consigneAbsence) -- ChambreManon
end
-- Heure Théo en vacances
if (heures >= coucheTheo or heures <= reveilTheo) and presenceTheo then
callDomoticz('ConsigneConfortTheo',consigneConfortTheo) -- ChambreTheo
else
callDomoticz('ConsigneConfortTheo',consigneAbsence) -- ChambreTheo
end
else
--
if otherdevices['AbsenceFamille'] == 'Off' then
if otherdevices["Zone B"] == 'On' or otherdevices["PresenceForcee"] == 'On' then
print('CONSIGNE Jour vacances zone B ')
if (heures >= 17 or heures <= 8) then
callDomoticz('ConsigneConfortChambre',consigneConfortChambre) -- Chambre
else
callDomoticz('ConsigneConfortChambre',consigneAbsence) -- Chambre
end
if (heures >= 21 or heures < 11 or (yaPersonne and heures < 16)) then
callDomoticz('ConsigneConfortCuisine',consigneAbsence) -- Salon
else
callDomoticz('ConsigneConfortCuisine',consigneConfortCuisine) -- Salon
end
if (heures >= 22 or heures < 16 or (yaPersonne and heures < 16)) then
callDomoticz('ConsigneConfortSalon',consigneAbsence) -- Salon
else
callDomoticz('ConsigneConfortSalon',consigneConfortSalon) -- Salon
end
if (
--heures >= 20 or heures < 9 or*/
(otherdevices['Akhesa'] == 'Off' and otherdevices['jerome'] == 'Off')
or (heures > 21 and heures < 7)
) then
callDomoticz('ConsigneConfortBureau',consigneHorsGel) -- Bureau
else
callDomoticz('ConsigneConfortBureau',consigneConfortBureau) -- Bureau
end
-- Heure Manon en vacances
if (heures >= coucheManon or heures <= reveilManon) and presenceManon then
callDomoticz('ConsigneConfortManon', consigneConfortManon) -- ChambreManon
else
callDomoticz('ConsigneConfortManon', consigneAbsence) -- ChambreManon
end
-- Heure Théo en vacances
if (heures >= coucheTheo or heures <= reveilTheo) and presenceTheo then
callDomoticz('ConsigneConfortTheo',consigneConfortTheo) -- ChambreTheo
else
callDomoticz('ConsigneConfortTheo',consigneAbsence) -- ChambreTheo
end
-- Heures hors vacances
-- Ecole
else --if (heures >= 17 or heures < 8) then
print('CONSIGNE Jour non Chômé pas de vacances '..tostring(heures).."h"..tostring(minutes))
if (heures >= 20 or heures <= 6) then
callDomoticz('ConsigneConfortChambre',consigneConfortChambre) -- Chambre
else
callDomoticz('ConsigneConfortChambre',consigneAbsence) -- Chambre
end
if (heures >= 21 or heures < 18 or (yaPersonne and heures < 18) --or temp_ext < 3
) then
callDomoticz('ConsigneConfortCuisine',consigneAbsence) -- Salon
else
callDomoticz('ConsigneConfortCuisine',consigneConfortCuisine) -- Salon
end
if (heures <= 16 or heures >= 22 or (yaPersonne and heures < 16) --or temp_ext < 3
) then
callDomoticz('ConsigneConfortSalon',consigneAbsence) -- Salon
else
callDomoticz('ConsigneConfortSalon',consigneConfortSalon) -- Salon
end
if (
(otherdevices['Akhesa'] == 'On' or otherdevices['jerome'] == 'On' or presenceMoi)
and (heures >= 7 and heures < 18)
) then
callDomoticz('ConsigneConfortBureau',consigneConfortBureau) -- Bureau
else
callDomoticz('ConsigneConfortBureau',consigneHorsGel) -- Bureau
end
-- Heure Manon école
if (presenceManon) then
callDomoticz('ConsigneConfortManon', consigneConfortManon) -- ChambreManon
else
callDomoticz('ConsigneConfortManon', consigneAbsence) -- ChambreManon
end
if (presenceTheo and (otherdevices['Akhesa'] == 'Off' or heures >= 21)) then
callDomoticz('ConsigneConfortTheo',consigneConfortTheo) -- ChambreTheo
else
callDomoticz('ConsigneConfortTheo',consigneAbsence) -- ChambreTheo
end
end
else
callDomoticz('ConsigneConfortCuisine',consigneAbsence)
callDomoticz('ConsigneConfortTheo',consigneHorsGel) -- ChambreTheo
callDomoticz('ConsigneConfortManon', consigneHorsGel) -- ChambreManon
-- Absence famille
if (
((heures == 8 and minutes <= 15) or heures < 8) or heures >= 20) or
(otherdevices['Moi'] == 'On'
or otherdevices['Akhesa'] == 'On' or otherdevices['Presence'] == 'On'
or otherdevices['Nefertiti'] == 'On' or otherdevices['jerome'] == 'On'
)
then
callDomoticz('ConsigneConfortChambre',consigneConfortChambre) -- Chambre
if (heures >= 22 or heures < 19) then
callDomoticz('ConsigneConfortSalon',consigneAbsence) -- Salon
else
callDomoticz('ConsigneConfortSalon',consigneConfortSalon) -- Salon
end
if (otherdevices['Akhesa'] == 'Off' and otherdevices['jerome'] == 'Off')
or ((heures > 21 and heures < 7) or cheminee_allumee)
then
callDomoticz('ConsigneConfortBureau',consigneHorsGel) -- Bureau
else
callDomoticz('ConsigneConfortBureau',consigneConfortBureau) -- Bureau
end
else
callDomoticz('ConsigneConfortChambre',consigneAbsence) -- Chambre
callDomoticz('ConsigneConfortBureau',consigneAbsence) -- Bureau
callDomoticz('ConsigneConfortSalon',consigneAbsence) -- Salon
callDomoticz('ConsigneConfortTheo',consigneAbsence) -- ChambreTheo
callDomoticz('ConsigneConfortManon', consigneAbsence) -- ChambreManon
callDomoticz('ConsigneConfortGrenier',consigneHorsGel) -- Salon
end
end
end
end
end
return commandArray

49
lua/script_time_fumee.lua Executable file
View File

@@ -0,0 +1,49 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- ------------------------------------------------------------------------------
-- Lampes eteinte après 22 heures 30 / 23 heures si pas d'activite depuis 10 minutes
-- ------------------------------------------------------------------------------
-- Pas de traitement en cas d'alerte fumée
if otherdevices['DétecteurFuméeCuisine'] == "Normal"
-- Pas de traitement si lampe allumée il y a moins d'une heure
and (lastUpdateOfDevice('Lampe_Buffet') > 3600 and otherdevices['Lampe_Buffet'] == 'On')
then
if ((heures >= 23 or (heures == 22 and minutes >= 30)) and (minutes%5==0)) then
t1 = os.time()
s = uservariables_lastupdate['DerniereDetection'] --otherdevices_lastupdate['Detecteur Salon']
-- 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("Eteindre les lumieres, DerniereDetection="..tostring(difference))
if (difference > 300 or heures >= 23) then
switchIfNeeded('Lampe_Halogene', 'Off')
switchIfNeeded('Lampe_Buffet', 'Off')
switchIfNeeded('Lampe_Tele', 'Off')
switchIfNeeded('SonoJasper', 'Off')
end
end
end
return commandArray

137
lua/script_time_gcal.lua Executable file
View File

@@ -0,0 +1,137 @@
---------------------------------
-- Script de lecture de calendrier Google.
-- Actionne un interrupteur ou remplie un capteur virtuel Text
-- Auteur : Aurelien Neutrino
-- Date : 29 Novembre 2015
-- Nécessite un capteur virtuel de type Text
-- Il faut suivre la source suivante et s'arrêter à la fin de l'étape 1
-- source :
-- http://easydomoticz.com/agenda-google-et-domoticz-version-2-partie-1/
-- Pour récupérer le code permettant de se connecter
-- exécuter : sudo gcalcli --cal=Domoticz agenda '00:00' '23:59' --tsv --military
-- puis coller l'adresse dans un navigateur
--
---------------------------------
require "scripts/lua/functions"
commandArray = {}
--Récupère l'heure et la date actuelle
time = os.time()
minutes=tonumber(os.date('%M',time))
hours=tonumber(os.date('%H',time))
jour = os.date('%d',time)
--Nombre de minutes depuis 00:00
maintenant=tonumber(hours*60+minutes)
--idx et nom du capteur Text
idxText = '203'
nomText="Agenda"
--nom de l'agenda google
domoticz_cal="Domoticz"
--fichier et chemin pour agenda
repertoire="/home/pi/"
file="googlecal.txt"
-- Toutes les heures, on récupère l'agenda de la journée
if(maintenant%60==0)then
options="--tsv --military"
agenda_start="00:00"
agenda_end="23:59"
-- Agenda Domoticz
lignecde="sudo gcalcli --cal="..domoticz_cal.." agenda ".."'"..agenda_start.."' '"..agenda_end.."' "..options
lignecde=lignecde.." > "..repertoire..file.." &"
os.execute(lignecde)
sleep(1)
-- Agenda Standard 4/ymDKXAZQtn9azD6vFmUPQ7fJ0jJFeJWOXu___bVKD68
lignecde="sudo gcalcli --cal=jerome.delacotte@gmail.com agenda '"..agenda_start.."' '"..agenda_end.."' "..options
lignecde=lignecde.." >> "..repertoire..file.." &"
os.execute(lignecde)
sleep(1)
-- Agenda Standard 4/ymDKXAZQtn9azD6vFmUPQ7fJ0jJFeJWOXu___bVKD68
lignecde="sudo gcalcli --cal=jerome.delacotte@vif.fr agenda '"..agenda_start.."' '"..agenda_end.."' "..options
lignecde=lignecde.." >> "..repertoire..file.." &"
os.execute(lignecde)
--end
local file = io.open(repertoire..file, "r") -- Ouvre le fichier en mode lecture
local ligne = {} -- Table pour les lignes du fichier
if(file~=nil)then
--le fichier n'est pas vide
for line in file:lines() do -- Pour chaque lignes
table.insert(ligne, line) -- On insère les lignes dans la table
end
end
for i, v in ipairs(ligne) do -- Lecture de la table des RDV
dateDebut,heureDebut,minutesDebut,dateFin,heureFin,minutesFin,action = v:match("([^;]+)\t([^;]+):([^;]+)\t([^;]+)\t([^;]+):([^;]+)\t([^;]+)")
action = action:gsub(" = ","=")
debutAction = heureDebut*60+minutesDebut
finAction = heureFin*60+minutesFin
anneeAction,moisAction,jourAction = dateDebut:match("([^;]+)-([^;]+)-([^;]+)")
if(action~=nil and action:find("=")~=nil and jourAction == jour)then
--L'action contient "=", c'est un interrupteur à actionner
debug("Action : "..action)
debug(maintenant.." : "..debutAction)
interrupteur,etat=action:match("([^;]+)=([^;]+)")
if(otherdevices[interrupteur]~=nil and(etat=='On' or etat=='Off' or etat=='ON' or etat=='OFF')and debutAction==maintenant)then
--L'interrupteur existe, l'état souhaité est reconnu
if(etat=='On'or etat=='Off')then
if(dateDebut~=dateFin)then
--l'action finit demain
finAction=finAction+(24*60)
end
debug(interrupteur.." passe à "..etat.." pendant "..tostring(finAction-maintenant).." minutes")
commandArray[interrupteur]=etat.." FOR "..tostring(finAction-maintenant)
if(otherdevices_svalues[nomText]=='')then
--Aucun pense-bête actuellement renseigné, on affiche l'action en cours.
--L'affichage d'un pense-bête est prioritaire sur l'affichage d'un changement d'état
debug("pense-bête : "..action)
commandArray['UpdateDevice']=idxText.."|0|"..action
end
elseif(etat=='ON')then
--ON (tout en majuscule) siginifie que l'action n'a pas de fin
debug(interrupteur.." passe à On")
commandArray[interrupteur]='On'
elseif(etat=='OFF')then
--OFF (tout en majuscule) siginifie que l'action n'a pas de fin
debug(interrupteur.." passe à Off")
commandArray[interrupteur]='Off'
else
--Etat non reconnu, on force l'interrupteur
debug(interrupteur.." passe à "..etat)
commandArray[interrupteur]=etat
end
elseif(otherdevices[interrupteur]==nil and debutAction==maintenant)then
--L'interrupteur n'existe pas, on affiche le pense-bête
commandArray['UpdateDevice']=idxText.."|0|"..action
elseif(finAction==maintenant and action == otherdevices_svalues[nomText])then
--L'action est terminée, on l'efface
commandArray['UpdateDevice']=idxText.."|0| "
end
elseif(action~=nil and action:find("Cong=")~=nil and jourAction == jour)then
commandArray['Presence']="on"
else
debug("###### Action : "..action)
if (debutAction==maintenant and jourAction == jour) then
--L'action ne correspond pas à un interrupteur à actionner, c'est donc un pense-bête, on l'affiche pendant la durée souhaitée
debug("####### Rappel agenda "..action)
commandArray['UpdateDevice']=idxText.."|0|"..action
else
if (finAction==maintenant and action == otherdevices_svalues[nomText]) then
--L'action est terminée, on l'efface
debug("####### Fin tâche agenda "..action)
commandArray['UpdateDevice']=idxText.."|0| "
end
end
end
end
end
return commandArray

View File

@@ -0,0 +1,119 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
capacite=76 * 12 --Wh
charge=200 --Wh
decharge=50 --Wh
tension_charge_max_off=13.3
tension_charge_max_on=13.8
tension_injection_min=11.2
tension_force_charge=10.8
--Initialise la commande de retour finale
commandArray={}
-- Tension repos V Conso charge W
-- 11.35 330
-- 12.35 270
-- 12.8 233
-- 12.67 190
-- 13.33 66
-- --------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------
if false and (seconds % 5 == 0 ) then
url = "http://192.168.1.40/getData"
--result = os.execute(curl..'"'..url..'"')
local jsonContent = getJSONContent(url)
--print(cmd)
local statuses = decodeJSON(jsonContent)
--printTableAsTree(statuses)
if isempty(statuses) then
print("BAT ERROR getData")
return commandArray
end
if (otherdevices['ForceChargeBatterie'] == 'On' and
((tonumber(lastUpdateOfDevice('ForceChargeBatterie')) > 3 * 3600) or tension > tension_charge_max_on))
then
--commandArray['ForceChargeBatterie'] = "Off"
switchOff("ForceChargeBatterie")
end
local tension = round(tonumber(statuses['VOLTAGE']) / 55,2) -- tonumber(otherdevices['BatterieTension'])
local power_theorique = -131.71 * tension + 1850.45
charge=power_theorique
print("BAT Power theorique"..tostring(power_theorique))
updatenum("BatterieTension", tension)
updatenum("TemperatureBatterie", temperature)
--commandArray['Batterie'] = ternary(statuses['PIN_POWER'] == 0, 'On', 'Off')
--commandArray['InjectionBatterie'] = ternary(statuses['PIN_INJECTION'] == 0, 'On', 'Off')
--commandArray['ChargeBatterie'] = ternary(statuses['PIN_CHARGE'] == 0, 'On', 'Off')
production = tonumber(split(otherdevices['SolaireProduction'], ";")[1])
injection = tonumber(split(otherdevices['Injection_Radiateur'], ";")[1])
chauffe = tonumber(split(otherdevices['Chauffe_Eau'], ";")[1])
conso = tonumber(split(otherdevices['Consommation_Apparente'], ";")[1])
print("BAT injection="..tostring(injection)
..' chauffe='..tostring(chauffe)
..' charge='..tostring(charge)
..' conso='..tostring(conso)
.. ' voltage='..tostring(round(tonumber(statuses['VOLTAGE']) / 55,2))
..' tension='..tostring(tension)
)
print("BAT PIN_POWER="..statuses['PIN_POWER'].." PIN_CHARGE="..statuses['PIN_CHARGE'].." PIN_INJECTION="..statuses['PIN_INJECTION'].." PIN_BATTERIE="..statuses['PIN_BATTERIE'])
-- status 0 = ON / 1 = OFF
if (statuses['PIN_CHARGE'] == 1) then --(otherdevices['ChargeBatterie'] == 'Off') then
if (uservariables['Dark'] == "False"
and (conso < - charge or injection > charge or (injection - conso > charge) or otherdevices['ForceChargeBatterie'] == 'On')
and tension <= tension_charge_max_off
)
then
print("BAT charge batterie / arret injection")
switchOff("InjectionBatterie")
switchOn("ChargeBatterie")
else
if tension <= tension_force_charge then
switchOn("ForceChargeBatterie")
else
if (statuses['PIN_INJECTION'] == 1) then --(otherdevices['InjectionBatterie'] == 'Off') then
if (conso > decharge and injection < decharge and tension >= tension_injection_min) then
print("BAT Injection batterie / arret charge")
switchOff("ChargeBatterie")
switchOn("InjectionBatterie")
end
else
if (injection > decharge / 2 or conso < - decharge / 2 or tension < tension_injection_min) then -- or (production <= 100 and heures < 23 and heures > 7)) then
print("BAT arret injection batterie")
switchOff("InjectionBatterie")
end
end
end
end
else
-- test sur statuses pour eviter les valeurs nulles
if (conso - injection > 14 or tension > tension_charge_max_on) then
print("BAT arret charge batterie")
switchOff("ChargeBatterie")
--switchOn("InjectionBatterie")
end
end
end
--if heures == 4 and minutes <= 2 then
-- switchOff("InjectionBatterie")
--end
return commandArray

View File

@@ -0,0 +1,56 @@
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
jour=tonumber(os.date('%w',time))
mois=tonumber(os.date('%M',time))
--Initialise la commande de retour finale
commandArray={}
-- --------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------
if (False and lastUpdateOfDevice('BatterieTension') > 60) then
url = "http://192.168.1.18/getData"
--result = os.execute(curl..'"'..url..'"')
local jsonContent = getJSONContent(url)
--print(cmd)
local statuses = decodeJSON(jsonContent)
--printTableAsTree(statuses)
updatenum("BatterieCharge", 0)
updatenum("BatterieInjection", 0)
if isempty(statuses) then
print("BAT ERROR getData")
return commandArray
end
local tension = round(tonumber(statuses['V']) / 1000,2) -- tonumber(otherdevices['BatterieTension'])
local temperature = round(tonumber(statuses['TEMPERATURE']),1) -- tonumber(otherdevices['BatterieTension'])
updatenum("BatterieTension", tension)
updatenum("BatterieCharge", tonumber(statuses['PPV']))
updatenum("TemperatureBatterie", temperature)
if tension > 20 and tension < 25.4 then
switchOff("Batterie")
-- switchOn("ChargeBatterie")
end
end
print('Capteur solaire redémarré'..tostring( lastUpdateOfDevice('SolaireProduction').. ' '..tostring(lastUpdateOfDevice('LUMIERE_PLANTE')) ))
if (lastUpdateOfDevice('Tuya_2') > 60 and lastUpdateOfDevice('LUMIERE_PLANTE') > 60) then
switchOff('LUMIERE_PLANTE')
sleep(3)
switchOn('LUMIERE_PLANTE')
print('Capteur solaire redémarré')
end
return commandArray

150
lua/script_time_livebox.lua Executable file
View File

@@ -0,0 +1,150 @@
---------------------------------
-- Script de détection de présence via livebox
-- Auteur : Sopalin
-- Date : 22 Juillet 2016
-- Nécessite un switch classique
-- source :
---------------------------------
require "scripts/lua/functions"
--recupere les minutes
time=os.time()
seconds=tonumber(os.date('%S',time))
minutes=tonumber(os.date('%M',time))
heures=tonumber(os.date('%H',time))
commandArray={}
function testActive(name, active)
if active then
--commandArray[name]='On'
switchIfNeeded(name, 'On')
else
switchIfNeeded(name, 'Off')
--commandArray[name]='Off'
end
debug("### Test active Name : "..name.." active "..tostring(active))
end
if heures == 8 then
commandArray['Variable:Detection_Manon_20H'] = "0"
commandArray['Variable:Detection_Theo_20H'] = "0"
--uservariables['Detection_Manon_20H'] = 0
--uservariables['Detection_Theo_20H'] = 0
--print('Detection_Theo_20H='..string(uservariables['Detection_Theo_20H']))
end
--time = os.date("*t")
if (minutes % 5 == 4) then
--if (true) then
--import des fontions pour lire le JSON
json = (loadfile "/opt/domoticz/scripts/lua/JSON.lua")()
--Récupération des informations sur la livebox
--Utilisation d'un script VBS sous windows
--Utilisation d'un script bash pour extraire les données
----------------------------------------------------------------
--Lecture des données
local f = assert(io.open("/tmp/Devices.txt","r"))
local livebox = f:read('*all')
f:close()
--Décodage ud fichier
local jsonLivebox = json:decode(livebox)
if jsonLivebox == nil then
return commandArray
end
--debug("DEBUG")
--debug(timedifference(otherdevices_lastupdate['Presence Thomas']))
commandArray['Domi']='Off'
commandArray['Domi_Work']='Off'
commandArray['Theo']='Off'
commandArray['Moi']='Off'
commandArray['Manon']='Off'
commandArray['orangepizero']='Off'
commandArray['jerome']='Off'
commandArray['R53PP2003X0247']='Off'
commandArray['R53PP2003X0247-1']='Off'
devices = jsonLivebox['status']
--Parcours du fichier pour vérifier la présence d'un téléphone
for result,status in pairs(devices) do
local name = status['Name']
debug("Name : "..name.." Mac : "..status['Key'].." "..tostring(status['Active']))
if (name == "Akhesa" or name == "Playstation3" or name == "DESKTOP-MUI1HPH" or name == "Theo") then
-- testActive('Theo', status['Active'])
if status['Active'] then
commandArray['Theo']='On'
if heures >= 19 then
commandArray['Variable:Detection_Theo_20H'] = "1"
end
end
end
if (--name == "Nefertiti" or
string.find(name,"Jerome") or name == "Achille" or string.find(name, "Moi")
or name == "iPhonedeJerome" or name == "iPhonedeJerome-1" or name == "jerome"
or name == "Iphone-jerome"
) then
if status['Active'] then
commandArray['Moi']='On'
end
end
if (name == "DomiPro" or name == "Domi") then
-- testActive('Domi', status['Active'])
if status['Active'] then
commandArray['Domi']='On'
end
end
if (name == "R53PP2003X0247-1" or name == "R53PP2003X0247") then
if status['Active'] then
commandArray['Domi_Work']='On'
end
end
if (name == "Akhenaton-3" or name == "Akhenaton") then
testActive("Akhenaton", status['Active'])
end
if (name == "Manon" or name == "AcerManon"
or name == "DESKTOP-KH8V15B" or name == "iPhone-de-Manon" or name == "IPhonedeManon")
then
-- testActive("Manon", status['Active'])
if status['Active'] then
commandArray['Manon']='On'
if heures >= 20 then
commandArray['Variable:Detection_Manon_20H'] = "1"
end
end
end
if (name == "TeleChambre" or name == "AcerManon" or name == "Akhesa" or name == "AkhesaNew"
or name == "Akhenaton" or name == "SoutiHP" or name == "Hackintosh"
or name == "Octoprint" or name == "jerome"
or name == "Volumio" or name == "LibreELEC"
or name == "Recovery") then
testActive(name, status['Active'])
end
if (--name == "orangepizero" or name == "orangepizero-1" or
name == "orangepizero-2") then
if status['Active'] then
commandArray['orangepizero']='On'
end
end
if (name == "RadiateurManon" or name == "RadiateurTheo" or name == "RadiateurBureau"
or name == "RadiateurChambre") then
if status['Active'] then
-- nothing
else
-- commandArray['SendNotification']='Alerte radiateur '..name..'#Alerte radiateur ne repond pas au ping '..name
end
end
end
end
return commandArray

139
lua/script_time_variables.lua Executable file
View File

@@ -0,0 +1,139 @@
require "scripts/lua/functions"
----------------------------------------------------------------------------------------------------------
-- Script parameters
----------------------------------------------------------------------------------------------------------
-- Setting the time variables:
-- %a abbreviated weekday name (e.g., Wed)
-- %A full weekday name (e.g., Wednesday)
-- %b abbreviated month name (e.g., Sep)
-- %B full month name (e.g., September)
-- %c date and time (e.g., 09/16/98 23:48:10)
-- %d day of the month (16) [01-31]
-- %H hour, using a 24-hour clock (23) [00-23]
-- %I hour, using a 12-hour clock (11) [01-12]
-- %M minute (48) [00-59]
-- %m month (09) [01-12]
-- %p either "am" or "pm" (pm)
-- %S second (10) [00-61]
-- %w weekday (3) [0-6 = Sunday-Saturday]
-- %x date (e.g., 09/16/98)
-- %X time (e.g., 23:48:10)
-- %Y full year (1998)
-- %y two-digit year (98) [00-99]
-- %% the character `%´
year = tonumber(os.date("%Y"));
month = tonumber(os.date("%m"));
day = tonumber(os.date("%d"));
hour = tonumber(os.date("%H"));
min = tonumber(os.date("%M"));
weekday = tonumber(os.date("%w"));
----------------------------------------------------------------------------------------------------------
-- Script functions
----------------------------------------------------------------------------------------------------------
function WhichSeason()
local tNow = os.date("*t")
local dayofyear = tNow.yday
local season
if (dayofyear >= 79) and (dayofyear < 172) then season = "Printemps"
elseif (dayofyear >= 172) and (dayofyear < 266) then season = "ete"
elseif (dayofyear >= 266) and (dayofyear < 355) then season = "Automne"
else season = "Hiver"
end
return season
end
function IsWeekend()
local dayNow = tonumber(os.date("%w"))
local weekend
if (dayNow == 0) or (dayNow == 6) then weekend = "True"
else weekend = "False"
end
return weekend
end
function IsDark()
local dark
-- local now = heureEnMinute(uservariables["Couche"]) - 30
local now = 60 * hour + min - 15
local now2 = 60 * hour + min + 15
debug (" variable sunset="..tostring(uservariables["Couche"]).." heureEnMinute="..tostring(heureEnMinute(uservariables["Couche"])))
local sunsetMin = heureEnMinute(uservariables["Couche"])
local sunriseMin = heureEnMinute(uservariables["Lever"])
if (now > sunsetMin --timeofday['SunsetInMinutes'] or
or now2 < sunriseMin --timeofday['SunriseInMinutes']
) then -- timeofday['Nighttime']) then
dark = "True"
else
dark = "False"
end
debug("####### sunset "..tostring(timeofday['SunsetInMinutes'])..' sunrise='
..tostring(timeofday['SunriseInMinutes'])..' '..tostring(now)..' '..tostring(dark))
return dark
end
----------------------------------------------------------------------------------------------------------
-- CommandArray
----------------------------------------------------------------------------------------------------------
commandArray = {}
if (min == 10 and hour == 0) then
saison = WhichSeason();
weekend = IsWeekend();
if (uservariables["Saison"] ~= season) then commandArray['Variable:Saison'] = tostring(saison) end
if (uservariables["Weekend"] ~= weekend) then commandArray['Variable:Weekend'] = tostring(weekend) end
debug(' Saison: ' .. saison .. ' ');
debug(' Weekend: ' .. weekend .. ' ');
end
if (min % 1 == 0 and (hour >= 17 or hour < 10)) then
dark = IsDark();
if (uservariables["Dark"] ~= dark) then
--commandArray['Variable:Dark'] = tostring(dark)
updateVar("Dark", dark)
end
debug(' Dark: ' .. dark .. ' ');
end
function checkLastUpdate(deviceIDX)
local lastUpdateTime = lastUpdateOfDevice(deviceIDX)
local currentTime = os.time()
local timeDifference = currentTime - lastUpdateTime
-- Si la dernière mise à jour remonte à plus de 5 minutes
if timeDifference > 300 then
print("Le dispositif n'a pas été mis à jour depuis plus de 5 minutes.")
-- Ajoutez ici le code pour effectuer une action en réponse à l'absence de mise à jour
else
print("Le dispositif a été mis à jour récemment.")
end
end
if (min % 1 == 0 ) then
checkLastUpdate(1182)
end
--if otherdevices['Debug'] == 'On' then
-- debug(' Year: ' .. year .. ' ');
-- debug(' Month: ' .. month .. ' ');
-- debug(' Day: ' .. day .. ' ');
-- debug(' Hour: ' .. hour .. ' ');
-- debug(' Minute: ' .. min .. ' ');
-- debug(' Weekday: ' .. weekday .. ' ');
--end
debug("Updating variables if necessary")
commandArray['Variable:Heure'] = tostring(hour)..":"..tostring(min)
return commandArray

View File

@@ -0,0 +1,71 @@
require "scripts/lua/functions"
----------------------------------------------------------------------------------------------------------
-- Script parameters
----------------------------------------------------------------------------------------------------------
-- Setting the time variables:
-- %a abbreviated weekday name (e.g., Wed)
-- %A full weekday name (e.g., Wednesday)
-- %b abbreviated month name (e.g., Sep)
-- %B full month name (e.g., September)
-- %c date and time (e.g., 09/16/98 23:48:10)
-- %d day of the month (16) [01-31]
-- %H hour, using a 24-hour clock (23) [00-23]
-- %I hour, using a 12-hour clock (11) [01-12]
-- %M minute (48) [00-59]
-- %m month (09) [01-12]
-- %p either "am" or "pm" (pm)
-- %S second (10) [00-61]
-- %w weekday (3) [0-6 = Sunday-Saturday]
-- %x date (e.g., 09/16/98)
-- %X time (e.g., 23:48:10)
-- %Y full year (1998)
-- %y two-digit year (98) [00-99]
-- %% the character `%´
year = tonumber(os.date("%Y"));
month = tonumber(os.date("%m"));
day = tonumber(os.date("%d"));
hour = tonumber(os.date("%H"));
min = tonumber(os.date("%M"));
weekday = tonumber(os.date("%w"));
-- ------------------------------------------------------------------------------
-- Function test montage
-- ------------------------------------------------------------------------------
function mountTest(disk)
local ret = os.execute("mount | grep " .. disk)
debug('######### Lancement du check Disk ' ..disk)
return ret
end
commandArray = {}
-- ----------------------
-- Check disk
-- ----------------------
if (min % 10 == 0) then
if (isempty(mountTest("WDBlue"))) then
commandArray['Variable:WDBlue'] = 'Off'
else
commandArray['Variable:WDBlue'] = 'On'
end
if (isempty(mountTest("WDGreen"))) then
commandArray['Variable:WDGreen'] = 'Off'
else
commandArray['Variable:WDGreen'] = 'On'
end
if (isempty(mountTest("WDPink"))) then
commandArray['Variable:WDPink'] = 'Off'
else
commandArray['Variable:WDPink'] = 'On'
end
if (isempty(mountTest("WDRed"))) then
commandArray['Variable:WDRed'] = 'Off'
else
commandArray['Variable:WDRed'] = 'On'
end
end
return commandArray

View File

@@ -0,0 +1,48 @@
require "scripts/lua/functions"
----------------------------------------------------------------------------------------------------------
-- Script parameters
----------------------------------------------------------------------------------------------------------
-- Setting the time variables:
-- %a abbreviated weekday name (e.g., Wed)
-- %A full weekday name (e.g., Wednesday)
-- %b abbreviated month name (e.g., Sep)
-- %B full month name (e.g., September)
-- %c date and time (e.g., 09/16/98 23:48:10)
-- %d day of the month (16) [01-31]
-- %H hour, using a 24-hour clock (23) [00-23]
-- %I hour, using a 12-hour clock (11) [01-12]
-- %M minute (48) [00-59]
-- %m month (09) [01-12]
-- %p either "am" or "pm" (pm)
-- %S second (10) [00-61]
-- %w weekday (3) [0-6 = Sunday-Saturday]
-- %x date (e.g., 09/16/98)
-- %X time (e.g., 23:48:10)
-- %Y full year (1998)
-- %y two-digit year (98) [00-99]
-- %% the character `%´
year = tonumber(os.date("%Y"));
month = tonumber(os.date("%m"));
day = tonumber(os.date("%d"));
hour = tonumber(os.date("%H"));
min = tonumber(os.date("%M"));
weekday = tonumber(os.date("%w"));
commandArray = {}
-- ----------------------
-- Heures creuses
-- ----------------------
if (min%10 == 0) then
debug('######### Lancement du check Heures Creuses ' ..hour..'h'..min)
if ((hour > 21 or (hour == 21 and min >= 30)) or (hour < 5 or (hour == 5 and min <= 30))) then
--switchIfNeeded('Variable:HeuresCreuses', 'On')
commandArray['Variable:HeuresCreuses'] = 'On'
else
commandArray['Variable:HeuresCreuses'] = 'Off'
end
end
return commandArray

View File

@@ -0,0 +1,471 @@
require "scripts/lua/functions"
commandArray = {}
local HEURE_DEB = 9
local HEURE_FIN = 17
local AZIMUTH_FIN = 270
local TEMP_MAX = 25.5
local TEMP_MAX_2 = 29
local MIN_LUX = 15000
local device_temp = 'BarometreLaGacilly'
--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
--jour=tonumber(os.date('%w',time))
heures=tonumber(os.date('%H',time))
mois=tonumber(os.date('%m',time))
local saison = uservariables["Saison"]
local delaiFermeture = uservariables["DelaiFermetureVoletCoucheSoleil"]
local jourS = josdGetJourSemaine()
local nuages = tonumber(otherdevices['Nuage_LaGacilly'])
local temp_ext = getExternalTempRef(device_temp)
-- -------------------------------------------------------------------
-- Verification des volets ouverts si température trop basse
-- -------------------------------------------------------------------
if (minutes == 0 or minutes == 30 ) then
print('Volets ########## Lancement du check fermeture velux du grenier ' ..heures..'h'..minutes)
--tab = getValuesInTab('Exterieur_Cellier')
-- val = otherdevices[device_temp]
val, val2 = otherdevices_svalues[device_temp]:match("([^;]+);([^;]+)")
local tmp = tonumber(val)
print('Volets ########## Lancement du check fermeture velux du grenier ' ..heures..'h'..minutes..' tmp='..tostring(tmp))
if (tmp < 14.0 and (otherdevices['Velux droit'] == 'Open' or otherdevices['Velux gauche'] == 'Open')) then
commandArray['notification']="Volet ouvert#Un des volets du grenier est reste ouvert #0"
end
end
-- -----------------------
-- Fermeture volet central
-- -----------------------
if minutes%5 == 0 and minutes < 2
and (
(heures >= 22 and (saison ~= "ete") and jourS ~= "mercredi" and (mois < 5 or mois >= 9)) -- or uservariables['Dark'] == "True")
or (heures >= 23)
)
then
print('Volets ------------------------------------------------------')
print('Volets Test fermeture volet Central '..otherdevices['VoletPorteSalon'])
print('Volets ------------------------------------------------------')
if (otherdevices['VoletPorteSalon'] ~= 'Closed') then
commandArray['VoletPorteSalon']='On'
end
end
-- -----------------------
-- Ouverture volets
-- -----------------------
if minutes%10 == 3
and heures < 10
and (otherdevices['VoletCuisine'] == 'Closed' or otherdevices['VoletSalonTele'] == 'Closed')
--and (saison == "Printemps" or saison == "ete")
then
print('Volets ------------------------------------------------------')
print('Volets Test ouverture volets jour chome='..tostring(josdJourChome())..' Absence='..otherdevices['AbsenceFamille']..' Vacances='..otherdevices['Vacances']
..' '..tostring(heures)..':'..tostring(minutes))
print('Volets ------------------------------------------------------')
local ouvertureVolet = false;
if (josdJourChome()
or otherdevices['AbsenceFamille'] == 'On'
or otherdevices['Vacances'] == 'On'
) then
print('Volets bloc 09:30 '..tostring(heures == 09 and minutes >= 30))
if (heures == 09 and minutes >= 30) then
ouvertureVolet = true;
end
end
if otherdevices['AbsenceFamille'] == 'Off'
and not josdJourChome()
and otherdevices['Vacances'] == 'Off'
then
print('Volets bloc 07:00 '..tostring(heures == 07 and minutes >= 00))
if (heures == 07 and minutes >= 00) then
ouvertureVolet = true;
end
end
print("Volets ouvertureVolet="..tostring(ouvertureVolet))
if (ouvertureVolet == true) then
print('Volets Ouverture volets jour chome='..tostring(josdJourChome())..' Absence='..otherdevices['AbsenceFamille']..' Vacances='..otherdevices['Vacances']
..tostring(heures)..' '..tostring(minutes))
switchIfNeeded('VoletPorteSalon', 'Off')
switchIfNeeded('VoletSalonTele', 'Off')
switchIfNeeded('VoletCuisine', 'Off')
--if (otherdevices['VoletVelux'] == 'Closed') then
switchIfNeeded('VoletVelux', 'Off')
--end
end
end
-- -----------------------
-- Ouverture volets chambres
-- -----------------------
if minutes%5 == 0 and heures > 6 and heures < 13
--and (saison == "Printemps" or saison == "ete")
then
print('Volets ------------------------------------------------------')
print('Volets Test ouverture volets chambres')
print('Volets ------------------------------------------------------')
local presenceManon = (otherdevices['Manon'] == "On" or jourS == "samedi" or (jourS == "dimanche" and heures < 18) or otherdevices['Zone B'] == 'On')
local presenceTheo = (otherdevices['Theo'] == "On" or jourS == "samedi" or (jourS == "dimanche" and heures < 18) or otherdevices['Zone B'] == 'On')
local val
local val2
val, val2 = otherdevices_svalues[device_temp]:match("([^;]+);([^;]+)")
--val = otherdevices[device_temp]
local temp = tonumber(val)
-- ----------------
-- Volet Somfy
-- ----------------
if (josdJourChome() or otherdevices['Vacances'] == 'On'
or (otherdevices['Conges'] == 'On' and otherdevices['AbsenceFamille'] == 'Off'))
then
print('Volets Test ouverture volets chambres bloc journee chomee')
if (heures == 10 and minutes >= 30) then
switchIfNeeded('VoletChambreVirtuel', 'Off')
end
if (heures == 12 and minutes >= 30 and minutes <= 32) then
if (temp >= TEMP_MAX) then
-- nothing
else
switchIfNeeded('VoletManonVirtuel', 'Off')
switchIfNeeded('VoletTheoVirtuel', 'Off')
end
end
else
print('Volets Test ouverture volets chambres bloc journee travaille')
if (heures == 07 and minutes >= 45) then
switchIfNeeded('VoletChambreVirtuel', 'Off')
end
if (heures == 07 and minutes >= 45 and not presenceManon) then
switchIfNeeded('VoletManonVirtuel', 'Off')
end
if (heures == 07 and minutes >= 45 and not presenceTheo) then
switchIfNeeded('VoletTheoVirtuel', 'Off')
end
if (heures == 12 and minutes >= 30 and minutes <= 32) then
if (temp >= TEMP_MAX) then
-- nothing
else
if presenceManon then
switchIfNeeded('VoletManonVirtuel', 'Off')
end
if presenceTheo then
switchIfNeeded('VoletTheoVirtuel', 'Off')
end
end
end
end
end
if minutes%1 == 0 and heures >= 19 and (saison == "ete")
and uservariables['VoletsSomfy'] ~= 'open'
and uservariables['Dark'] ~= "True"
then
local evolution = tonumber(uservariables['AugmentationTempExterieure'])
local tempChambre = getTemperatureFromDevice('Chambre')
print("tempChambre="..tostring(tempChambre).." temp_ext="..tostring(temp_ext).." evolution="..tostring(evolution))
if (temp_ext + evolution <= tempChambre) then
commandArray['Variable:VoletsSomfy'] = "open"
print("SOMFY Volets test ouverture volets : temp en baisse")
print("SOMFY Volets Lancement script somfy")
os.execute("/opt/domoticz/scripts/voletsSomfy.sh u")
end
end
-- ---------------------------------------------------------------------------------------
-- Fermeture des volets
-- ---------------------------------------------------------------------------------------
--print("Volets DARK=="..tostring(uservariables['Dark'] == "True"))
if minutes%5 == 0
-- (saison ~= "Ete")
and (
otherdevices['VoletCuisine'] == 'Open' or otherdevices['VoletSalonTele'] == 'Open'
--or otherdevices['VoletChambreVirtuel'] == 'Open'
--or otherdevices['VoletManonVirtuel'] == 'Open'
--or otherdevices['VoletTheoVirtuel'] == 'Open'
)
and (heures >= 18 or
(
(heures >= 17 and minutes >= 30) and (
uservariables['Dark'] == "True"
or (
tonumber(otherdevices['Lux']) < tonumber(uservariables["LuxMini"])
)
)
)
)
then
print('Volets ------------------------------------------------------')
print('Volets Test fermeture volet ')
print('Volets ------------------------------------------------------')
print('Volets ####### Comparaison heure vs Couche du soleil ========>'..uservariables["Heure"].." couché "..uservariables["Couche"])
--print('Volets ####### Lancement du check test ' ..heures..'h'..minutes..' volet cuisine '..otherdevices['Exterieur_Cellier']..' svalues='..otherdevices_svalues['Exterieur_Cellier']..' VoletCuisine='..otherdevices['VoletCuisine'])
--tmp = otherdevices_svalues['Exterieur_Cellier']
--tab = split(tmp, ";")
-- val = otherdevices[device_temp]
print("Volets ######### Check fermeture : temperature lue par "..device_temp.." "..temp_ext)
temp = temp_ext --tonumber(val)
if (
(
(
(temp < 6.0 and whenDark() <= 0)
or (temp < 8 and whenDark() <= -10)
or (temp < 10 and whenDark() <= -20)
)
)
or (
uservariables['Dark'] == "True"
)
)
then
local temp_chambre = getTemperatureFromDevice('Chambre')
print(temp_chambre)
print("Volets ######### Dans temperature exterieure la gacilly "..tostring(temp_ext)..' temp_chambre'..tostring(temp_chambre))
if mois >= 6 and mois <= 9 and temp_ext < temp_chambre and temp_ext >= 21 and temp_chambre > 23 then
if (otherdevices['VoletCuisine'] == 'Open' and otherdevices['VoletSalonTele'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20)) then
print("Volets Lancement volets2 On 17")
os.execute("/opt/domoticz/scripts/volets2.sh On 17 &")
end
else
print("Volets Lancement un par un")
if (otherdevices['VoletCuisine'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20) ) then
commandArray['VoletCuisine']='On'
end
if (otherdevices['VoletSalonTele'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20)) then
commandArray['VoletSalonTele']='On'
end
if (otherdevices['VoletChambreVirtuel'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20)) then
commandArray['VoletChambreVirtuel']='On'
end
if (otherdevices['VoletManonVirtuel'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20)) then
commandArray['VoletManonVirtuel']='On'
end
if (otherdevices['VoletTheoVirtuel'] == 'Open') then -- or (minutes % 10 == 0 and heures <=20)) then
commandArray['VoletTheoVirtuel']='On'
end
end
switchIfNeeded('VoletVelux', 'On')
else
print("Volets ############ PAS DANS LE IF")
end
end
-- ------------------------------------------------------------------------------
-- Ouverture des volets en fonction de la temperature exterieure Hiver et Automne
-- ------------------------------------------------------------------------------
if minutes%5 == 0
and heures <= HEURE_DEB
and ((heures >= 9 and josdJourChome()) or (heures > 6 and not josdJourChome()))
and (saison == "Hiver" or saison == "Automne")
and (greater2(uservariables["Heure"],uservariables["Lever"], - 30)) -- heures >= 20
and (otherdevices['VoletCuisine'] == 'Closed'
or otherdevices['VoletSalonTele'] == 'Closed'
or otherdevices['VoletPorteSalon'] == 'Closed'
or otherdevices['VoletVelux'] == 'Closed'
or otherdevices['VoletChambreVirtuel'] == 'Closed'
or otherdevices['VoletManonVirtuel'] == 'Closed'
or otherdevices['VoletTheoVirtuel'] == 'Closed'
)
then
print('Volets ------------------------------------------------------')
print('Volets Test ouverture volet ')
print('Volets ------------------------------------------------------')
print('Volets ####### Comparaison heure vs Lever du soleil ========>'..uservariables["Heure"]..
" "..uservariables["Lever"])
print('Volets ####### Lancement du check test ' ..heures..'h'..minutes..' volet cuisine '
..otherdevices['Exterieur_Cellier']..' svalues='..otherdevices_svalues[device_temp]..' VoletCuisine='..otherdevices['VoletCuisine'])
temp = temp_ext --
if (temp > 12.0
or (heures >=9 and minutes >= 30 and josdJourChome())
or (heures > 6 and not josdJourChome())
) then
if (otherdevices['VoletCuisine'] == 'Closed' or (minutes % 10 == 0 and heures == 9)) then
commandArray ['VoletCuisine']='Off'
end
if (otherdevices['VoletSalonTele'] == 'Closed' or (minutes % 10 == 0 and heures == 9)) then
commandArray['VoletSalonTele']='Off'
end
if (otherdevices['VoletPorteSalon'] == 'Closed' or (minutes % 10 == 0 and heures == 9)) then
commandArray['VoletPorteSalon']='Off'
end
if (otherdevices['VoletVelux'] == 'Closed' or (minutes % 10 == 0 and heures == 9)) then
commandArray['VoletVelux']='Off'
end
-- if (otherdevices['VoletChambreVirtuel'] == 'Closed') then -- or (minutes % 10 == 0 and heures <=20)) then
-- commandArray['VoletChambreVirtuel']='Off'
-- end
-- if (otherdevices['VoletManonVirtuel'] == 'Closed') then -- or (minutes % 10 == 0 and heures <=20)) then
-- commandArray['VoletManonVirtuel']='Off'
-- end
-- if (otherdevices['VoletTheoVirtuel'] == 'Closed') then -- or (minutes % 10 == 0 and heures <=20)) then
-- commandArray['VoletTheoVirtuel']='Off'
-- end
end
end
-- ------------------------------------------------------------------------------
-- fermeture des volets en fonction de la temperature exterieure en ete
-- ------------------------------------------------------------------------------
if (minutes%5 == 0 --and uservariables['Dark'] == "False"
and (heures > HEURE_DEB and heures < HEURE_FIN))
--and (saison == "ete")
--and (greater(uservariables["Heure"] , uservariables["Lever"])) -- heures >= 20
--and (otherdevices['VoletCuisine'] == 'Open' or otherdevices['VoletSalonTele'] == 'Open' or otherdevices['VoletPorteSalon'] == 'Open')
then
print('Volets ------------------------------------------------------')
print('Volets Test fermeture volet Ete')
print('Volets ------------------------------------------------------')
print('Volets ####### Lancement du check test ' ..heures..'h'..minutes..
' temp cellier '..otherdevices['Exterieur_Cellier']..
' svalues='..otherdevices_svalues[device_temp]..
' VoletCuisine='..otherdevices['VoletCuisine']..
' nuages='..tostring(nuages))
local temp = temp_ext
if (saison == "ete" or temp >= TEMP_MAX) then
-- Lecture des lux pour ne pas fermer si ciel couvert
-- local lux = tonumber(otherdevices['Lux'])
print("Volets "..device_temp.." "..otherdevices_svalues[device_temp]
.." volet cuisine "..otherdevices['VoletCuisine']..
" volet tele "..otherdevices['VoletSalonTele']..
" volet salon"..otherdevices['VoletPorteSalon'])
if temp >= TEMP_MAX
and (otherdevices['VoletCuisine'] == 'Open'
and otherdevices['VoletSalonTele'] == 'Open'
and otherdevices['VoletPorteSalon'] == 'Open')
--and tonumber(otherdevices['Sun Altitude']) > 50
--sand (nuages < 50 or temp >= TEMP_MAX_2)
then
commandArray['Variable:VoletsSomfy'] = "close"
print("Volets test fermeture volets : temp élevée lux"..tostring(lux))
-- if lux > MIN_LUX then
if temp >= TEMP_MAX_2 then
print("Volets Lancement script 2 temp élevée volets2.sh on 15")
os.execute("/opt/domoticz/scripts/volets2.sh On 15 &")
else
print("Volets Lancement script 1 temp élevée volets.sh on ")
os.execute("/opt/domoticz/scripts/volets.sh On &")
end
-- end
end
end
if (temp >= TEMP_MAX_2 and heures == 13 and minutes == 00
and jours ~= 'samedi' and jours ~= "dimanche"
) then
commandArray['Variable:VoletsSomfy'] = "close"
print("Volets test fermeture volets : temp très élevée lux"..tostring(lux))
print("Volets Lancement script somfy")
os.execute("/opt/domoticz/scripts/voletsSomfy.sh d")
-- end
end
end
-- print("Volets Sun Altitude=" ..otherdevices['Sun Altitude'])
-- ------------------------------------------------------------------------------
-- Réouverture après la vague de chaleur ETE
-- ------------------------------------------------------------------------------
-- print("Volets Azimuth="..otherdevices["Sun Azimuth"])
if (minutes%5 == 0
and ((heures > HEURE_FIN and whenDark() > 60)) --heures <= 19))
and (saison == "ete" or (mois >= 5 and mois <= 10 ))
) then
-- val = otherdevices[device_temp]
print("Volets -- ------------------------------------------------------------------------------")
print("Volets -- Réouverture après la vague de chaleur ETE")
print("Volets -- ------------------------------------------------------------------------------")
print("Volets "..device_temp.." "..otherdevices["Exterieur_Cellier"].." "..tostring(temp_ext)..
otherdevices['VoletCuisine'].." "..otherdevices['VoletSalonTele'].." "..otherdevices['VoletPorteSalon'])
local temp = temp_ext
if ((temp <= 26 or (temp <= TEMP_MAX and heures >= 18) or (heures >= 19)
or tonumber(otherdevices['Sun Altitude']) <= 30
)
--or tonumber(otherdevices["Sun Azimuth"]) > AZIMUTH_FIN)
and (otherdevices['VoletCuisine'] == 'Closed' or
otherdevices['VoletSalonTele'] == 'Closed' or
otherdevices['VoletPorteSalon'] == 'Closed'))
then
print("Volets Ouverture volets : temp en baisse")
if temp <= TEMP_MAX then
print("Volets Lancement volets2 Off 20")
os.execute("/opt/domoticz/scripts/volets2.sh Off 20 &")
else
print("Volets Lancement volets3 Off 20")
os.execute("/opt/domoticz/scripts/volets3.sh Off 20 &")
end
end
end
-- ------------------------------------------------------------------------------
-- Activation ventilation grenier
-- ------------------------------------------------------------------------------
if (minutes%5 == 0
) then
local temp = tonumber(otherdevices_svalues['Cheminee'])
print("Volets "..device_temp.." Test ventilation "..otherdevices_svalues[device_temp].." externe="..temp_ext.." salon="..temp)
local variation = variationTemp2('Cheminee', 30) -- variation des 10 dernières minutes
print("Variation Chemine="..tostring(variation))
if (temp_ext < 15 and (temp >= 20 or variation > 1) and heures >= 10) then
print("Activation ventilation")
commandArray['Ventilation'] = 'On'
else
print("Désactivation ventilation")
commandArray['Ventilation'] = 'Off'
end
end
return commandArray

18
lua/sqlite.lua Executable file
View File

@@ -0,0 +1,18 @@
-- Ne fonctionne plus require "luasql.sqlite3"
luasql = require "luasql.sqlite3"
env = luasql.sqlite3()
conn = env:connect("/opt/domoticz/domoticz.db")
cursor = assert(conn:execute("select temperature,date from temperature where devicerowid = 101 order by date desc limit 10"))
row = {}
while cursor:fetch(row) do
print(table.concat(row, '|'))
end
cursor:close()
conn:close()
env:close()

112
lua/test.lua Executable file
View File

@@ -0,0 +1,112 @@
-- script domoticz/scripts/lua/script_device_compteurHC-HP.lua
-- Initialisation des variables locales
local capteurGlobal = uservariables['Capteur électricité']
local capteurCptHP = uservariables['ConsoCapteurHP']
local capteurCptHC = uservariables['ConsoCapteurHC']
local idxCptHP = uservariables['IdxCptHP']
local idxCptHC = uservariables['IdxCptHC']
local flagHC = uservariables['FlagHC']
local flagHP = uservariables['FlagHP']
local lastValueCptElecGlobal = uservariables['LastValueCptElecGlobal']
-- Mode debug Oui / Non
local debug = uservariables['debug']
-- Fonction de mise à jour
function update(device, id, power, energy, index)
commandArray[index] = {['UpdateDevice'] = id .. "|0|" .. power .. ";" .. energy}
return
end
commandArray = {}
-- On prend en compte a chaque changement de valeur du compteur global
if (devicechanged[capteurGlobal]) then
if (debug == 'OUI') then
print('-- Calcul Compteurs HC / HP --')
print('CapteurGlobal = '..capteurGlobal)
print('CapteurCptHP = '..capteurCptHP)
print('CapteurCptHC = '..capteurCptHC)
print('idxCptHP = '..tostring(idxCptHP))
print('idxCptHC = '..tostring(idxCptHC))
print('flagHP = '..tostring(flagHP))
print('flagHC = '..tostring(flagHC))
print('LastValueCptElecGlobal = '..tostring(lastValueCptElecGlobal))
end
-- Recuperation des valeurs du compteur global
local consoCumule
local consoInstant
consoInstant, consoCumule = otherdevices_svalues[capteurGlobal]:match("([^;]+);([^;]+)")
consoInstant = tonumber(consoInstant)
consoCumule = tonumber(consoCumule)
if (debug == 'OUI') then
print('Conso Instant = '..tostring(consoInstant)..' / Conso Cumule = '..tostring(consoCumule)..' ')
end
-- Calcul de l'ecart avec le dernier envoi de donnees
lastValueCptElecGlobal = tonumber(lastValueCptElecGlobal)
local consoDelta = consoCumule - lastValueCptElecGlobal
if (debug == 'OUI') then
print('Delta conso = '..tostring(consoDelta))
end
local consoCumuleCible
local consoInstantCible
if (otherdevices[flagHC] == 'On') then
-- Periode heures creuse
-- Recuperation des valeurs du compteur global
consoInstantCible, consoCumuleCible = otherdevices_svalues[capteurCptHC]:match("([^;]+);([^;]+)")
-- Seul le cumule du compteur nous interesse pour calculer la nouvelle valeur
consoCumuleCible = tonumber(consoCumuleCible)
if (debug == 'OUI') then
print('Compteur cible = HC')
print('Valeur precedente = '..tostring(consoCumuleCible))
print('Valeur ajustee = '..tostring(consoCumuleCible + consoDelta))
end
consoCumuleCible = consoCumuleCible + consoDelta
-- Mise à jour du compteur
update(capteurCptHC, idxCptHC, consoInstant, consoCumuleCible, 1)
-- Mise à 0 de la conso intantanee du compteur HP
consoInstantHP, consoCumuleHP = otherdevices_svalues[capteurCptHP]:match("([^;]+);([^;]+)")
consoInstantHP = 0
update(capteurCptHP, idxCptHP, consoInstantHP, consoCumuleHP, 2)
else
-- Periode heures pleines
-- Recuperation des valeurs du compteur global
consoInstantCible, consoCumuleCible = otherdevices_svalues[capteurCptHP]:match("([^;]+);([^;]+)")
-- Seul le cumule du compteur nous interesse pour calculer la nouvelle valeur
consoCumuleCible = tonumber(consoCumuleCible)
if (debug == 'OUI') then
print('Compteur cible = HP')
print('Valeur precedente = '..tostring(consoCumuleCible))
print('Valeur ajustee = '..tostring(consoCumuleCible + consoDelta))
end
consoCumuleCible = consoCumuleCible + consoDelta
-- Mise à jour du compteur
update(capteurCptHP, idxCptHP, consoInstant, consoCumuleCible, 3)
-- Mise à 0 de la conso intantanee du compteur HC
consoInstantHC, consoCumuleHC = otherdevices_svalues[capteurCptHC]:match("([^;]+);([^;]+)")
consoInstantHC = 0
update(capteurCptHC, idxCptHC, consoInstantHC, consoCumuleHC, 4)
end
-- Sauvegarde de la valeur du compteur global pour prochain calcul
commandArray['Variable:LastValueCptElecGlobal'] = tostring(consoCumule)
if (debug == 'OUI') then
print('-- Fin Calcul Compteur HC / HP --')
end
end
return commandArray

533
lua/vigilance.html Normal file
View File

@@ -0,0 +1,533 @@
<html>
<head>
<style type="text/css" >
html {
padding:0px;
margin:0px;
}
body {
font-size: 12px;
font-family: Verdana, Arial, SunSans-Regular, Sans-Serif;
color:#564b47;
margin:0px;
}
p, h2 {
margin:0px
}
h1 {
font-size: 11px;
color: #564b47;
padding:5px 15px;
margin:0px
}
h2 {
font-size:14px;
padding:5px 15px;
text-transform:uppercase;
color: #564b47;
background-color: transparent;
}
a {
color: #ff66cc;
font-size: 11px;
background-color:transparent;
text-decoration: none;
}
#menu {
position: absolute;
width: 200px;
left: 20px;
background-color: #ffffCC;
padding:0px;
margin:0px
}
#content {
background-color:#fff;
overflow: hidden;
position: absolute;
left: 460px;
top: 30px;
}
img {
border:none;
}
/*RAJOUTER LES DIV INFO ICI AUSSI*/
#info1 ,#info2, #info3, #info4, #info5, #info6, #info7, #info8, #info9, #info10, #info11, #info12, #info13, #info14, #info15, #info16, #info17, #info18, #info19, #info20, #info21, #info22, #info23, #info24, #info25, #info26, #info27, #info28, #info29, #info30, #info31, #info32, #info33, #info34, #info35, #info36, #info37, #info38, #info39, #info40, #info41, #info42, #info43, #info44, #info45, #info46, #info47, #info48, #info49, #info50, #info51, #info52, #info53, #info54, #info55, #info56, #info57, #info58, #info59, #info60, #info61, #info62, #info63, #info64, #info65, #info66, #info67, #info68, #info69, #info70, #info71, #info72, #info73, #info74, #info75, #info76, #info77, #info78, #info79, #info80, #info81, #info82, #info83, #info84, #info85, #info86, #info87, #info88, #info89, #info90, #info91, #info92, #info93, #info94, #info95, #info96{
position: absolute;
left: 1030px;
top: 140px;
visibility: hidden;
}
#bulletin{
position: absolute;
top: 100px;
width: 460px;
}
#logo{
position: absolute;
top: 40px;
left: 490px;
}
#paris{
position: absolute;
top: 10px;
left: 900px;
}
#copyright{
position: absolute;
top: 350px;
left: 480px;
}
.center2{
text-align: center;
}
</style>
<script type="text/javascript">
function afficher(info){
var tooltip = document.getElementById(info);
tooltip.style.visibility = "visible";
run= true ;
}
function masquer(info){
var tooltip = document.getElementById(info) ;
tooltip.style.visibility = "hidden";
run= false ;
}
</script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-60171478-1', 'auto');
ga('send', 'pageview');
</script>
</head>
<body>
<p><h2><u>Carte de vigilance des pollens - valable jusqu'au 23 mars.</u></h2></p>
<p><h1>Survolez le département de votre choix pour connaître le risque <br/>d'allergie pour chaque pollen.</h1></p>
<div id="content">
<img name="carte" src="Departements_de_France-simple.png" border="0" usemap="#map" id="carte"/>
<map name="map" id="map">
<area shape="poly" coords="426,296,420,317,421,321,418,324,418,331,424,334,427,339,434,338,437,341,443,334,447,333,458,350,459,344,461,343,461,338,464,335,464,329,462,326,464,319,469,316,470,312,475,308,477,302,474,302,469,310,460,310,457,309,448,313,447,308,445,307,439,300,433,298,426,297" onmousemove="afficher('info1')" onmouseout="masquer('info1')"/>
<area shape="poly" coords="345,69,345,75,340,83,343,92,342,105,345,108,338,117,340,123,343,124,343,128,346,133,346,136,356,143,358,139,362,135,359,133,361,126,364,122,362,120,362,115,368,110,373,108,379,106,379,99,375,96,378,92,383,91,384,87,385,85,385,73,381,74,372,72,370,70,366,69,362,71,357,70,352,73" onmousemove="afficher('info2')" onmouseout="masquer('info2')"/>
<area shape="poly" coords="310,298,307,301,309,304,309,309,312,308,316,312,319,317,319,321,322,321,324,315,328,314,329,311,335,311,337,314,337,318,341,322,346,323,354,324,356,321,360,325,364,326,368,330,373,329,373,320,371,314,372,311,380,307,380,300,370,297,369,292,365,283,361,290,355,287,345,287,339,283,336,280,330,285,327,286,325,284,321,288,323,294,318,298,313,298,309,299,308,301" onmousemove="afficher('info3')" onmouseout="masquer('info3')"/>
<area shape="poly" coords="516,417,511,421,507,427,499,427,496,426,490,426,491,431,488,434,483,428,476,444,465,445,462,449,459,449,459,459,463,463,463,466,469,470,475,469,482,475,486,468,493,467,497,470,500,465,508,467,510,461,517,457,511,453,509,447,510,439,514,433,517,428" onmousemove="afficher('info4')" onmouseout="masquer('info4')"/>
<area shape="poly" coords="503,385,500,384,499,388,492,389,495,394,494,402,489,402,482,403,475,404,476,407,470,410,471,414,460,418,461,421,463,424,454,430,456,433,459,433,464,436,465,440,471,440,469,436,473,430,482,423,487,425,496,421,501,423,505,423,508,417,511,416,517,409,521,407,521,400,511,400,508,390,505,384,500,384" onmousemove="afficher('info5')" onmouseout="masquer('info5')"/>
<area shape="poly" coords="519,432,517,434,515,438,513,441,514,446,515,450,525,458,522,462,518,462,513,463,513,466,513,469,517,470,518,475,522,477,524,483,532,481,532,473,538,472,541,469,547,469,547,465,548,464,548,460,550,457,551,453,555,451,557,447,555,441,539,446,531,440,522,439,522,435,519,433" onmousemove="afficher('info6')" onmouseout="masquer('info6')"/>
<area shape="poly" coords="417,373,419,375,418,383,424,398,419,407,419,417,414,422,415,432,417,436,414,437,407,434,404,436,400,435,397,439,393,434,389,435,389,430,386,428,386,424,382,419,380,411,387,403,393,404,396,399,400,399,400,393,403,392,403,387,407,383,408,380,413,378,416,374" onmousemove="afficher('info7')" onmouseout="masquer('info7')"/>
<area shape="poly" coords="406,65,407,71,395,76,389,73,391,80,388,82,389,88,383,98,382,107,387,106,391,111,397,114,405,114,408,116,419,116,421,110,424,106,420,102,423,95,429,94,431,94,430,90,423,89,420,86,413,86,412,75,409,73,410,65,407,64" onmousemove="afficher('info8')" onmouseout="masquer('info8')"/>
<area shape="poly" coords="238,535,238,527,246,525,245,518,246,516,249,516,254,519,261,519,261,515,258,513,262,511,269,510,271,508,277,509,278,513,289,517,289,531,285,532,282,535,288,542,295,543,298,544,293,545,288,547,280,551,278,547,266,546,261,541,253,541,250,537,239,536" onmousemove="afficher('info9')" onmouseout="masquer('info9')"/>
<area shape="poly" coords="359,162,355,173,359,174,365,181,365,188,371,188,374,192,375,197,378,202,384,202,389,199,400,201,402,196,410,197,407,193,414,189,414,178,410,177,407,170,408,165,397,167,392,160,391,155,388,155,382,161,378,159,371,165,365,166,360,162" onmousemove="afficher('info10')" onmouseout="masquer('info10')"/>
<area shape="poly" coords="340,532,333,527,325,530,326,532,306,532,305,541,302,543,298,537,291,538,287,535,294,534,291,514,281,510,280,507,286,499,292,499,303,501,304,496,317,498,315,502,326,510,331,509,333,505,345,512,344,515,337,513,334,517,337,522,340,523,340,531" onmousemove="afficher('info11')" onmouseout="masquer('info11')"/>
<area shape="poly" coords="287,429,289,434,290,439,292,448,298,445,302,445,311,450,316,454,324,473,327,475,331,473,339,478,343,477,341,468,345,466,349,468,350,464,353,463,356,460,350,456,353,450,346,446,343,442,344,430,340,427,339,423,333,414,333,408,329,404,326,401,323,403,318,418,304,419,301,425,294,424,288,429" onmousemove="afficher('info12')" onmouseout="masquer('info12')"/>
<area shape="poly" coords="401,491,412,484,408,480,410,478,417,478,418,466,423,464,431,466,438,476,446,475,454,479,463,479,469,476,463,482,466,492,463,495,464,502,467,504,465,507,455,507,452,497,442,499,437,499,428,492,424,494,425,499,416,498,419,495,416,490,403,491" onmousemove="afficher('info13')" onmouseout="masquer('info13')"/>
<area shape="poly" coords="163,111,163,113,166,117,170,117,173,119,172,122,173,129,170,137,164,141,161,143,163,146,168,144,171,149,178,142,184,143,189,140,193,143,202,143,212,137,224,136,222,131,224,128,220,119,219,109,198,119,188,114,172,111,169,110" onmousemove="afficher('info14')" onmouseout="masquer('info14')"/>
<area shape="poly" coords="302,416,303,408,300,404,298,399,301,395,299,392,304,384,304,379,310,375,310,370,315,373,319,372,319,368,326,372,331,370,335,376,341,376,346,378,353,396,348,399,344,397,338,414,336,406,331,398,327,395,317,401,315,414,309,416,302,415" onmousemove="afficher('info15')" onmouseout="masquer('info15')"/>
<area shape="poly" coords="238,324,231,326,225,325,222,328,218,326,210,327,208,324,203,327,202,331,198,333,197,345,185,344,185,353,192,359,192,372,197,371,202,378,207,378,211,374,212,365,222,359,222,352,229,348,232,343,236,339,238,334,242,331,239,325" onmousemove="afficher('info16')" onmouseout="masquer('info16')"/>
<area shape="poly" coords="159,305,155,308,154,310,150,315,156,324,153,338,149,340,146,341,147,347,150,348,168,363,169,371,178,371,180,373,185,375,184,380,192,385,198,385,199,381,195,375,188,375,185,369,188,365,187,359,182,354,179,342,190,338,194,340,195,330,190,324,183,325,181,321,172,320,168,309,161,309,160,306" onmousemove="afficher('info17')" onmouseout="masquer('info17')"/>
<area shape="poly" coords="301,228,307,234,305,239,301,241,300,248,295,251,290,250,286,256,293,256,297,258,297,262,300,265,299,267,302,270,299,276,301,279,299,285,303,289,304,300,308,292,316,295,318,286,324,279,329,280,333,277,337,276,338,263,334,247,330,242,332,236,323,238,318,230,312,230,304,226" onmousemove="afficher('info18')" onmouseout="masquer('info18')"/>
<area shape="poly" coords="316,350,310,351,306,353,300,349,294,349,289,351,285,354,282,352,277,357,274,360,269,359,266,362,262,366,263,369,259,374,261,378,261,382,262,384,267,383,267,392,274,390,279,391,283,398,288,395,296,396,295,390,301,387,299,381,301,375,306,373,307,365,315,370,313,361,312,354,315,351" onmousemove="afficher('info19')" onmouseout="masquer('info19')"/>
<area shape="poly" coords="533,510,534,530,526,529,521,531,519,534,514,535,509,542,505,541,502,547,500,551,502,558,505,561,500,565,504,570,507,572,505,577,504,584,512,583,513,587,510,593,519,595,515,604,529,611,535,615,537,615,536,608,541,600,543,585,542,576,547,568,548,558,545,552,545,538,538,533,540,526,540,519,537,510" onmousemove="afficher('info20')" onmouseout="masquer('info20')"/>
<area shape="poly" coords="412,199,406,199,401,204,395,204,394,207,398,212,388,235,388,240,389,246,393,248,394,255,396,258,401,258,407,263,409,266,414,268,424,263,436,263,437,259,441,255,444,249,446,243,445,238,440,233,444,226,435,226,432,225,432,222,423,221,418,215,420,210" onmousemove="afficher('info21')" onmouseout="masquer('info21')"/>
<area shape="poly" coords="56,140,53,151,56,154,56,162,55,166,56,177,61,179,64,178,68,181,74,177,79,179,84,180,88,185,90,183,93,187,98,181,104,180,107,185,111,177,118,172,121,175,122,164,123,162,118,157,112,158,105,153,92,162,88,164,87,159,84,156,84,151,80,146,80,144,76,139,67,142,57,140" onmousemove="afficher('info22')" onmouseout="masquer('info22')"/>
<area shape="poly" coords="271,303,269,308,269,310,267,317,270,317,273,325,273,333,276,332,279,335,277,339,283,336,289,343,291,347,294,343,304,346,307,350,311,347,308,340,316,336,319,329,315,325,315,318,310,312,306,310,306,304,298,306,285,302,282,307,275,307,272,304" onmousemove="afficher('info23')" onmouseout="masquer('info23')"/>
<area shape="poly" coords="234,351,227,354,226,360,216,366,215,376,208,381,203,383,206,386,202,401,206,402,213,399,217,403,215,406,219,411,219,414,226,411,233,412,240,411,243,416,250,415,251,417,253,411,258,411,257,406,263,403,265,400,263,397,264,388,259,386,255,376,259,370,256,367,251,367,250,362,246,357,236,360,234,352" onmousemove="afficher('info24')" onmouseout="masquer('info24')"/>
<area shape="poly" coords="510,230,500,225,496,227,497,229,490,230,486,228,476,239,468,242,460,246,462,249,462,260,471,260,471,268,481,273,481,279,479,283,484,281,489,276,488,263,499,258,499,252,505,251,509,244,509,240,512,238,505,236,510,232" onmousemove="afficher('info25')" onmouseout="masquer('info25')"/>
<area shape="poly" coords="421,374,421,381,427,396,422,409,422,420,418,424,419,429,422,436,427,428,431,426,436,432,435,437,441,433,441,441,450,442,455,447,459,443,462,440,450,436,448,430,450,427,450,424,460,422,458,414,462,411,457,408,450,408,451,391,435,389,436,377,428,374,421,375" onmousemove="afficher('info26')" onmouseout="masquer('info26')"/>
<area shape="poly" coords="223,108,224,112,227,116,227,132,228,141,233,141,241,147,244,153,256,149,263,149,266,144,270,142,268,133,276,128,283,115,283,112,269,108,263,116,257,116,251,121,245,119,242,115,243,111,236,111,230,107,223,109" onmousemove="afficher('info27')" onmouseout="masquer('info27')"/>
<area shape="poly" coords="273,143,268,149,267,154,255,153,243,158,245,161,249,165,249,176,242,181,244,189,249,191,254,192,260,202,267,201,272,196,276,193,284,195,289,191,290,186,290,176,289,174,283,173,275,158" onmousemove="afficher('info28')" onmouseout="masquer('info28')"/>
<area shape="poly" coords="3,163,6,158,4,151,10,152,13,148,20,149,20,146,26,149,30,146,36,146,39,151,43,152,45,147,50,146,50,151,51,158,53,176,44,181,47,194,57,197,50,204,37,203,34,194,31,198,25,196,18,200,18,195,12,187,6,185,22,183,23,179,20,174,13,171,16,170,26,170,17,161,4,163" onmousemove="afficher('info29')" onmouseout="masquer('info29')"/>
<area shape="poly" coords="356,450,354,454,360,454,361,460,360,464,366,466,371,459,378,459,378,465,385,466,395,474,397,483,394,487,395,492,398,492,400,486,404,484,407,475,413,475,415,466,423,461,423,457,416,451,416,446,409,439,406,442,402,441,398,443,390,439,387,438,386,434,384,434,386,442,384,450,381,453,371,452,363,455,357,451" onmousemove="afficher('info30')" onmouseout="masquer('info30')"/>
<area shape="poly" coords="219,542,219,533,224,532,227,527,228,523,223,517,220,513,225,510,229,502,234,499,246,502,250,490,256,486,250,479,248,478,245,475,251,472,255,476,260,474,262,469,270,468,273,473,276,479,276,484,285,491,288,494,282,495,282,497,278,503,275,505,266,502,258,502,257,508,253,512,242,515,243,523,237,524,234,530,227,530,227,541,218,542" onmousemove="afficher('info31')" onmouseout="masquer('info31')"/>
<area shape="poly" coords="197,462,189,463,191,467,187,481,191,484,195,480,200,483,202,487,206,494,212,497,228,501,231,495,243,496,246,488,251,487,243,475,237,472,239,466,232,464,233,458,224,455,219,459,210,458,204,460,203,465,198,466,196,463" onmousemove="afficher('info32')" onmouseout="masquer('info32')"/>
<area shape="poly" coords="170,373,172,386,170,389,168,390,164,371,151,358,145,405,153,410,153,413,146,415,143,424,148,421,152,420,155,426,161,427,168,424,173,427,172,429,178,433,183,439,186,444,188,439,194,440,194,434,198,433,196,428,205,417,203,411,209,408,200,406,198,401,199,397,201,390,195,389,188,389,182,383,180,376,177,375,170,372" onmousemove="afficher('info33')" onmouseout="masquer('info33')"/>
<area shape="poly" coords="393,482,386,486,360,505,355,505,347,510,338,504,334,500,328,504,318,502,321,498,326,494,326,491,323,488,324,483,329,486,337,481,345,480,345,473,354,473,353,469,357,466,365,471,370,467,374,462,377,470,382,469,386,473,392,475" onmousemove="afficher('info34')" onmouseout="masquer('info34')"/>
<area shape="poly" coords="123,154,127,163,125,179,118,180,112,186,110,194,115,196,118,200,117,203,120,205,117,215,121,213,133,213,135,209,139,208,142,206,151,209,155,196,160,195,159,190,158,183,157,179,160,173,159,166,154,165,149,170,145,169,142,165,140,159,128,158,124,154" onmousemove="afficher('info35')" onmouseout="masquer('info35')"/>
<area shape="poly" coords="298,300,298,286,292,281,295,272,293,261,282,258,281,252,278,248,268,253,267,259,260,267,257,264,251,280,246,286,248,291,255,292,261,302,267,305,272,299,279,302,282,297,299,300" onmousemove="afficher('info36')" onmouseout="masquer('info36')"/>
<area shape="poly" coords="245,278,236,263,230,260,227,264,220,267,220,261,208,253,213,241,215,234,217,228,224,229,228,224,235,221,241,221,241,225,247,227,251,230,252,247,259,250,262,256,258,262,250,262,247,273,247,280" onmousemove="afficher('info37')" onmouseout="masquer('info37')"/>
<area shape="poly" coords="445,337,458,356,461,366,472,368,474,363,479,364,481,368,479,373,482,383,486,384,484,391,490,392,493,396,476,399,466,408,453,404,454,385,448,388,439,385,439,374,430,368,422,371,420,369,421,364,428,361,424,357,434,354,437,346,443,344,445,339" onmousemove="afficher('info38')" onmouseout="masquer('info38')"/>
<area shape="poly" coords="448,245,448,252,445,259,440,262,440,266,448,271,448,275,445,277,447,283,447,290,445,292,448,296,445,301,449,304,451,308,456,302,462,307,474,300,473,292,472,288,473,281,477,277,477,274,469,272,469,264,457,262,460,253,456,247,451,247,449,246" onmousemove="afficher('info39')" onmouseout="masquer('info39')"/>
<area shape="poly" coords="142,429,150,424,150,430,162,432,167,429,170,434,181,445,190,447,196,450,199,451,200,458,187,461,183,482,146,485,142,483,135,485,128,485,135,467,141,430" onmousemove="afficher('info40')" onmouseout="masquer('info40')"/>
<area shape="poly" coords="245,193,244,196,244,208,242,209,235,218,246,219,254,226,255,244,262,245,265,250,273,247,279,246,288,251,289,246,296,245,299,238,301,235,297,228,300,223,288,223,281,226,278,221,272,217,270,204,259,205,254,198,248,197,244,194" onmousemove="afficher('info41')" onmouseout="masquer('info41')"/>
<area shape="poly" coords="375,315,376,333,371,334,374,336,372,343,377,350,381,355,384,361,382,368,387,370,391,366,402,369,409,376,412,371,416,365,411,365,410,359,405,358,398,352,398,347,397,343,398,339,395,333,395,327,395,321,381,321,374,316" onmousemove="afficher('info42')" onmouseout="masquer('info42')"/>
<area shape="poly" coords="397,374,397,372,391,369,386,375,374,373,363,373,362,371,352,370,346,373,349,374,353,385,357,386,355,390,361,406,365,405,367,399,379,408,385,402,392,400,393,395,396,394,397,390,399,389,399,385,403,381,403,378,396,377,396,373" onmousemove="afficher('info43')" onmouseout="masquer('info43')"/>
<area shape="poly" coords="94,241,95,234,98,231,107,230,117,226,117,219,119,216,135,217,139,213,145,209,150,214,156,222,153,227,153,231,160,231,162,237,150,237,145,241,148,246,152,247,149,251,147,256,143,259,139,257,133,261,136,268,132,268,129,263,122,262,110,251,111,245,112,243,116,238,108,239,104,241,100,238,96,241" onmousemove="afficher('info44')" onmouseout="masquer('info44')"/>
<area shape="poly" coords="310,182,303,181,294,183,293,189,292,192,288,196,281,199,278,198,276,199,276,213,284,222,291,219,302,219,308,225,315,225,323,231,327,228,333,228,332,222,326,214,334,213,338,210,333,207,340,201,338,198,334,191,328,195,309,195,309,189,313,188,314,185,309,182" onmousemove="afficher('info45')" onmouseout="masquer('info45')"/>
<area shape="poly" coords="269,394,267,395,269,399,264,409,258,418,255,417,251,427,247,427,248,431,253,431,254,437,258,439,261,442,264,442,268,438,286,436,283,428,292,421,299,421,296,414,299,409,296,406,296,397,282,404,278,397,277,394" onmousemove="afficher('info46')" onmouseout="masquer('info46')"/>
<area shape="poly" coords="207,412,212,412,214,418,221,420,225,417,229,416,237,417,237,421,246,421,244,428,246,433,239,432,237,446,232,453,218,452,216,456,203,455,207,449,194,446,200,442,203,435,200,429,212,416,207,413" onmousemove="afficher('info47')" onmouseout="masquer('info47')"/>
<area shape="poly" coords="354,398,358,409,365,409,369,406,374,408,378,411,379,417,379,423,383,424,382,428,377,432,380,436,380,446,376,449,371,445,368,445,367,448,362,450,358,445,354,444,351,444,348,441,347,430,345,427,345,422,341,415,345,403,349,406,353,398" onmousemove="afficher('info48')" onmouseout="masquer('info48')"/>
<area shape="poly" coords="153,212,160,223,157,227,163,228,166,234,165,237,161,240,150,241,148,242,154,244,154,250,154,254,158,258,159,261,169,260,178,262,179,256,197,256,205,251,207,242,210,240,210,232,214,230,200,222,188,220,188,216,183,215,177,218,171,217,167,214,162,216,154,213" onmousemove="afficher('info49')" onmouseout="masquer('info49')"/>
<area shape="poly" coords="132,87,132,105,138,112,140,116,141,127,144,133,143,141,141,144,144,150,149,153,150,157,145,159,147,164,157,160,163,162,168,162,172,161,174,154,166,151,160,149,157,144,163,139,161,132,165,132,167,122,158,115,159,111,157,107,157,103,152,97,154,90,146,89,140,93,132,88" onmousemove="afficher('info50')" onmouseout="masquer('info50')"/>
<area shape="poly" coords="375,110,374,114,367,114,365,116,364,118,370,123,369,126,364,128,363,131,367,135,363,140,360,144,355,149,357,157,367,162,373,157,380,157,387,151,394,151,395,159,398,163,405,161,411,162,415,159,415,154,420,153,414,147,418,138,421,134,417,131,419,126,417,121,411,121,406,121,401,118,396,118,383,111,378,114,375,111" onmousemove="afficher('info51')" onmouseout="masquer('info51')"/>
<area shape="poly" coords="418,157,418,162,410,166,412,173,418,176,418,193,412,195,426,212,424,213,426,219,432,218,437,223,441,221,441,217,443,216,450,217,452,216,451,211,454,207,459,203,454,201,456,198,451,194,450,184,440,177,438,170,422,162,418,158" onmousemove="afficher('info52')" onmouseout="masquer('info52')"/>
<area shape="poly" coords="162,167,164,171,164,177,161,180,162,190,165,193,164,200,157,200,155,209,162,209,163,211,168,211,174,214,178,213,182,211,186,213,187,206,185,203,190,202,189,196,194,192,194,187,198,185,198,176,202,173,199,166,193,169,186,169,179,171,174,172,172,172,169,167,163,167" onmousemove="afficher('info53')" onmouseout="masquer('info53')"/>
<area shape="poly" coords="441,101,442,105,449,103,453,112,454,118,456,124,458,129,460,138,456,155,459,158,456,163,462,164,464,171,470,171,472,168,489,167,490,162,496,167,501,166,505,162,510,161,505,156,498,156,480,147,474,139,464,136,463,133,461,130,460,125,462,122,461,117,461,115,458,110,458,102,452,99,442,100" onmousemove="afficher('info54')" onmouseout="masquer('info54')"/>
<area shape="poly" coords="436,97,432,100,427,97,425,100,427,103,423,118,421,120,423,130,424,132,424,139,420,142,420,145,423,151,424,156,444,170,447,167,453,165,450,160,451,150,455,141,452,138,455,132,454,129,449,119,450,112,449,107,439,111,436,99" onmousemove="afficher('info55')" onmouseout="masquer('info55')"/>
<area shape="poly" coords="47,182,49,189,62,193,61,202,54,205,57,209,61,208,68,218,75,216,83,216,87,220,86,225,94,224,99,226,105,227,112,223,112,216,110,211,114,208,111,204,112,199,105,198,105,193,108,190,100,186,96,191,88,188,74,182,68,187,63,183,55,181,47,183" onmousemove="afficher('info56')" onmouseout="masquer('info56')"/>
<area shape="poly" coords="463,103,462,107,467,117,466,130,470,132,477,136,482,143,501,151,506,152,514,157,518,152,517,148,518,144,515,143,510,146,501,136,504,130,506,127,510,124,516,128,523,131,527,129,529,130,530,125,524,119,520,123,507,123,503,119,494,121,488,112,485,106,480,103,470,101,467,105,463,104" onmousemove="afficher('info57')" onmouseout="masquer('info57')"/>
<area shape="poly" coords="334,231,337,238,335,243,338,246,343,264,342,281,347,285,351,281,353,285,356,283,359,285,364,278,374,280,380,277,381,270,379,265,383,257,388,253,385,246,371,242,361,237,349,236,335,231" onmousemove="afficher('info58')" onmouseout="masquer('info58')"/>
<area shape="poly" coords="314,2,300,7,306,18,312,20,312,24,313,27,324,29,329,27,330,32,328,33,336,37,340,42,339,47,341,53,344,56,342,67,364,65,381,68,382,66,380,60,383,54,378,50,368,50,361,52,361,43,358,41,350,40,344,38,343,26,338,23,330,27,323,25,318,19,316,15,317,11,318,7,315,3" onmousemove="afficher('info59')" onmouseout="masquer('info59')"/>
<area shape="poly" coords="284,89,284,100,287,103,284,109,287,119,284,122,291,123,297,119,302,124,308,123,319,128,321,128,324,129,328,128,338,129,338,124,333,125,333,121,335,119,333,115,338,112,341,106,340,97,340,92,330,91,324,98,317,97,312,97,309,92,299,92,292,92,290,91,285,89" onmousemove="afficher('info60')" onmouseout="masquer('info60')"/>
<area shape="poly" coords="174,168,172,166,177,161,177,153,174,150,179,147,184,147,189,144,192,147,196,147,200,148,212,141,222,141,226,146,231,146,238,152,237,155,242,160,244,166,246,167,246,173,238,177,240,186,237,180,230,182,225,177,225,171,222,167,213,167,208,173,205,173,205,169,200,161,194,161,192,164,187,163,182,167,177,165" onmousemove="afficher('info61')" onmouseout="masquer('info61')"/>
<area shape="poly" coords="297,8,292,9,287,9,277,15,277,44,280,47,285,46,293,49,299,56,311,55,315,56,316,59,315,61,320,63,323,60,329,65,333,67,338,66,332,64,334,60,339,60,341,56,335,55,337,51,334,46,336,43,334,40,327,39,325,33,311,30,307,28,297,9" onmousemove="afficher('info62')" onmouseout="masquer('info62')"/>
<area shape="poly" coords="333,316,325,320,323,324,318,324,322,329,322,334,313,341,318,347,318,350,316,356,319,363,322,364,326,366,332,368,335,369,339,374,342,370,346,369,351,365,356,366,361,365,365,368,370,367,372,370,375,367,381,363,380,358,373,354,372,348,369,344,369,337,370,336,366,332,362,330,357,330,356,328,341,327,334,323,334,317" onmousemove="afficher('info63')" onmouseout="masquer('info63')"/>
<area shape="poly" coords="127,488,116,497,121,497,122,501,126,500,133,502,134,507,131,510,129,515,135,511,137,516,142,516,145,520,150,520,152,523,160,523,163,528,170,534,173,532,176,532,179,532,180,527,181,520,187,518,186,514,193,509,196,499,194,493,195,490,193,485,187,486,180,488,175,487,169,488,165,487,153,487,145,490,141,491,140,488,131,490,128,488" onmousemove="afficher('info64')" onmouseout="masquer('info64')"/>
<area shape="poly" coords="183,531,182,528,185,526,185,520,189,520,189,515,194,512,199,499,197,493,198,491,196,485,200,490,203,490,203,498,206,501,211,500,215,502,224,504,223,507,219,512,219,517,222,520,221,525,224,525,222,529,217,530,217,541,213,541,210,543,205,539,194,542,188,534,183,532" onmousemove="afficher('info65')" onmouseout="masquer('info65')"/>
<area shape="poly" coords="340,535,340,553,346,558,344,559,335,557,329,558,326,562,322,562,321,566,315,566,307,560,298,560,294,564,291,564,290,559,281,557,279,553,284,553,293,549,294,546,304,547,311,543,308,538,308,536,330,536,330,532,333,531" onmousemove="afficher('info66')" onmouseout="masquer('info66')"/>
<area shape="poly" coords="555,128,553,138,548,140,547,146,541,150,540,156,538,165,538,177,534,183,531,177,524,177,521,172,517,171,515,171,514,162,521,157,522,153,521,149,522,144,514,139,511,140,505,134,509,133,510,129,517,132,522,134,525,134,532,136,535,127,538,125,541,127,546,127" onmousemove="afficher('info67')" onmouseout="masquer('info67')"/>
<area shape="poly" coords="518,174,515,184,515,188,512,194,508,196,508,204,507,207,509,208,514,212,514,219,517,220,518,225,521,226,523,230,528,230,531,227,533,223,534,219,532,216,532,203,534,197,535,194,533,192,533,186,529,185,529,180,523,180,518,176" onmousemove="afficher('info68')" onmouseout="masquer('info68')"/>
<area shape="poly" coords="402,311,404,319,401,322,398,321,397,329,401,333,400,337,403,339,402,345,403,348,402,350,409,355,414,355,416,357,414,362,419,361,422,360,418,355,431,351,434,346,430,345,431,341,424,342,424,337,415,334,415,323,417,319,415,317,414,310,409,313,403,312" onmousemove="afficher('info69')" onmouseout="masquer('info69')"/>
<area shape="poly" coords="445,233,448,227,448,223,443,219,456,220,457,213,457,210,461,208,465,203,465,200,471,198,475,203,481,202,485,201,487,206,493,202,502,207,499,209,500,221,496,221,493,227,484,226,473,236,464,238,461,241,457,243,452,244,449,242,447,241,448,237" onmousemove="afficher('info70')" onmouseout="masquer('info70')"/>
<area shape="poly" coords="385,259,388,262,384,266,385,271,388,274,386,276,386,281,372,287,368,284,371,290,372,294,375,295,381,297,383,309,380,313,383,317,386,315,396,317,400,307,410,308,414,308,418,316,421,295,425,291,431,295,435,292,438,296,443,295,441,293,441,291,443,287,443,283,440,279,440,275,442,272,436,268,433,267,427,268,412,272,406,270,405,265,400,262,394,261,391,256,388,256,386,258" onmousemove="afficher('info71')" onmouseout="masquer('info71')"/>
<area shape="poly" coords="218,170,210,176,203,176,201,186,199,190,198,195,194,197,196,203,190,206,191,214,194,216,214,226,217,224,220,227,221,223,226,222,230,219,230,217,238,212,238,206,241,205,241,200,238,196,242,191,238,189,236,186,227,186,222,181,222,171" onmousemove="afficher('info72')" onmouseout="masquer('info72')"/>
<area shape="poly" coords="465,338,465,345,462,347,461,352,463,359,469,363,470,357,476,358,480,360,487,366,485,371,483,372,487,378,491,380,496,385,498,380,505,381,509,378,515,378,524,371,523,367,525,363,517,353,517,348,512,347,509,343,504,345,503,339,498,337,497,335,491,347,483,347,481,344,474,345,472,341,466,338" onmousemove="afficher('info73')" onmouseout="masquer('info73')"/>
<area shape="poly" coords="504,300,496,300,489,305,486,303,484,306,488,310,480,317,473,318,467,323,468,330,470,337,477,341,480,340,486,344,491,336,495,330,500,330,501,335,508,340,509,336,510,333,517,331,516,325,511,323,511,316,506,313,509,307,505,301" onmousemove="afficher('info74')" onmouseout="masquer('info74')"/>
<area shape="poly" coords="307,143,305,145,304,146,306,147,308,148,309,147,311,146,311,145,310,143" onmousemove="afficher('info75')" onmouseout="masquer('info75')"/>
<area shape="poly" coords="213,101,214,96,219,88,237,81,256,76,266,67,270,68,280,78,283,87,280,89,281,99,282,103,283,106,281,109,275,106,266,106,262,112,256,112,251,116,250,112,245,107,237,107,237,105,234,105,232,102,229,102,226,105,218,105" onmousemove="afficher('info76')" onmouseout="masquer('info76')"/>
<area shape="poly" coords="319,131,321,149,319,154,318,159,317,160,317,166,316,169,318,173,317,176,312,179,312,183,316,184,316,189,316,191,322,191,326,189,331,190,337,185,336,180,340,175,351,176,354,171,353,166,356,160,355,158,355,153,354,150,354,145,351,143,343,135,343,130,341,129,337,132,331,133,326,133" onmousemove="afficher('info77')" onmouseout="masquer('info77')"/>
<area shape="poly" coords="271,133,274,136,273,139,277,145,277,151,278,153,277,158,282,161,284,163,286,170,289,171,290,165,290,163,293,163,294,161,293,159,293,157,298,152,301,150,299,148,300,142,300,141,300,138,297,136,290,137,287,133,280,133,277,131" onmousemove="afficher('info78')" onmouseout="masquer('info78')"/>
<area shape="poly" coords="167,264,168,269,174,274,173,278,176,281,175,284,177,287,177,299,181,303,170,310,173,312,174,316,181,318,184,320,190,322,196,326,198,329,201,324,212,321,208,317,208,314,209,309,205,311,203,308,202,299,201,295,204,289,201,286,204,282,202,278,202,273,202,268,199,264,199,260,197,258,187,260,182,259,180,263,178,265,172,264" onmousemove="afficher('info79')" onmouseout="masquer('info79')"/>
<area shape="poly" coords="268,65,271,65,282,77,285,87,288,87,289,90,295,90,301,90,310,90,313,95,318,95,322,96,328,90,339,90,338,84,338,81,339,79,341,73,342,71,342,70,339,68,334,68,332,71,329,67,325,69,325,65,321,66,313,63,310,66,309,61,310,58,304,58,298,59,295,58,294,55,291,53,288,51,285,48,281,50,278,50,276,48,276,53,280,58,280,62,274,58,269,64" onmousemove="afficher('info80')" onmouseout="masquer('info80')"/>
<area shape="poly" coords="295,448,298,448,303,452,309,452,311,457,314,458,318,471,320,475,324,478,330,477,335,478,333,480,327,482,323,481,320,487,322,490,323,492,318,496,310,495,303,492,301,496,294,496,294,491,290,491,285,486,280,484,281,480,274,468,273,463,276,461,279,458,278,455,284,455,291,450,295,451" onmousemove="afficher('info81')" onmouseout="masquer('info81')"/>
<area shape="poly" coords="241,435,241,439,243,441,243,444,242,446,242,451,235,451,234,454,240,455,240,456,235,462,239,462,241,464,241,468,244,471,248,471,251,470,254,470,256,473,260,471,260,467,263,465,267,465,270,463,269,461,274,460,274,453,276,452,281,452,288,449,287,446,287,444,286,440,281,440,279,440,275,442,272,445,268,445,269,443,264,446,259,445,258,443,254,442,250,439,249,437,244,436" onmousemove="afficher('info82')" onmouseout="masquer('info82')"/>
<area shape="poly" coords="469,473,473,477,467,481,467,484,468,487,468,489,471,494,472,496,466,496,468,498,468,500,470,501,470,505,468,507,467,511,470,512,472,513,472,516,475,518,479,513,486,514,490,511,497,513,498,513,499,510,503,508,505,508,506,506,512,506,512,502,508,501,513,497,513,492,519,491,524,488,522,486,521,483,521,478,518,478,516,476,515,471,512,471,509,468,501,468,497,473,494,470,490,470,488,472,481,477,479,476,475,473,473,472,470,473" onmousemove="afficher('info83')" onmouseout="masquer('info83')" />
<area shape="poly" coords="416,439,419,444,421,451,426,456,426,463,432,465,439,473,448,473,454,476,464,477,466,474,467,473,464,469,458,469,458,466,459,463,459,462,455,459,455,456,457,454,455,453,454,450,451,448,448,444,441,443,438,443,438,439,431,439,432,433,430,431,428,432,428,435,430,439,430,441,427,442,424,444,422,444,422,438,419,438" onmousemove="afficher('info84')" onmouseout="masquer('info84')"/>
<area shape="poly" coords="115,260,110,266,109,270,117,278,117,279,122,292,125,294,131,298,135,298,138,303,143,303,148,308,149,306,152,307,158,303,162,303,163,305,167,304,170,306,178,303,175,303,175,298,175,288,175,286,173,283,173,281,171,278,171,275,168,270,166,269,167,266,163,262,156,262,153,261,150,258,146,261,145,265,143,266,139,266,138,261,136,261,137,266,138,269,137,271,130,271,128,269,126,266,122,265,119,264,118,261" onmousemove="afficher('info85')" onmouseout="masquer('info85')"/>
<area shape="poly" coords="206,253,201,259,201,264,203,264,205,270,205,274,205,278,206,281,204,286,206,288,203,297,205,298,204,303,205,305,206,307,207,305,211,306,211,311,210,315,214,317,213,323,216,324,218,322,221,322,223,324,223,319,226,318,229,322,234,320,234,319,239,319,238,317,239,315,243,311,248,310,248,306,252,304,257,304,257,302,254,297,249,297,243,291,243,283,240,280,240,276,235,271,235,266,231,264,231,268,226,269,216,269,216,262,212,261,212,257,207,257" onmousemove="afficher('info86')" onmouseout="masquer('info86')"/>
<area shape="poly" coords="264,306,253,306,249,308,248,312,244,312,241,316,241,327,244,327,245,334,240,335,240,340,231,348,237,349,239,351,238,355,242,353,249,353,251,358,255,358,256,361,256,363,259,364,260,362,263,362,267,358,273,357,275,356,278,354,281,352,283,350,287,351,286,345,281,341,274,341,273,339,275,335,270,334,271,326,267,319,264,318,265,312,266,310,267,307,265,306" onmousemove="afficher('info87')" onmouseout="masquer('info87')"/>
<area shape="poly" coords="442,174,443,172,446,172,446,170,450,169,454,167,458,165,459,165,460,168,460,171,463,173,466,174,473,174,475,171,478,171,482,171,487,170,490,169,493,169,503,169,509,164,513,163,512,166,513,173,516,175,512,184,513,188,510,192,507,195,507,204,504,206,494,199,490,203,486,198,480,198,478,200,475,199,475,195,470,194,467,198,464,197,461,200,460,199,458,195,454,193,453,188,456,184,456,182,453,182,452,179,449,179,447,175" onmousemove="afficher('info88')" onmouseout="masquer('info88')"/>
<area shape="poly" coords="335,188,339,192,340,194,343,199,343,205,339,209,338,215,336,217,330,217,335,222,336,228,338,228,340,226,344,227,346,229,353,232,356,231,358,231,358,228,361,230,365,232,364,234,368,234,372,238,374,238,375,235,377,238,381,239,381,242,384,241,383,238,385,235,385,230,391,219,392,216,394,214,394,212,390,210,391,206,389,204,387,206,377,206,371,198,371,194,369,192,365,192,361,189,361,182,357,178,354,176,348,177,342,177,340,180,341,183,339,185,336,188" onmousemove="afficher('info89')" onmouseout="masquer('info89')"/>
<area shape="poly" coords="502,210,502,222,513,228,517,226,515,225,516,222,511,222,511,218,513,216,512,212,509,209,505,208" onmousemove="afficher('info90')" onmouseout="masquer('info90')"/>
<area shape="poly" coords="302,152,300,153,299,156,296,157,296,161,297,162,295,165,292,165,291,171,292,172,293,181,298,181,302,177,305,179,310,179,310,177,315,174,314,173,314,165,315,164,313,161,315,158,316,157,316,154,312,154,305,155,301,152" onmousemove="afficher('info91')" onmouseout="masquer('info91')"/>
<area shape="poly" coords="305,139,302,141,301,144,301,148,303,150,304,152,306,153,307,150,305,148,303,147,302,146,304,144,307,142,307,141,307,139" onmousemove="afficher('info92')" onmouseout="masquer('info92')"/>
<area shape="poly" coords="307,138,308,142,310,142,312,145,315,145,318,148,318,141,317,140,317,136,315,138,313,139,308,138" onmousemove="afficher('info93')" onmouseout="masquer('info93')"/>
<area shape="poly" coords="307,148,307,152,309,152,311,153,317,154,318,152,317,149,314,146,312,146,312,148" onmousemove="afficher('info94')" onmouseout="masquer('info94')"/>
<area shape="poly" coords="281,122,278,129,281,131,288,131,292,135,298,135,302,139,307,137,313,137,317,135,317,131,314,128,308,126,303,126,298,124,294,126,283,126,281,123" onmousemove="afficher('info95')" onmouseout="masquer('info95')"/>
<area shape="poly" coords="266,549,263,554,264,557,265,559,263,561,263,562,266,563,268,561,270,559,272,560,273,558,276,557,277,555,277,553,276,549,266,549" onmousemove="afficher('info96')" onmouseout="masquer('info96')" />
</map>
<br/>
</div>
<div id="paris" style="border:1px solid black;">
<img src="Petite_couronne.png" width="100" height="103" border="0" usemap="#map2" />
<map name="map2">
<area shape="poly" coords="38,84,32,83,27,79,23,75,19,73,16,71,13,69,10,67,9,61,11,57,9,55,9,45,10,43,18,37,21,34,25,30,28,28,33,27,39,28,39,33,35,36,36,39,32,43,29,47,21,48,20,52,22,58,36,62,38,63,38,68,40,75,39,77,40,81,39,84" onmousemove="afficher('info92')" onmouseout="masquer('info92')"/>
<area shape="poly" coords="63,60,56,60,52,59,46,61,40,63,37,62,33,60,26,60,23,59,22,52,22,49,31,49,34,44,36,39,46,40,49,40,52,44,53,46,53,53,55,55,60,54,62,54,63,59" onmousemove="afficher('info75')" onmouseout="masquer('info75')"/>
<area shape="poly" coords="85,64,83,61,76,55,73,51,68,49,65,49,59,51,54,53,52,51,52,46,52,42,48,40,43,40,36,41,36,38,41,33,41,28,39,28,30,28,30,24,36,25,40,23,43,20,47,22,49,25,58,25,61,21,66,20,71,14,76,10,79,13,79,18,84,22,84,29,81,35,81,41,81,47,85,56,85,62,85,64" onmousemove="afficher('info93')" onmouseout="masquer('info93')"/>
<area shape="poly" coords="85,93,83,89,85,84,87,81,87,79,89,75,89,69,86,69,86,65,79,59,75,56,70,52,68,51,61,52,58,53,62,53,64,57,64,61,57,63,51,63,45,65,42,65,40,65,42,75,41,79,47,79,49,83,50,86,56,85,71,84,74,82,75,90,79,90,83,94" onmousemove="afficher('info94')" onmouseout="masquer('info94')"/>
</map>
</div>
<div id="bulletin">
<p><h2><u>Quels pollens pour la Saint-Patrick ?</u></h2></p>
<p><h1>Pour la fête de la Saint-Patrick, les pollens de cyprès seront de sortie surtout dans le sud du pays avec un risque d'allergie maximal tout autour de la Méditerranée.<br/>
En attendant l'arrivée des pollens de bouleau (annoncée pour la fin du mois), il faudra se méfier des pollens d'aulne qui sont de la même famille et gêneront fortement les allergiques sur l'ensemble du territoire avec un risque moyen à localement élevé comme dans plusieurs départements du Nord-Est, du Centre et de l'Est.<br/>
Les noisetiers quant à eux risquent de rater la Saint-Patrick car ils sont en fin de pollinisation avec un risque d'allergie ne dépassant pas le niveau faible tandis que les pollens de frêne gagnent du terrain et envahissent le pays avec des quantités partout en augmentation mais un risque globalement faible. Les pollens de peuplier et de saule seront aussi présents sur l'ensemble du pays mais ils ne sont pas très allergisants et ils gêneront peu les allergiques.<br/>
Les pollens de graminées continuent à gagner du terrain par le sud-ouest avec un risque associé de niveau faible.<br/>
Les averses orageuses et le froid limiteront la dispersion des pollens ces prochains jours mais le retour du beau temps sur toute la France dès lundi fera repartir à la hausse les quantités de pollens.<br/>
Les allergiques devront rester vigilants et bien suivre leurs traitements ou consulter leur médecin en cas de symptômes.
</h1></p>
<p>&nbsp;</p>
<p><h1>Risque d'allergie <sup>*</sup></h1></p>
<p><h1><img src="blanc.PNG" width="10" height="10"/> : nul <img src="vert.PNG" width="10" height="10"/> : très faible <img src="vert_fonce.PNG" width="10" height="10"/> : faible <img src="jaune.PNG" width="10" height="10"/> : moyen <img src="orange.PNG" width="10" height="10"/> : élevé <img src="rouge.PNG" width="10" height="10"/> : très élevé</h1></p>
<p><h1><sup>*</sup> <font size='1'>Le risque d'allergie prévisionnel est établi à partir des quantités de pollens mesurées, des prévisions météorologiques pour les jours à venir, du stade phénologique des végétaux et de l'intensité des symptômes constatés par les médecins chez leurs patients allergiques aux pollens.</font></h1></p>
</div>
<div id="copyright">
<b>© RNSA 2018</b>
</div>
<div id="logo">
<img src="Logo.bmp">
</div>
<div id="info1">
<img src="http://internationalragweedsociety.org/vigilance/d 01.gif">
</div>
<div id="info2">
<img src="http://internationalragweedsociety.org/vigilance/d 02.gif">
</div>
<div id="info3">
<img src="http://internationalragweedsociety.org/vigilance/d 03.gif">
</div>
<div id="info4">
<img src="http://internationalragweedsociety.org/vigilance/d 04.gif">
</div>
<div id="info5">
<img src="http://internationalragweedsociety.org/vigilance/d 05.gif">
</div>
<div id="info6">
<img src="http://internationalragweedsociety.org/vigilance/d 06.gif">
</div>
<div id="info7">
<img src="http://internationalragweedsociety.org/vigilance/d 07.gif">
</div>
<div id="info8">
<img src="http://internationalragweedsociety.org/vigilance/d 08.gif">
</div>
<div id="info9">
<img src="http://internationalragweedsociety.org/vigilance/d 09.gif">
</div>
<div id="info10">
<img src="http://internationalragweedsociety.org/vigilance/d 10.gif">
</div>
<div id="info11">
<img src="http://internationalragweedsociety.org/vigilance/d 11.gif">
</div>
<div id="info12">
<img src="http://internationalragweedsociety.org/vigilance/d 12.gif">
</div>
<div id="info13">
<img src="http://internationalragweedsociety.org/vigilance/d 13.gif">
</div>
<div id="info14">
<img src="http://internationalragweedsociety.org/vigilance/d 14.gif">
</div>
<div id="info15">
<img src="http://internationalragweedsociety.org/vigilance/d 15.gif">
</div>
<div id="info16">
<img src="http://internationalragweedsociety.org/vigilance/d 16.gif">
</div>
<div id="info17">
<img src="http://internationalragweedsociety.org/vigilance/d 17.gif">
</div>
<div id="info18">
<img src="http://internationalragweedsociety.org/vigilance/d 18.gif">
</div>
<div id="info19">
<img src="http://internationalragweedsociety.org/vigilance/d 19.gif">
</div>
<div id="info20">
<img src="http://internationalragweedsociety.org/vigilance/d 20.gif">
</div>
<div id="info21">
<img src="http://internationalragweedsociety.org/vigilance/d 21.gif">
</div>
<div id="info22">
<img src="http://internationalragweedsociety.org/vigilance/d 22.gif">
</div>
<div id="info23">
<img src="http://internationalragweedsociety.org/vigilance/d 23.gif">
</div>
<div id="info24">
<img src="http://internationalragweedsociety.org/vigilance/d 24.gif">
</div>
<div id="info25">
<img src="http://internationalragweedsociety.org/vigilance/d 25.gif">
</div>
<div id="info26">
<img src="http://internationalragweedsociety.org/vigilance/d 26.gif">
</div>
<div id="info27">
<img src="http://internationalragweedsociety.org/vigilance/d 27.gif">
</div>
<div id="info28">
<img src="http://internationalragweedsociety.org/vigilance/d 28.gif">
</div>
<div id="info29">
<img src="http://internationalragweedsociety.org/vigilance/d 29.gif">
</div>
<div id="info30">
<img src="http://internationalragweedsociety.org/vigilance/d 30.gif">
</div>
<div id="info31">
<img src="http://internationalragweedsociety.org/vigilance/d 31.gif">
</div>
<div id="info32">
<img src="http://internationalragweedsociety.org/vigilance/d 32.gif">
</div>
<div id="info33">
<img src="http://internationalragweedsociety.org/vigilance/d 33.gif">
</div>
<div id="info34">
<img src="http://internationalragweedsociety.org/vigilance/d 34.gif">
</div>
<div id="info35">
<img src="http://internationalragweedsociety.org/vigilance/d 35.gif">
</div>
<div id="info36">
<img src="http://internationalragweedsociety.org/vigilance/d 36.gif">
</div>
<div id="info37">
<img src="http://internationalragweedsociety.org/vigilance/d 37.gif">
</div>
<div id="info38">
<img src="http://internationalragweedsociety.org/vigilance/d 38.gif">
</div>
<div id="info39">
<img src="http://internationalragweedsociety.org/vigilance/d 39.gif">
</div>
<div id="info40">
<img src="http://internationalragweedsociety.org/vigilance/d 40.gif">
</div>
<div id="info41">
<img src="http://internationalragweedsociety.org/vigilance/d 41.gif">
</div>
<div id="info42">
<img src="http://internationalragweedsociety.org/vigilance/d 42.gif">
</div>
<div id="info43">
<img src="http://internationalragweedsociety.org/vigilance/d 43.gif">
</div>
<div id="info44">
<img src="http://internationalragweedsociety.org/vigilance/d 44.gif">
</div>
<div id="info45">
<img src="http://internationalragweedsociety.org/vigilance/d 45.gif">
</div>
<div id="info46">
<img src="http://internationalragweedsociety.org/vigilance/d 46.gif">
</div>
<div id="info47">
<img src="http://internationalragweedsociety.org/vigilance/d 47.gif">
</div>
<div id="info48">
<img src="http://internationalragweedsociety.org/vigilance/d 48.gif">
</div>
<div id="info49">
<img src="http://internationalragweedsociety.org/vigilance/d 49.gif">
</div>
<div id="info50">
<img src="http://internationalragweedsociety.org/vigilance/d 50.gif">
</div>
<div id="info51">
<img src="http://internationalragweedsociety.org/vigilance/d 51.gif">
</div>
<div id="info52">
<img src="http://internationalragweedsociety.org/vigilance/d 52.gif">
</div>
<div id="info53">
<img src="http://internationalragweedsociety.org/vigilance/d 53.gif">
</div>
<div id="info54">
<img src="http://internationalragweedsociety.org/vigilance/d 54.gif">
</div>
<div id="info55">
<img src="http://internationalragweedsociety.org/vigilance/d 55.gif">
</div>
<div id="info56">
<img src="http://internationalragweedsociety.org/vigilance/d 56.gif">
</div>
<div id="info57">
<img src="http://internationalragweedsociety.org/vigilance/d 57.gif">
</div>
<div id="info58">
<img src="http://internationalragweedsociety.org/vigilance/d 58.gif">
</div>
<div id="info59">
<img src="http://internationalragweedsociety.org/vigilance/d 59.gif">
</div>
<div id="info60">
<img src="http://internationalragweedsociety.org/vigilance/d 60.gif">
</div>
<div id="info61">
<img src="http://internationalragweedsociety.org/vigilance/d 61.gif">
</div>
<div id="info62">
<img src="http://internationalragweedsociety.org/vigilance/d 62.gif">
</div>
<div id="info63">
<img src="http://internationalragweedsociety.org/vigilance/d 63.gif">
</div>
<div id="info64">
<img src="http://internationalragweedsociety.org/vigilance/d 64.gif">
</div>
<div id="info65">
<img src="http://internationalragweedsociety.org/vigilance/d 65.gif">
</div>
<div id="info66">
<img src="http://internationalragweedsociety.org/vigilance/d 66.gif">
</div>
<div id="info67">
<img src="http://internationalragweedsociety.org/vigilance/d 67.gif">
</div>
<div id="info68">
<img src="http://internationalragweedsociety.org/vigilance/d 68.gif">
</div>
<div id="info69">
<img src="http://internationalragweedsociety.org/vigilance/d 69.gif">
</div>
<div id="info70">
<img src="http://internationalragweedsociety.org/vigilance/d 70.gif">
</div>
<div id="info71">
<img src="http://internationalragweedsociety.org/vigilance/d 71.gif">
</div>
<div id="info72">
<img src="http://internationalragweedsociety.org/vigilance/d 72.gif">
</div>
<div id="info73">
<img src="http://internationalragweedsociety.org/vigilance/d 73.gif">
</div>
<div id="info74">
<img src="http://internationalragweedsociety.org/vigilance/d 74.gif">
</div>
<div id="info75">
<img src="http://internationalragweedsociety.org/vigilance/d 75.gif">
</div>
<div id="info76">
<img src="http://internationalragweedsociety.org/vigilance/d 76.gif">
</div>
<div id="info77">
<img src="http://internationalragweedsociety.org/vigilance/d 77.gif">
</div>
<div id="info78">
<img src="http://internationalragweedsociety.org/vigilance/d 78.gif">
</div>
<div id="info79">
<img src="http://internationalragweedsociety.org/vigilance/d 79.gif">
</div>
<div id="info80">
<img src="http://internationalragweedsociety.org/vigilance/d 80.gif">
</div>
<div id="info81">
<img src="http://internationalragweedsociety.org/vigilance/d 81.gif">
</div>
<div id="info82">
<img src="http://internationalragweedsociety.org/vigilance/d 82.gif">
</div>
<div id="info83">
<img src="http://internationalragweedsociety.org/vigilance/d 83.gif">
</div>
<div id="info84">
<img src="http://internationalragweedsociety.org/vigilance/d 84.gif">
</div>
<div id="info85">
<img src="http://internationalragweedsociety.org/vigilance/d 85.gif">
</div>
<div id="info86">
<img src="http://internationalragweedsociety.org/vigilance/d 86.gif">
</div>
<div id="info87">
<img src="http://internationalragweedsociety.org/vigilance/d 87.gif">
</div>
<div id="info88">
<img src="http://internationalragweedsociety.org/vigilance/d 88.gif">
</div>
<div id="info89">
<img src="http://internationalragweedsociety.org/vigilance/d 89.gif">
</div>
<div id="info90">
<img src="http://internationalragweedsociety.org/vigilance/d 90.gif">
</div>
<div id="info91">
<img src="http://internationalragweedsociety.org/vigilance/d 91.gif">
</div>
<div id="info92">
<img src="http://internationalragweedsociety.org/vigilance/d 92.gif">
</div>
<div id="info93">
<img src="http://internationalragweedsociety.org/vigilance/d 93.gif">
</div>
<div id="info94">
<img src="http://internationalragweedsociety.org/vigilance/d 94.gif">
</div>
<div id="info95">
<img src="http://internationalragweedsociety.org/vigilance/d 95.gif">
</div>
<div id="info96">
<img src="http://internationalragweedsociety.org/vigilance/d 99.gif">
</div>
</body>
</html>

213
lua/xml2lua.lua Normal file
View File

@@ -0,0 +1,213 @@
--- @module Module providing a non-validating XML stream parser in Lua.
--
-- Features:
-- =========
--
-- * Tokenises well-formed XML (relatively robustly)
-- * Flexible handler based event API (see below)
-- * Parses all XML Infoset elements - ie.
-- - Tags
-- - Text
-- - Comments
-- - CDATA
-- - XML Decl
-- - Processing Instructions
-- - DOCTYPE declarations
-- * Provides limited well-formedness checking
-- (checks for basic syntax & balanced tags only)
-- * Flexible whitespace handling (selectable)
-- * Entity Handling (selectable)
--
-- Limitations:
-- ============
--
-- * Non-validating
-- * No charset handling
-- * No namespace support
-- * Shallow well-formedness checking only (fails
-- to detect most semantic errors)
--
-- API:
-- ====
--
-- The parser provides a partially object-oriented API with
-- functionality split into tokeniser and handler components.
--
-- The handler instance is passed to the tokeniser and receives
-- callbacks for each XML element processed (if a suitable handler
-- function is defined). The API is conceptually similar to the
-- SAX API but implemented differently.
--
-- XML data is passed to the parser instance through the 'parse'
-- method (Note: must be passed a single string currently)
--
-- License:
-- ========
--
-- This code is freely distributable under the terms of the [MIT license](LICENSE).
--
--
--@author Paul Chakravarti (paulc@passtheaardvark.com)
--@author Manoel Campos da Silva Filho
local xml2lua = {}
local XmlParser = require("XmlParser")
---Recursivelly prints a table in an easy-to-ready format
--@param tb The table to be printed
--@param level the indentation level to start with
local function printableInternal(tb, level)
if tb == nil then
return
end
level = level or 1
local spaces = string.rep(' ', level*2)
for k,v in pairs(tb) do
if type(v) == "table" then
print(spaces .. k)
printableInternal(v, level+1)
else
print(spaces .. k..'='..v)
end
end
end
---Instantiates a XmlParser object to parse a XML string
--@param handler Handler module to be used to convert the XML string
--to another formats. See the available handlers at the handler directory.
-- Usually you get an instance to a handler module using, for instance:
-- local handler = require("xmlhandler/tree").
--@return a XmlParser object used to parse the XML
--@see XmlParser
function xml2lua.parser(handler)
if handler == xml2lua then
error("You must call xml2lua.parse(handler) instead of xml2lua:parse(handler)")
end
local options = {
--Indicates if whitespaces should be striped or not
stripWS = 1,
expandEntities = 1,
errorHandler = function(errMsg, pos)
error(string.format("%s [char=%d]\n", errMsg or "Parse Error", pos))
end
}
return XmlParser.new(handler, options)
end
---Recursivelly prints a table in an easy-to-ready format
--@param tb The table to be printed
function xml2lua.printable(tb)
printableInternal(tb)
end
---Handler to generate a string prepresentation of a table
--Convenience function for printHandler (Does not support recursive tables).
--@param t Table to be parsed
--@return a string representation of the table
function xml2lua.toString(t)
local sep = ''
local res = ''
if type(t) ~= 'table' then
return t
end
for k,v in pairs(t) do
if type(v) == 'table' then
v = xml2lua.toString(v)
end
res = res .. sep .. string.format("%s=%s", k, v)
sep = ','
end
res = '{'..res..'}'
return res
end
--- Loads an XML file from a specified path
-- @param xmlFilePath the path for the XML file to load
-- @return the XML loaded file content
function xml2lua.loadFile(xmlFilePath)
local f, e = io.open(xmlFilePath, "r")
if f then
--Gets the entire file content and stores into a string
return f:read("*a")
end
error(e)
end
---Gets an _attr element from a table that represents the attributes of an XML tag,
--and generates a XML String representing the attibutes to be inserted
--into the openning tag of the XML
--
--@param attrTable table from where the _attr field will be got
--@return a XML String representation of the tag attributes
local function attrToXml(attrTable)
local s = ""
local attrTable = attrTable or {}
for k, v in pairs(attrTable) do
s = s .. " " .. k .. "=" .. '"' .. v .. '"'
end
return s
end
---Gets the first key of a given table
local function getFirstKey(tb)
if type(tb) == "table" then
for k, v in pairs(tb) do
return k
end
return nil
end
return tb
end
---Converts a Lua table to a XML String representation.
--@param tb Table to be converted to XML
--@param tableName Name of the table variable given to this function,
-- to be used as the root tag.
--@param level Only used internally, when the function is called recursively to print indentation
--
--@return a String representing the table content in XML
function xml2lua.toXml(tb, tableName, level)
local level = level or 0
local firstLevel = level
local spaces = string.rep(' ', level*2)
local xmltb = level == 0 and {'<'..tableName..'>'} or {}
for k, v in pairs(tb) do
if type(v) == "table" then
--If the keys of the table are a number, it represents an array
if type(k) == "number" then
local attrs = attrToXml(v._attr)
v._attr = nil
table.insert(xmltb,
spaces..'<'..tableName..attrs..'>\n'..xml2lua.toXml(v, tableName, level+1)..
'\n'..spaces..'</'..tableName..'>')
else
level = level + 1
if type(getFirstKey(v)) == "number" then
table.insert(xmltb, spaces..xml2lua.toXml(v, k, level))
else
table.insert(
xmltb,
spaces..'<'..k..'>\n'.. xml2lua.toXml(v, level+1)..
'\n'..spaces..'</'..k..'>')
end
end
else
table.insert(xmltb, spaces..'<'..k..'>'..tostring(v)..'</'..k..'>')
end
end
if firstLevel == 0 then
table.insert(xmltb, '</'..tableName..'>\n')
end
return table.concat(xmltb, "\n")
end
return xml2lua

136
lua/xmlhandler/dom.lua Normal file
View File

@@ -0,0 +1,136 @@
---- @module Handler to generate a DOM-like node tree structure with
-- a single ROOT node parent - each node is a table comprising
-- the fields below.
--
-- node = { _name = <Element Name>,
-- _type = ROOT|ELEMENT|TEXT|COMMENT|PI|DECL|DTD,
-- _attr = { Node attributes - see callback API },
-- _parent = <Parent Node>
-- _children = { List of child nodes - ROOT/NODE only }
-- }
-- where:
-- - PI = XML Processing Instruction tag.
-- - DECL = XML declaration tag
--
-- The dom structure is capable of representing any valid XML document
--
-- Options
-- =======
-- options.(comment|pi|dtd|decl)Node = bool
-- - Include/exclude given node types
--
-- License:
-- ========
--
-- This code is freely distributable under the terms of the [MIT license](LICENSE).
--
--@author Paul Chakravarti (paulc@passtheaardvark.com)
--@author Manoel Campos da Silva Filho
local dom = {
options = {commentNode=1, piNode=1, dtdNode=1, declNode=1},
current = { _children = {n=0}, _type = "ROOT" },
_stack = {}
}
---Parses a start tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
function dom:starttag(tag)
local node = { _type = 'ELEMENT',
_name = tag.name,
_attr = tag.attrs,
_children = {n=0}
}
if self.root == nil then
self.root = node
end
table.insert(self._stack, node)
table.insert(self.current._children, node)
self.current = node
end
---Parses an end tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
function dom:endtag(tag, s)
--Table representing the containing tag of the current tag
local prev = self._stack[#self._stack]
if tag.name ~= prev._name then
error("XML Error - Unmatched Tag ["..s..":"..tag.name.."]\n")
end
table.remove(self._stack)
self.current = self._stack[#self._stack]
end
---Parses a tag content.
-- @param text text to process
function dom:text(text)
local node = { _type = "TEXT",
_text = text
}
table.insert(self.current._children, node)
end
---Parses a comment tag.
-- @param text comment text
function dom:comment(text)
if self.options.commentNode then
local node = { _type = "COMMENT",
_text = text
}
table.insert(self.current._children, node)
end
end
--- Parses a XML processing instruction (PI) tag
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
function dom:pi(tag)
if self.options.piNode then
local node = { _type = "PI",
_name = tag.name,
_attr = tag.attrs,
}
table.insert(self.current._children, node)
end
end
---Parse the XML declaration line (the line that indicates the XML version).
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
function dom:decl(tag)
if self.options.declNode then
local node = { _type = "DECL",
_name = tag.name,
_attr = tag.attrs,
}
table.insert(self.current._children, node)
end
end
---Parses a DTD tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
function dom:dtd(tag)
if self.options.dtdNode then
local node = { _type = "DTD",
_name = tag.name,
_attr = tag.attrs,
}
table.insert(self.current._children, node)
end
end
---Parses CDATA tag content.
dom.cdata = dom.text
return dom

108
lua/xmlhandler/print.lua Normal file
View File

@@ -0,0 +1,108 @@
---@module Handler to generate a simple event trace which
--outputs messages to the terminal during the XML
--parsing, usually for debugging purposes.
--
-- License:
-- ========
--
-- This code is freely distributable under the terms of the [MIT license](LICENSE).
--
--@author Paul Chakravarti (paulc@passtheaardvark.com)
--@author Manoel Campos da Silva Filho
local print = {}
---Parses a start tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:starttag(tag, s, e)
io.write("Start : "..tag.name.."\n")
if tag.attrs then
for k,v in pairs(tag.attrs) do
io.write(string.format(" + %s='%s'\n", k, v))
end
end
end
---Parses an end tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:endtag(tag, s, e)
io.write("End : "..tag.name.."\n")
end
---Parses a tag content.
-- @param text text to process
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:text(text, s, e)
io.write("Text : "..text.."\n")
end
---Parses CDATA tag content.
-- @param text CDATA content to be processed
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:cdata(text, s, e)
io.write("CDATA : "..text.."\n")
end
---Parses a comment tag.
-- @param text comment text
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:comment(text, s, e)
io.write("Comment : "..text.."\n")
end
---Parses a DTD tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:dtd(tag, s, e)
io.write("DTD : "..tag.name.."\n")
if tag.attrs then
for k,v in pairs(tag.attrs) do
io.write(string.format(" + %s='%s'\n", k, v))
end
end
end
--- Parse a XML processing instructions (PI) tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:pi(tag, s, e)
io.write("PI : "..tag.name.."\n")
if tag.attrs then
for k,v in pairs(tag.attrs) do
io. write(string.format(" + %s='%s'\n",k,v))
end
end
end
---Parse the XML declaration line (the line that indicates the XML version).
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
-- @param s position where the tag starts
-- @param e position where the tag ends
function print:decl(tag, s, e)
io.write("XML Decl : "..tag.name.."\n")
if tag.attrs then
for k,v in pairs(tag.attrs) do
io.write(string.format(" + %s='%s'\n", k, v))
end
end
end
return print

159
lua/xmlhandler/tree.lua Normal file
View File

@@ -0,0 +1,159 @@
local function init()
local obj = {
root = {},
options = {noreduce = {}}
}
obj._stack = {obj.root, n=1}
return obj
end
--- @module XML Tree Handler.
-- Generates a lua table from an XML content string.
-- It is a simplified handler which attempts
-- to generate a more 'natural' table based structure which
-- supports many common XML formats.
--
-- The XML tree structure is mapped directly into a recursive
-- table structure with node names as keys and child elements
-- as either a table of values or directly as a string value
-- for text. Where there is only a single child element this
-- is inserted as a named key - if there are multiple
-- elements these are inserted as a vector (in some cases it
-- may be preferable to always insert elements as a vector
-- which can be specified on a per element basis in the
-- options). Attributes are inserted as a child element with
-- a key of '_attr'.
--
-- Only Tag/Text & CDATA elements are processed - all others
-- are ignored.
--
-- This format has some limitations - primarily
--
-- * Mixed-Content behaves unpredictably - the relationship
-- between text elements and embedded tags is lost and
-- multiple levels of mixed content does not work
-- * If a leaf element has both a text element and attributes
-- then the text must be accessed through a vector (to
-- provide a container for the attribute)
--
-- In general however this format is relatively useful.
--
-- It is much easier to understand by running some test
-- data through 'testxml.lua -simpletree' than to read this)
--
-- Options
-- =======
-- options.noreduce = { <tag> = bool,.. }
-- - Nodes not to reduce children vector even if only
-- one child
--
-- License:
-- ========
--
-- This code is freely distributable under the terms of the [MIT license](LICENSE).
--
--@author Paul Chakravarti (paulc@passtheaardvark.com)
--@author Manoel Campos da Silva Filho
local tree = init()
---Instantiates a new handler object.
--Each instance can handle a single XML.
--By using such a constructor, you can parse
--multiple XML files in the same application.
--@return the handler instance
function tree:new()
local obj = init()
obj.__index = self
setmetatable(obj, self)
return obj
end
--Gets the first key of a table
--@param tb table to get its first key
--@return the table's first key, nil if the table is empty
--or the given parameter if it isn't a table
local function getFirstKey(tb)
if type(tb) == "table" then
for k, v in pairs(tb) do
return k
end
return nil
end
return tb
end
--- Recursively removes redundant vectors for nodes
-- with single child elements
function tree:reduce(node, key, parent)
for k,v in pairs(node) do
if type(v) == 'table' then
self:reduce(v,k,node)
end
end
if #node == 1 and not self.options.noreduce[key] and
node._attr == nil then
parent[key] = node[1]
else
node.n = nil
end
end
---Parses a start tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
function tree:starttag(tag)
local node = {}
if self.parseAttributes == true then
node._attr=tag.attrs
end
--Table in the stack representing the tag being processed
local current = self._stack[#self._stack]
if current[tag.name] then
table.insert(current[tag.name], node)
else
current[tag.name] = {node; n=1}
end
table.insert(self._stack, node)
end
---Parses an end tag.
-- @param tag a {name, attrs} table
-- where name is the name of the tag and attrs
-- is a table containing the atributtes of the tag
function tree:endtag(tag, s)
--Table in the stack representing the tag being processed
local current = self._stack[#self._stack]
--Table in the stack representing the containing tag of the current tag
local prev = self._stack[#self._stack-1]
if not prev[tag.name] then
error("XML Error - Unmatched Tag ["..s..":"..tag.name.."]\n")
end
if prev == self.root then
-- Once parsing complete, recursively reduce tree
self:reduce(prev, nil, nil)
end
local firstKey = getFirstKey(current)
table.remove(self._stack)
end
---Parses a tag content.
-- @param t text to process
function tree:text(text)
local current = self._stack[#self._stack]
table.insert(current, text)
end
---Parses CDATA tag content.
tree.cdata = tree.text
tree.__index = tree
return tree