Any way for one child app to run another child app?

Curious if there is a way to have one child app trigger another child app of the same parent? Without using a device or middle man.

A simple 'If this happens' run(xxx) type of thing.

Thanks

Just bounce whatever you're trying to do off of the parent app. I assume the one child that wants to interact with another child knows either label or id and can pass that info to the parent.

@bravenel , anyway to do this (like RM does) ? Would be great to trigger one child app from another, that has the same parent.

Thanks

Think @tomw may be right. If you expose the getAllChildApps() method from the parent app to the child it should then be able to ask the parrent app to trigger a specific child app.

1 Like

Yes, this was what I had in mind (and have done in a few of my apps). Is there a reason it won't work for your need, @bptworld?

1 Like

How, I haven't seen any command to do that?

Again, in one child app I would like (in simplest terms):

if(x happens) {
run(other child app)
}

Thanks

Thinking

childInstance.run()

Where run() is the method inside the child that executes the code you are interested in.

Sure, the parent is the intermediary. One child calls a parent method (parent.method(appId)), with the request, and then the parent calls the other child's method.

See Rule Machine API for some hints on how to do it.

Also, doesn't even have to be sibling app. Use location events to send messages between apps.

4 Likes

You could do:

if(x) { parent.run(child id) }

Or even additionally pass data, method name on the child, and the like, as needed.

@bravenel's suggestion on location events hadn't occurred to me and would be even more versatile.

1 Like

Here's a quick example. Install the parent, and use it to install a child. Then open and save the child to trigger updated(). The child calls back into itself via the parent, but you could obviously use this structure to call another child.

parent:

/*
 * lifted from Joel Wetzel's Combined Presence parent app
 */


definition(
    name: "misc app examples",
    namespace: "tomw",
    author: "tomw",
    description: "",
    category: "Convenience",
	iconUrl: "",
    iconX2Url: "",
    iconX3Url: "")


preferences {
     page name: "mainPage", title: "", install: true, uninstall: true
}

def installed() {
    log.info "Installed with settings: ${settings}"
    initialize()
}

def updated() {
    log.info "Updated with settings: ${settings}"
    initialize()
}

def initialize() {
    log.info "There are ${childApps.size()} child apps installed."
    childApps.each { child ->
    	log.info "Child app: ${child.label}"
    }
}

def installCheck() {         
	state.appInstalled = app.getInstallationState()
	
	if (state.appInstalled != 'COMPLETE') {
		section{paragraph "Please hit 'Done' to install '${app.label}' parent app "}
  	}
  	else {
    	log.info "Parent Installed OK"
  	}
}

def mainPage()
{
    dynamicPage(name: "mainPage")
    {
        installCheck()
		
		if (state.appInstalled == 'COMPLETE')
        {
            section("<b>Presence Utils:</b>")
            {
                app(name: "anyOpenApp", appName: "child comms", namespace: "tomw", title: "<b>Add a new child comms instance</b>", multiple: true)
			}
		}
	}
}

child:

/*

 */

definition(
    name: "child comms",
    parent: "tomw:misc app examples",
    namespace: "tomw",
    author: "tomw",
    description: "",
    category: "Convenience",
    iconUrl: "",
    iconX2Url: "",
    iconX3Url: "")

preferences
{
    page(name: "mainPage1")
}

def mainPage1()
{
    dynamicPage(name: "mainPage1", title: "", install: true, uninstall: true)
    {
        section
        {
            input name: "instanceName", type: "string", title: "Name for this child instance", required: true
            input name:	"enableLogging", type: "bool", title: "Enable Debug Logging?", defaultValue: true, required: true
        }
    }
}

def logDebug(msg)
{
    if(enableLogging)
    {
        log.debug "${msg}"
    }
}

def installed()
{
    app.updateLabel("child comms - ${instanceName}")
}

def updated()
{
    installed()
    getParent()?.getChildAppByLabel(app.getLabel())?.soundOff()
}

def uninstalled()
{
    unsubscribe()
}

def soundOff()
{
    logDebug("child comms instance ${app.getLabel()}")
}
1 Like

Awesome! Thanks all, I'll be playing around with this tonight.

3 Likes

HSM is an example of an app that uses location events to communicate with other apps, notably with Maker API and RM. One nice thing about this approach is that you can send a Map as data in an event. A recipient app subscribes to the location event. HSM itself both sends location events, and subscribes to them so that RM or Maker API can arm/disarm it, and/or trigger off HSM events.

One minor disadvantage of the child-parent-child approach is that each such message has to load the parent app and the destination app, compared to location event just loading the recipient app. But both have their uses.

This is the line of Maker API that sets HSM status:

sendLocationEvent(name: "hsmSetArm", value: id.toString())

You can also create Location Variables (not to be confused with Hub Variables coming soon, or with RM variables).

createLocationVariable("myLocVar", ["value 1", "value 2"])

After doing that, location.myLocVar holds the most recent value sent in a location event. The location variable will only take on pre-defined values, although sendLocationEvent can send any value.

5 Likes

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