Who has got some clever ideas for item naming schemes?

It has come time to re-write all my config as it has evolved into a bit of a mess over the last few years. I am trying to come up with a clever naming system for my various items, both physical bindings and virtual items. This needs to include group names etc as well.

Just wondering what others are doing in terms of how they structure their item names etc? Any clever schemes in use which make your life a lot easier?

I am also thinking about how to integrate other control systems, such as an Amazon Echo (which is on route!). So something that makes it easier for voice activated controls to parse/match to items would be useful. Although not sure how feasible this really is.

Open to any ideas here - thought it might be a worthwhile discussion - especially for those of us with slightly more advanced configs.

Cheers,
Ben

2 Likes

Hi Ben,

I’m very new to OH, but have used a number of open source applications in the past. Naming items is one of the areas I try and think about first.

So for me I try and keep to something sensible, such as: Living_Room_Floor_Lamp. So I know where it’s located and what it is. I create groups for each room and item types. Where I have a cross over, such as thermostats I then use the model number, such as: First_Floor_Landing_HRT4_ZW_Temperature.

As yet I haven’t come any where close to mastering OH but making gains slowly. So I will follow this discussion with interest.

Cheers,

Garry

Greetings,

naming is always a subject for discussions, it highly depends on you personal preferences.

For me the following scheme has worked out fine (If not required I skip e.g. BuildingPart or Room to keep it shorter):
<PrimaryBinding>_<Building>_BuildingPart>_<Room>_<Item>

Examples:

  • KNX_B1_F1_RR_CeilingLight (KNX connection, Building 1, Floor 1, Restroom, Ceiling Light)
  • MQTT_G1_Humidity ( MQTT-Binding, Garage 1, Humidity-Sensor)

For more complex technical things (e.g. Heating) I prefer:
<PrimaryBinding>_<Building>_BuildingPart>_<Room>_<Object>_<ObjectAttribute>

Example:

  • MQTT_B1_F0_TR_HEATING_FlameStatus (MQTT Binding, Building1, Cellar, Technic Room, Heating, Status of flame)

The PrimaryBinding part can be questioned, for me this makes it easier in debugging/developing.
Following the pure “thing” pov this would be obsolete as ideally it should not matter where a “thing” is connected to.

Another option is to use the grouping functionality to group items on various criteria, e.g. group everything like thermostats, room temperatures, central heating in a “Heating” group and/or group be the location (e.g. Thermostat, windows contact lights, sensors, shutters etc. into the group “Livingroom”).
This may lead to easier site map creation.

In the end, as I said in the beginning, this highly depends on your point of view. Sometime the lazy me names a thing simply “thing1” during testing… :wink:

Cheers,
Oggerschummer

PS: One nasty behavior I discovered: When connecting to Apples HomeKit the item name is used to identify it, nothing else. So having technical names will be a problem then.

What an excellent question. This is something I’ve given a lot of thought to and I admit I’ve not come up with anything satisfying.

So here are what I consider when it comes to naming things:

  1. what sort of coding/naming standards seem to exist in the community, written or unwritten (e.g. look at examples)
  2. when I’m writing code or debugging logs, what information would I want to know that could be encoded in the name
  3. how do I want to organize my code and how can naming conventions contribute to that
  4. will I ever need to construct the name of an Item based on some other information (e.g. find a switch in a Group based on the name of a sensor that tripped)?

So I’ve come up with the following naming scheme:

  • I use first letter capitalized for Item names (1.) which helps distinguish them from vars and vals in Rules
  • I separate major parts of an Item name with an “_” (1., 4.) which makes it easy to strip out the common part of a name and add to it (e.g. when N_D_Front is opened, I can pull N_D_Front_Last_Opened out of the group gDoorSensorsTime with the line: gDoorSensorsTime.members.filter(dt|dt.name == door.name+"_Last_Opened").head
  • Group names all start with a lowercase ‘g’ (1., 2.)
  • I prepend Item names with some letters to indicate what the Item is for and what sort of object the Item represents (2., 3.):
// Naming Conventions:
//  - Groups all start with a lowercase g
//  - Takes the form of X_X_Name
//      - The first letter denotes the Item type:
//              None    Internal utility
//              'N'             Sensor
//              'S'             Switch
//              'T'             Trigger (switch without a state)
//              'W'             Weather
//      - The second letter denotes the object type
//              None    Internal utility
//              'C'             Controller
//              'D'             Door
//              'I'             Input
//              'L'             Light
//              'V'             Value
//              'W'             Window

For example, the Garage Door reed sensor is named N_D_GarageDoor1 while the relay that opens the door is named T_D_GarageDoor1.

Unfortunately I’ve not had the discipline to stick with these naming conventions throughout my system and I’ve not spent the time to refactor everything to follow it. I’ve actually found the prepended letters to be more of a pain than a benefit because I have to keep going back to the little comment I pasted above that I put in one of my .items file to remember what the letters stand for and thus far I’ve found them of limited use. If I keep this approach I may drop the letters for words or drop the concept entirely.

One last consideration is how I organize everything into files which is tangential to your question but relevant to your refactoring activity. I’ve seen two approaches. One approach is to organize your Items based on their location (e.g. firstFloor.items, basement.items, etc.) and the other approach is to organize by function (e.g. lighting.items, hvac.items, etc.). I’m a strong proponent of the latter approach.

When Items and particularly Rules are organized by function it increases your opportunities for merging rules, utilizing lambdas, and otherwise avoiding duplication of code. This is because while there is likely to be little in common in your rules for sensing your exterior doors on your first floor and the lights on the first floor, there is going to be a lot in common with controlling the lights on the first floor and in the basement.

The reason I bring this up is because the same reasoning can be applied to how one uses Groups. In my mind there are three reasons to use Groups.

  1. Grouping things for display on your sitemap, e.g. putting everything in one room in a Group and just putting the Group on your sitemap
  2. Grouping things for persistence, e.g. set up your .persist files using Groups and then just assign those Groups to Items to control how they are persisted
  3. Grouping things to help simplify Rules, e.g. triggering a Rule based on an update to one of its members, getting a reference to an Item by its name, checking the state of all the members of a Group.

I’ve actually abandoned 1. in my setup. When you put a Group on a sitemap you have no ability to customize how its members are displayed and I almost always want to customize them (e.g. change color, provide a mapping for switches, etc). 2. is something I just thought of and think I’m going to start looking into. 3. is exceptionally powerful and I cannot express in strong enough terms how doing this provides opportunities to simplify your code. Since I adopted this approach I’ve more than halved my lines of code and accomplish more. See this posting for how I use it in my lighting.

7 Likes

Now I have to redo everything. grrr. but thanks man. Appreciate you for putting this together.

I did think about this, but I am not sure about locking items to a particular technology. For example I have changed my Weather_TempOut item binding a number of times, from an HTTP binding (Wunderground), to the Weather Binding, to an MQTT binding reading a value from my custom built weather station.

IMO the beauty of openHAB is the abstraction it provides from the real world technology. So including the binding type in the name is a non-starter for me, although I can see how it would make parsing rules and errors quite useful! Maybe it would make more sense to add items to binding groups - i.e. all KNX items would belong to a gKNX group?

@rlkoshak I also started down the route of putting a type code at the start, e.g. Physical Sensor, Physical Actuator, Virtual Sensor, Virtual Actuator etc. But like you, decided this didn’t really give me much benefit and would be a pain to remember/maintain.

I also toyed with the idea of using codes for areas/locations but decided on full words to help with voice command parsing and recognition.

I definitely agree with your comments around file organisation, and have done exactly that since day one. Not planning to change that much at all. Same with groups, they are very powerful when designed right. Initially I was a bit eager with my groups and created them for everything - as part of this refactoring I am planning to simplify a bit and only use groups where I get tangible benefits, i.e. persistence (most useful) and rule streamlining.

Looks like I am not alone with this then! Thanks for the feedback guys!!

Mine is decent, but I like his coding standard, so I am going to change
//Begin Kitchen Items

    Switch  SmartFridge         "Fridge Outlet"                                     (gFirstFloorKitchen,outlet)       { zwave="5:command=switch_binary,refresh_interval=30" }
Number  SmartFridge_Power   "Fridge Power  [%.2f W]"            (gFirstFloorKitchen,power)    { zwave="5:command=meter,meter_scale=E_W" }
Number  SmartFridge_Energy  "Fridge Consumption  [%.2f KWh]"    (gFirstFloorKitchen,power)    { zwave="5:command=meter,meter_scale=E_KWh" }
Number  SmartFridge_Volts   "Fridge Voltage [%.1f V]"           (gFirstFloorKitchen,power)    { zwave="5:command=meter,meter_scale=E_V" }
Number  SmartFridge_Amps    "Fridge Amperage [%.2f A]"          (gFirstFloorKitchen,power)    { zwave="5:command=meter,meter_scale=E_A" }

//End Kitchen Items

//Begin Washer and Heater Items

    Switch SmartWasher         "Washer"                             (gSecondFloorWasher,outlet)             {zwave="2:command=switch_binary,refresh_interval=30" }
Number SmartWasher_Power   "-> Power  [%.2f W]"                     (gSecondFloorWasher,power)      {zwave="2:command=meter,meter_scale=E_W" }
Number SmartWasher_Energy  "-> Consumption  [%.2f KWh]"             (gSecondFloorWasher,power)      {zwave="2:command=meter,meter_scale=E_KWh" }
Number SmartWasher_Volts   "-> Voltage [%.2f V]"                    (gSecondFloorWasher,power)      {zwave="2:command=meter,meter_scale=E_v"}
Number SmartWasher_Amps    "-> Amperage [%.2f A]"                   (gSecondFloorWasher,power)      {zwave="2:command=meter,meter_scale=E_A"}

    Switch SmartWaterHeater         "Water Heater"                  (gSecondFloorWasher,outlet)             {zwave="4:command=switch_binary,refresh_interval=30" }
Number SmartWaterHeater_Power   "-> Power  [%.2f W]"            (gSecondFloorWasher,power)          {zwave="4:command=meter,meter_scale=E_W" }
Number SmartWaterHeater_Energy  "-> Consumption  [%.2f KWh]"    (gSecondFloorWasher,power)          {zwave="4:command=meter,meter_scale=E_KWh" }
Number SmartWaterHeater_Volts   "-> Voltage [%.2f V]"           (gSecondFloorWasher,power)          {zwave="4:command=meter,meter_scale=E_v"}
Number SmartWaterHeater_Amps    "-> Amperage [%.2f A]"          (gSecondFloorWasher,power)          {zwave="4:command=meter,meter_scale=E_A"}

//End Washer and Heater Items

1 Like

What an interesting topic! Thanks for sharing your toughts and experiences guys.

Preface: I am coming from a software background where we used an interlinked object model to create hierarchy, relationships, location, etc. For example a reference to a weather station could be a link from a building object, and you just need to look up the heirarchy for a weather station, but one weather station can be used for many buildings. The same principle would apply for something like an electric meter: building->elec, or building->kitchen->fridge->elec.

Now to comment on what I have struggled with Item naming. I basically use things like floor, room, etc., but have not been satisfied when say things fall outside of my naming scope… like outside. My basement is really a cellar, so is outside (of the house) but in fact part of the house. Same goes for the carport which is part of the house. The weather station is half in the house and half outside. Sprinklers are in the yard. Servers may move. Tablets, smart phones, laptops are all moving and could be home, away, inside, outside the house. Certain aspects of some spaces may be shared together, whereas others shared with different spaces (heating zone serving 4 rooms but with 2 lighting zones, intelligent lightswitch in the salon with the possibility of controlling lights outside, location of robot vacuum). Possibility for context to be changing.

All of these possibilities cannot be coded into the names, and they will change anyway. Despite perhaps being overly complicated, this is why I think that this all needs to be object oriented.

So what do you guys think about how this could be done in OpenHAB? (Perhaps OH 2 is more appropriate) It would be nice to be see an “Item/Thing/Objects” parent, which could perhaps be a group. You could then for example have a group that showed all lights on, and a group for a room for which you could set a mode/theme/mood light “Movie”, “Guest Room”, “Office”, “Away”, “Homework”, “Cooking”, etc.

Sorry if this is too conceptual and not tangible and technical enough. :thinking:

And now we have two problems. :stuck_out_tongue_winking_eye:

I hate being the devil’s advocate but that seems to be the role I’ve picked for myself on this forum.

Anyway, my first thoughts are:

  • If you swapped your hierarchy to use the device’s function rather than location I think a lot of these problems will go away or at least be easier to deal with. Then you can have a hierarchy similar to weather->outside->temp or weather->temp->outside. You could even have parallel hierarchies using groups, one for functionality and another for location and then an Item can be in multiple groups (i.e. multiple locations). I find organizing and naming Items based on their function to be way more useful from a rules and items files organization than by physical location. Location isn’t always important but function always is. So only worry about location when it is relevant. And for Items which can be in multiple locations or change locations, handle that through Group membership or through a separate location tracking Item.

  • I’m glad you provided your preface because this smells a bit like the “when the only tool you have is a hammer all problems look like nails.” Perhaps it is worth taking a step back and considering whether applying your interlinked object model approach actually makes sense in an OH context, or whether a different approach would be more appropriate. For example, I personally think OH lends itself to more of a Set Theory type organization with its Groups than it does to a hierarchical organization.

  • I don’t know OH 2 yet so all of this is from an OH 1 perspective.

  • Your last paragraph seems to extend far beyond just naming and is bringing in behaviors (i.e. rules). And I agree that OO could be an alternative way to implement behaviors. However, when you look almost any other event driven system (Tasker, Asterisk, HomeGenie, FreeSwitch, etc) they all follow the OH pattern. You define “nouns” (i.e. Items in OH), which can generate or receive events (i.e. Updates or Commands in OH) and some logic which executes in response to those events (i.e. Rules in OH). Given the prevalence of this pattern I there must be advantages to using a more Actor based approach like is currently implemented in OH than an OO approach.

  • Moving to an OO approach would require a complete overhaul of the core of OH and be even more difficult for newcomers/non-programmers to learn, and thus far I’m not convinced that you have presented a compelling reason why the the change would be worth the effort. There are alternative ways to represent an HA system that provide similar capability and do not require any changes to the core. But perhaps there is some hard problem that I’m not seeing.

You can do this now with Groups and rules.

1 Like

Ok - well I have completed this task and it was a bit of a mission - took me about a week of evening coding to change all the names, after a couple of ideas/attempts at a naming convention. Then I stupidly decided <location>-<type>-<name> was a clever way to name my items, forgetting that the item openHAB parser treats - as a separator.

So after renaming everything and double checking all my changes, I deployed them to my live server only to see everything go t!ts up!! I couldn’t face starting again so did a global search+replace for - -> _. Unfortunately this screwed up a load of icon names, host names and many labels. So let that be a warning to all, don’t use - in your item names!!

Anyway - long story short it is all done. Here is the naming convention I decided upon;

<area>_<room>_<type>_<name>

Where <area> is one of GF (ground floor), FF (first floor), OU (outside), or VT (virtual). And <name> is optional if the type adequately describes it. Also, the VT items often don’t have a <room> for things like presence items etc.

So some examples;

GF_Kitchen_CoffeeMachine - coffee machine in the kitchen
FF_Ensuite_PIR - motion sensor in the ensuite
GF_Living_Light_Dining - living room dining table light
GF_Garage_Temp - temperature sensor in the garage
VT_Presence_Ben_Owntracks - virtual switch which is updated by Owntracks for presence detection
VT_Online_FreeNAS - virtual switch indicating if my NAS is online (via the networkhealth binding)

I also decided on name groups GP_<name>, e.g. GP_Presence_Ben which I have a number of virtual items belonging to, if any are ON then my presence group is ON.

I have already been able to streamline some of my rules, in particular sensor threshold warning rules, to build more human-readable messages since I can deconstruct the sensor name from the item name.

I also created a couple of groups for persistence, i.e. GP_Persist_MapDB and GP_Persist_InfluxDB. So any item I want to be persisted to my timeseries DB (i.e. InfluxDB) I just add to that group. Anything I want stored and restored on startup I add to the MapDB group.

I also created a couple of groups for storing config and state, GP_Config and GP_State. These belong to the MapDB group. This means I can simply add an item to the GP_Config group and it will be auto-persisted and restored by MapDB. If I decided to use a different persistence engine for this I can change one group config and all child items will be automatically updated to use the new engine. Thought this was quite a good idea!

The immediate benefits haven’t really been worth the amount of time and effort but I am hopeful that over time as I streamline more of my rules etc this naming scheme will make life a lot easier.

BTW - I lost all my historical data in InfluxDB (my persistence engine) since all the names changed! Wasn’t too bad as I took the opportunity to upgrade from v8 -> v11 which was long overdue.

4 Likes

I’m glad that worked out. I’ve not had any time to try this out myself yet. Definitely going to be implementing this myself soon.

Hey @rlkoshak,

Firstly, thanks for your detailed and thoughful response.

I am not trying to convince anyone; just exchanging ideas and opinions.

Yes, it is inside my brain, or whole being. I think I am perhaps trying to architect and understand the world as if each system was a piece in the worldwide interconnected IoT. However as you point out, this is a home automation system… so best to keep it at that!

I think you are bang on (no pun intended)… thank you for helping me turn on the light in the garage to find and choose better tools!

Yes - I think that this simpler function oriented organization with groups would do the trick and keep things simple enough to easily work with rules, site maps, etc.

Thanks for your perspective… reminding me not to be blinded by what I already know.