Adding Metadata Namespace via UI OH3

When adding Custom Metadata to an Item via the UI as below:

The metadata (in this case just a value) is added to the Item and can be accessed via my Javascript. However, unlike the “Well-known namespaces” (e.g State Description) the namespace is not shown under Metadata in the UI. Although it can still be accessed from the UI by using “Add Metadata” and typing in the namespace. I would be good if it could appear in the Item’s Metadata list, is this possible? Is it a case of its not there because of something I’m not doing, or is it intended that it is not displayed?

2 Likes

@ysc any ideas why the UI doesn’t display custom metadata namespaces that have been added?

As you can see I posed the the same question, although not so succinctly, a while back but no answer yet🙁

It’s simply not possible now to retrieve the list of metadata namespaces, so that’s the best we can do.
Here I offered an idea to make it possible - let the user describe their custom metadata namespaces and consider those as well, in addition to the “well-known” namespaces.

I don’t have an understanding of OH3’s underlying architecture so I can only speculate on a solution. But just a thought, given that the Well-known namespaces associated with an Item are displayed it means that either they are searched for within the Item and then listed or they are tagged/indexed in some way. Presumably it is the former and therefore you can’t list custom namespaces as you have no way of knowing their names. So, and I appreciate that this may well be easier said than done, would it be possible for a future update to index the metadata names associated with an Item. This would allow all of them to be listed while removing the need to search for each of the Well-known namespaces before listing them.

@ysc @danielwalters86
Having played around a bit the following, crude & thrown together, Javascript extracts the metadata from the registry and identifies the namespaces for a particular Item and therefore could presumably be used as a basis for providing a list of custom namespaces:

var logger          = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil");
var _bundle = FrameworkUtil.getBundle(scriptExtension.class);
var bundle_context = _bundle.getBundleContext()
var MetadataRegistry_Ref = bundle_context.getServiceReference("org.openhab.core.items.MetadataRegistry");
var MetadataRegistry = bundle_context.getService(MetadataRegistry_Ref);
var Metadata = Java.type("org.openhab.core.items.Metadata");
var MetadataKey = Java.type("org.openhab.core.items.MetadataKey");


var ItemOfInterest = "gStudy";
var i=0;
var ArrayOfMetadata = [];
var Namespace = [];
var Item = [];
var a = 0;
var b= 0;
var returnvalue = MetadataRegistry.getAll().stream().forEach(function(metadata){ArrayOfMetadata[i] = String(metadata); 
                                                              a = ArrayOfMetadata[i].indexOf("key=")+ 4;
                                                              b = ArrayOfMetadata[i].indexOf(":");
                                                              Namespace[i] = ArrayOfMetadata[i].slice(a,b);
                                                              a = b + 1;
                                                              b = ArrayOfMetadata[i].indexOf(","); 
                                                              Item[i] = ArrayOfMetadata[i].slice(a,b);
                                                              i++;
                                                              });     // Get all Metadata

logger.info("MetadataRegContent type is: " +typeof ArrayOfMetadata);
for (var j=0; j<i; j++){logger.info("MetadataRegContent keys are: " +ArrayOfMetadata[j])};
logger.info("\n\n");
for (var j=0; j<i; j++){logger.info("Metadata namespaces for Item (" +Item[j] +") are: " +Namespace[j]);};
logger.info("\n\n");
logger.info("Metadata namespaces for Item (" +ItemOfInterest +") are: ");
for (var j=0; j<i; j++){if (Item[j] == ItemOfInterest)logger.info("                                           " + Namespace[j]);};
logger.info("\n\n");

The logger output is:

2021-01-25 12:52:32.842 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'PIR01_MotionIntrusion' changed from OFF to ON

==> /var/log/openhab/openhab.log <==

2021-01-25 12:52:43.959 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata type is: object

2021-01-25 12:52:44.021 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:gBirchcroft, value=Location, configuration=[]]

2021-01-25 12:52:44.054 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:Desk, value=Location, configuration=[isPartOf=gStudy]]

2021-01-25 12:52:44.077 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:InLineSwitch01_Switch, value=Point, configuration=[hasLocation=gStudy]]

2021-01-25 12:52:44.095 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:LocalSun_Rise_Start, value=Point, configuration=[isPointOf=LocalSun]]

2021-01-25 12:52:44.111 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:gStudyStatus, value=Point, configuration=[hasLocation=gStudy]]

2021-01-25 12:52:44.128 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=MotionParameters:Study_TestSwitch2, value= , configuration=[]]

2021-01-25 12:52:44.145 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=OccupancyParameters:gStudy, value=Test Namespace, configuration=[OccupiedDelay=0.0, UnoccupiedDelay=4.0]]

2021-01-25 12:52:44.163 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:PIR01_MotionIntrusion, value=Point, configuration=[hasLocation=gStudy]]

2021-01-25 12:52:44.194 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=Motion:Study_TestSwitch2, value= , configuration=[]]

2021-01-25 12:52:44.212 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:LocalSun_CivilDusk_Start, value=Point, configuration=[isPointOf=LocalSun]]

2021-01-25 12:52:44.228 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:TestSwitch_01, value=Point, configuration=[hasLocation=gLounge]]

2021-01-25 12:52:44.246 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:gDownstairs, value=Location, configuration=[isPartOf=gBirchcroft]]

2021-01-25 12:52:44.262 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:LocalSun, value=Equipment, configuration=[hasPoint=LocalSun_Rise_Start]]

2021-01-25 12:52:44.280 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:gStudy, value=Location, configuration=[isPartOf=gDownstairs]]

2021-01-25 12:52:44.296 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:gLounge, value=Location, configuration=[isPartOf=gDownstairs]]

2021-01-25 12:52:44.313 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:LocalSun_CivilDawn_Start, value=Point, configuration=[isPointOf=LocalSun]]

2021-01-25 12:52:44.329 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:ExtensionLead01_3_Switch, value=Point, configuration=[hasLocation=gStudy]]

2021-01-25 12:52:44.347 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:ExtensionLead01_2_Switch, value=Point, configuration=[hasLocation=gStudy]]

2021-01-25 12:52:44.363 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:ExtensionLead01_1_Switch, value=Point, configuration=[hasLocation=gStudy]]

2021-01-25 12:52:44.380 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:LocalSun_Set_Start, value=Point, configuration=[isPointOf=LocalSun]]

2021-01-25 12:52:44.397 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=OccupancyParameters:gLounge, value= , configuration=[OccupiedDelay=0.0, UnoccupiedDelay=3.0]]

2021-01-25 12:52:44.414 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata elements are: Metadata [key=semantics:gLoungeStatus, value=Point, configuration=[hasLocation=gLounge]]

2021-01-25 12:52:44.441 [INFO ] [org.openhab.rule.1ac199dff6         ] - 




2021-01-25 12:52:44.510 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gBirchcroft) are: semantics

2021-01-25 12:52:44.534 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (Desk) are: semantics

2021-01-25 12:52:44.552 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (InLineSwitch01_Switch) are: semantics

2021-01-25 12:52:44.568 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (LocalSun_Rise_Start) are: semantics

2021-01-25 12:52:44.586 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gStudyStatus) are: semantics

2021-01-25 12:52:44.602 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (Study_TestSwitch2) are: MotionParameters

2021-01-25 12:52:44.624 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gStudy) are: OccupancyParameters

2021-01-25 12:52:44.641 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (PIR01_MotionIntrusion) are: semantics

2021-01-25 12:52:44.659 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (Study_TestSwitch2) are: Motion

2021-01-25 12:52:44.676 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (LocalSun_CivilDusk_Start) are: semantics

2021-01-25 12:52:44.693 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (TestSwitch_01) are: semantics

2021-01-25 12:52:44.710 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gDownstairs) are: semantics

2021-01-25 12:52:44.728 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (LocalSun) are: semantics

2021-01-25 12:52:44.747 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gStudy) are: semantics

2021-01-25 12:52:44.769 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gLounge) are: semantics

2021-01-25 12:52:44.789 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (LocalSun_CivilDawn_Start) are: semantics

2021-01-25 12:52:44.836 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (ExtensionLead01_3_Switch) are: semantics

2021-01-25 12:52:44.863 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (ExtensionLead01_2_Switch) are: semantics

2021-01-25 12:52:44.898 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (ExtensionLead01_1_Switch) are: semantics

2021-01-25 12:52:44.915 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (LocalSun_Set_Start) are: semantics

2021-01-25 12:52:44.945 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gLounge) are: OccupancyParameters

2021-01-25 12:52:44.972 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gLoungeStatus) are: semantics

2021-01-25 12:52:45.019 [INFO ] [org.openhab.rule.1ac199dff6         ] - 




2021-01-25 12:52:45.074 [INFO ] [org.openhab.rule.1ac199dff6         ] - Metadata namespaces for Item (gStudy) are: 

2021-01-25 12:52:45.164 [INFO ] [org.openhab.rule.1ac199dff6         ] -                                            OccupancyParameters

2021-01-25 12:52:45.184 [INFO ] [org.openhab.rule.1ac199dff6         ] -                                            semantics

2021-01-25 12:52:45.216 [INFO ] [org.openhab.rule.1ac199dff6         ] - 


Where:

  • the first block are the data extracted from the Metadata Registry and converted to an array of strings.

  • the second block is a list of all Item/Namespace pairs

  • and the third block is a list of namespaces for a particular Item (gStudy)

I’m sure there is room for improvement. In particular by accessing “ArrayOfMetadata” directly as an object rather than converting to a string. Unfortunately as I am just teaching myself JS as I go I’ve not managed to crack that yet since although it says it of type object, when I try an operation such as Object.keys(ArrayOfMetadata) eg:

ArrayOfMetadata = MetadataRegistry.getAll();
logger.info("ArrayOfMetadata type is: " +typeof ArrayOfMetadata);
var ArrayOfKeys = Object.keys(ArrayOfMetadata);
logger.info("MetadataRegContent keys are: " +ArrayOfKeys);

it crashes with a type error :unamused:

2021-01-25 13:09:46.624 [INFO ] [org.openhab.rule.1ac199dff6         ] - ArrayOfMetadata type is: object

2021-01-25 13:09:46.669 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '1ac199dff6' failed: TypeError: [Metadata [key=semantics:gBirchcroft, value=Location, configuration=[]], Metadata [key=semantics:Desk, value=Location, configuration=[isPartOf=gStudy]], Metadata [key=semantics:InLineSwitch01_Switch, value=Point, configuration=[hasLocation=gStudy]], Metadata [key=semantics:LocalSun_Rise_Start, value=Point, configuration=[isPointOf=LocalSun]], Metadata [key=semantics:gStudyStatus, value=Point, configuration=[hasLocation=gStudy]], Metadata [key=MotionParameters:Study_TestSwitch2, value= , configuration=[]], Metadata [key=OccupancyParameters:gStudy, value=Test Namespace, configuration=[OccupiedDelay=0.0, UnoccupiedDelay=4.0]], Metadata [key=semantics:PIR01_MotionIntrusion, value=Point, configuration=[hasLocation=gStudy]], Metadata [key=Motion:Study_TestSwitch2, value= , configuration=[]], Metadata [key=semantics:LocalSun_CivilDusk_Start, value=Point, configuration=[isPointOf=LocalSun]], Metadata [key=semantics:TestSwitch_01, value=Point, configuration=[hasLocation=gLounge]], Metadata [key=semantics:gDownstairs, value=Location, configuration=[isPartOf=gBirchcroft]], Metadata [key=semantics:LocalSun, value=Equipment, configuration=[hasPoint=LocalSun_Rise_Start]], Metadata [key=semantics:gStudy, value=Location, configuration=[isPartOf=gDownstairs]], Metadata [key=semantics:gLounge, value=Location, configuration=[isPartOf=gDownstairs]], Metadata [key=semantics:LocalSun_CivilDawn_Start, value=Point, configuration=[isPointOf=LocalSun]], Metadata [key=semantics:ExtensionLead01_3_Switch, value=Point, configuration=[hasLocation=gStudy]], Metadata [key=semantics:ExtensionLead01_2_Switch, value=Point, configuration=[hasLocation=gStudy]], Metadata [key=semantics:ExtensionLead01_1_Switch, value=Point, configuration=[hasLocation=gStudy]], Metadata [key=semantics:LocalSun_Set_Start, value=Point, configuration=[isPointOf=LocalSun]], Metadata [key=OccupancyParameters:gLounge, value= , configuration=[OccupiedDelay=0.0, UnoccupiedDelay=3.0]], Metadata [key=semantics:gLoungeStatus, value=Point, configuration=[hasLocation=gLounge]]] is not an Object in <eval> at line number 183

@Birchcroft are you now trying to access metadata within a rule, or are you trying to work out whether it’s technically possible to manage custom namespaces from the UI?

@danielwalters86 Primarily I’m using metadata to control what actions a generic rule performs for a particular item. A simple example being that if a motion sensor controls 2 lights I might want one to switch off 5 mins after motion ceases and the other one to switch off 10 mins after motion ceases. I don’t want to hard code these values into the rule (eg as a variable) as they may change. So, for better or worse, I have decided the approach to take is to store the time-to-remain-on in metadata associated with each Item so it can be easily changed without having to update the rule. It also means that when combined with groups I can dyanmically add/remove/change items processed by the rule without modifying the rule. Another example is to use the metadata to specify periods of time when actions can/cannot happen.

I now have the ability to read metadata from any namespace I know the name of, including custom name spaces, which enables me to execute the simple example above. Of course the rule has to know the name of the namespace which is not a problem since namespaces created via the UI it can be hard-coded because the namespace will have been created for a specific purpose, i.e. to be used by a rule. And in the unlikely event the need arises to dynamically create a namespace then the rule will of course know the name of the namespace it has created. I’ve yet to try writting data to a namespace which is something I will want to do in the future and am confident is achievable

As part of the above I created a custom namespace from the UI and was surprised when it did not show up in the Metadata list, although the UI does allow one to edit the namespace as long as you can remember its name. This is why I posted the original question as it would make life a bit easier if the name was available via the UI.

Further, as it stands to only way to find out which namespaces an Item has is either to keep a “paper” record or by writing a bit of code to get and display the list. Also of course as it stands it is not possible to delete custom namespaces via the UI so if you need to remove one it has to be done via code unlike with Well-known namespaces which can be deleted via the UI. So I new at some inderminate time in the future if access from the UI was not possible I would need to produce some code to manipulate namespaces although I did not consider it urgent. However, when the statement:

was made as part of this thread I decided to have a quick look to see if that was in fact the case and if not report back in oder that it might make it possible for the UI to be updated at sometime in the future.

I’m completely on board as I’m doing something similar - I’m adding metadata to my motion items that specify which lights to turn on and how long to keep them on for.

I’m using the following code in my script action section of the rule (which may or may not help you):

load(OPENHAB_CONF+'/automation/lib/javascript/core/metadata.js');
var METADATA_NAMESPACE = "my_namespace"

function get_timeout(itemName){

       var metadata_key_timeout = "timeout";
       var metadata_key_value_timeout = get_key_value(itemName, METADATA_NAMESPACE, metadata_key_timeout)
       Log.logDebug("my rule", "Metadata config timeout value = " + metadata_key_value_timeout);
       return (metadata_key_value_timeout === null ) ? "15m" : metadata_key_value_timeout;

}

It certainly is from the jsr223 rule engine, I’m not sure if @ysc meant that it’s not possible to do this in the context of the UI code.

Yes, it is helpful in so far as, allowing for coding styles, it is very similar to my approach and therefore gives me confidence that I am on the right track.

Where I differ slightly is that while I use a function (getMetadataKeyValue) similar to your: get_key_value to get a single metadata value I also have a routine: getMetadata which allows me to get all the metadata from a custom namespace and access it using the keys. Of course I appriciate that you may also have such a routine you use elsewhere.

In the following snipit from my generic rule which sets room occupancy status for any room it derives the ‘room name’ from the location of the trigger (as contained in the trigger’s semantic namespace. I.e. the UI’s “hasLocation”) and then uses the ‘room name’ to define the Item used to display the room’s status and get 2 timers from the room’s metadata, accessing the values using their keys. One timer determines how long the sensor has to be ON before the room is marked Occupied and the other determines how long it has to be OFF before the room is considered Unoccupied.

var Trigger = event.itemName;
if (LogingEnabled)logger.info("Trigger was: " + Trigger);
var Room = getMetadataKeyValue(Trigger, SemanticModelNamespace, LocationOfItem);
if (LogingEnabled)logger.info("Trigger Event was: " +Trigger +"  Room is: " +Room);

var RoomStatus = Room + "Status";     // String Item to be updated with status

// Get Metadata and set delay time
var RoomMetadata = getMetadata(Room, OccupancyParametersNamespace);
if (RoomMetadata !== null)
{
  if (LogingEnabled)logger.info("" + Room +" Metadata is: " + RoomMetadata);
  RoomMetadata = RoomMetadata.configuration;
}
if (LogingEnabled)logger.info("" + Room +" Metadata is: " + RoomMetadata);
if (RoomMetadata !== null)
{
  OccupiedDelayPeriod = RoomMetadata[OccupiedDelay];
  if (OccupiedDelayPeriod === undefined)OccupiedDelayPeriod = DefaultOccupiedDelayPeriod;
  UnoccupiedDelayPeriod = RoomMetadata[UnoccupiedDelay];
  if (UnoccupiedDelayPeriod === undefined)UnoccupiedDelayPeriod = DefaultOccupiedDelayPeriod;
}
else
{
  OccupiedDelayPeriod = DefaultOccupiedDelayPeriod;
  UnoccupiedDelayPeriod = DefaultUnoccupiedDelayPeriod;
}
if (LogingEnabled)logger.info("Occupied Delay period for: " + Room +" is: " + OccupiedDelayPeriod);
if (LogingEnabled)logger.info("Unoccupied Delay period for: " + Room +" is: " + UnoccupiedDelayPeriod);

I actually hadn’t thought about attaching the metadata to the semantic room items but that probably makes sense.

I’m actually in two minds myself. In most common cases I suspect it is a reasonable thing to do, particularly for something like room status. However, I occasionally think of scenarios, and so far dismiss them as over complicating things, where I envisage a motion sensor additionally controlling something in a different room. One such scenario could be: if it’s night, the house is unoccupied, and motion is detected on the path up to the house then switch the entrance hall light on for a short period as well as the outside lights. This would ensure the light is on as I enter and before the internal motion sensor is triggered (sensor location not optimal for the door). However, this could be achieved simply by the alternative of putting a contact sensor on the door or using a second motion sensor, both of which would also eliminate false triggers.

What I may do is have a metadata item associated with the trigger that tells it which list of items to use, which will provide what may or may not prove to be useful flexibility.

UPDATE:

I have now made a decision, of sorts, as to the way I am moviing forward. The main features of the approach I am going to take are:

  • Rules will relate to a specific function. E.g. Update occupancy status, manage ON/OFF devices, Manage more complex systems such as the heating, etc.

  • Each Rule will require a specific Namespace to be associated with the Trigger. It will use the metadata contained in that namespace to determine what Items the rule is to be run for.
    * Each Trigger will have associated with it the Namespace required by the Rule it is triggering. The metadata within the namespace will provide the name of a Group which contains the Items to be controlled and the name of the Item Namespace to use. (An alternative would be for the Trigger to have a single namespace for all rules which defines the names of the Group and Item Namespace to be used by each Rule.).

  • Each Rule will use the metadata contained in each Item’s namespace to manage how that Item is controlled (The name of the Namespace having been defined by the Trigger, as above). If the namespace does not exist or elements of the metadata are missing default actions will be taken.
    * Each Item will, optionally, have associated with it the Namespace specified by the Trigger. The namespace will contain the operational parameters. E.g. delay times, periods of activity, time dependent dimmer levels, (follow-on rules to be triggered ?) etc.
    * An Item may be controlled by different rules under different circumstances. E.g. a light might be controlled by a motion-rule when the house is occupied, but be controlled by a timer-rule when the house is unoccupied. Thus an Item may have Namespaces associated with more than one Rule. That is, if it is in multiple groups each associated with a different Trigger it can have a different Namespace for each Trigger.

Thus: If TriggerA was expected to trigger 2 rules, RuleA and RuleX, it would have the Namespaces: RuleA and RuleX, each namespace containing the name of the Group to which the Items the rule applies to belong and, the name of the Namespace associated with the Item which would contain the metadata required by the rule. So the Namespace RuleA (belonging to TriggerA) would contain GROUP:gTriggerARuleA and ITEMNAMESPACE:TriggerALights. The Namespace RuleX (belonging to TriggerA) would contain GROUP:gTriggerARuleZ and ITEMNAMESPACE:TriggerZLights. Accordingly RuleA would act on each Item in Group gTriggerARuleA in accordance with the metadata in the Items Namespace TriggerALights and, RuleZ would act on each Item in Group gTriggerARuleZ in accordance with the metadata in the Items Namespace TriggerZLights.

Items in gTriggerARuleA would, optionally, have the Namespace defined by the Trigger which the rule would use to determine what actions to take. An Item could also be a member of other groups and hence have additional namespaces for the Rule action on those groups. E.g ItemA may be a member of Groups gTriggerARuleB and gTriggerARuleZ in which case it would, optionally, have associated with it the Namespaces RuleB_Parameters and RuleZ_Parameters.

If I’ve got it right this would mean that once a rule is written it could be invoked by any number of Triggers and control any number of Items without having to be modified in anyway. It would also mean that as the system grows/develops Items can be added/removed/relocated etc without the need to do anything other than update the metadata and/or move an Item between Groups as required.

Finally if I find I need to persist data over reboots or implement global data between different Rules and/or Items I will probalby do this by creating an Item “PersistantData” and use one or more custom Namespaces to store the data.

Maybe so, but logically I can’t see why that would be the case, since the UI can:

  1. Read/Write the Metadata Register, as demonstrated by it adding Custom Namespaces and linking namespaces to Items.

  2. Determine which Well-known Namespaces are associated with an Item and display them in the UI. To do this it must either (a)get the infromation from the Metadat Registry, or (b)have access to a separate list of Item/Namespace dependancies which it compiles and maintains itself. If (a) then as my code demonstrated there would be nothing stopping it getting the names of Custom Namespaces. If (b) I can think of no reason that the Custom Namespaces could not be added to the list when they are created.

You can try to create your own UI using the REST interface. I had the same problem and decided to go this way. There even is a project which allows to create UI for REST interfaces w/o any coding. See https://www.appsmith.com/ I did this for a custom metadata namespace in a couple of hours.


It might not be the nicest interface (yet) but it does exactly what I want - add metadata to items and edit it.

@UrksiWurksi thanks for the response. As you suggest I will eventually get around to writing a UI/form to enter the metadata I need. However, at the moment I’m concentrating on the backend/automation (while teaching myself OH and JavaScript) so I’m happy entering the small amount of metadata I need at the moment by hand. My original post was really to express my surprise/disappointment that the OH UI does not list all namespaces associated with an Item and that maybe it should be added in the future.