My goal is to create a system involving dynamic assets.
Assets within OpenRemote will be created / deleted to match whats happening in my data.
My issue is that I shouldn’t rely on my external clients to remember each Asset ID for each asset, for various reasons.
I would prefer to use a request or series of requests to obtain an array of all my Asset IDs.
I have them all parented by a Group Asset, where it’s ID should remain constant.
There’s no “children” key, or anything similar, within the JSON returned by ‘/api/master/asset/’ or other GET requests. Nor, do I believe, there is a GET children Request.
How can I go about this?
I was thinking of comparing the paths of Assets - try to check if they contain the Group Asset’s ID. But how would I get every Asset paths to check?
When viewing the Group Asset, you can see “Underlying Assets”. I know this isn’t a real attribute, but being able to obtain this would be perfect.
There also might be a way of re-creating my own “Underlying Assets” attribute which is automated through Groovy. But I am not sure if rules can be used in this way.
Thank you for the link.
I have worked on it today and have built a solution that works for me.
My rule automates an array attribute in the parent, given a few options.
Here’s the GROOVY code:
/*
* This rule will Automate an array of children for a parent Asset
* parentAssetId -- The AssetID of the parent which you would like to automate
* arrayAttribute -- The name of the Attribute within the parent which acts as the child array
* idAttribute -- The name of the Attribute within each child that contains the Integer to use as array index
*/
package org.openremote.test.rules
import org.openremote.manager.rules.RulesBuilder
import org.openremote.model.attribute.AttributeEvent
import org.openremote.model.query.AssetQuery
import org.openremote.model.rules.AssetState
import org.openremote.model.rules.Assets
import org.openremote.model.rules.Notifications
import org.openremote.model.rules.Users
import java.util.logging.Logger
Logger LOG = binding.LOG
RulesBuilder rules = binding.rules
Users users = binding.users
Notifications notifications = binding.notifications
Assets assets = binding.assets
// Options
String parentAssetId = "3kHesLOoFlis8aNGxWPlqB"
String arrayAttribute = "children"
String idAttribute = "id"
//LOG.info("COMPILING")
rules.add()
.name("Obtain Group Asset Children")
.when(
{ facts ->
//LOG.info("TRIGGERED")
//LOG.info("RAW Facts: "+ facts)
//Get array of children
//-------------------------------
//Obtain assets with Parent
def children = facts.matchAssetState(
new AssetQuery().parents(parentAssetId)
).map { childState ->
//LOG.info("CHILD")
//LOG.info("RAW CHILD STATE: "+childState)
//Obtain Details
def name = childState.assetName
def assetId = childState.id
def childId = childState.value
//LOG.info("Found: "+name+", '"+assetId+"'")
//Return as list of pairs
[childId, assetId]
}.toList()
//LOG.info("Children: " + children)
//Array of children, to be built
def childArray = []
children.each{ key, val ->
//Convert Optional to Int to use as key
def intKey = key.mapToInt(x -> x)
if(key.asBoolean())
{
childArray[intKey.getAsInt()] = val
}
}
//LOG.info("ARRAY: "+childArray)
//Compare to previous
//-----------------------------
//Get Parent
def parent = facts.matchAssetState(
new AssetQuery().ids(parentAssetId).attributeName(arrayAttribute)
).toList()[0]
//LOG.info("PARENT: "+parent)
//Get previous value
def optVal = parent.value
def oldVal = []
if(optVal.isPresent())
{
oldVal = optVal.get()
}
//LOG.info("VALUE: "+oldVal)
def eq = Arrays.equals(oldVal, childArray.toArray())
//LOG.info("OLD: "+oldVal+"\nNEW: "+childArray+"\nEQUAL: "+eq)
//Bind child array
//--------------------------
facts.bind("children", childArray)
return !eq
}
)
.then(
{ facts ->
//LOG.info("EXCECUTE")
//LOG.info("RAW Facts: "+facts)
//Get array and format into AttributeEvent
//------------------------------------------------
def children = facts.bound("children")
//LOG.info("RETAINED: "+children)
//Get Parent
def parent = facts.matchAssetState(
new AssetQuery().ids(parentAssetId).attributeName(arrayAttribute)
).toList()[0]
//LOG.info("Parent: "+parent)
//Create AttributeEvent to update parent
def assetId = parent.id
def pub = new AttributeEvent(assetId, arrayAttribute, children, new Date().getTime())
//LOG.info("PUBLISH EVENT: "+pub)
assets.dispatch(pub)
}
)