I’ve just released a new version of BAC0 on Pypi. Thanks to many users who identified bugs and suggested improvements.
As I waited a little too long to publish to Pypi, there has been a lot of little improvements that were only in the develop branch for almost a year… and recently, I began to push more regularly to the master branch (which trigger new Pypi releases) because there is no reason to hold back fixes and new features.
Here is a quick list of the things you may like in the new version. (There may be “not so new” items here…but it’s been so long since an official release, let’s put them here anyway)
Calendar versioning
It seems like I would never ever be ready enough to present version 1. And in fact, it’s probably the same with all of software outside. They could always be better. For this reason and for you to know easily the release date of the version, I switched to calendar versioning.
I don’t plan to offer any guaranteed backward compatibility. I want this library to evolve, I want to add features. I’ll do my best to “not break” everything… that is the best I can do. So… no more 0 versioning.
BAC0 Lite version
BAC0 can come with a lot of options which are sometimes too much. The lite version will load just the minimum and fits perfectly for little scripts that do not require the web interface. It was there in last version but it is worth repeating this.
import BAC0
bacnet = BAC0.lite()
Support for trendLogs
To be honest, working with JCI devices in the office and Niagara Jaces, makes a world without the immediate need to support trendLogs most of the time. But there is more and more devices out there providing them so it was more than time that BAC0 support theses. The implementation is yet to be improved but the biggest work has been done and we can easily recover trendLogs and output them with pandas format.
Super easy to do analytics then.
To support trendLogs, BAC0 now implement the Read Range function. If you need it.
import BAC0
bacnet = BAC0.lite()
dev_with_trendLogs = BAC0.device('2:5', 5, bacnet)
dev_with_trendLogs.trendlogs
# will output a dict with keys being
# objectType_address_property
Name_of_log, Av1_trendLog = dev_with_trendLogs['analogValue_1_presentValue']
Act as a Foreign Device
You can now use BAC0 as a foreign device on a network and cross subnets. Pretty useful when you are using VPN with TUN mode… or any other situation where you would need the feature. Just provide bbmdAddress and bbmdTTL.
Based on Flask and using a bootstrap dashboard theme, the new Web Interface opens the door to a lot of future features.
BAC0 dashboard view
The web interface contains the new Trend page with the live trending feature provided by Bokeh. The implementation has been improved to use callbacks and BAC0 will be ready for Bokeh version 1 coming soon. Some work need to be done to improve readability but having the trends live is pretty cool when testing your device !
Bokeh server running in the Flask Dashboard of BAC0
I also included a simple table presenting the result of a global Who Is on the network.
Devices found on network
Logging
To keep track of bug and internal messages, I’ve configured a logging module with a specific text format that will allow a better reading of what’s happening in the app, what bugs occurred… but also, the possibility to add your own messages in your script which will result in your notes being “saved” in the log file.
Logging text format
Supporting new bacpypes versions
Bacpypes is also evolving fast and I try to keep in phase with bacpypes. BAC0 is nothing without bacpypes so better keep up pace ! Actual bacpypes version is 0.17.6. Stay tuned as there is some nice improvements coming.
Documentation improvement
I’ve added a few sections and tried to be more precise on other. Regarding this specific topic, don’t be shy ! If you want to help, improving documentation is really appreciated. BAC0’s documentation
Couple new built-in functions added
Dealing with overrides
I use BAC0 in my day-to-day work and sometimes, I add some features to ease my work. I also try to listen to users and some features come from their suggestions.
During startup of big BMS jobs, we often find ourselves dealing with a lot of overrides made by anyone in the team while doing there work… But what if somebody forgot to remove the overrides in one controller ?
PAUSE. In my world, overrides are made by writing @ priority 8 on points. In the documentation we can see that called Manual Operator writing… To know if a point is “overridden”… aka commanded @ priority 8, you need to read a special property on the point (priority array)… which require a specific reading as usually, BAC0 will read the present value of the point. And in real life, it can get really hard to tell if all 200 thermostats that have been installed are free of overrides.
BAC0 have a special function that allow the detection of overrides in a device… and another function that allow to release those overrides if needed. Just use :
device.find_overrides()
# or
device.release_all_overrides()
# or
device['point'].is_overridden
The two functions running on device (find_overrides and release_all_overrides) will start a thread to do all the work they have to and you can continue to work with BAC0 without being blocked. The logging function will inform you when everything is done.
Example of running the overrides functions
Finding points
If you don’t know the name of a point, but you know its object type and address, you can get it using :
device.find_point('analogValue',1)
Proprietary object support
In one big project, I worked with the TEC3000 thermostat from Johnson Controls. To be sure everything was ok with the communication, we thought using the “Supervisor Online” property which is a proprietary object in the device. To make it work, I had to include a few things in BAC0 and now, it’s possible for you, following what’s been done for this thermostat, to add new proprietary object to your script if you need.
If you work with those devices, you’ll see I also provide a basic custom object list to accelerate the loading of the devices. Have a look to the documentation.
New tests suite
It’s been a while I was looking for a way to test BAC0 and I could not find something I liked. Until I discovered (yeah, sometimes I’m slow learner)… that I could create 2 instances of BAC0 and make them talk together. This way I could tests a lot of functions easily. It’s not perfect, I know. Mostly because I’m actually testing using the socket for real… and it slows down the tests. But it allows me to make tests easily and for a lot of situation so I made the choice to be patient when the tests suite runs.
To do that, I also started to implement a feature I had not touched with BAC0, which is adding local object to the instance (like an analog value for example). This is a completely new field that open a lot of possibilities… and a few question on bacpypes side. But some users did ask for that and I think they will like the fact that it’s possible.
Improve SQLite saving support
SQLite support is there from a long time but it was not working every times. I put some effort to that and now it is super easy to save your device, and connect to a SQL backup after that.