BAC0 icon indicating copy to clipboard operation
BAC0 copied to clipboard

Issue with connecting to device

Open maciejbak85 opened this issue 1 year ago • 6 comments

Hi,

I am using library ( and bacnet ) first time, so maybe I am doing it totally wrong but I have situation that in some local network under IP: 192.168.1.215 there is some Eclypse ECY-Tu203-96B019, and I have access to router under address 10.x.y.z, I have setup port forwarding there to be able to access 192.168.1.215. I was told that via this Eclypse I am able to read from many devices in this network ( its some kind IP Driver at least what I heard ) . While using nmap I see:

sudo nmap --script bacnet-info --script-args full=yes -sU -n -sV -p 47808 10.x.y.z
Starting Nmap 7.95 ( https://nmap.org ) at 2024-08-09 09:34 CEST
Nmap scan report for 10.x.y.z
Host is up (0.25s latency).

PORT      STATE SERVICE VERSION
47808/udp open  bacnet
| bacnet-info: 
|   Vendor ID: Distech Controls Inc. (364)
|   Vendor Name: Distech Controls, Inc.
|   Object-identifier: 1215
|   Firmware: 1.14.17191.1
|   Application Software: 1.13.19189.607
|   Object Name: ECY-TU203-96B019
|   Model Name: ECY-TU203 Rev 1.0A
|   Description: 
|_  Location: 

so according to that I can assume that router with port forwarding is fine as Object name is fine ( I have a photo from bacnet config of this device ).

So I try with this script:

import BAC0

print(BAC0.version)

bbmdIP = '10.x.y.z:47808'
bbmdTTL = 900
bacnet = BAC0.lite(bbmdAddress=bbmdIP, bbmdTTL=bbmdTTL) #Connect

print(bacnet.vendorName.strValue)
print(bacnet.modelName.strValue)

whois_results = bacnet.whois()
print("WhoIs results:", whois_results)

print(bacnet.devices)

bacnet.discover(networks='known')

but I get a response:

23.07.03
2024-08-09 10:36:14,549 - INFO    | Starting BAC0 version 23.07.03 (Lite)
2024-08-09 10:36:14,549 - INFO    | Use BAC0.log_level to adjust verbosity of the app.
2024-08-09 10:36:14,549 - INFO    | Ex. BAC0.log_level('silence') or BAC0.log_level('error')
2024-08-09 10:36:14,549 - INFO    | Starting TaskManager
2024-08-09 10:36:14,551 - INFO    | Using ip : 192.168.1.33 on port 47808 | broadcast : 192.168.1.255
2024-08-09 10:36:14,560 - INFO    | Starting app...
2024-08-09 10:36:14,561 - INFO    | BAC0 started
2024-08-09 10:36:14,561 - INFO    | Registered as Foreign Device
2024-08-09 10:36:14,561 - INFO    | Device instance (id) : 3056745
2024-08-09 10:36:14,562 - INFO    | Update Local COV Task started (required to support COV)
b'SERVISYS inc.'
b'BAC0 Scripting Tool'
WhoIs results: []
[]
2024-08-09 10:36:18,670 - INFO    | Found those networks : set()
2024-08-09 10:36:18,670 - INFO    | No BACnet network found, attempting a simple whois using provided device instances limits (0 - 4194303)

192.168.1.33 is my local machine IP. Whgat am i doing it wrong ? thanks!

maciejbak85 avatar Aug 09 '24 08:08 maciejbak85

Port forwarding is not enough. You need to register the BAC0 instance as a foreign device and the router needs to support BBMD.

Then you will be able to use something like

improt BAC0
bacnet = BAC0.lite(ip="192.168.1.33/24", bbmdAddress="10.x.y.z", bbmdTTL=900)

Please be aware that exposing BACnet device to the wild by a simple port forward is not good. In fact, anyone that find the address will have complete access to your device.

ChristianTremblay avatar Aug 10 '24 01:08 ChristianTremblay

@ChristianTremblay thanks for the reply, right I see in device setup pictures that I have ( as I dont have access to this page ) that BBMD is turned off :( I will ping guy responsible for that to turn it on.

You need to register the BAC0 instance as a foreign device can you clarify this a bit ? you mean maybe:

bacnet.register_as_foreign_device() # Register

? thanks

maciejbak85 avatar Aug 12 '24 07:08 maciejbak85

ok guy turned it on but still no luck hmm ( btw port forwarding in my case is safe coz I need vpn anyway ;) )

❯ python connect_bacnet.py
2024-08-13 12:10:43,205 - INFO    | Starting BAC0 version 23.07.03 (Lite)
2024-08-13 12:10:43,205 - INFO    | Use BAC0.log_level to adjust verbosity of the app.
2024-08-13 12:10:43,205 - INFO    | Ex. BAC0.log_level('silence') or BAC0.log_level('error')
2024-08-13 12:10:43,205 - INFO    | Starting TaskManager
2024-08-13 12:10:43,208 - INFO    | Using ip : 192.168.1.33 on port 47808 | broadcast : 192.168.1.255
2024-08-13 12:10:43,217 - INFO    | Starting app...
2024-08-13 12:10:43,217 - INFO    | BAC0 started
2024-08-13 12:10:43,217 - INFO    | Registered as Foreign Device
2024-08-13 12:10:43,217 - INFO    | Device instance (id) : 3057109
2024-08-13 12:10:43,218 - INFO    | Update Local COV Task started (required to support COV)
b'SERVISYS inc.'
b'BAC0 Scripting Tool'
WhoIs results: []
[]
2024-08-13 12:10:47,326 - INFO    | Found those networks : set()
2024-08-13 12:10:47,326 - INFO    | No BACnet network found, attempting a simple whois using provided device instances limits (0 - 4194303)

maciejbak85 avatar Aug 13 '24 10:08 maciejbak85

Connecting as a foreign device means : register to a BACnet device which is a BBMD on another subnet, without being ourselves a BBMD.

by using BAC0.lite(ip="myip/port", bbmdAddress="ipofbbmdrouteronothersubnet:47808, bbmdTTL=900)

BAC0 will be part of the distribution of broadcast messages We will receive Whois, iam, requests.

The router must accept "foreign devices"

ChristianTremblay avatar Aug 16 '24 01:08 ChristianTremblay

hi, going back here, yeah flag was turned off there, I can connect now and I see in wireshark UDp packets on my local machine Uncofirmed-Req who-ai, I am and uncofirmedCovNotifcations but when I try this:

import BAC0
import logging
import time

# Set up logging
logging.basicConfig(level=logging.DEBUG)  # Change to INFO or WARNING to reduce verbosity

def initialize_bacnet(ip, bbmd_ip, bbmd_ttl):
    try:
        logging.info(f"Initializing BACnet with IP: {ip}, BBMD IP: {bbmd_ip}, BBMD TTL: {bbmd_ttl}")
        bacnet = BAC0.lite(ip=ip, bbmdAddress=bbmd_ip, bbmdTTL=bbmd_ttl)
        logging.info("BACnet initialized successfully")
        return bacnet
    except Exception as e:
        logging.error(f"Error initializing BACnet: {e}")
        raise

def perform_discovery(bacnet):
    try:
        logging.info("Performing WhoIs request")
        whois_results = bacnet.whois()
        logging.info(f"WhoIs results: {whois_results}")

        # Print discovered devices
        devices = bacnet.devices
        logging.info(f"Discovered devices: {devices}")

        return whois_results, devices
    except Exception as e:
        logging.error(f"Error during discovery: {e}")
        return None, None

def main():
    # Configuration
    ip = "10.x.y.z"
    bbmd_ip = "x.y.q:47808"
    bbmd_ttl = 1200  # Increased timeout (2 minutes)

    # Initialize BACnet
    bacnet = initialize_bacnet(ip, bbmd_ip, bbmd_ttl)

    # Retry discovery if no devices found
    retries = 30
    while retries > 0:
        whois_results, devices = perform_discovery(bacnet)
        if devices:
            break
        retries -= 1
        logging.info(f"No devices found. Retrying in 5 seconds ({retries} attempts left)")
        time.sleep(15)  # Wait before retrying

    if not devices:
        logging.warning("No BACnet devices discovered after retries")

if __name__ == "__main__":
    main()

I get in logs;

024-08-30 08:47:27,772 - DEBUG - Configurating app 2024-08-30 08:47:27,780 - DEBUG - To be able to run the web server, you must install pandas, bokeh, flask and flask_bootstrap 2024-08-30 08:47:27,780 - DEBUG - Those are not all installed so BAC0 will work in Lite mode only. 2024-08-30 08:47:27,780 - DEBUG - Create Local Device 2024-08-30 08:47:27,780 - DEBUG - - request: <bacpypes.apdu.IAmRequest(0) instance at 0x7ac7fb2c7690> 2024-08-30 08:47:27,780 - DEBUG - Starting 2024-08-30 08:47:27,780 - INFO | Starting app... 2024-08-30 08:47:27,780 - INFO - Starting app... 2024-08-30 08:47:27,780 - INFO | BAC0 started 2024-08-30 08:47:27,780 - INFO - BAC0 started 2024-08-30 08:47:27,780 - INFO | Registered as Foreign Device 2024-08-30 08:47:27,780 - INFO - Registered as Foreign Device 2024-08-30 08:47:27,780 - DEBUG - Running 2024-08-30 08:47:27,780 - DEBUG - finally 2024-08-30 08:47:27,780 - INFO | Device instance (id) : 3056465 2024-08-30 08:47:27,780 - INFO - Device instance (id) : 3056465 2024-08-30 08:47:27,780 - DEBUG - do_iam 2024-08-30 08:47:27,780 - DEBUG - - request: <bacpypes.apdu.IAmRequest(0) instance at 0x7ac7f6d084d0> 2024-08-30 08:47:27,781 - DEBUG - 2847.781812 *:* idle 2024-08-30 08:47:27,781 - DEBUG - 2847.781868 *:* active 2024-08-30 08:47:27,781 - DEBUG - 2847.781972 *:* idle 2024-08-30 08:47:27,782 - INFO | Update Local COV Task started (required to support COV) 2024-08-30 08:47:27,782 - INFO - Update Local COV Task started (required to support COV) b'SERVISYS inc.' b'BAC0 Scripting Tool' 2024-08-30 08:47:27,782 - DEBUG - do_whois 'any' 2024-08-30 08:47:27,782 - DEBUG - - request: <bacpypes.apdu.WhoIsRequest(8) instance at 0x7ac7fab7ed90> 2024-08-30 08:47:27,782 - DEBUG - 2847.782833 * idle 2024-08-30 08:47:27,782 - DEBUG - 2847.782871 * active 2024-08-30 08:47:27,782 - DEBUG - 2847.782934 * idle WhoIs results: [] [] 2024-08-30 08:47:27,888 - DEBUG - FunctionTask <bound method IOCB.abort of <bacpypes.iocb.IOCB(3) instance at 0x7ac7f6d08650>> (RuntimeError('timeout',),) {} 2024-08-30 08:47:27,888 - DEBUG - - task: <bacpypes.task.FunctionTask.<locals>._FunctionTask object at 0x7ac7fb2c7d10> 2024-08-30 08:47:27,888 - DEBUG - 2847.888683 * idle 2024-08-30 08:47:27,888 - DEBUG - 2847.888750 * active 2024-08-30 08:47:29,888 - DEBUG - process_task (<bound method IOCB.abort of <bacpypes.iocb.IOCB(3) instance at 0x7ac7f6d08650>> (RuntimeError('timeout',),) {}) 2024-08-30 08:47:29,888 - DEBUG - 2849.888984 * idle 2024-08-30 08:47:29,889 - DEBUG - FunctionTask <bound method IOCB.abort of <bacpypes.iocb.IOCB(4) instance at 0x7ac7f6d08750>> (RuntimeError('timeout',),) {} 2024-08-30 08:47:29,889 - DEBUG - - task: <bacpypes.task.FunctionTask.<locals>._FunctionTask object at 0x7ac7f6d08e10> 2024-08-30 08:47:29,889 - DEBUG - 2849.889647 * active 2024-08-30 08:47:31,890 - DEBUG - process_task (<bound method IOCB.abort of <bacpypes.iocb.IOCB(4) instance at 0x7ac7f6d08750>> (RuntimeError('timeout',),) {}) 2024-08-30 08:47:31,890 - DEBUG - 2851.890759 * idle 2024-08-30 08:47:31,890 - INFO | Found those networks : set() 2024-08-30 08:47:31,890 - INFO - Found those networks : set() 2024-08-30 08:47:31,890 - INFO | No BACnet network found, attempting a simple whois using provided device instances limits (0 - 4194303) 2024-08-30 08:47:31,890 - INFO - No BACnet network found, attempting a simple whois using provided device instances limits (0 - 4194303) 2024-08-30 08:47:31,890 - DEBUG - do_whois ['0', '4194303'] 2024-08-30 08:47:31,891 - DEBUG - - request: <bacpypes.apdu.WhoIsRequest(8) instance at 0x7ac7f6d08e50> 2024-08-30 08:47:31,891 - DEBUG - 2851.891457 * idle 2024-08-30 08:47:31,891 - DEBUG - 2851.891520 * active 2024-08-30 08:47:31,891 - DEBUG - 2851.891698 * idle

any ideas ?

maciejbak85 avatar Aug 30 '24 06:08 maciejbak85

If you want, try the new async version (now the default pip install version

import asyncio
import BAC0
from BAC0.scripts.script_runner import run

bacnet = None

async def main():
    # Configuration
    ip = "10.x.y.z"
    bbmd_ip = "x.y.q:47808"
    bbmd_ttl = 1200  # Increased timeout (20 minutes)

    # Initialize BACnet
    
    async with BAC0.start(ip=ip, bbmdAddress=bbmd_ip, bbmdTTL=bbmd_ttl) as bacnet:

        await bacnet._discover()
        lst = await bacnet._devices(_return_list=True)
        print(lst)


if __name__ == "__main__":
    #run(main, bacnet) # Run the script and deals with SIGINT and SIGTERM, useful for long time runnign scripts.
    asyncio.run(main())

ChristianTremblay avatar Sep 08 '24 19:09 ChristianTremblay

This issue had no activity for a long period of time. If this issue is still required, please update the status or else, it will be closed. Please note that an issue can be reopened if required.

github-actions[bot] avatar Nov 08 '24 01:11 github-actions[bot]