Little helper library for javascript rules

Hey Forum,

I have started the openhab-js-helper as a private openHAB JavaScript helper library to improve the quality of my JavaScript (ECMAScript 2022+) automation rules. The library uses the yarn package manager for testing and building.

It also comes with a test suite using Jest. Jest not only let you test your code, but also has an integrated mocking that I use to mock openHAB specific objects.

In this way the code can be developed, tested and build outside an openHAB instance.

Code can be found here: GitHub - FSeidinger/openhab-js-helper

Currently it is not more than some formatting support for quantities, temperatures and percentage values as well as a function that tells you if you script was triggered manually by the GUI.

Code is in index.js. The tests are in index.test.js and there is a small library index.test-helpers.js that is used in the test to make them more reusable and setup mocking objects.

If you like it, give me some feedback and leave suggestions via issues.

See ya.

1 Like

I like the automated testing. I’ve had that high on my list to add to openhab_rules_tools but other things have been a priority.

Given that JS Scripting is a node like environment, what drove the decision to use yarn as opposed to npm? I’m not questioning the decision, just want to understand the reasoning since I’m not supper into JS package managers and the wider JS ecosystem.

Shouldn’t index.js be more of just an index and you actual library code be in other files? I imagine it will get hard to maintain in the long run in one file like that.

assertNotUndefinedOrNull is not needed. The Item Object has isUninitialized which returns true if the Item’s state is NULL or UNDEF. items/items.js - Documentation

Similarly, if you call numericState on an Item whose state cannot be converted to a number, it will return null: items/items.js - Documentation. The same goes for getQuantity: items/items.js - Documentation.

If you still want the exceptions to be thrown, you should at least use these function in yours as it’s possible that how some of this stuff may change and if it does, these helper library functions will be adjusted to adopt to those changes. If you reimplement them yourself, you’ll need to adjust to the breaking changes yourself.

Thx, man.

Well, I guess in this case it is kind of a personal preferences. There are many articles on the net that list the pros and cons of yarn vs npm. Mainly they state that yarn is faster, uses less resources, is more secure but most of all is much younger in development.

Luckily yarn uses the same “interface”, so to speak and will maintain and understand the good old npm package.json, so the project stays compatible with npm and so it is not enforced to use or work on my library with yarn.

Also in my profession as a software architect it is part of my job to bring innovations into developer teams and coach teams how to use and benefit from them. I guess this has also influenced my choice.

As I understand, naming the entry point of your library index.js is just a convention. You can name the main file in package.json with the script property like:

"scripts": {"start": "node server.js"}

Often for the script the names app.js, main.js or server.js are used. If the script property is missing, node searches for the names index.js and index.node.

The main reason of the start file is to name the exported functions and modules. But no one enforces you to put your functions and modules in separate files. For small libraries, like mine currently is, I personally see no use of having more than one file.

You already mentioned that it gets hard to maintain a single file, when the library gets bigger. Well, for that refactoring is the right method, right?

Good to know. I will test if that can be helpful in setItemState. But I did this for another reason. It will give me a good debug log of what the state really is, despite what my assumptions was. And also it gives the possibility to track changes on the items for rules that are executed on a recurrent basis. I have some rules checking if ventilation is needed in the bathroom. Also my experience told me to be paranoid when checking item states.

Also good hints. I use them to give a proper message if something, like my assumptions, went wrong. I wrap all my rules into a function with error handling and so get real good feedback on errors.

Thx man, for taking the time to look into it and give me a propper feedback. I appreciate it.