by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • May 25 16:11
    ChristianTremblay commented #199
  • May 25 13:39
    ChristianTremblay closed #199
  • May 25 13:39
    ChristianTremblay commented #199
  • May 25 13:18
    Rojj commented #199
  • May 25 12:35
    ChristianTremblay commented #199
  • May 25 12:22
    Rojj commented #199
  • May 25 12:07
    ChristianTremblay commented #199
  • May 25 12:07
    ChristianTremblay commented #199
  • May 25 12:06
    ChristianTremblay commented #199
  • May 25 12:01
    ChristianTremblay reopened #199
  • May 25 06:04
    Rojj commented #199
  • May 25 02:38
    ChristianTremblay closed #199
  • May 25 02:38
    ChristianTremblay commented #199
  • May 25 02:36

    ChristianTremblay on develop

    Discover was not handling corre… Fix issue with proprietary prop… Adding modeltype and state of J… and 1 more (compare)

  • May 25 02:12
    ChristianTremblay commented #199
  • May 24 10:27
    Rojj opened #199
  • May 23 22:09
    ChristianTremblay closed #197
  • May 23 22:08
    ChristianTremblay closed #198
  • May 22 12:22
    spokale01 commented #198
  • May 20 13:08
    ChristianTremblay commented #198
Christian Tremblay
@ChristianTremblay
@/all New version pushed to Pypi : 20.02.20
shreyasrp-access
@shreyasrp-access
Hey, I wanted to know how you exit the while loop in run() of bacpypes.core, when executing:
bacnet = BAC0.connect()
b = bacnet.whois()
Christian Tremblay
@ChristianTremblay
I don't.... BAC0 is a BACnet device on the network and the way BACnet works, it requires the device being always active on the network, ready to answer to any request.
using bacnet.disconnect()would close the socket....but you would need to reconnect when you need to read from the network.
shreyasrp-access
@shreyasrp-access
I put a print(loopCount) inside the run() function, and ran the above code. It loops 9 times inside the while loop and then comes back to the terminal. So you must be exiting that while loop, right?
Christian Tremblay
@ChristianTremblay
No, I don't think so... maybe it's a behaviour of enable_sleeping ... https://github.com/ChristianTremblay/BAC0/blob/master/BAC0/scripts/Base.py
Joel Bender
@JoelBender
From BACpypes, the run() function in bacpypes.core loops around until something calls stop() In Base.py that function is imported as stopBacnetIPApp() which is called by bacnet.disconnect(). The enable_sleeping() just makes sure that the run/select loop “sleeps” every once in a while to make sure other threads have a chance to get work done.
Christian Tremblay
@ChristianTremblay
That would explain the behaviour explained (the print that gets back to terminal... ) right ?
shreyasrp-access
@shreyasrp-access
bacnet = BAC0.connect()
b = bacnet.whois()
print( b[0][0] )
This prints the IP address of the first BACnet device found. How does the print statement get executed if the previous statement is still inside the while loop?
Joel Bender
@JoelBender
The run() function is being called in a separate thread.
shreyasrp-access
@shreyasrp-access
When I do netstat -ano | findStr "47808" on cmd, it does not show any process running.
Whereas when I run WhoIsIAm.py, mini_device.py or some other program, it shows a process.
Joel Bender
@JoelBender
Yep, it only keeps the socket open while the application is running.
shreyasrp-access
@shreyasrp-access
I meant when I do netstat -ano | findStr "47808" after I run b = bacnet.whois() , it does not show any process. It stores the addresses received in 'b' .
So, bacnet.whois() gets the addresses and then somehow exits the while loop. I even put a print(loopCount) inside the while loop inside run() in bacpypes.core. It prints up to 9, and then automatically comes back to the terminal.
Joel Bender
@JoelBender
Ah, that’s BAC0 for @ChristianTremblay , I was thinking maybe it was a BACpypes issue…I’ll be quiet now :).
Christian Tremblay
@ChristianTremblay
No please, don't be quiet :)
@shreyasrp-access what do you want to do ?
shreyasrp-access
@shreyasrp-access
I'm trying to make a program which runs the whois command, gets all the IP addresses, and then run ReadAllProperties.py on them. I just wanted to know how you managed to make the whois() function in BAC0 which returns the IP addresses and then exits the loop. (I wanted to all this in bacpypes itself to prevent importing BAC0)
shreyasrp-access
@shreyasrp-access
loopcount9.JPG
This is the output for:
bacnet = BAC0.connect()
b=bacnet.whois()
print( b[0][0] )
And print( "loopcount = ", loopCount) is present inside the while loop in run().
Joel Bender
@JoelBender
There is sample code here that does this and saves the output in a tab delimited text file. Note that this is in the stage branch and it is going to replace the samples/Discover.py sample in the master branch in the next release.
shreyasrp-access
@shreyasrp-access
@JoelBender Thank you, I will have a look at that.
Christian Tremblay
@ChristianTremblay
Or just
import BAC0
bacnet = BAC0.lite()
bacnet.discover()
bacnet.discoveredDevices # contains the result
bacnet.disconnect()
Joel Bender
@JoelBender
LOL — but that’s so simple…
Christian Tremblay
@ChristianTremblay
Because you already made all the complicated stuff inside :)
shreyasrp-access
@shreyasrp-access
In ReadAllProperties.py, there is a property_list, and when this list becomes empty stop() is executed, hence exiting the while loop. (This is bacpypes)
I was asking if you were calling stop ( or stopBacnetIPApp() ) so that whois() exits automatically in BAC0.
Christian Tremblay
@ChristianTremblay
I only call stop if I explicitly bacnet.disconnect()
BAC0 is kept alive at all time
shreyasrp-access
@shreyasrp-access
Suppose there are 10 Bacnet devices in the network. When a whois() is broadcasted, does it keep a count of the 10 devices and then fetch the data one at a time? How exactly does the process take place from there?
Christian Tremblay
@ChristianTremblay

whois is a special BACnet message that is sent to a subnet (as a broadcast). When devices on the network sees this message, they respond with a i-am containing their address. At this point, no data is exchanged. It's only a ping, if the analogy can be made... or maybe more an ARP to look for a DHCP server maybe.. something like that.

So the whois is sent, then everyone on the network respond with their respective i-am. For really big networks, a global broadcast could mean a large amount of responses. This is why the bacnet.discover()will poke one network at a time... to give time to BAC0 to get everything.

Each i-amresponse is kept in bacnet.discoveredDevices. They will be there forever...even if they are disconnected from the network... it is not typical that BACnet devices disappear...

You can then use the list of discovered devices to connect to them an interact with them. Reading their data. There are messages that can be sent to ask for object list, object name, etc. Then messages can be sent to read particular objects, or a bynch of objects and their properties.

shreyasrp-access
@shreyasrp-access
In whois() function of the class Discover in BAC0, you have given time.sleep(3). Is there any reason why you chose 3 seconds?
Christian Tremblay
@ChristianTremblay
In the tests I made, it gave enough time to majority of networks to respond. Guess you can tune that
shreyasrp-access
@shreyasrp-access
How many connections can the socket handle at a time? Eg: When we send a whois, if 10 BACnet devices reply, will it be handled? What is the maximum number it can handle?
Joel Bender
@JoelBender
BACnet is connectionless, and the operating system will buffer up a number of responses before throwing them out, so it depends on how big the buffer is (adjustable depending on your OS) and how quickly the applications can drain it. But more than that, field bus networks like MS/TP can very quickly become so congested that even if they wanted to respond they couldn't. A global broadcast Who-Is at Cornell with 17,000 devices you would be lucky to get a small handful of responses.
Christian Tremblay
@ChristianTremblay
This is why I think it is important to explore the network instead of yelling a global broadcast hoping to get all responses.
shreyasrp-access
@shreyasrp-access
@JoelBender @ChristianTremblay Thank you very much!
shreyasrp-access
@shreyasrp-access

In ReadAllProperties.py, there is a property_list, and when this list becomes empty stop() is executed, hence exiting the while loop. (This is bacpypes)
I was asking if you were calling stop ( or stopBacnetIPApp() ) so that whois() exits automatically in BAC0.

I guess I answered this myself (correct me if I'm wrong). What was happening is the whois() function had a time.sleep(3) and then "returned" the list of devices. Since there was nothing in main() after that, the python code terminated, hence coming out of the while loop and to the terminal.

andrew-wcislo
@andrew-wcislo
Hello Christian. Thank you for bringing BAC0 module to us. It looks very interesting and helpful. I am new to Python and run into some issues already. Some values, notably Priority Array, are returned in a format that I am not sure how to parse. I am getting something like: <bacpypes.basetypes.PriorityArray object at 0x7fe1c52dda20> when trying to read it from an object. At index 0 it reads 16, which I presume is length, but at other values of index it reads: <bacpypes.basetypes.PriorityValue object at 0x7f67b13a5550>. Any help will be highly appreciated. Regards.
Christian Tremblay
@ChristianTremblay
Hi. BAC0 being a high level interface for bacpypes, sometimes I just throw what bacpypes give. One way of inspecting the object is to use obj.debug_content()and you will have an idea of what this contains. I made things a little simple in the contact of a BAC0.device for points priority array
Joel Bender
@JoelBender
typo: debug_contents()
Christian Tremblay
@ChristianTremblay
oups
andrew-wcislo
@andrew-wcislo
@ChristianTremblay and @JoelBender thank you for the prompt reply. Both ways worked for me. I hope I can use the same approach to deal with the similar cases like TimeStamp and AddressBinding. But, I will cross that bridge when I get to it.
Your help is appreciated.
shweta9579
@shweta9579
Can I send ReadProperty i.e read request to MSTP device using bacpypes? If 'yes' then how can I do that?
Christian Tremblay
@ChristianTremblay
Using BAC0 (which use bacpypes under the hood) :
# You must have a BACnet/IP - BACnet/MSTP router providing a route to MSTP network
# you must know the MSTP network number, let's assume it's "2" for now
import BAC0
bacnet = BAC0.lite()
# optional if you already know
# bacnet.discover() # will tell you what's on the network
# Now connect to device in network #2 (MSTP) at MAC address 4, having a device instance of 2004
dev = BAC0.device('2:4',2004,bacnet)

# dev.points will list all points inside the device

# Without creating a device
bacnet.read('2:4 analogInput 1 presentValue') # if you want to read analogInput 1
# if you don't know what are the objects in the controller
bacnet.read('2:4 device 2004 objectList')
For anything else, there is masterca.... I mean, the doc : https://bac0.readthedocs.io/en/latest/
shweta9579
@shweta9579
@ChristianTremblay thank you very much for your response. It is really helpful.
hvacking
@hvacking
@ChristianTremblay .hi , Christian, i can find the network, but i can not find the devices , i have shut down the windows' firewall.
import BAC0
bacnet = BAC0.connect(ip="192.168.1.203/24")
2020-05-18 11:37:18,780 - INFO | Starting BAC0 version 20.02.20 (Complete)
2020-05-18 11:37:18,843 - INFO | Use BAC0.log_level to adjust verbosity of the app.
2020-05-18 11:37:18,843 - INFO | Ex. BAC0.log_level('silence') or BAC0.log_level('error')
2020-05-18 11:37:18,859 - INFO | Using ip : 192.168.1.203
2020-05-18 11:37:18,859 - INFO | Starting app...
2020-05-18 11:37:18,874 - INFO | BAC0 started
2020-05-18 11:37:18,874 - INFO | Registered as Simple BACnet/IP App
2020-05-18 11:37:19,937 - INFO | Server started : http://192.168.1.203:8111
  • Serving Flask app "BAC0.web.FlaskServer" (lazy loading)
  • Environment: production
    WARNING: This is a development server. Do not use it in a production deployment.
    Use a production WSGI server instead.
  • Debug mode: off
    2020-05-18 11:37:20,062 - WARNING | 192.168.1.226 Rejected message to network (reason : It is an unknown network layer message)
  • Running on http://0.0.0.0:8111/ (Press CTRL+C to quit)
    2020-05-18 11:37:22,093 - INFO | 192.168.1.202 router to [2]
    2020-05-18 11:37:24,030 - INFO | Addr : 192.168.1.202
    2020-05-18 11:37:25,108 - INFO | 192.168.1.202 routing table
    2020-05-18 11:37:25,108 - INFO | 1 1 bytearray(b'')
    2020-05-18 11:37:25,124 - INFO | 2 2 bytearray(b'')
    2020-05-18 11:37:26,108 - INFO | Found those networks : {2}
    2020-05-18 11:37:26,124 - INFO | Discovering network 2
    bacnet.devices
    Empty DataFrame
    Columns: [Manufacturer, Address, Device ID]
    Index: []
i got "Empty DataFram" result when i use 'bacnet.devices'
hvacking
@hvacking
image.png