Web Interface and Code Generation

I installed the latest OpenHAB, then started to play around with the Web based interface.

One of the ways I learn a new language, especially one that has a GUI, is to add features in the GUI, then study the generated code to see how it is set up to create what the GUI shows.

I installed a serial binding. But then I could not find where the resultant text file was which held that binding.

Inferring from the documentation, and from the trial, can I assume that the GUI stores its setup in a separate place, possibly in a binary format? There are warnings not to mix GUI vs text configuration, but it only warns about confusion about which configuration is the “good one”.

Is there a way for the GUI to export the settings it creates, so that I can inspect them?

A binding isn’t a text file. It’s a whole compiled plug-in written in Java. You can see the source code at GitHub - openhab/openhab-addons: Add-ons for openHAB.

There is a jar file somewhere under $OH_USERDATA/cache which is where the compiled add-on goes when it’s installed, but it’s byte code, not a text file you can just look at. Bindings are basically whole programs unto themselves, not just configuration.

Setup is different and if you are just looking to see where OH makes a note that you’ve installed a binding, that’s in $OH_USERDATA/config/org/openhab/addons.confg.

It’s pretty much all text. You just need to know where to look. Things, Items, Rules, and UI Widgets all get stored in $OH_USERDATA/jsondb. But there is no way to, for example, generate a .items file under $OH_CONF/items when using the UI.

Sigh, sorry for the incorrect nomenclature. This is a learning process for me…

I was sort of expecting to see something like:

Bridge serial:serialBridge:sensors [serialPort="/dev/ttyUSB01", baudRate=57600] {

That’s something different. It really helps both you and us to make sure you go through the Concepts section of the docs at least, perhaps even the Getting Started tutorial too because there are a lot of terms of art, nomenclature, and concepts that make up OH and it’s really hard to understand what is being asked when the wrong terms are used and if you don’t have a basic grasp of the concepts.

Don’t worry, we don’t expect you to get it all right away, but do please return to those sections periodically for refreshers and to help integrate new things into the overall concepts as you learn.

In this case, you are not asking about an add-on nor a binding. You are asking about a Thing. As stated in the concepts, a Thing represents a device. So far so good.

What you are expecting is what you would need to write if you were to manually define that Thing yourself in a .things file.

But you’ve created/discovered that Thing in the UI. So you have three places to look for the text code that represents the Thing.

  1. Navigate to the Things’ page in MainUI. Click on the “Code” tab.

  2. Navigate to Developer Tools → API Explorer in MainUI. Go to the Things section and query for the Thing.

  3. On the file system go to $OH_USERDATA/jsondb, open the file with “Things” in the name and search for the UID of the Thing (will show the same JSON as you get from API Explorer).

OH only has a parser that can read a .things file and place it into its memory. It doesn’t have a way to write it back out again. Inside OH, it’s all JSON. The MainUI Code tab is a YAML translation of the actual JSON presented in a more human friendly format.

Yes, getting the nomenclature down will be fun…

My confusion comes from my view of systems. A sensor (temperature, etc) is a thing. The arduinos (five of them) are aggregators of the sensors (270+ of them), the serial port bridge is a pathway for the sensor values, OpenHAB is the consumer of the sensor readings and performs logic on the values. That logic then persists, displays, and/or commands other “things” to do stuff.

I have read over the OpenHAB semantic model and concepts, but it has not yet sunk in to the point where I can just casually express my self. Sorry about that…

I will be writing all the interfacing code and logic manually, as I always believe that a UI cannot give me the fine control I will want. I was just hoping to find out “best practices” from generated UI code.

Thanks

For OH concepts:

  • the Serial Port is a special type of thing called a Bridge; it provides a way for other Things to communicate with the devices

  • any one given arduino is a Thing

  • the individual sensor is a Channel on the arduino Thing.

Things represent the connections between OH and devices. But you never command them directly. Instead you link Items to Channels. It’s the Items you command, not the Things. Items are the layer of abstraction between Things which have all sorts of fiddly bits specific to the technology you are using, and the abstract concepts that make up your home automation. A Switch Item is a Switch Item no matter what it’s linked to. Serial, Zwave, MQTT, Nest, KNX, whatever it is, the Item always behaves and is used the same.

Note that I tend to always use the capital when referring to OH concepts to distinguish between “the MQTT Bridge Thing” which refers to OH and “that box if full of bits and things.”

Do what you are comfortable with but know this:

  • you’ll have to translate anything done in the UI to the text file formats

  • there is nothing you can do in text configs that cannot be done in the UI with three exceptions which can only be done through text configs: persistence configs, ephemeris configs to define custom day types or holidays, and the Exec binding whitelist

  • there is a growing number of things that cannot be done in text configs at all including: some bindings only support certain things through the UI (e.g. Zwave can only set configuration properties on end devices through the UI), rule templates, and Custom UI widgets.

So there is no special fine control features you will suddenly get by using text files to config OH. It may better fit your work style and the like but it’s not going to give you extra parameters or new capabilities. To the contrary, it will limit you in some ways (ways which may not matter to you).

But what I can say is I personally have given up helping people with syntax errors. Based on my experience with my setup and helping hundreds or others, any time lost to using the UI is more than exceeded by the time lost to fighting syntax errors that are impossible to make when using the UI.

What about specific transformations (MAP/SCALE/JS)?

Map: It depends. Most of the time it’s used in an Item’s labels and now we have the State Description Options metadata that can take the place of the Map transformation there. When used in rules, Things and Profiles though yes, a file is needed.

Scale: I never really used scale but yes, this probably does require a text file.

JS: As of OH 3.2 there is now support for doing an inline definition so a separate file is not necessary, though recommended if the code is going to be more than a few statements of JS code.

This could be the most confusing part. A sensor is an end point (which contains a value). There is nothing “past” the sensor. It “reads” the natural world which impacts the sensor in some way.

Calling a sensor a channel is confusing for me. What information is it channeling? The sensor IS the information source. Without the sensor the natural world would be unknown to the rest of the hardware/software.

I have set up:

  • temperature/humidity sensor. This is hard wired into a pin on an arduino

  • the arduino polls the sensor on a regular basis, compares the current value to the previous value, and if the difference is large enough, it puts out the new value on the serial port (using Serial.println())

  • then I am planning for OH to parse the serial port string

    • which sensor it is (each will have a global unique name)

    • type of information (temperature, humidity, etc)

    • get the actual value (int, float, state, on/off, etc)

  • Then based on this information I will persist it for later graphs, update the internal OH value and update any displays

I also want to have all the global names held by constants. So if a sensor name is “WD_02” I would have a constant
WINDOW_GUEST_BEDROOM = "WD_02"
then use the constant everywhere else. The arduino string would look like:
$WD_02:TEMP:27.2$

Can this be created/managed using a GUI interface? If I manually create a constants file, then will the GUI pick it up? I noticed that the OH rule syntax allows for try/catch blocks, does the GUI support this? Or are all rules text, whereas the underlying structure is GUI created?

I might be over thinking this :crazy_face:

That’s what a Channel is in openHAB terminology. Consider a thermostat. The thermostat is the device. It would be represented by a single Thing. However, a thermostat has a bunch of sensors and actuators (current temp reading (sensor), target temp setting (actuator), heating/cooling mode (actuator), etc.). Each sensor and actuator is represented by a Channel.

The current temperature reading is “channeled” from the device (i.e. Arduino) into openHAB and on to the Item linked to that Channel.

Yes, but the current temperature is what’s channeled. I didn’t invent the nomenclature used by OH. I’m not particularly a fan of the terms chosen. But don’t try to take the common dictionary definition for an openHAB term and use that to understand what it means in openHAB.

In openHAB, a Channel represents a single point on a device. That single point might be an actuator (i.e. we can send it a command to cause it to do something). That single point might be a sensor (i.e. all it does is feed openHAB data). But in both cases they are called “Channels” in openHAB.

One very important thing to understand about openHAB is its first and primary job is to make lots of very different technologies work together. To achieve that there are a number of layers of abstraction. By the time we get to the Channel concept, openHAB doesn’t care that you have a DHT22 wired to an arduino that’s being communicated with via a serial connection. All openHAB cares is “this Channel produces Number:Temperature values”. The Item ultimately Linked to that Channel does not and should not have to care where it comes from or how it’s delivered.

That’s not how it works in OH.

You would create a Thing to represent that specific Arduino, give it a meaningful to you the human name, let’s call it “Guest Bedroom Multisensor”.

You would add Channels to that Thing, one for each sensor reading produced by that Arduino and one for each thing you can command on that Arduino. That is where you make the mapping between “WD_02” and “Guest Bedroom Window”. The Channel config is and should be the only thing that knows or cares about “WD_02”. That’s way low level technology specific configuration stuff. So that window sensor Channel would have a meaningful name. Let’s say “Window Sensor”. You already know it’s in the Guest Bedroom because of the Thing it belongs to.

Ultimately you would then create an Item that links to that Window Sensor Channel. This Item is so far removed from the raw stuff delivered by the serial connection that if “WD_02” is mentioned anywhere you are doing it wrong.

There is no such thing. And you shouldn’t need it. That mapping will be captured naturally by the configuration. Once you get out of the Thing and Channel conifiguration, all the names and IDs you deal with should be meaningful to you the human.

Yes. Though be aware that there are some types of errors that can occur that do not make it back up to your rule. It’s possible for an error to occur that throws an exception that kills your rule before a catch or finally clause can be called.

In truth, all rules are something that lives inside of OH’s memory, whether they are created by parsing a text file or directly deserialized into memory from the JSONDB. Once in memory a rule, no matter how its defined will have triggers, optionally conditions (though not all text file languages support separate conditions), and actions. All a text based rules file does is gets parsed and executed when it’s loaded. During that execution it interacts with the OH Java API to build the rule in OH’s memory. A UI rule basically does the same thing only it interacts with OH’s REST API to add the rule. But once in memory, they are all the same.

The “code” part of your rules are the actions. No matter if they are in a text file or defined in the UI, the code is passed to an interpreter to execute. By the time OH gets to that point, it’s all the same.

I feel sometimes like I followed the rabbit…

I WILL get this, it is a learning curve, and I do want to make this happen. I am at the very early stages of the project, mapping out hardware (lots of soldering), and planning out what I want to make the system do.

It’s been very helpful in this thread. I have read through the documentation, but I am afraid that my software development background is working against me. I need to realign my thoughts…

Thanks :beers:

Orient yourself that simple idealized Items are at the heart of openHAB. Everything else is there to serve them.

User-facing GUI presents Item states, issues Item commands.
Rules examine Item states and events, issue updates and commands.
Persistence stores and retrieves Item states.
Channels link simple, homogeneous Items to highly customized Things, which represent complex external systems - zwave thermostat, weather web service.

Of course there are “fiddle factors” that don’t fit this model - e.g. rules may check a Thing status directly - but these are exceptions.

And again of course, we need a “system admin UI” to mess with rules, Thing settings etc. but this is secondary machinery too (even if it is rolled into one of the user UI in OH3). It’s the first point of contact for new OH users, but it is just a tool, not “the system”.

I think you’ve started out looking at the wiring and plumbing in the engine room, before appreciating what the ship does :smiley:

Is there a page which lays out the complete OH code syntax?

Which rules language?

Those are the languages that come with OH. If you install an Automation add-on, see that add-on’s readme (and often there will be a corresponding thread here on the forum) for details. Though the syntax will primarily be what ever the language is (e.g. JS Scripting is standard ECMAScript 2021) so the docs focus mostly on interacting with openHAB.