A template-based OpenHAB .things and .items file generator written in Python using Jinja2 template engine.
The thing and items definitions are usually repetitive when you have multiple devices of the same type. The process of adding and maintaining .things and .items files involve tedious copy pasting and renaming. Changing how they are all defined is even more tedious.
ohgen enables you to create a template for each type of device and then generate the actual .things and .items files from a list of devices stored in devices.yaml file.
Example Device list:
Light1:
template: tasmota-light
features:
- color
- ct
groups:
- Group1
- Group2
tags:
- Tag1
- Tag2
metadata:
- ga: Light
Switch1:
template: tasmota-switch
switches:
- name: Light1_Switch
label: Light1 Switch
groups:
- gInsideLights
- name: Light2_Switch
label: Light2 Switch
groups:
- gOutsideLights
metadata:
- ga: Light- Copy
quickexample.yamltodevices.yaml - Copy the directory
sample-templatestotemplates
For convenience, devices.yaml will be used by default when no file is specified on the command line:
./ohgen.py
To use a different file, specify it on the command line:
./ohgen.py fullexample.yaml
By default, ohgen will prompt for confirmation if the output file already exists. To overwrite without prompting, specify -o or --overwrite in the command line, i.e.:
./ohgen.py -o
The devices.yaml file contains list of devices/things to be generated. For examples: see quickexample.yaml and fullexample.yaml
settings:
output: mydefaultoutput
template: tasmota-light-cct
outputs:
mydefaultoutput:
things-file: /openhab/conf/things/mythings.things
items-file: /openhab/conf/items/myitems.items
things-file-header: |+
// This is going at the top of the things file
items-file-header: |+
// This goes into the top of the items file
Group gMyGroupThe settings: section inside devices.yaml consists of three areas:
-
Global variables - variables that appear directly under the
settingssection. These variables act as a fall back / default for the corresponding setting.output:the default output when nothing is specified in thetemplatessection. It refers to the entry in theoutputssection.template:the default template to use when not specified by the thing entry. It refers to the entry in thetemplatessection, or directly to./templates/+ templatename +.tpl.header:Global headers to insert into every output file both things and items. For specific headers to insert in a specific file, see theoutputssection below.
-
templates:# defines the list of template names This section is optional. By default, the templates will load from a subdirectory./templates/template-name.tpl. The extension.tplwill be added to the template name. This section can be added to override the default output file for specific template(s), or if you want to store your templates in a different place or name.template1-name:# the name of the template-
template-file:(optional) path to the template-file, including the file name. This path can be an absolute path, or relative to devices.yaml file.When this setting is omitted, the default is set to "templates/template1-name.tpl" - where
template1-nameis the name of the template section above. -
output: (optional) outputname that applies for this template, overrides the globaloutputvariable
-
template2-name:# another template, for a different type of device or the same device but different configurationstemplate-file:path-to-the-template-fileoutput:outputnameMultiple templates can be directed to the same outputname, which in turn will be saved in to the same files
-
outputs:#The list of output file definitions. Multiple output files can be specified here, for example if you'd like to have a separate file for lights, switches, sensors, etc.output1-name:things-file:path to the .things file, absolute or relative to this file (devices.yaml). Example: /openhab/conf/things/thingsfilename.thingsitems-file:path to the .items file. Example: /openhab/conf/items/itemsfilename.itemsthings-file-header:# extra headers to insert at the top of the generated .things file. Note that multiple lines can be entered in yaml using|+directly after the colon.items-file-header:# extra headers to put at the top of the generated .items file
By default, template files are stored in templates/ subdirectory, relative to the devices.yaml file, however this can be overridden in the devices.yaml file.
A template file contains the template of both Things and Items required for a particular type of device. The general format for the template file is as follows:
# Hash comments are allowed and will be omitted from the generated file
// Thing / Item comments starting with double slashes will be included.
Thing thingid ..... {
// put Thing comments inside the Thing declaration, otherwise they will go into the Items file.
}
Switch ItemName_XX ......
Number ItemName_YY ....A template can contain only Thing, or only Items, or both. Multiple Things, Bridges, and Items can exist in a template.
Rules for Thing and Bridge definition in the template:
- The opening brace must be at the end of the same line as
ThingorBridge - The closing brace must be on its own separate line
- A
Thingcan be nested inside aBridgeobserving the rules above
Variables from devices.yaml for the device will be substituted in the template file. Each thing entry in the yaml file will be loaded as a dictionary, which can be used inside the template. For detailed information about the template syntax, see Jinja2 Template Designer.
For more detailed examples, see the included templates in the sample-templates directory. Note that the included templates may change in the future.
Filters are functions or variable modifiers in the template that takes the variable as an input and can produce a different output. To run a variable through a filter, add a pipe symbol between the variable and the filter like this: {{variablename|filtername}}
In addition to the builtin filters from Jinja2, ohgen provides the following special filters:
-
groups: applies to an array of group names. It will automatically create a comma separated list enclosed in parentheses. Example:Item1: groups: - Group1 - Group2
Inside the template:
Number {{name} {{groups|groups}}Which will produce:
Number Item1 (Group1, Group2) -
tagsapplies to an array of tag names. It will automatically create a comma separated list enclosed in square brackets, with each tag enclosed in double quotes. Example:Item1: tags: - Tag1 - Tag2
Template:
Number {{name} {{tags|tags}}Which will produce:
Number Item1 ["Tag1", "Tag2"] -
metadataapplies to an array of metadata. It supports several different ways of specifying metadata in the yaml file. Example:Item1: metadata: - style1a="value" - style1b="value" [ config1="value1", config2="value2" ] - style2: value - key: style3a value: value3 configuration: - config1: value1 - config2: value2 - key: style3b value: value3 configuration: - config1="value1" - config2="value2"
Template:
Number {{name} { {{metadata|metadata}} }Output:
Number Item1 { style1a="value", style1b="value" [ config1="value1", config2="value2" ], style2="value", style3a="value3" [ config1="value1", config2="value2" ], style3b="value3" [ config1="value1", config2="value2" ] } -
quotewill enclose a non-empty value with double quotes. This is handy for labels.
Note that the above constructs can also be created purely using Jinja2's loop and conditional statements. They are provided by ohgen for simplicity.
Jinja2 has a feature to include another template and import macros. This is supported by ohgen also. The path reference inside the template is relative to the template folder.