christiantremblay / bac0 Goto Github PK
View Code? Open in Web Editor NEWBAC0 - Library depending on BACpypes (Python 3) to build automation script for BACnet applications
License: GNU Lesser General Public License v3.0
BAC0 - Library depending on BACpypes (Python 3) to build automation script for BACnet applications
License: GNU Lesser General Public License v3.0
Cannot use the script without nose hanging...
New Bokeh version makes it clear as push session should not be used.
I'm actually re-writing the Bokeh part to start the server inside BAC0 instead of starting a subprocess.... and I'm embedding it inside a Flask application. This will open new opportunities to the application...
Thanks for your patience.
Hello, Christian,
Thank you for opportunity to use BAC0. I am trying to save data points from controllers.
I am trying 2 ways - first default. I recognized, that after some while there is no history from controller.
For example:
cosmos['Merijumi stavos\Z-1 rad. Udems turpgaita'].history
Out[26]:
2018-01-26 13:02:51.972672 38.799999
2018-01-26 13:02:55.979902 38.799999
2018-01-26 13:03:07.093537 38.900002
2018-01-26 13:03:20.208287 38.799999
2018-01-26 13:03:33.340038 38.799999
2018-01-26 13:03:46.469789 38.799999
2018-01-26 13:03:59.988563 38.700001
2018-01-26 13:04:10.604170 38.700001
2018-01-26 13:04:23.073883 38.700001
2018-01-26 13:04:36.350642 38.700001
2018-01-26 13:04:49.477393 38.700001
2018-01-26 13:05:02.748152 38.700001
2018-01-26 13:05:14.863845 38.700001
2018-01-26 13:05:27.998596 38.600002
2018-01-26 13:05:40.598317 38.600002
2018-01-26 16:21:10.349221 38.900002
Name: COSMOS 810 OPEN/Merijumi stavos\Z-1 rad. Udems turpgaita, dtype: float64
There is no data between last measurement and previous measurement.
Second way to save data was python code, which every minute saves date to sql lite data base. Then after some time I got error message (not equal sizes of arrays):
ValueError: cannot copy sequence with size 1483 to array axis with dimension 148
2
Is there some ways hot to store data from controller for a long period in database? Is it possible to use SQL database built in BAC0?
Thank you,
Andris
In the documentation on using bokeh to plot points I was wondering where you're getting the 'nvo' value from. I understand that AI2 = Analog Input 2.
# This script will add four plots to the server
lst = ['nvoAI1', 'nvoAI2', 'nvoDO1', 'nvoTempRdC']
fx.chart(lst, title = 'First Floor temperature')
I've noticed that in the docs there aren't explanations about how to:
Is it possible to provide these infos?
This par in BokehServer will cause trouble :
if 'win' in sys.platform:
commandToExecute = "bokeh.bat serve"
should read if 'win32'
will allow getting access to point using device['point']
Also... write, default, sim and read function will not be in the device anymore... those functions apply to points, not devices.
This will allow device['point'].sim(21)
or device['point'].write(100)
read... is simply the result of device['point']
when trying to initialize a bacnet instance I get the following error when calling bacnet.devices:
File "C:\Users\continuum\AppData\Local\Programs\Python\Python35\lib\site-packages\BAC0\scripts\BasicScript.py", line 186, in devices
deviceName, vendorName = self.readMultiple('%s device %s objectName vendorName' % (device[0], device[1]))
ValueError: not enough values to unpack (expected 2, got 0)
Hi,
If I try to write to a analogValue on a eclypse controller the first attempt fails. If I interrupt and set the point to 'auto' I get an error message, but after this I can write to the point.
Also, to write I have to put the value between quotes.
>>> my_controller['variable_1'] = '4'
^CERROR:BAC0.core.devices.Device:Value must be numeric
>>> my_controller['variable_1'] = 'auto'
ERROR:BAC0.core.devices.Device:Value was not simulated or overridden, cannot release to auto
>>> my_controller['variable_1'] = '4' # now the value in the controller changes
@kjlockhart proposed some changes to GetIPAddr
It was not working on windows so some work has to be done to validate.
I use the previous file in the meantime. I will study the proposition.
I used the fix of issue 34 on Window.
I list what I got as follows:
bacnet.whois()
defaultdict(int, {('192.168.0.16', 1000): 1, ('3:96', 96): 1})
bacnet.devices
Manufacturer Address Device ID
Name
BACnet Router FieldServer Technologies 192.168.0.16 1000
SER835x Schneider Electric 4:36 96
fx = BAC0.device('3:96', 96, bacnet)
Changing device state to <class 'BAC0.core.devices.Device.DeviceDisconnected'>
Provide dbname to connect to device offline
Ex. controller.connect(db = 'backup')
As shown in two command, the device SER835x got two different Address.
For bacnet.whois, its address is 3:96. For bacnet.devices, its address
is 4:96
Sometimes, it shows the correct address, like
bacnet.devices
Manufacturer Address Device ID
Name
BACnet Router FieldServer Technologies 192.168.0.16 1000
SER835x Schneider Electric 3:96 96
However, no matter what bacnet.devices replied, I cannot find BACnet device by using BAC0.device('3:96', 96, bacnet)
Hi Christian,
After your suggestion to wait for some time before issuing the ~.points command, I tried waiting for 15 minutes after the BAC0.device() command, but with the same result:
PS, this is on the master branch
bacnet.devices
Manufacturer Address Device ID
Name
Norwich_100 Tridium 192.168.25.101 100
Norwich=BAC0.device('192.168.25.101',100,bacnet)
Norwich.points
Traceback (most recent call last):
File "", line 1, in
File "C:\Users\henkwitte.GROENHOLLAND\AppData\Local\Continuum\Anaconda3\lib\site-packages\BAC0\core\devices\Points.py", line 410, in repr
return '%s : %.2f %s' % (self.properties.name, self.history.dropna().iloc[-1], self.properties.units_state)
File "C:\Users\henkwitte.GROENHOLLAND\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\core\indexing.py", line 1328, in getitem
return self._getitem_axis(key, axis=0)
File "C:\Users\henkwitte.GROENHOLLAND\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\core\indexing.py", line 1749, in _getitem_axis
self._is_valid_integer(key, axis)
File "C:\Users\henkwitte.GROENHOLLAND\AppData\Local\Continuum\Anaconda3\lib\site-packages\pandas\core\indexing.py", line 1638, in _is_valid_integer
raise IndexError("single positional indexer is out-of-bounds")
IndexError: single positional indexer is out-of-bounds
Use pytest instead of nose
Some problems related to coverage to fix
We have a pretty abused network, bacnet wise, so I guess I'm running into issues which shouldn't happen to most users.
Today I got this error from one of my script:
Exception in thread rpm_poll:
Traceback (most recent call last):
File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
self.run()
File "/home/fgervais/.local/lib/python3.5/site-packages/BAC0/tasks/TaskManager.py", line 44, in run
self.process()
File "/home/fgervais/.local/lib/python3.5/site-packages/BAC0/tasks/TaskManager.py", line 50, in process
self.task()
File "/home/fgervais/.local/lib/python3.5/site-packages/BAC0/tasks/Poll.py", line 71, in task
self._device.read_multiple(list(self._device.points_name), points_per_request=25)
File "/home/fgervais/.local/lib/python3.5/site-packages/BAC0/core/devices/mixins/read_mixin.py", line 134, in read_multiple
points_values = zip(big_request[1][i:i + len(val)], val)
TypeError: object of type 'NoneType' has no len()
It looks like the Read.py:readMultiple() can return None if we expect an ACK but we receive something else.
if not isinstance(apdu, ReadPropertyMultipleACK): # expecting an ACK
log_debug(ReadProperty," - not an ack")
return
I don't know about other calls to this function but an empty return will always fail in the case of read_mixin.py:read_multiple().
try:
request = ('{} {}'.format(self.properties.address, ''.join(request)))
val = self.properties.network.readMultiple(request)
...
else:
points_values = zip(big_request[1][i:i + len(val)], val)
i += len(val)
for each in points_values:
each[0]._trend(each[1])
Is there a quick fix that would make sense in that case?
Return an empty list maybe?
C:\Users\Matt\python programming\BAC0-master\BAC0-master>python setup.py install
Traceback (most recent call last):
File "setup.py", line 5, in
import BAC0.infos as infos
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0_init_.py", line 4, in
from . import core
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0\core_init_.py", line 3, in
from . import app
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0\core\app_init_.py", line 3, in
from . import ScriptApplication
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0\core\app\ScriptApplication.py", line 30, in
from ..functions.debug import log_debug
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0\core\functions_init_.py", line 3, in
from . import discoverPoints
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0\core\functions\discoverPoints.py", line 21, in
from ..devices.Points import EnumPoint, BooleanPoint, NumericPoint
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0\core\devices_init_.py", line 3, in
from . import Device
File "C:\Users\Matt\python programming\BAC0-master (1)\BAC0-master\BAC0\core\devices\Device.py", line 101
def init(self, address, device_id, network, *, poll=10,
^
SyntaxError: invalid syntax
Hi,
i have recently done the following things:
sudo apt-get update
sudo pip install bacpypes (installation = no problem)
sudo pip install BAC0 (installation throws errors)
here is the screenshot of the error:
http://aaph.itc-haas.at/resources/jpg/bac0_error.png
Am i doing something wrong?
New version of Bokeh (0.11) in dev... will change a lot of things on the server side.
I'll try to stick to the new version for next couple weeks...
The feature is not yet "mature" enough anyway.
I get a NoResponseFromController exception from Read.py while doing a simple:
bacnet = BAC0.connect("10.59.78.20")
vav = BAC0.device('10.59.50.50', 410, bacnet)
for i in vav.points:
...
It's pretty obvious what the problem is but since it happens in an internal BAC0 thread, I'd like to make sure how to properly recover from it.
Should I just:
bacnet = BAC0.connect("10.59.78.20")
vav = BAC0.device('10.59.50.50', 410, bacnet)
for retry in range(10):
try:
for i in vav.points:
...
catch NoResponseFromController:
continue
break
Also on top of your head could you tell what kind of error handling is done internally on this to get a feel of how bad the exception is. Does it retry like a hundred times before throwing the exception?
After establishing connection successful to a device, I've simply tried to read a point value, and then this error appeared:
File "/BAC0/core/devices/mixins/read_mixin.py", line 173, in retrieve_type
if point_type_key in point_type:
TypeError: argument of type 'int' is not iterable
After giving a look to code, I've simple edited file with this quick-n-dirt fix:
if point_type_key in str(point_type):
Probably not the best approach, but for the moment it works.
Needs to
Hello, I am just getting started with BAC0 and so far i love it,but I need my script to query if a point exists in the controller and then set it at a specific priority, any help?
Team,
I am trying to use python 3.6 version and when trying to install BACO. I am facing problem with the installation.
Could you please help us out in this process.
Regards,
Srinivas Padilam.
First off, thanks for your great library!
With at least one of my devices, I ran into a stack overflow due to an endless recursion in /core/devices/Device.py
. It begins in _buildPointList()
of DeviceConnected
:
except NoResponseFromController as error:
self._log.error('Cannot retrieve object list, disconnecting...')
self.segmentation_supported = False
self.new_state(DeviceDisconnected)
The call of new_state()
triggers line
self.__class__ = newstate
self._init_state()
which in turn runs DeviceDisconnected._init_state()
:
def _init_state(self):
self.connect()
After a successful connection:
if segmentation_supported:
self.new_state(RPMDeviceConnected)
else:
self.new_state(RPDeviceConnected)
We again are in new_state
(see above), which then calls DeviceConnected._init_state()
:
def _init_state(self):
self._buildPointList()
...which closes our endless loop, since another NoResponseFromController
exception triggers the next round.
As this is my second day working with your code, I'll refrain from posting my "solution" as a PR, as it might not be sufficient for not breaking other parts. However, it goes like this:
except NoResponseFromController as error:
self._log.error('Cannot retrieve object list, disconnecting...')
self.segmentation_supported = False
self._log.info('Changing device state to {}'.format(DeviceDisconnected))
self.__class__ = DeviceDisconnected
setup should not try to install xlwings when on Linux
Need to clarify best way to stop a chart
bokeh serve works now on Windows.... don't need .bat
few deprecated functions...
BAC0 should try read instead of read_multiple
Hello,
I'm struggling to get the most basic part of BAC0 working: program execution is getting stuck on the BAC0.connect() call. It outputs the IP it is using then hangs.
import BAC0
bacnet = BAC0.connect()
Using ip : 192.168.2.55
..and then it waits indefinitely.
Has anyone else encountered this issue?
I'd appreciate any help I can get, I imagine I'm missing something simple. Thanks.
So I'm finding that connecting to a device with a lot of points is taking a very long time. One of our devices has 1000 points and it takes somewhere around 10m to connect to that device. I was just wondering if BAC0 has support for something like bacrpm
, to read the present value of a single point without creating a controller object.
Additionally, people who use the library, do you tend to keep multiple devices connected at the same time in order to speed up access?
Thanks in advance!
add_periodic_callback is used to call the update_data function. But when playing with the controller, modifying data.... I saw the bokeh trend lagging..... then once the bacnet network is diconnected.... things return to normal.
Find a better way to handle debug and populate through code
There's actually 2-3 different methods.
Hello,
I am trying to connect to a device behind a BACnet router. I know the following:
The router has the IP - Adress 192.168.0.4
The Device ID of the router is 1050658
The Device ID I want to connect to is 2131969
I can connect to the router and get it's (empty) object list. I can however not find a way to connect to the actual device I want to connect to the actual device.
The router is BACnet/IP to LON.
Some addded problems: I connect from a different network, where broadcasts are not possible. YABE on a maintanance PC in the 192.168.0.1/24 network shows device 2131969 with the address "1 1 via 192.168.0.4", so the device is there, and it has all its points. I cannot use YABE myself.
Is there anyway to establish this connection?
Hi,
I'm trying to check out BAC0. It seemed to install successfully but, I'm hitting snag. I installed BAC0 on OS X and Linux and I'm running into the following issue on both systems:
Python 3.5.2 (default, Sep 14 2017, 22:51:06)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import BAC0
/home/xxx/.local/lib/python3.5/site-packages/BAC0/core/devices/Device.py:22: FutureWarning: The pandas.lib module is deprecated and will be removed in a future version. These are private functions and can be accessed from pandas._libs.lib instead
from pandas.lib import Timestamp
xlwings not installed. If using Windows or OSX, install to get more features.
cannot import name 'gridplot'
>>> bacnet = BAC0.connect()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'BAC0' has no attribute 'connect'
I'm wondering if the problem is related to cannot import name gridplot
.
Any ideas?
Would be nice to have the chart as a html afterward
From an email @MichelleNing
I have a question for using chart.
lst1 = ['Room Temperature']
controller.chart(lst1, title = 'Room Temp')
C:\ProgramData\Anaconda3\lib\site-packages\bokeh\models\sources.py:89: BokehUserWarning: ColumnDataSource's columns must be of the same length
lambda: warnings.warn("ColumnDataSource's columns must be of the same length", BokehUserWarning))
This warning message only can be stopped by force exit from bokeh server.
Do you have any idea about this?
There could be improving to the starting flow of the server when starting bacnet (bacnet = BAC0.connect() )
Modification required to illustrate new example with getitem functions now working
Using the Python 3 REPL:
Python 3.5.3 (default, Jan 19 2017, 14:11:04)
[GCC 6.3.0 20170124] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import BAC0
Missing required dependencies ['numpy']
>>>
KeyboardInterrupt
>>> bacnet = BAC0.connect("192.168.0.150/24")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'BAC0' has no attribute 'connect'
Doesn't work at all.
One more question, is it possible to use this library without bokeh?
discover points do not work
will need another function that use read property only to build the points
For big object list, if segmentation is not supported, need to iterate through object one at a time.
Hi,
If I open a python shell and enter these commands all runs well:
>>> import BAC0
>>> bacnet=BAC0.connect(bokeh_server=False)
Starting BAC0 version 0.99.105
Using ip : 192.168.25.38
WARNING:BAC0.script.ReadWriteScript:Bokeh server not started. Trend feature will not work
>>> bacnet.devices
Manufacturer Address Device ID
Name
Norwich_100 Tridium 192.168.25.101 100
pCOWeb77000 Carel S.p.A. 192.168.25.22 77000
>>> cntry_ecy=BAC0.device('192.168.25.101',100,bacnet)
>>> for point in cntry_ecy.points:
... print(point.value)
...
15.5
>>>
However, if I put the commands in a test.py file and run this with "python test.py":
print("Starting bacnet processing")
import BAC0
bacnet=BAC0.connect(bokeh_server=False)
bacnet.devices
cntry_ecy=BAC0.device('192.168.25.101',100,bacnet)
for point in cntry_ecy.points:
print(point.value)
an error is raised:
Starting BAC0 version 0.99.105
Using ip : 192.168.25.38
WARNING:BAC0.script.ReadWriteScript:Bokeh server not started. Trend feature will not work
Exception in thread rpm_poll:
Traceback (most recent call last):
File "/home/groenhol/miniconda3/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/home/groenhol/miniconda3/lib/python3.4/site-packages/BAC0-0.99.105-py3.4.egg/BAC0/tasks/TaskManager.py", line 44, in run
self.process()
File "/home/groenhol/miniconda3/lib/python3.4/site-packages/BAC0-0.99.105-py3.4.egg/BAC0/tasks/TaskManager.py", line 50, in process
self.task()
File "/home/groenhol/miniconda3/lib/python3.4/site-packages/BAC0-0.99.105-py3.4.egg/BAC0/tasks/Poll.py", line 71, in task
self._device.read_multiple(list(self._device.points_name), points_per_request=25)
File "/home/groenhol/miniconda3/lib/python3.4/site-packages/BAC0-0.99.105-py3.4.egg/BAC0/core/devices/mixins/read_mixin.py", line 134, in read_multiple
points_values = zip(big_request[1][i:i + len(val)], val)
TypeError: object of type 'NoneType' has no len()
See e1dc495 for fix in develop branch
INFO:bokeh.client.connection:Failed to connect to server: ConnectionRefusedError(10061, 'Unknown error')
Bug received from user by email
I had test some reading with the save feature to save to SQLite database,
And i found there always be insert 9 blank row of NULL value into the database โ
Any idea is this normal.. (refer to below screenshot )
Hi, noted this on debian and now also on ubuntu (beaglebone black):
If I run import BAC0 and then bacnet=BAC0.connect() I get an error "bokeh server not running". BAC0 fails
If I run first import bokeh, then import BAC0 and BAC0.connect() I get an error "Failed running bokeh server,Bokeh server already running" . BAC0 is running ok after this, so it does not seem to affect the software.
Henk
Hello,
I am trying to get BAC0 to work on beaglebone (debian 8, jessie). I ran into the bokeh issue described in another post and installed the development branch. I can then run the bacnet=BAC0.connect(bokeh_server=False) command.
After this I run the bacnet.devices command and get the following error:
bacnet.devices
Traceback (most recent call last):
File "", line 1, in
File "/home/groenhol/BAC0/BAC0/scripts/BasicScript.py", line 193, in devices
return pd.DataFrame(lst, columns=['Name', 'Manufacturer', 'Address',' Device ID']).set_index('Name').sort_values('Address')
File "/home/groenhol/miniconda3/lib/python3.4/site-packages/pandas/core/generic.py", line 2150, in getattr
(type(self).name, name))
AttributeError: 'DataFrame' object has no attribute 'sort_values'
Sorry if the fault is something obvious - I am new to python and its modules and installing the complete environment on the beaglebone has been an experience...
Any idea what I can do about this?
Thanks!
Will reduce bandwith issues
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.