How to call an app from RM with parameters

I have an app which sends data to InfluxDb on my Synology. The app requires three parameters.
The top level name or category of the data (string) e.g. "Pump".
The specific name of the measurement (string) e.g. "On".
The value of the measurement (real/boolean - in this case boolean) e.g. true.

In the rule machine I can set up a trigger whereby the changed value of a power measuring outlet can be tested to determine if the pump is on or not. This part is Ok.
How do I call my "WriteToInfluxDb" app from RM? How do I pass the three parameters (the first 2 are just strings, the 3rd being (in this case) a boolean).

In another use case I will receive an event when the water volume in a tank changes. This time Rm needs to call my app with parameters "Water", "Volume", Value ( real).

This probably seems like a trivial question, but after reading and searching for several days, I cannot see how to send these parameters to my app.
Please give me some details that I can work with, not just generalisations. I am happy to give more info if I have not expressed my problem clearly enough.
Thanks.

I would say we need more information. You cannot "call" apps from other apps (parent/child relationships and things like location events excepted); what you can do is call commands on devices from an app, either a child device or (usually this is how it works) a device the user selects in the app UI. You also can't really pass parameters to apps per se, though there are ways to get values into an app (e.g., from a device or user input) for whatever purpose if needed. There are certainly ways to pass parameters into device commands.

But none of this is really clear without seeing how your current setup should work.

The easiest way to do this, imo, will be to use a custom driver, that has a command you define that accepts the parameters you want to pass to your app. You would create a virtual device with this driver.

Then, that command in the driver does

def myCommand(param1, param2, param3) {
   sendEvent(name: "yourSpecialName", value: x, [data: param1: value1, param2: value2, param3:value3])
}

Your app subscribes to that device and "yourSpecialName" event:

subscribe(mySpecialDevice, "yourSpecialName", myHandler)

In the handler, the data (params) is Json encoded in evt.data.

void myHandler(evt) {
...
} 

Finally to make this happen from RM you use a custom action on that device, passing the params to the device command.

2 Likes

Thanks for your ideas. First a bit of clarification...
At the moment I have written my WriteToInfluxDb as a library. This was just to test it and get it working. This is "#include"d in my Water Volume device driver (with associated Virtual Device) which received volume measurements (in unsolicited Html messages) from my measuring device. It has a signature (wrong word?) like this... void SendToInfluxdb(Measurementstring, Keystring, Value) . All of this is working.
But I also wish to get other event data sent to InfluxDB, starting with a Tasmota outlet device which measures the current used by a water pump. I did not write the driver for this so I cannot simply include my library in it.
So I started converting my library to a device driver with capability "Actuator" and command "SendToInfluxdb", ["string", "string", "number"]. The idea was to set up two rules in RM which would respond to water pump current changes and then "call" my virtual device via it's custom command with parameters "Water", "Pump", true (or false) - true indicating that the current was above a certain value . i.e. the pump was on - false indicating that the pump was off. But it is not clear to me exactly how to set these parameters in RM. (edit: maybe this is not so difficult - maybe I could figure it out myself - but what about the following....)
I would then need to set up a rule which would respond to events generated by my Water Volume device driver (using sendEvent(name: "waterVolume", value: Volume, isStateChange: true)). This rule would also "call" my virtual device via it's custom command, but with "Water", "Volume", value - i.e. the number of litres. But how do I get the value from the trigger event into the value parameter of the custom command?
I could then use this method for events produced by other people's drivers which include values which I would like to log in InfluxDb.

Use %value% to access the most recent trigger event value. That's a string. If you need to convert it to an integer, you can put that string into a Number variable, and then use the Number variable as a parameter in your Custom Action.

The next release will support putting %value% directly into a param, not requiring the step of putting it into a variable first. Rule-4.1 allowed this.

Thanks for the reply - but OMG this seems like a convoluted process.
First it seems I had to create a local variable...
|Name|Type|Connector|Value|Delete|
|VolumeRM|Decimal|Create|0.0|Delete|

Then transfer my input parameter to it in Actions....
Set VolumeRM to value as decimal

Then "call" my custom command with 3 parameters...
SendToInfluxdb('Water', 'Volume', VolumeRM) on InfluxDB

But I must have done something wrong. I get ....
2021-08-30 03:07:06.099 pm errorjava.lang.NumberFormatException: For input string: "value" on line 6624 (method allHandler)
2021-08-30 03:07:06.087 pm infoAction: Set VolumeRM to value as decimal
2021-08-30 03:07:06.064 pm infoWaterVolumeToInfluxDB Triggered

Can you help?

Did you look at the screenshot above? You have to do that with %value%. Your logs show "value", not %value%. Use screenshots to post logs, not copy/paste, as the copied text gets treated by the forum...

Alternatively to having to do something "convoluted", make your custom driver do the .toInteger() conversion on the value you pass in with the custom command, and just pass %value% as a String.

Is this Ok?

No. It has to be %value%, not *value*

Event values are strings, so if you want a number, somewhere it has to be converted. You can do that in RM, or more directly in your driver.

Sorry for being so stupid - and thanks for your patience.
With regard to doing the conversion in my driver - I will look into it. My first thought was "yes but sometimes I will be logging a boolean, sometimes a real, sometimes a string, etc so how would my driver know what the parameter is supposed to be. Still, I will look into it.
Two more questions:
Can RM handle incoming events that have more than one parameter?
Is the procedure I am trying to use here documented or discussed anywhere?

Assuming you know by context in the rule, pass the type as another parameter. Or use separate methods (device commands).

No. Events only have a single value. Events can pass a map object as data (described in a post above), but these have to be specifically implemented.

Another way to do multiple values would be to encode them into a string (sent as the event value), and then take the string apart (which RM can do with variable actions).

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.