# How to call a Homey script from an App

**URL:** <https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313>\
**Category:** Questions & Help\
**Created:** [July 10, 2023, 12:05pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313 "2023-07-10T12:05:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 12:05pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/1 "2023-07-10T12:05:08Z")

</div>

Is it possible to call a Homey script (bij it’s name) with a parameter from a .js file in an App. I tried:

result = window[ScriptName](ScriptPara);  
result = this[ScriptName](ScriptPara);  
result = self[ScriptName](ScriptPara);  
result = top[ScriptName](ScriptPara);  
result = globalThis[ScriptName](ScriptPara);  
result = global[ScriptName](ScriptPara);

(ScriptName contains the name of the script and ScriptPara it’s parameter as a string object.)

the above all crash.

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 12:12pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/2 "2023-07-10T12:12:22Z")

</div>

`window`, `top`, etc won’t work because Homey apps have no DOM because they’re not running in a browser (nor do they run in some sort of global context, apps are self-contained).

It’s probably possible by executing a flow card through the [Web API](https://athombv.github.io/node-homey-api/HomeyAPI.html#.createAppAPI), but from what I can see in the [HomeyScript app source](https://github.com/athombv/com.athom.homeyscript/tree/master), it doesn’t return the result of the script in any useful way.

Besides that: why…?

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 1:02pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/3 "2023-07-10T13:02:20Z")

</div>

I’m busy changing the MQTT Hub App, fixing some bugs and add functionality.  
There is an item that’s called outputTemplate and I changed the code so that it will accept a string like {“RoomTemp” : “#value#”} which I need for my ECODAN Heat Pump.

And than is there a bug if you change the Topics in settings the displayName will revert back to it’s defaults. A quick and dirty trick is to change de item “displayName” by “title” and that will fix it, but I’m busy to fix it in code.

```auto
{
  "target_temperature": {
    "capability": "target_temperature",
    "stateTopic": "ECODAN/tele/0x09",
    "commandTopic": "ECODAN/cmnd",
    "valueTemplate": "Zone1_Room_Temp_Setpoint",
    "outputTemplate": "<<{\"SetRoomTemperature\" : \"#value#\"}",
    "title": "Room Temperature"
  }
}

```

note the “valueTemplate” (\<\< is a trigger) and the “title” which previously was “displayName”.

The new code will take the string in outputTemplate and swap the #value# with the real value received earlier from MQTT and send it out.

This is working fine for now but sometimes you need to do more complex operations before sending it to MQTT and that’s why I got the idea of calling a user defined Homey script.

But if that’s not possible I can always fill the string with a javascript and execute that script with eval or with:

var Func=new Function(outputTemplate);

and call it to get the result.

This is not easy for me because I just started using Homey and altough I’m a Assembler/C++ programmer for 40 years I’m strugling with Java 🙂

---

<div class="post-metadata">

**Author:** ![ChrisBoer](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/chrisboer/32/1252_2.png) [@ChrisBoer](https://community.homey.app/u/ChrisBoer)\
**Post date:** [July 10, 2023, 1:08pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/4 "2023-07-10T13:08:25Z")

</div>

Webhook is also possible

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 1:17pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/5 "2023-07-10T13:17:01Z")

</div>

> [@Teun\_Pasterkamp](#):
>
> This is working fine for now but sometimes you need to do more complex operations before sending it to MQTT and that’s why I got the idea of calling a user defined Homey script.
> 
> But if that’s not possible I can always fill the string with a javascript and execute that script with eval or with:
> 
> var Func=new Function(outputTemplate);
> 
> and call it to get the result.

HomeyScript really isn’t meant for that, it’s main purpose is to allow for more complex flows than what’s possible with existing cards. So another solution would probably be better.

However, are you sure that it’s not already possible to do what you want using the existing app? The documentation [says here](https://github.com/harriedegroot/nl.hdg.mqtt#mqtt-device) that _" If JSON output is required, JSON-T style formatting is implemented"_.

> [@](#):
>
> This is not easy for me because I just started using Homey and altough I’m a Assembler/C++ programmer for 40 years I’m strugling with Java 🙂

Homey is JavaScript, not Java. Very different 😉

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 1:23pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/6 "2023-07-10T13:23:14Z")

</div>

> [@robertklep](#):
>
> However, are you sure that it’s not already possible to do what you want using the existing app? The documentation [says here](https://github.com/harriedegroot/nl.hdg.mqtt#mqtt-device) that _" If JSON output is required, JSON-T style formatting is implemented"_.

I tried but I have no idea how to create a value with JSON-T that looks like:  
{“SetRoomTemperature” : “#value#”} where #value# is the value received by valueTemplate. The original code piece is:

```
    if(config.outputTemplate && config.outputTemplate.replace("{{", "").replace("}}", "").trim() !== 'value') {
        const template = config.outputTemplate;
        try {
            let state = this.getState() || {};
            state.value = payload;
            const mathjs = this.compiled.get(template);
            if(mathjs) { // math?
                payload = mathjs.evaluate(state);
            } else { // json-t
                if(!template.startsWith('{{') && (template.startsWith('{') || template.startsWith('['))) {
                    payload = jsontObject(template, state);
                } else {
                    payload = jsontString(template, state);
                }
            }
            
        } catch(e) {
            this.log("failed to format output message", e);
        }
    }

```

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 1:26pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/7 "2023-07-10T13:26:35Z")

</div>

~~My guess would be:~~

~~ 

```auto
{ "SetRoomTemperature" : "$[value]" }

```

 ~~

Never mind, wrong JSON-T.

It looks like the app uses [this package](https://www.npmjs.com/package/json-templater), so:

```auto
{ "SetRoomTemperature" : "{{value}}" }

```

But it depends on what `state` contains.

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 1:29pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/8 "2023-07-10T13:29:07Z")

</div>

The idea was a simple way for the normal user by creating a script for that purpose. I don’t think there is a way to trigger a webhook which will call a script and send the result of that script back to the original caller.

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 1:30pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/9 "2023-07-10T13:30:02Z")

</div>

I tried that one and it didn’t work?

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 1:32pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/10 "2023-07-10T13:32:07Z")

</div>

What are the contents of `state`?

I don’t use this app so can’t test myself.

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 1:47pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/11 "2023-07-10T13:47:32Z")

</div>

Result in MQTT " { “SetRoomTemperature” : “{{value}}” }" so value is taken literal. I tried so many different ways and nothing worked so I decided to change the code 🙂

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 1:49pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/12 "2023-07-10T13:49:08Z")

</div>

What does the original developer (@HarriedeGroot) have to say about it not working?

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 1:49pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/13 "2023-07-10T13:49:46Z")

</div>

Until now no response…

---

<div class="post-metadata">

**Author:** ![HarriedeGroot](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/harriedegroot/32/56160_2.png) [@HarriedeGroot](https://community.homey.app/u/HarriedeGroot)\
**Post date:** [July 10, 2023, 2:12pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/14 "2023-07-10T14:12:40Z")

</div>

> [@Teun\_Pasterkamp](#):
>
> { “SetRoomTemperature” : “{{value}}” }

Did you try this example:

> [@MQTT Hub/Gateway](https://community.homey.app/t/mqtt-hub-gateway/6766/842):
>
> MQTT Devices are now able to handle JSON input & output. Version 3.1.0 MQTT device: grab input value from json messages (jsonPath) MQTT device: format output message payload to json (JSON-T template) I added two optional config parameters per capability: value path: point to a value within the JSON payload of the state messate using [JSONPath](https://github.com/dchester/jsonpath#readme). output template: format the output using [JSON-T](https://github.com/lightsofapollo/json-templater). Both string & object output are supported. All values from the device state (capabilities)…

So:  
{ “SetRoomTemperature” : {{value}} }

HUB Version 3.1.0+

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 2:18pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/15 "2023-07-10T14:18:17Z")

</div>

> [@HarriedeGroot](#):
>
> { “SetRoomTemperature” : {{value}} }

And also make sure everything is properly quoted.

Here’s an example I’m testing with, which is working fine:

```auto
{
  "measure_battery": {
    "capability": "measure_battery",
    "stateTopic": "test/state",
    "setTopic": "test/set",
    "valueTemplate": "$.value",
    "outputTemplate": "{\"xxx\":{{value}}}",
    "displayName": "Battery"
  }
}

```

Pushing a value:

```auto
$ mqtt_pub -vh 192.168.23.2 'test/state' '{"value":80}'

```

Output (on the `test/set` topic):

```auto
{"xxx":80}

```

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 2:45pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/16 "2023-07-10T14:45:37Z")

</div>

Yes it works, “{"SetRoomTemperature":"{{value}}"}” gives the output “cmnd = {“SetRoomTemperature”:“20”}” cmd is the topic.

Thanks for helping that’s one problem solved, is it also possible to do some calculations in JSON-T like {{value\*100}}?

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 2:53pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/17 "2023-07-10T14:53:47Z")

</div>

> [@Teun\_Pasterkamp](#):
>
> Thanks for helping that’s one problem solved, is it also possible to do some calculations in JSON-T like {{value\*100}}?

It doesn’t look like that’s supported, no, not with the JSON templater lib nor with the app (which looks like it supports _either_ MathJS _or_ a JSON template, but not both at the same time).

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 10, 2023, 3:02pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/18 "2023-07-10T15:02:10Z")

</div>

Yes it works, thanks.  
There are also a few bugs (3) I put below, maybe you have some spare time left and will be so kind to fix them?. May thanks in advance and I love your App.

1. If you change a Topics in settings the displayName is reset to default. You can fix this with replacing “displayName” with “title” in Topics or to fix the code so that it calls setCapabilityOptions (when the displayName changes) i’m trying to find a good spot to call it, I tried to use it in onSettings but that’s not working ok.

2. Your GitHub code can’t be run in debug mode (homey app run) it gives the error:

× App Crashed. Stack Trace:  
× Inspector is already activated. Close it with inspector.close() before activating it again.  
───────────────────────────────────────────────────────  
✓ Uninstalling `nl.hdg.mqtt`…  
✓ Removing container…  
node:internal/process/promises:288  
triggerUncaughtException(err, true /\* fromPromise \*/);  
^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason “Inspector is already activated. Close it with inspector.close() before activating it again.”.] {  
code: ‘ERR\_UNHANDLED\_REJECTION’  
}

1. Some warnings:

Warning: flow.triggers[‘device\_changed’].tokens[‘value’].type is missing, it defaults to “string”. Specifying a token type will be required in the future.  
Warning: flow.triggers[‘device\_changed’].tokens[‘Capability’].type is missing, it defaults to “string”. Specifying a token type will be required in the future.  
Warning: flow.triggers[‘device\_changed’].tokens[‘device’].type is missing, it defaults to “string”. Specifying a token type will be required in the future.  
Warning: flow.actions[‘set\_value’].titleFormatted is missing. Specifying a Flow card’s formatted title will be required in the future.

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [July 10, 2023, 3:03pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/19 "2023-07-10T15:03:35Z")

</div>

> [@Teun\_Pasterkamp](#):
>
> Your GitHub code can’t be run in debug mode (homey app run)

That’s exactly how I run it (well, using `homey app run --remote`) so that’s something local to you. Did you run `npm install` before `homey app run`?

---

<div class="post-metadata">

**Author:** ![Teun\_Pasterkamp](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/teun_pasterkamp/32/81191_2.png) [@Teun\_Pasterkamp](https://community.homey.app/u/Teun_Pasterkamp)\
**Post date:** [July 11, 2023, 3:47pm UTC](https://community.homey.app/t/how-to-call-a-homey-script-from-an-app/84313/20 "2023-07-11T15:47:51Z")

</div>

About de displayName problem, I have changed the code with the part below and it seems to work fine. Maybe you could implent it because there are more people with this problem.

And I also have a suggestion to enhance the "\_publishMessage"routine with a function mode to be called from a string. This way you can do more complex things, combine JSON-T and Mathjs to make a layout like {“Name”, “value”} and also do complex calculations on value. I put the code also below it’s tested and seems to work ok.

```
    if (changedKeys && changedKeys.includes('topics') && settings.topics) {
        try {
            await this.unsubscribeFromTopics();
            await this._updateCapabilities(capabilities);
            this.initTopics();
            await this.subscribeToTopics();
            await this.broadcast();

            // TSP Start
            for (let capabilityId in capabilities) { 
              var DPN = capabilities[capabilityId].displayName;
              if (DPN){
                await this.setCapabilityOptions( capabilityId, {title: DPN} ).catch(this.error); 
              };
            }
            // TSP - End 

        } catch(e) {
            // probably invalid JSON
            this.log("failed to update MQTT Device topics", e);
            this.restoreSettingsTopics(settings);
            this.initTopics();
        }
    } else {
        this.initTopics();
    }

```

* * *

```
    // output template?
    if(config.outputTemplate && config.outputTemplate.replace("{{", "").replace("}}", "").trim() !== 'value') {
        const template = config.outputTemplate;
        try {
            let state = this.getState() || {};
            state.value = payload;
            const mathjs = this.compiled.get(template);
            //
            // TSP - Start
            //
            // outputTemplate example
            //
            // "<<SetRoomTemperature@@if (Para != \"\" && Val){\n RV = '{\"' + Para + '\" : \"' + Math.round(State.value) + '\"}'\n return( RV );\n}"
            //
            // The format of the outputTemplate is:
            // "<<" - The Trigger to let this routine know that is has an embedded function
            // Para - Your passed value for the subroutine as string (can be multiple with a delimiter)
            // @@ - Delimiter for the Para and the Function code as String after @@ is your function code in a string
            //
            // The Subroutine has 2 passed variables:
            // Para - Your string para (e.g SetRoomTemperature)
            // State - the state variable which contains all current values of the device
            // e.g. {"target_temperature":null,"measure_temperature":22,"measure_temperature.1":24.5,"target_temperature.1":20,"value":20}
            // value is the value of the current item that's being processed
            //
            // Good web tool to convert your funtion to a string: https://tomeko.net/online_tools/cpp_text_escape.php?lang=en
            //
            if (template.startsWith("<<")){ // Embedded Function Trigger
              const Dum = template.replace("<<", "").split("@@"); // Remove Trigger and split rest of outputTemplate
              var Para = Dum[0]; // Get user parameter
              var Func = Dum[1]; // Get embedded function
              try {
                var FNC = new Function("Para", "State", Func);
                payload = FNC( Para, state );
              } catch(e) {
                this.log("TSP - Error calling Function.");
								} // TSP - End (Including the if then else loop)
            } else {
                if(mathjs) { // math?
                    payload = mathjs.evaluate(state);
                } else { // json-t
                    //
                    // JASON-T in the format {"SetRoomTemperature":"{{value}}"} or {"SetRoomTemperature":"{{measure_temperature.1}}"} etc...
                    //
                    if(!template.startsWith('{{') && (template.startsWith('{') || template.startsWith('['))) {
                        payload = jsontObject(template, state);
                    } else {
                        payload = jsontString(template, state);
                    }
                }
            }                
        } catch(e) {
            this.log("failed to format output message", e);
        }
    }

```
