Page 1 sur 1

ghost simulateur de présence copie du VERA

Posté : 11 nov. 2019, 15:10
par jbhallez
Bonjour, je recherche a allumer aléatoirement dès la tombé" de la nuit des ampoules et les éteindre de même à des heures aléatoire durant la nuit jusqu'a une certaine heure... je suis arriver sur cela:
https://community.getvera.com/t/vacatio ... s/177691/3

Quelqu'un peut me l'adapter pour Domoticz Merci beaucoup ! je ne sais pas si il faut le faire en Lua ou Dzventz ou un melange des deux... Je bux a cause des fonctions luup... qui n'existe pas sur Domoticz

Code : Tout sélectionner

-- This scene
-- . needs a virtual switch to know when somebody is home
-- . needs a virtual switch to enable/disable simulation when nobody is home
-- . is triggered 1 hour before sunset, at Vera startup and when virtual switch is turned ON
-- -- -- -- -- https://community.getvera.com/t/vacation-ghosts/177691/3 


local at_home_virtual_switch_device = 122
local ghost_virtual_switch_device = 42
local dry_run = false

local sunset_time = os.date("*t", luup.sunset())
local sunset = sunset_time.hour * 60 + sunset_time.min
luup.log("Sunset is at " .. string.format("%02i:%02i:%02i", sunset_time.hour, sunset_time.min, sunset_time.sec))

local offset_times = 0

local ghost_rules = {
    living_room = {
        switch_devices = { 10, 11 },
        dimmer_devices = { 12 },
        dimmer_level = 33, -- 33%
        start_min = sunset - 10, start_max = sunset + 15, -- start between t-10 and t+15 minutes
        end_min = 22*60, end_max = 23*60 -- end between 10pm & 11pm
    },
    bedside_room1 = {
        switch_devices = { 20 },
        start_min = sunset, start_max = sunset + 30, -- start between t and t+30 minutes
        end_min = 20.5*60, end_max = 21*60, -- end between 8:30pm and 9:00pm
        cycles = true,
        cycles_on_min = 30, cycles_on_max = 3 * 60, -- each cycle should leave light ON for 30 to 3 hours
        cycles_off_min = 5, cycles_off_max = 30 -- each cycle should leave light OFF for 5 to 30 minutes
    },
    ceiling_room1 = {
        switch_devices = { 21 },
        start_min = sunset, start_max = sunset + 30, -- start between t and t+30 minutes
        end_min = 20.5*60, end_max = 21.5*60, -- end between 8:30pm and 9:30pm
        cycles = true,
        cycles_on_min = 30, cycles_on_max = 60, -- each cycle should leave light ON for 30 to 1 hour
        cycles_off_min = 15, cycles_off_max = 60 -- each cycle should leave light OFF for 15 to 60 minutes
    },
    bedside_room2 = {
        switch_devices = { 28 },
        start_min = sunset, start_max = sunset + 30, -- start between t and t+30 minutes
        end_min = 21*60, end_max = 23*60, -- end between 9:00pm and 11:00pm
    }
}

function ghostDeviceIdToName(device_id)
    return luup.devices[device_id].description .. " " .. luup.rooms[luup.devices[device_id].room_num] .. " (#" .. device_id .. ")"
end

function generateGhosts()
    -- Reinitialize ghost list
    if ghosts then
        terminateAllGhosts() -- terminate all current ghosts if any
    end
    ghosts = {}
    sorted_ghosts = {}

    -- Calc ghosts start/end
    luup.log("Generating ghosts...")
    math.randomseed(os.time())
    for rule_name, rule in pairs(ghost_rules) do
        local starts = math.random(rule['start_min'] * 60, rule['start_max'] * 60) + (offset_times * 60)
        local ends = math.random(rule['end_min'] * 60, rule['end_max'] * 60) + (offset_times * 60)

        local ghost_i = 1
        local ghost_starts = starts
        local ghost_ends = ends
        while ghost_starts < ends do
            local ghost_name = rule_name .. " #" .. ghost_i
            if rule['cycles'] then
                ghost_ends = math.min(ghost_starts + math.random(rule['cycles_on_min'] * 60, rule['cycles_on_max'] * 60), ends)
            end
            ghosts["" .. ghost_starts .. "/" .. ghost_name] = { name = ghost_name, rule_name = rule_name, starts = ghost_starts, duration = ghost_ends - ghost_starts }
            if rule['cycles'] then
                ghost_starts = ghost_ends + math.random(rule['cycles_off_min'] * 60, rule['cycles_off_max'] * 60)
            else
                ghost_starts = ghost_ends
            end
            ghost_i = ghost_i + 1
        end
    end

    -- Sort ghosts by start time
    for ghost_id in pairs(ghosts) do
        table.insert(sorted_ghosts, ghost_id)
    end
    table.sort(sorted_ghosts)
end

function wakeGhost(ghost_id)
    if (luup.variable_get("urn:upnp-org:serviceId:VSwitch1", "Status", at_home_virtual_switch_device) == "1") then
        luup.log("Not waking up ghost " .. ghost_id .. ", somebody is home")
    else
        if (luup.variable_get("urn:upnp-org:serviceId:VSwitch1", "Status", ghost_virtual_switch_device) == "0") then
            luup.log("Not waking up ghost " .. ghost_id .. ", virtual switch has been turned OFF")
        else
            local ghost = ghosts[ghost_id]
            if ghost then
                luup.log("Waking up ghost " .. ghost_id)
                rule = ghost_rules[ghost['rule_name']]
                if rule['switch_devices'] then
                    for i, device_id in ipairs(rule['switch_devices']) do
                        if luup.variable_get("urn:upnp-org:serviceId:SwitchPower1", "Status", device_id) == "1" then
                            luup.log("Ghost " .. ghost_id .. " is NOT switching " .. ghostDeviceIdToName(device_id) .. " ON, it's already ON!")
                        else
                            luup.log("Ghost " .. ghost_id .. " is switching " .. ghostDeviceIdToName(device_id) .. " ON")
                            if not ghost['switch_devices_to_turn_off'] then
                                ghost['switch_devices_to_turn_off'] = {}
                            end
                            table.insert(ghost['switch_devices_to_turn_off'], device_id)
                            if not dry_run then
                                luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", { newTargetValue = "1" }, device_id)
                            end
                        end
                    end
                end
                if rule['dimmer_devices'] then
                    for i, device_id in ipairs(rule['dimmer_devices']) do
                        if luup.variable_get("urn:upnp-org:serviceId:SwitchPower1", "Status", device_id) == "1" then
                            luup.log("Ghost " .. ghost_id .. " is NOT switching " .. ghostDeviceIdToName(device_id) .. " ON, it's already ON!")
                        else
                            local dimmer_level = rule['dimmer_level'] or 25
                            luup.log("Ghost " .. ghost_id .. " is switching " .. ghostDeviceIdToName(device_id) .. " ON to " .. dimmer_level .."%")
                            if not ghost['dimmer_devices_to_turn_off'] then
                                ghost['dimmer_devices_to_turn_off'] = {}
                            end
                            table.insert(ghost['dimmer_devices_to_turn_off'], device_id)
                            if not dry_run then
                                luup.call_action("urn:upnp-org:serviceId:Dimming1", "SetLoadLevelTarget", { newLoadlevelTarget = "" .. dimmer_level }, device_id)
                            end
                        end
                    end
                end
                luup.log("Schedule ghost termination in " .. ghost['duration'] .. " seconds")
                luup.call_delay("terminateGhost", ghost['duration'], ghost_id)
            else
                luup.log("Ghost " .. ghost_id .. " already killed, do nothing")
            end
        end
    end
end

function terminateAllGhosts()
    for i, ghost_id in ipairs(sorted_ghosts) do
        ghost = ghosts[ghost_id]
        terminateGhost(ghost_id)
    end
end

function terminateGhost(ghost_id)
    if (luup.variable_get("urn:upnp-org:serviceId:VSwitch1", "Status", at_home_virtual_switch_device) == "1") then
        luup.log("Not terminating ghost " .. ghost_id .. ", somebody is home")
    else
        local ghost = ghosts[ghost_id]
        if ghost then
            luup.log("Terminating ghost " .. ghost_id)
            if ghost['switch_devices_to_turn_off'] then
                for i, device_id in ipairs(ghost['switch_devices_to_turn_off']) do
                    luup.log("Ghost " .. ghost_id .. " is switching " .. ghostDeviceIdToName(device_id) .. " OFF")
                    if not dry_run then
                        luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", { newTargetValue = "0" }, device_id)
                    end
                end
            end
            if ghost['dimmer_devices_to_turn_off'] then
                for i, device_id in ipairs(ghost['dimmer_devices_to_turn_off']) do
                    luup.log("Ghost " .. ghost_id .. " is switching " .. ghostDeviceIdToName(device_id) .. " OFF")
                    if not dry_run then
                        luup.call_action("urn:upnp-org:serviceId:SwitchPower1", "SetTarget", { newTargetValue = "0" }, device_id)
                    end
                end
            end
        else
            luup.log("Ghost " .. ghost_id .. " already terminated")
        end
    end
end

function scheduleGhosts()
    local current_time = os.date("*t", os.time())
    local seconds_from_midnight = current_time.hour * 3600 + current_time.min * 60 + current_time.sec

    luup.log("Scheduling ghosts...")
    local report = ""
    local ghosts_count = 0
    local scheduled_ghosts_count = 0
    for i, ghost_id in ipairs(sorted_ghosts) do
        ghost = ghosts[ghost_id]

        ghosts_count = ghosts_count + 1

        local starts_in = ghost['starts'] - seconds_from_midnight
        local ends_in = starts_in + ghost['duration']
        local status = ""
        if ends_in < 60 then
            status = "skipped, too late"
        elseif starts_in < 0 then
            status = "started " .. -starts_in .. " seconds ago, run now"
            ghost['duration'] = ghost['duration'] + starts_in
            scheduled_ghosts_count = scheduled_ghosts_count + 1
            wakeGhost(ghost_id)
        else
            status = "scheduled"
            scheduled_ghosts_count = scheduled_ghosts_count + 1
            luup.call_delay("wakeGhost", starts_in, ghost_id)
        end

        -- report
        local start_h = math.floor(ghost['starts'] / 3600)
        local start_m = math.floor((ghost['starts'] - (start_h * 3600)) / 60)
        local start_s = ghost['starts'] - (start_h * 3600) - (start_m * 60)
        local start_str = string.format("%02i:%02i:%02i", start_h, start_m, start_s)
        local duration_h = math.floor(ghost['duration'] / 3600)
        local duration_m = math.floor((ghost['duration'] - (duration_h * 3600)) / 60)
        local duration_s = ghost['duration'] - (duration_h * 3600) - (duration_m * 60)
        local duration_str = string.format("%02i:%02i:%02i", duration_h, duration_m, duration_s)
        local ends = ghost['starts'] + ghost['duration']
        local end_h = math.floor(ends / 3600)
        local end_m = math.floor((ends - (end_h * 3600)) / 60)
        local end_s = ends - (end_h * 3600) - (end_m * 60)
        local end_str = string.format("%02i:%02i:%02i", end_h, end_m, end_s)

        local report_line = string.format("%25s %s => %s (%s): %s", ghost['name'], start_str, end_str, duration_str, status)
        luup.log(report_line)
        report = report .. report_line .. "\n"
    end

    report_file = io.open('/tmp/ghosts.txt', 'w')
    report_file:write('Ghosts generated ' .. os.date("%x %X", os.time()) .. "\n\n")
    report_file:write(report)
end

if (luup.variable_get("urn:upnp-org:serviceId:VSwitch1", "Status", at_home_virtual_switch_device) == "0") then
    if (luup.variable_get("urn:upnp-org:serviceId:VSwitch1", "Status", ghost_virtual_switch_device) == "1") then
        generateGhosts()
        luup.call_delay('scheduleGhosts', 10)
    else
        luup.log("Not generating any ghost, virtual switch is OFF")
    end
else
    luup.log("Not generating any ghost, somebody is home")
end

Re: ghost simulateur de présence copie du VERA

Posté : 11 nov. 2019, 16:51
par vil1driver
Salut,

Domoticz intègre cela nativement dans ses planning.

Il te suffit de choisir l'heure d'allumage et de cocher aléatoire.
Idem pour l'extinction.

Dans les paramètres, tu définis la notion aléatoire, de quelques minutes à plusieurs heures..

C'est le plus simple.

Re: ghost simulateur de présence copie du VERA

Posté : 03 janv. 2020, 22:44
par LucasC
Bonjour,
Sans aller aussi loin, je souhaite allumer un éclairage disons une heure après le coucher du soleil.
Je n'arrive pas à ajouter 1h à sunset.
Aurriez vous le script pour cela ?
Merci bien pour votre aide

Re: ghost simulateur de présence copie du VERA

Posté : 04 janv. 2020, 00:17
par thier
pour avoir l'heure du coucher de soleil en minutes:
coucherSoleilEnMinutes = timeofday['SunsetInMinutes']
pour décaler par exemple de 10 minutes:
decalage = timeofday['SunsetInMinutes'] + 10
pour avoir l'heure en cours en minute:
heureminutes = (tonumber(os.date('%H',os.time()))*60)+tonumber(os.date('%M',os.time()))
Aprés tu compares heureminutes avec decalage pour allumer ta lampe.

Re: ghost simulateur de présence copie du VERA

Posté : 04 janv. 2020, 11:50
par vil1driver
Également possible par planning

Re: ghost simulateur de présence copie du VERA

Posté : 04 janv. 2020, 13:34
par denis_brasseur
vil1driver a écrit :
04 janv. 2020, 11:50
Également possible par planning
Capture.PNG
Capture.PNG (28.82 Kio) Vu 357 fois

Re: ghost simulateur de présence copie du VERA

Posté : 05 janv. 2020, 10:28
par LucasC
Bonjour,

J'avais une erreur du style " xxx[string]: 34 attempt to perform arithmectic on global xxxx" et en le refaisant en minute comme le porpose THIER cela fonctionne
Je préfère faire en code, je me dis que si mon RPI meure, je n'ai qu'a télécharger le code alors que les réglages plannings seront à refaire. Et pour ma culture perso je voulais savoir comment faire (ça peut me servir pour d'autres scripts).

Au final voila mon code, je repasse en heure juste apres le calcul pour faciliter la lecture du log
Heure_Allumage_minutes = timeofday['SunsetInMinutes'] + 10
Heure_Allumage = string.sub(os.date("!%X",60*Heure_Allumage_minutes),1,5)
print ('Heure Allumage ' ..Heure_Allumage)
if (heure = Heure_Allumage) then
...
end


Merci pour votre aide, bonne journée