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

24

Comments

  • HomeyScript can possibly change the need to have Apps installed for all kinds of functionality.
    Getting the scripts to work is not the hardest part. I use the Net Scan app and made this script to get a list of online devices. I put all my devices in a zone called Network.

    //Gets all online Net Scan devices
    let devices = await Homey.devices.getDevices();
    Object.values(devices).forEach(device => {
    if(device.zone.name != 'Network') return false;
    if(!device.available) return false;
    console.log(device.name);
    });

    However I still get double output and I want to use this output in a flow, but I have no idea how to do this.
    Maybe fill a Global Tag, still trying to work that out.
  • Idea for a script that I would really like to have:

    Listing each flow and the content of the flow: devices, setting, formulas etc - kind of manual back up in case you have to reconstruct everything... Or just would like to get some kind of overview of where you used a specific variable or so...
  • bvdbosbvdbos Member
    edited September 2017
    @nagash1979If you login through http:// instead of https:// the doubles will be gone probably :)
  • Hi,

    somebody have an idea how I could set a Z-Wave device configuration parameter?
    I can read it with
    console.log(device.settings);
    or
    let devsettings = device.settings;
    console.log(devsettings.anyparam);
    But would like to modify the setting.
    Do not find the right syntax for this.
    Yes, I know, device must be online (or wakeup) - this is clear, I'm testing with an online device.

    Would be nice if somebody could help ;)

    Thanks!
  • home78home78 Member
    edited September 2017
    bvdbos said:
    @nagash1979If you login through http:// instead of https:// the doubles will be gone probably :)
    That does indeed seem to work, although I don't like the idea of having an insecure connection to my home network. @bvdbos Is it possible to implement the fix for https: also?
  • I would like to invoke some app functionality, probably need to use the WebAPI for this. Does anyone have an example of say, how to send an email using the Email Sender app?

    For example:
    let Mailer = await Homey.apps.getApp({ id: 'email.sender' } );
    Mailer.send_mail(from, to, subject, body);
    I'm missing a few nuts and bolts here, I guess.   :#
  • Probably, you'd have to ask Athom :) If you file a bug at https://github.com/athombv/com.athom.homeyscript/ as a reminder for Jeroen, he will pick it up I guess (he already knows...)
  • @home78
    The only way that would be possible is by using the app api. If Email Sender has an API, otherwise it needs a PR or you need to mail the dev :)
  • xAPPOxAPPO Member
    edited September 2017
    If I have a trigger from something that has tags.. How would I get the value of one of those tags at trigger time into a variable within a Homeyscript in the 'then' portion ?

    I adapted this example but the (Flow) tags don't get listed here. Do I have to get them into a variable first with say Better Logic ?
    • useTagsOrTokensinHomeyScript
  • xAPPO said:
    If I have a trigger from something that has tags.. How would I get the value of one of those tags at trigger time into a variable within a Homeyscript in the 'then' portion ?

    I adapted this example but the (Flow) tags don't get listed here. Do I have to get them into a variable first with say Better Logic ?
    • useTagsOrTokensinHomeyScript
    Arguments are not yet possible, I asked Jeroen last week on Slack:
    dijker [1:30 PM]  anyone an idea how to use the Args? is it possible to call the script from a flow like:  ExampleScript.js arg1 arg2 and what should I do to use the args in the script?
    jeroenvollenbrock [1:53 PM]  args are not available from the flow editor yet
    [1:53] you can specify them in the body of the post request though

    but setting the token from a trigger to a variable and execute te HomeyScript with above example the next second should work as workaround.


  • xAPPOxAPPO Member
    edited September 2017
    So can I directly reference a Homey variable in a Homey script  and change its value ?

    If not...then I can get the value of the variable using the token example script but how would I then update it with a new value .. and hence update the variable value ? I don''t see a setToken method.

     I'm trying to do a bit of string manipulation in a script to extract a substring of a tag value.   Are there any other apps that might help with this ?  String manipulation seems totally absent.


    Kevin
  • Is there a way to let a script run in a loop with a wait time of 100msec or to call a script every 100msec?
  • Just some food for thought (didn't experiment with HomeyScript that much yet). If you really do need some npm module and don't mind if the script will take longer to execute you could use a RunKit endpoint to run some code and wait for a response in your HomeyScript script!

    https://runkit.com/docs/endpoint
  • home78 said:
    bvdbos said:
    @nagash1979If you login through http:// instead of https:// the doubles will be gone probably :)
    That does indeed seem to work, although I don't like the idea of having an insecure connection to my home network. @bvdbos Is it possible to implement the fix for https: also?
    Should be resolved now. (You might need a refresh)
  • I tried to make a script which reboots Homey and use following command
    Homey.system.reboot();

    But it doesnt work, any idea ?

  • Is there a way to use delays in a script?

    JavaScript has the setTimeout and setInterval command, but HomeyScript doesn't seem to recognize it.
  • I've created this script to split command and arguments from a Telegram bot message.
    It works, but I'd like to accomplish more. The script uses Better Logic and relies on apiPut(), but I want it to be more versatile.
    How can I trigger programmatic flows? I can find the flows, but have no clue how to trigger them.
    How do I change the value of Logic variables? Same story, I can find the tokens, but cannot change their values.
    The API documentation doesn't quite match with the objects I've observed. Any pointers to other docs? Did I miss something?
    Thanks in advance. I'd appreciate your feedback. 
    // Split a message from a Telegram bot into command and argument(s).
    // Command and argument are stored in Better Logic string variables. 
    // Option 1: Run this script with "/cmd and some extra's, x, y"
    // The result will be: x == "cmd" and y == "and some extra's"
    // Option2: "/trig x, y, z" will trigger variable x. y and z are ignored.
    
    if (args[0] === '') {
        console.log ('Missing argument');
        return false;
    }
    
    let bl = await Homey.apps.getApp({ id: 'net.i-dev.betterlogic' } );
    if (!bl) {
        console.error('Better Logic not installed!');
        return false;
    }
    
    let tokens = args[0].split(',');
    if (tokens.length < 3) {
        console.log('Need 3 arguments: \n'+
                    '\t1. the message text\n'+
                    '\t2. the name of the command variable\n'+
                    '\t3. the name of the arguments variable');
        return false;
    };
    
    let argVar = tokens.pop().trim();
    let cmdVar = tokens.pop().trim();
    let ln = tokens.join(',').trim();
    let tcmd = '0';
    let targ = '0';
    
    if (ln.substr(0,1) == '/') {
    
        var pos = ln.indexOf(' ');
        if (pos > 0) {
            tcmd = ln.substr(1, pos - 1);
            targ = ln.substr(pos + 1);
        }
        else {
            tcmd = ln.substr(1);
        }
        console.log('%s => %s(%s)', ln, tcmd, targ);
    }
    else {
        // This sentence is not a command. Ok, not an error.
        return true;
    }
    
    if (tcmd == 'trig') {
        // special case
        bl.apiPut('trigger/' + targ)
            .then(console.log, console.error);
        return true;
    }
    
    // argument first!
    if (targ !== '') 
        bl.apiPut(argVar + '/' + targ)
            .then(console.log, console.error);
    if (tcmd !== '') 
        bl.apiPut(cmdVar + '/' + tcmd)
            .then(console.log, console.error);
    
    return true;
  • Hi,
    Is there anyone who has some Idea how to add a thirdparty library (like Mobus) to Homey?
  • Slofware said:
    Is there a way to let a script run in a loop with a wait time of 100msec or to call a script every 100msec?
    Hi Slofware, a bit late but you can use the lodash delay:
    function delayedLoop() {
    _.delay(function(text) { <Your delayed code>; delayedLoop(); }, 100, ''); }
  • Has someone figured out yet how to set a BetterLogic variable from HomeyScript?
    Or is that just impossible?
  • Hi Sietse, the script 4 posts up sets BL variables.
  • Hi, could someone help a scriptkiddie out?
    If i have a device with ID: '123abc'.
    How do i fetch the onoff state of this device in homey script.
  • @Baron
    if you just want to read the onoff state, you can do it this way:
    Homey.devices.getDeviceState({id :'123abc'}).then( (state) => {
    if (state.onoff) { <do something when state is on>
    } else { <do something when state is off>
    }
    })
  • oh thank you @tb1962, works like a charm  :*
  • BaronBaron Member
    edited December 2017
    Okay, so here is my first script then.
    I have a virtual device that is on if my alarm is triggered. This script will turn all my hue bulbs red and keep blinking them once every 1500ms, until the alarm is not triggered anymore.

    // Lets make all the lamps blink red if the alarm is triggered

    let devices = await Homey.devices.getDevices(); //get all devices from homey
    let light_state = true; //boolean to swap the state of the lights

    _.forEach(devices, device => {
    if(device.class != 'light') return; //filter out all non light devices
    //console.log(device.name); //debugg devices left after filter
    // set the lamps red, full dim
    device.setCapabilityValue('onoff', false);
    device.setCapabilityValue('dim', 1);
    device.setCapabilityValue('light_hue', 1);
    device.setCapabilityValue('light_saturation', 1);
    device.setCapabilityValue('light_temperature', 0);
    device.setCapabilityValue('light_mode', 'color');
    //console.log(device.state); //debugg settings for bulbs (only shows correct values on second run, why???)
    });

    //
    // if virtual device representing the alarm state is true, toggle the lights on and off
    //
    function delayedLoop() {
    _.delay(function() {
    light_state = !light_state; //swap the toggle state for the lamps
    //fetch the onoff state of the alarm (if it's triggered or not), and toggle the lamps on/off until the alarm state is off
    Homey.devices.getDeviceState({id :'b2ab67c9-cfc5-42a5-b350-19990f2e9212'}).then( (state) => {
    if (state.onoff) {
    _.forEach(devices, device => {
    if(device.class != 'light') return; //filter out all non light devices
    device.setCapabilityValue('onoff', light_state); //toggle the lamp
    });
    delayedLoop();
    }
    })
    }, 1500, ''); // toggle the light once every 1500ms
    }
    delayedLoop()
    return true;


    I am not a programmer, and never have written java before, so this is not a good structure. And I am sure the script could be written in a much simpler matter. But I'm not coder enough to do that my self. Most of the code above is just copy/pasted and edited.

    I have almost 50 hue bulbs at home, this script is not working perfect for that amount of bulbs. It works very well when i test it with just a few ones instead. I think the problem is that it takes some time for the lopp to go through all the 50 lights and turn then on/off individually on every loop. It would probably be better if I could write the script to turn on/off ALL lights in one command, and not do it individually for every single one. But don't know if that is possible.

    If you want to use this script your self, i think the only thing you'd have to adjust is the id on line 27, so the script can check if your alarm is triggered or not.


  • tb1962tb1962 Member
    edited December 2017
    @Baron

    Unfortunately, there, as far as i know, no way to set all lights on or off at ones.
    But I have modified your script a little:


    let devices = await Homey.devices.getDevices(); //get all devices from homey let light_state = true; //boolean to swap the state of the lights _.forEach(devices, device => { if(device.class != 'light') return; //filter out all non light devices //console.log(device.name); //debugg devices left after filter // set the lamps red, full dim device.setCapabilityValue('onoff', false); device.setCapabilityValue('dim', 1); device.setCapabilityValue('light_hue', 1); device.setCapabilityValue('light_saturation', 1); device.setCapabilityValue('light_temperature', 0); device.setCapabilityValue('light_mode', 'color'); //console.log(device.state); //debugg settings for bulbs (only shows correct values on second run, why???) }); async function wait (timeout) { return new Promise((resolve) => { _.delay(function(text) { resolve(); }, timeout) }) } // // if virtual device representing the alarm state is true, toggle the lights on and off // async function delayedLoop() { let state = {onoff: true}; while (state.onoff) { await wait(1500); light_state = !light_state; state = await Homey.devices.getDeviceState({id :'b2ab67c9-cfc5-42a5-b350-19990f2e9212'}); if (state.onoff) { _.forEach(devices, device => { if(device.class != 'light') return; //filter out all non light devices device.setCapabilityValue('onoff', light_state); //toggle the lamp }); } else { _.forEach(devices, device => { if(device.class != 'light') return; //filter out all non light devices device.setCapabilityValue('onoff', false); //turen of the lights }); } } } delayedLoop() return true;

    First you can see that i set the lights ON at start. Second: i have recoded your delayedLoop. It now switches of the lights when the alarm trigger goes in the 'off' state and the it will leave the loop.

    I have not tested the modification but i think it should work 


  • Thanks a million @tb1962.
    I saw the promise and subscribe functions in the documentation for the API, but did never understand how to use them (and to be honest, even in the code you wrote, I do not understand fully how it works, but understand what it does). 

    I've been at the stove all day, so didn't have time to do more than paste and test, and it seems to work fine. Just some small timing quirks, all lights did not turn off after the loop stops, and some times some lights does not have time to turn off between the loops, this is most likely due to the amount of bulbs I have. Will test more intensively when time comes by.

    Two follow up question, how can I trigger a flow from the script (a flow with "this flow started" in "when", or with a bitflip)? I have a flow that resets the lights to the standard scenes depending on daytime/presence/etc.

    Is there a smart way to filter out the bulbs that is not capable of color (have 6 lights that are white only)
    similar to this part of the script, "if(device.class != 'light') return;"

    the differense between the whites and the color bulbs
    White just have: capabilitiesOptions: { onoff: {}, dim: [Object] }
    color have: { onoff: {}, dim: [Object], light_hue: [Object], light_saturation: [Object], light_temperature: [Object], light_mode: {} }

  • @Baron

    You can trigger a flow this way:
    Homey.flow.triggerProgrammaticFlow({id : '1a921f06-1c47-4bb5-8fbc-d5c3bc8aae8f'});

    to filter out bulbs that are color, you can use the device.capabilities object
    methode 1: device.capabilities.light_mode.values is an array of objects. One of the objects should have an id = 'color'
    methode 2: you can test if the device.capabilities object has an light_hue and/or light_saturation object and that object should have an propertie setable=true
  • My first working script ever!!


    //Get all devices in zone *(Lys) and turns them off
    let devices = await Homey.devices.getDevices();
    Object.values(devices).forEach(device => {
    if(device.zone.name.substr(device.zone.name.length - 5) != "(Lys)" ) return true;
    if(!device.state.onoff) return false;
    device.setCapabilityValue('onoff', false);
    console.log(device.name);
    });


  • LurendrejerLurendrejer Member
    edited December 2017
    If i wan't to use the above script in the flow "and column" - how do i get it to return TRUE if any light is on, and FALSE if off?

    //Edit

    This Works 

    / Returns true if light is on in "*(Lys)"
    let devices = await Homey.devices.getDevices();

    return Object.values(devices).some(device => {
    if(device.zone.name.substr(device.zone.name.length - 5) != "(Lys)" ) return false;
    if(!device.state.onoff) return false;
    console.log(device.name);
    return true;
    });
Sign In or Register to comment.