This is the forum archive of Homey. For more information about Homey, visit the Official Homey website.

The Homey Community has been moved to https://community.athom.com.

This forum is now read-only for archive purposes.
Official HomeyScript

HomeyScript - share your scripts - main discussion topic

13

Comments

  • ketra90ketra90 Member
    edited December 2017
    hey guys, 

    am fooling around with the Homeyscript for some time now and thought i would share some of my scripts.

    shown below is a script that will use any motion sensor and use the naming for switching it on or off. so now only 1 flow is needed for all motion sensors as long as naming is correct.

    PIRDN5WC

    name above is:
    PIR to indicate its a motion sensor 
    D for a dimmer
    N for a night dimmer (will be less bright at night)
    5 for the time it should be ON
    and the last text is used for the name of the lamp to switch.



    // script is executed in a flow when sensor is triggered.
    // Motion.js
    var d = new Date().getHours();
    let devices = await Homey.devices.getDevices()
    var SearchString = args[0].substring(6)
    if (args[0].substring(3,4) == 'D') var dimmer = true;
    if (args[0].substring(4,5) == 'N') var night = true;
    if (args[0].substring(0,3) != 'PIR' && args[0].substring(0,3) != 'SEC') return;
    var Trigger = _.find(devices, function(o) { return o.name == args[0]; });
    var device = _.find(devices, function(o) { return o.name == SearchString; });
    console.log(device.name)
    console.log(Trigger.name)
    if (Trigger.state.alarm_motion)
    {
        try 
        {
            if(dimmer)
            {
                if (night && (d < 5 || d > 23))
                {
                    device.setCapabilityValue('dim', 0.35);
                    console.log('Swithed '+ device.name + ' To 35 percent')
                }
                else
                {
                    device.setCapabilityValue('dim', 0.75);
                    console.log('Swithed '+ device.name + ' To 75 percent')
                }
            }
            else
            {
                device.setCapabilityValue('onoff', device.state.onoff);
                console.log('Swithed '+ device.name)
            }
        }
        catch (err) 
        {
            console.error(err)
        }
    }
    return device.name; 

    The script below is the one i use to switch off the lights, wich are switched on with the script above

    // Script is executed in flow with trigger every 1 minute
    // Motion_Timed.js
    try {
        let devices = await Homey.devices.getDevices();
        Object.values(GetDevices(devices)).forEach(dev => {
            if (CheckIfDeviceOn(dev)) {
                var SearchString = dev.name.substring(6)
                var device = _.find(devices, function (o) { return o.name == SearchString; });
                device.setCapabilityValue('onoff', !device.state.onoff);
            }
        });
    }
    catch (err) {
        console.error(err)
    }
    function getMinutesBetweenDates(startDate, endDate) {
        //console.log('Checking : '+ startDate + ' Against : ' + endDate)
        var diff = endDate.getTime() - startDate.getTime();
        diff = diff / 60000
        return Math.round(diff);
    }
    function GetDevices(devices) {
        d = new Date()
        var DevicesToSwitch = []
        Object.values(devices).forEach(device => {
            if (device.class != 'sensor') return false;
            //if(!device.state.onoff) return false;
            if (device.name.substring(0, 3) != 'PIR') return false;
            var ontime = parseInt(device.name.substring(5, 6))
            if (getMinutesBetweenDates(new Date(device.lastUpdated.alarm_motion), d) < ontime) return false;
            DevicesToSwitch.push(device)
            return true;
        });
        return DevicesToSwitch
    }
    function CheckIfDeviceOn(dev) {
        var SearchString = dev.name.substring(6)
        var device = _.find(devices, function (o) { return o.name == SearchString; });
        return device.state.onoff
    }

    the below link is of the full implementation of the motion script since i added State control for managing SEC sensors.

    Motion.js

  • @Lurendrejer

    I have rewriten your script a little so you can use it in the and / or column:
    let devices = await Homey.devices.getDevices();
    function anyLightOn(devices) {
        let result = false;
        _.some(devices, device => {
            if (device.class === 'light' && device.state.onoff) {
                result = true;
            }
            return result;
        });
        return result;
    }
    
    return anyLightOn(devices)
    
    This should work but keep in minds that the first line ( getDevices() ) takes some time to execute (depending on how many devices you have. at this time i do not known of a method to make that faster because you need the <class> property

  • I was specifically trying to avoid the classes - since they can't be changed. Thats why i use the folder-name :)

    I'll spend another week getting your solution fittet into my script, thank you !
  • @Nattelip

    What did you try to ask?

  • tb1962 said:
    @Nattelip

    What did you try to ask?

    He posted the most optimized homeyscript ever :)
  • LurendrejerLurendrejer Member
    edited December 2017
    Hmm...

    When turning of devices stuff is left on - but seen as off in homey. I need to stagnate the commands I guess.
  • @Lurendrejer

    If you are using your <first ever script> that you posted a few days ago, try modifying the line device.setCapabilityValue('onoff', false);

    Create a function to set the state to off:
    async function setStateOff(device) {
        await device.setCapabilityValue('onoff', false);
    }
    and change the line device.setCapabilityValue('onoff', false) 
    to: setStateOff(device)
    doing so will ensure that all device are set to off synchronously and not asynchronously
    If this does not work what lights are you using? I use Philips Hue lamps with the Philips Hue app and with the bridge. That works great. If you are using zigbee then that may be the cause. Lots of complaints at zigbee at this moment
  • Im trying to call SimpleLog to add an entry to the logfile - i have tried some stuff

    Im able to find the SimpleLog app object and see the info on it - but how do i invoke an action?

    Here is the app https://github.com/nklerk/nl.nielsdeklerk.log/blob/master/app.js and my script is like this

    let sl = await Homey.apps.getApp({ id: 'nl.nielsdeklerk.log' })
    console.log(sl);
    sl.actionInputLog("Log entry");
    return true;
    Im really not sure what to call to get what i'm expecting..

    All i want to do is add a log entry - from a Homey Script - does the app need to expose some API's or?
  • @exiof

    As far as i know, you can't. There is no api interface. That's needed to use the app from HomeyScript. Because i also want that option i have already commented on this in the app store. Please add one comment there.

    At this time i have solved this by using a better logic variable. That works in 99% but sometimes, when two scripts are fighting to be the first to log something. it goes wrong. So that's not reliable enough. I hope @nklerk will add this option soon!
  • tb1962 said:
    @exiof

    As far as i know, you can't. There is no api interface. That's needed to use the app from HomeyScript. Because i also want that option i have already commented on this in the app store. Please add one comment there.

    At this time i have solved this by using a better logic variable. That works in 99% but sometimes, when two scripts are fighting to be the first to log something. it goes wrong. So that's not reliable enough. I hope @nklerk will add this option soon!
    I have planned to give the app some love  next week. Hope this helps.
  • tb1962 said:
    @Lurendrejer

    If you are using your <first ever script> that you posted a few days ago, try modifying the line device.setCapabilityValue('onoff', false);

    Create a function to set the state to off:
    async function setStateOff(device) {
        await device.setCapabilityValue('onoff', false);
    }
    and change the line device.setCapabilityValue('onoff', false) 
    to: setStateOff(device)
    doing so will ensure that all device are set to off synchronously and not asynchronously
    If this does not work what lights are you using? I use Philips Hue lamps with the Philips Hue app and with the bridge. That works great. If you are using zigbee then that may be the cause. Lots of complaints at zigbee at this moment
    I'll try that when i get home, thank you so much! :)

    All my z-wave devices turns off instantly - but the zigbee stuff just grinds to a halt, an leaves a random light or two on.
    I'm using ikea and hue connected directly to homey - sometimes ikea bulbs are left on, sometimes hues.

    Probably just zigbee in general.
  • tb1962 said:
    @Lurendrejer

    If you are using your <first ever script> that you posted a few days ago, try modifying the line device.setCapabilityValue('onoff', false);

    Create a function to set the state to off:
    async function setStateOff(device) {
        await device.setCapabilityValue('onoff', false);
    }
    and change the line device.setCapabilityValue('onoff', false) 
    to: setStateOff(device)
    doing so will ensure that all device are set to off synchronously and not asynchronously
    If this does not work what lights are you using? I use Philips Hue lamps with the Philips Hue app and with the bridge. That works great. If you are using zigbee then that may be the cause. Lots of complaints at zigbee at this moment
    I'll try that when i get home, thank you so much! :)

    All my z-wave devices turns off instantly - but the zigbee stuff just grinds to a halt, an leaves a random light or two on.
    I'm using ikea and hue connected directly to homey - sometimes ikea bulbs are left on, sometimes hues.

    Probably just zigbee in general.
    I got this script working with a test-zone, i'll test it later.
    Right now, if i do something wrong that turns on all the lights - i'll wake two kids and crazy woman.

    But thank you, it did stagnate the off-commands as far as i have been able to test.
  • tb1962 said:
    function delayedLoop() {
    _.delay(function(text) { <Your delayed code>;
    delayedLoop(); }, 100, ''); }
    tb1926, this is a delay loop where you need to call your code inside it. Do you know if there is a function or way that i just can call a function that delays x ms for me? Just like the settimeout function in js.
    I am running a for loop that needs a delay, want to fade my ikea lights on or off.
  • @Lithium
    if you want simple setTimeout functionality you can use this:

    <some code>
    
    _.delay(function(test) {
      <Your delayed code  that wil be executed after 1 sec.>
    }, 1000);
    
    <some code>

    or you can use this:
    async function wait (timeout) {  return await new Promise((resolve) => {    _.delay(function(text) {        resolve();    }, timeout)  })}
    
    <some code>
    
    await wait(1000); /*Halt execution for 1 sec*/
    
    <some code that will be executed after 1 sec>
    
    
    

  • Thanks :)

    I found this one that also works:

    function sleep(delay) {
    var start = new Date().getTime();
    while (new Date().getTime() < start + delay);
    }
  • tb1962tb1962 Member
    edited January 2018
    Is anyone using HomeyScript Betterlogic having problems after updating HomeyScript to version 1.0.3?

    I get an exception when reading a variable using apiGet or write to a variable using apiPut
  • Hi, anyone that could help pointing me in the right direction, I am not a programmer, but would like to get a grip in my weatherstation.
    I have made a dashboard, showing me weather data, but could be usefull to trigger flows from the weatherstation
    Every data I have in txt files updating every 2 seconds.
    The weatherstation is a Davis Vantage Pro2
  • For some inspiration about getting  a Day Of The Year calculation with returning a Tag tothe Flow.

    https://forum.athom.com/discussion/comment/66458/#Comment_66458

  • khangweikhangwei Member
    edited February 2018
    hi everyone. has anyone wrote a script that gets messages/updates from a telegram bot and trigger certain flows? tried searching around but couldn't find any. 

    thanks in advance!
  • khangwei said:
    hi everyone. has anyone wrote a script that gets messages/updates from a telegram bot and trigger certain flows? tried searching around but couldn't find any. 

    thanks in advance!
    I haven't seen it,
    Why do you want to do that from HomeyScript ? 
    Is the app not working? https://apps.athom.com/app/org.telegram.api.bot
  • hey, the app is working. but the app sends messages based on conditions by flows - the bot reporting in, essentially 1 way.

    I would like to trigger flows or ask questions by talking to the bot - so was trying to make it a 2 way thing.

  • I thought i share this script that saves me time every morning now then it is winter and the temperature is below 0. The script is triggered in a flow 60 min before my alarm goes of in the morning:

    The script itself checks the temperature outside and starts the heater in my car to make sure it's warm and cosy and there is no ice on the windscreen. I have a small car with a small engine. For larger cars you might have to modify the calculations so the heater is on for a longer time.

    You can find the script on GItHub https://github.com/tomhur/homeyscripts/blob/master/carheater.js
  • Hi
    I'm having trouble calling another script from one script. I think I have been trying every variant of this :)
    let HomeyScript = await Homey.apps.getApp('com.athom.homeyscript');
    HomeyScript.ApiPost('script/<ScriptID>/run', [arg1, arg2]);
    But triggering one script script from another is just a work around for I really would like to do.

    Since I want one script that wait x number of seconds and one that waits a random number of seconds, what I really would like to do is create one global function that waits the inputed number of seconds so I can call that from both my wait script and my random script.

    Cheers!
  • LammyLammy Member
    edited May 2018
    Here is a script that finds flows based on their title and triggers them. 
    I use it to trigger flows from the Telegram Bot app.
    As a convenience the script has an array of shortcuts, so you don't need to enter the full title for frequently used flows.
    // Find a flow based on its name or shortcut and trigger it
    // 
    // Execute the script from a flow and pass the shortcut or flow name 
    // as argument. 
    // The script returns true if a flow was triggered, false otherwise.
    
    // Add your shortcuts here. Enter shortcuts in lowercase. 
    var commands = {
        'ikea': "Ik kom er aan",
        "k" : "Koffieautomaat aan",
        "h" : "ShowHelp",
        "?" : "ShowHelp"
     };
    
    if (args[0] == undefined) {
        console.log ('Missing argument');
        return false;
    }
    
    var token = "" + args[0];
    token = token.trim();
    var cmd = token.toLowerCase();
    
    var flowname;
    _.forEach (commands, function (value, key) {
            if (cmd == key) flowname = value;
        }
    );
    
    if (flowname == undefined) {
        // No shortcut found. Assume the argument is a flow's title.
        flowname = token;
    }
        
    // find the flow and trigger it
    let found = false;
    let flowman = await Homey.flow;
    let flows = await flowman.getFlows();
    _.forEach(flows, flow => {
        if (flow.title == flowname && 
            flow.broken == false &&                         // don't attempt to trigger broken flows
            flow.enabled == true &&                         // skip disabled flows
            flow.trigger.id == "programmatic_trigger") {    // Only trigger programmatic flows
                flowman.triggerProgrammaticFlow({id : flow.id});
                found = true;
        }
    });
    
    // return true only if at least one flow was triggered.
    return found == true;
    I've added the following flow to run this script whenever the Telegram Bot receives a message. If no flow was triggered, the text is speech emulated, so Homey handles it with speech recognition. 

  • What is a 'disbaled' flow?

    Just kidding ;-)
  • LammyLammy Member
    Let's say it is a slip of the mind ;-)
    Thanks for pointing out.
  • khangweikhangwei Member
    edited June 2018
    hello,

    may i ask if anyone can provide some guidance if i can load the telegram app via homeyscript to send myself a text based on the script i created?

    i see from the examples that it is possible to load an app. would it be possible to fire off a method within homeyscript to take advantage of the telegram app to send myself some text?


    i am trying to loop through my devices based on certain criteria and use a bot to inform when certain appliances are not turned off

    thanks!

    @jorden sorry i am not good at this but did you expose any API?
  • Hello Community,

    maybe it's because I am a newbie, but could someone explain this to me:

    if(device.class != 'light') return;

    != means "not equal" so why is this used to return classes equal light?

    Regards
    Andreas
  • @Seraphim
    it depends on the code around this line, I guess it gets ALL devices, loops over them and skips the loop when it is not equal to Light,,,, So processes  (and maybe returns) somewhere else all lights....
Sign In or Register to comment.