Script/Algorithm for screens / blinds - reinvent the wheel

Moderator: leecollings

Post Reply
ensingg
Posts: 65
Joined: Saturday 22 April 2017 17:35
Target OS: Windows
Domoticz version:
Contact:

Script/Algorithm for screens / blinds - reinvent the wheel

Post by ensingg »

HI,

I am thinking for a script to control my blinds.
Parameters that could be used in my idea :

difference between inside/outside temperature
outside temp should increase
buienradar sun power watt/m2

But I still don't have the good idea.
How to prevent sudden changes/spikes ? How to see a average increase? can I look at the history data or should I put the data in variables myself.

Anyone like to help me ?

Best regards,
Gert
Jan Jansen
Posts: 229
Joined: Wednesday 30 April 2014 20:27
Target OS: Raspberry Pi / ODroid
Domoticz version: Stable
Location: The Netherlands
Contact:

Re: Script/Algorithm for screens / blinds - reinvent the wheel

Post by Jan Jansen »

ensingg wrote: Thursday 25 June 2020 9:58 HI,

I am thinking for a script to control my blinds.
I try to automate my sun protection by trial and error. I still have some time, our new house is under construction. In my case it concerns several screens, each with a different geographical orientation. A selector switch has been created for each screen with the following buttons (Up = level 10, Stop = level 20 and Down = level 30). There is also a master with the same buttons and a switch that allows the automation to be turned on/off.
From the web I get the following information via Nodered:
Cloud coverage (Integer), Sun azimuth (Integer) and Sun elevation (String), they become user variables ( see:https://www.domoticz.com/forum/viewtopi ... 56#p250856).
After I did the above, I started scripting. I started with DzVents, but at the time it is still a bridge too far. So I fell back on the well-known Blockly.

For me, the following script works.
zonwering.png
zonwering.png (39.15 KiB) Viewed 610 times
The values entered in the script must be set in practice.
The master switch can be triggered to protect all screens against strong winds or to close all the screens against the cold in winter.
Perhaps later solar power in relation to indoor temperature will be added. It will also be necessary (need some help) to avoid unnecessary closing and opening of the screens, for example no more than once every 30 minutes.

Perhaps also interesting for me to include the solar energy in relation to the indoor temperature in the script.

Maybe also interesting for you (https://flows.nodered.org/node/node-red ... n-position)

Regards
User avatar
bewo
Posts: 74
Joined: Monday 13 July 2015 12:27
Target OS: Linux
Domoticz version: 2021.1
Location: Bavaria - Germany
Contact:

Re: Script/Algorithm for screens / blinds - reinvent the wheel

Post by bewo »

Hi ensingg,

Your wishes are no problem. ;-) Maybe this could be a start... My comments are german. Look at the script, if you would give it a try, i'll can translate and adjust it. :P

Code: Select all

-- Dieses Skript sorgt für das automatische Schließen und Öffnen der Rolläden Abends bei Dunkelheit und
-- morgens bei Helligkeit. Beachtet wird hierbei, dass der Stromhauptschalter überhaupt und das WLAN aktiviert ist.
-- Außerdem werden die Rolläden der Schlafräume frühestens um 9:30 Uhr automatisch geöffnet.
-- Die anderen Rolläden frühestens um 6:30 Uhr, jeweils abhängig von der Helligkeit.

-- Stand: 08.09.2019


commandArray = {}

-- Hier werden die jeweiligen Zeiten und Werte gesetzt:

jetzt = os.date("%H") * 60 + os.date("%M")
zeitfenster_schliessen = (timeofday['SunsetInMinutes'] - 30)

-- Zeiten zum Öffnen setzen (nach Sonnenaufgang, aber nicht vor xx Uhr)
sonnenaufgang = timeofday['SunriseInMinutes']
if sonnenaufgang > 370 then
    oeffnungszeit_wohnraum = sonnenaufgang
    else oeffnungszeit_wohnraum = 370 -- bedeutet 6:10 Uhr (370 Minuten des Tages)
end
if sonnenaufgang > 565 then
    oeffnungszeit_schlafraum = sonnenaufgang
    else oeffnungszeit_schlafraum = 565 -- bedeutet 9:30 Uhr (565 Minuten des Tages)
end


-- Hier die einzelnen Rolläden und Werte bestimmen:
--------------------------------------------------------------------------------
Wohnraeume = {
 -- { Aktor = 'Name des Aktors', Wunschlevel = 'Gewünschtes unteres Level', Kontakt = 'Kontaktname', Kontaktart = 'normal (ZU = Closed) oder gedreht (ZU = Open)' },
    { Aktor = 'WZ bei Fernseher' },
    { Aktor = 'WZ Tür Terrasse', Wunschlevel = '60', Kontakt = 'Kontakt Markise', Kontaktart = 'gedreht' },
    { Aktor = 'WZ bei Esstisch' },
    { Aktor = 'WZ Ri. Straße' },
    { Aktor = 'Fenster Gäste-WC' },
    { Aktor = 'Küche Fenster' },
    { Aktor = 'Küche Tür' },
    { Aktor = 'Gang oben' },
    { Aktor = 'Dachfenster Bad' }
}
--------------------------------------------------------------------------------
Schlafraeume = {
    { Aktor = 'Schlafzimmer Rolladen', Wunschlevel = '60' },
    { Aktor = 'Kind1', Wunschlevel = '55' },
    { Aktor = 'Kind2', Wunschlevel = '55' }
}
--------------------------------------------------------------------------------
Alle_Raeume = tabelle_verbinden(Wohnraeume, Schlafraeume)

-- Helligkeitssensor (inkl. Backup)

-- Notwendige Zeitfunktion
function timedifference(timestamp)
  y, m, d, H, M, S = timestamp:match("(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)")
  difference = os.difftime(os.time(), os.time{year=y, month=m, day=d, hour=H, min=M, sec=S})
  return difference
end

Helligkeit = tonumber(otherdevices_svalues['Helligkeitssensor'])
    -- Backup Helligkeitssensor
    if timedifference(otherdevices_lastupdate['Helligkeitssensor']) > 300 then
        Helligkeit = tonumber(otherdevices_svalues['Helligkeitssensor-Backup'])
    end
-- Validierungsvariable
Helligkeit_Validierung = 'Helligkeitsvalidierung'


--------------------------------------------------------------------------------
-- Um im Sommer ein Hochfahren bei wegen starkem Sonnenschein geschlossenen Rolläden zu vermeiden,
-- wird im Obergeschoss auch die Temperatur am Windsender geprüft. Hierfür muss der Temperaturwert
-- aus dem gesamten Datenstring ausgelesen werden:

s1, s2, s3, s4, sTemperatur, s6 = otherdevices_svalues['Windsender Dach']:match("([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);([^;]+)")

--------------------------------------------------------------------------------

if otherdevices['Netz-Versorgung Rolladen'] == 'On' and otherdevices['WLAN (Bayerisch-Irish)'] == 'On' then
        
    -- ## SCHLIEßEN ALLE ###########################################################################
    for Raeume,Alle_Rolladen in pairs(Alle_Raeume) do
        
        -- Level setzen, wenn kein besonderes Wunschlevel gesetzt ist
        if Alle_Rolladen.Wunschlevel == nil then Alle_Rolladen.Wunschlevel = '100' end
        
        -- Richtigen Kontaktstatus auswählen, bzw. setzen, wenn keiner vorhanden
        if Alle_Rolladen.Kontakt then
            -- Situation 1/3: Normaler Kontakt (ZU = Closed)
            if Alle_Rolladen.Kontaktart == 'normal' then
                if otherdevices[Alle_Rolladen.Kontakt] == 'Closed' then
                    Rolladenfahrt = 'Erlaubt'
                else
                    Rolladenfahrt = 'Verboten'
                end
                
            -- Situation 2/3: Gedrehter Kontakt (ZU = Open)
            elseif Alle_Rolladen.Kontaktart == 'gedreht' then
                if otherdevices[Alle_Rolladen.Kontakt] == 'Open' then
                    Rolladenfahrt = 'Erlaubt'
                else
                    Rolladenfahrt = 'Verboten'
                end
            end
        -- Situation 3/3: Gar kein Kontakt (dann ohne Prüfung):
        else
            Rolladenfahrt = 'Erlaubt'
        end
        
        -- Eigentliches Fahren
        if jetzt >= zeitfenster_schliessen and uservariables[Helligkeit_Validierung] == 0 then
            
            if tonumber(otherdevices_svalues[Alle_Rolladen.Aktor]) <= (tonumber(Alle_Rolladen.Wunschlevel) - 25) and
                uservariables['Status_Rolladenautomatik '..Alle_Rolladen.Aktor] == 'geoeffnet' and Rolladenfahrt == 'Erlaubt' then
                    commandArray[Alle_Rolladen.Aktor] = 'Set Level '..Alle_Rolladen.Wunschlevel
                    commandArray['Variable:Status_Rolladenautomatik '..Alle_Rolladen.Aktor] = 'geschlossen'
                    print('Rolladenautomatik -> Rolladen '..Alle_Rolladen.Aktor..' wurde auf Level '..Alle_Rolladen.Wunschlevel..' gesetzt.')
                        
            -- Status setzen, falls schon geschlossen wurde:        
            elseif tonumber(otherdevices_svalues[Alle_Rolladen.Aktor]) > (tonumber(Alle_Rolladen.Wunschlevel) - 30) and
                otherdevices[Alle_Rolladen.Aktor] ~= 'Open' and uservariables['Status_Rolladenautomatik '..Alle_Rolladen.Aktor] == 'geoeffnet' then
                    commandArray['Variable:Status_Rolladenautomatik '..Alle_Rolladen.Aktor] = 'geschlossen'
                    print('Rolladenautomatik -> Rolladen '..Alle_Rolladen.Aktor..' wurde bereits geschlossen. Status aktualisiert.')
            end
            
        -- ## SCHLIEßEN Schlitzstellung der Rolläden Richtung Straße etwas früher ##################
        elseif jetzt >= zeitfenster_schliessen and
            (Alle_Rolladen.Aktor == 'WZ Ri. Straße' or Alle_Rolladen.Aktor == 'Fenster Gäste-WC') and 
            uservariables[Helligkeit_Validierung] <= 5 and uservariables[Helligkeit_Validierung] > 0 then
                if tonumber(otherdevices_svalues[Alle_Rolladen.Aktor]) <= 60 and
                    uservariables['Status_Rolladenautomatik '..Alle_Rolladen.Aktor] == 'geoeffnet' then
                        commandArray[Alle_Rolladen.Aktor] = 'Set Level 75'
                        print('Rolladenautomatik -> Rolladen '..Alle_Rolladen.Aktor..' wurde auf Schlitzstellung gefahren.')
                end
        end
        
    end
    
    
    -- ## ÖFFNEN Wohnräume ####################################################################################
    for Raeume,Wohnraum_Rolladen in pairs(Wohnraeume) do
        
        if Wohnraum_Rolladen.Wunschlevel == nil then Wohnraum_Rolladen.Wunschlevel = '100' end
        
        -- ## Zuerst sanft öffnen (nur falls weit geschlossen) ################
        if jetzt >= oeffnungszeit_wohnraum and jetzt < zeitfenster_schliessen and
            uservariables[Helligkeit_Validierung] > 5 and uservariables['Status_Rolladenautomatik '..Wohnraum_Rolladen.Aktor] == 'geschlossen' then
                if tonumber(otherdevices_svalues[Wohnraum_Rolladen.Aktor]) >= 75 then    
                    Oeffnungswert = tonumber(otherdevices_svalues[Wohnraum_Rolladen.Aktor]) - 35
                        commandArray[Wohnraum_Rolladen.Aktor] = 'Set Level '..Oeffnungswert
                        commandArray['Variable:Status_Rolladenautomatik '..Wohnraum_Rolladen.Aktor] = 'sanft-geoeffnet'
                        print('Rolladenautomatik -> Rolladen '..Wohnraum_Rolladen.Aktor..' wurde auf Level '..Wohnraum_Rolladen.Wunschlevel..' gesetzt.')
                else
                    commandArray['Variable:Status_Rolladenautomatik '..Wohnraum_Rolladen.Aktor] = 'sanft-geoeffnet'
                end
                if uservariables['Status_Rolladenautomatik_Zeit'] ~= jetzt then
                    commandArray['Variable:Status_Rolladenautomatik_Zeit'] = tostring(jetzt)
                end
            
        -- ## ÖFFNEN Wohnräume vollständig ###############################################################
        elseif jetzt >= (uservariables['Status_Rolladenautomatik_Zeit'] + 2) and
            uservariables['Status_Rolladenautomatik '..Wohnraum_Rolladen.Aktor] == 'sanft-geoeffnet' then
                    commandArray[Wohnraum_Rolladen.Aktor] = 'Set Level 0'
                    commandArray['Variable:Status_Rolladenautomatik '..Wohnraum_Rolladen.Aktor] = 'geoeffnet'
                    print('Rolladenautomatik -> Rolladen '..Wohnraum_Rolladen.Aktor..' wurde geöffnet.')
        end
        
    end



    -- ## ÖFFNEN Schlafräume  ###################################################################################
    for Raeume,Schlafraum_Rolladen in pairs(Schlafraeume) do
        
        if Schlafraum_Rolladen.Wunschlevel == nil then Schlafraum_Rolladen.Wunschlevel = '100' end
          
        -- ## Zuerst sanft öffnen (nur falls weit geschlossen) ################
        if jetzt >= oeffnungszeit_schlafraum and uservariables[Helligkeit_Validierung] > 5 and
            tonumber(sTemperatur) < 21 and uservariables['Status_Rolladenautomatik '..Schlafraum_Rolladen.Aktor] == 'geschlossen' then
                if tonumber(otherdevices_svalues[Schlafraum_Rolladen.Aktor]) >= 75 then    
                    Oeffnungswert = tonumber(otherdevices_svalues[Schlafraum_Rolladen.Aktor]) - 35
                        commandArray[Schlafraum_Rolladen.Aktor] = 'Set Level '..Oeffnungswert
                        commandArray['Variable:Status_Rolladenautomatik '..Schlafraum_Rolladen.Aktor] = 'sanft-geoeffnet'
                        print('Rolladenautomatik -> Rolladen '..Schlafraum_Rolladen.Aktor..' wurde auf Level '..Schlafraum_Rolladen.Wunschlevel..' gesetzt.')
                else 
                    commandArray['Variable:Status_Rolladenautomatik '..Schlafraum_Rolladen.Aktor] = 'sanft-geoeffnet'
                end
                if uservariables['Status_Rolladenautomatik_Zeit'] ~= jetzt then
                    commandArray['Variable:Status_Rolladenautomatik_Zeit'] = tostring(jetzt)
                end    
            
        -- ## ÖFFNEN Schlafräume vollständig #############################################################
        elseif jetzt >= (uservariables['Status_Rolladenautomatik_Zeit'] + 2) and tonumber(sTemperatur) < 21 and
            uservariables['Status_Rolladenautomatik '..Schlafraum_Rolladen.Aktor] == 'sanft-geoeffnet' then
                    commandArray[Schlafraum_Rolladen.Aktor] = 'Off'
                    commandArray['Variable:Status_Rolladenautomatik '..Schlafraum_Rolladen.Aktor] = 'geoeffnet'
                    print('Rolladenautomatik -> Rolladen '..Schlafraum_Rolladen.Aktor..' wurde geöffnet.') 
        end
        
    end


end




-- ## Status setzen, falls manuell geöffnet wird ##################################################################
for Raeume,Alle_Rolladen in pairs(Alle_Raeume) do
     
    if jetzt > oeffnungszeit_wohnraum and jetzt < zeitfenster_schliessen and otherdevices[Alle_Rolladen.Aktor] == 'Open' and 
        uservariables['Status_Rolladenautomatik '..Alle_Rolladen.Aktor] ~= 'geoeffnet' then
            commandArray['Variable:Status_Rolladenautomatik '..Alle_Rolladen.Aktor] = 'geoeffnet'
            print('Rolladenautomatik -> Rolladen '..Alle_Rolladen.Aktor..' wurde bereits geöffnet. Status aktualisiert.')
    end
    
end    




-- ################################################################################################################

-- Validierung der Helligkeit
-- Um z.B. ein Schließen aufgrund einer "Dunkelheitsspitze" zu vermeiden (Minute mit mehr Dunkelheit durch Wolke,
-- oder ähnliches) werden die Werte des Helligkeitssensors in einer Nutzervariable validiert:


-- Valideren der leichten Dunkelheit
if Helligkeit < 150 and jetzt > (zeitfenster_schliessen - 60) and
    uservariables[Helligkeit_Validierung] <= 10 and uservariables[Helligkeit_Validierung] > 5 then
        Validierungslevel = 10 - (uservariables[Helligkeit_Validierung] - 1)
        commandArray['Variable:'..Helligkeit_Validierung] = tostring(uservariables[Helligkeit_Validierung] - 1)
        print('Helligkeitssensor -> Validierung '..Validierungslevel..' von 5 für leichte Dunkelheit läuft')
        
-- Valideren der kräftigen Dunkelheit
elseif Helligkeit < 45 and jetzt > (zeitfenster_schliessen - 60) and
    uservariables[Helligkeit_Validierung] <= 5 and uservariables[Helligkeit_Validierung] > 0 then
        Validierungslevel = 5 - (uservariables[Helligkeit_Validierung] - 1)
        commandArray['Variable:'..Helligkeit_Validierung] = tostring(uservariables[Helligkeit_Validierung] - 1)
        print('Helligkeitssensor -> Validierung '..Validierungslevel..' von 5 für kräftige Dunkelheit läuft.')

-- Und Rücklauf bei Helligkeit
elseif Helligkeit > 35 and uservariables[Helligkeit_Validierung] < 10 and jetzt < 700 then
    Validierungslevel = uservariables[Helligkeit_Validierung] + 2
    commandArray['Variable:'..Helligkeit_Validierung] = tostring(Validierungslevel)
    print('Helligkeitssensor -> Validierung '..math.ceil(Validierungslevel / 2)..' von 5 für Helligkeit läuft.')
end




return commandArray

Individual projects:
Domoticz on a Intel Xeon Server | AeonLabs Z-Wave Gen.5 | RFXCOM RFXtrx433E USB | ESP-Wifi-Modules | Shellys
Wall-mounted 22" Touch Control Display (self construct) | LUA wind monitor| LUA heating control | and many many more :)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest