### Install BAC0 Package Source: https://bac0.readthedocs.io/en/latest/getstarted Installs the BAC0 library from PyPI using pip. This command downloads and sets up all necessary components for BAC0. ```shell pip install BAC0 ``` -------------------------------- ### Install BAC0 using pip Source: https://bac0.readthedocs.io/en/latest/_sources/getstarted This command installs the BAC0 library from the Python Package Index (PyPI). It ensures all necessary dependencies are downloaded and installed for BAC0 to function. ```bash pip install BAC0 ``` -------------------------------- ### Start BAC0 Session (Asyncio REPL) Source: https://bac0.readthedocs.io/en/latest/getstarted Starts an asyncio REPL session and initializes a BAC0 connection. This is a basic check to confirm BAC0 is operational. ```python >>> import BAC0 >>> async with BAC0.start() as bacnet: ... # connected, ready to use ... pass ``` -------------------------------- ### Start BAC0 with Async Context Manager Source: https://bac0.readthedocs.io/en/latest/connect Demonstrates how to initialize BAC0 using an asynchronous context manager, which handles connection and cleanup automatically. It includes an example of discovering devices on the network. ```Python import asyncio import BAC0 async defmain(): # auto-detect interface async with BAC0.start() as bacnet: # or specify IP/mask: async with BAC0.start(ip='192.168.1.10/24') as bacnet: # do work, e.g. discovery await bacnet._discover(global_broadcast=True) asyncio.run(main()) ``` -------------------------------- ### BAC0 Session Management (Manual) Source: https://bac0.readthedocs.io/en/latest/getstarted Demonstrates manual management of a BAC0 session using asyncio. It shows how to start, perform operations like discovery, and properly disconnect. ```python >>> import BAC0,asyncio >>> async defdemo(): ... bacnet = BAC0.start() # or BAC0.connect(), BAC0.lite() ... try: ... # use bacnet ... await bacnet._discover(global_broadcast=True) ... finally: ... await bacnet._disconnect() # or: await bacnet.disconnect() ... >>> asyncio.run(demo()) ``` -------------------------------- ### Start BAC0 session with asyncio REPL Source: https://bac0.readthedocs.io/en/latest/_sources/getstarted This Python code snippet demonstrates how to start an asyncio REPL session and import the BAC0 library. It then shows how to initiate a BAC0 session using a context manager, indicating a successful connection. ```python import BAC0 async with BAC0.start() as bacnet: # connected, ready to use pass ``` -------------------------------- ### Start BAC0 with Async Context Manager Source: https://bac0.readthedocs.io/en/latest/_sources/connect This snippet demonstrates how to start BAC0 using an asynchronous context manager, which automatically handles connection and cleanup. It shows auto-detection of the network interface and an example of discovering devices on the network. ```Python import asyncio import BAC0 async def main(): # auto-detect interface async with BAC0.start() as bacnet: # or specify IP/mask: async with BAC0.start(ip='192.168.1.10/24') as bacnet: # do work, e.g. discovery await bacnet._discover(global_broadcast=True) asyncio.run(main()) ``` -------------------------------- ### Start BAC0 with Direct Assignment Source: https://bac0.readthedocs.io/en/latest/_sources/connect This example shows how to start BAC0 by directly assigning the BAC0 object to a variable. It includes a try-finally block to ensure explicit disconnection when not using a context manager, and demonstrates discovering devices. ```Python import asyncio import BAC0 async def main(): # create and start immediately bacnet = BAC0.start() # aliases: BAC0.connect(), BAC0.lite() try: # you can use bacnet right away await bacnet._discover(global_broadcast=True) finally: # when not using a context manager, disconnect explicitly await bacnet._disconnect() # or: await bacnet.disconnect() asyncio.run(main()) ``` -------------------------------- ### Basic BAC0 Start with IP/Mask Source: https://bac0.readthedocs.io/en/latest/_sources/connect A basic example of starting BAC0 with a specified IP address and subnet mask. This is useful when BAC0 needs to connect to a specific network interface. ```Python async with BAC0.start(ip='xxx.xxx.xxx.xxx/mask') as bacnet: ... ``` -------------------------------- ### Start BAC0 Instance (Basic) Source: https://bac0.readthedocs.io/en/latest/connect Demonstrates the basic usage of starting a BAC0 instance with a specified IP address and subnet mask. This is the fundamental step to initialize BAC0 for network communication. ```Python async with BAC0.start(ip='xxx.xxx.xxx.xxx/mask') as bacnet: ... ``` -------------------------------- ### Minimal Async COV Subscription Example (BAC0) Source: https://bac0.readthedocs.io/en/latest/_sources/cov An asynchronous example demonstrating how to start BAC0, connect to a remote device, access a point, and subscribe to COV notifications for a specified lifetime. This showcases the basic setup for COV handling in an async environment. ```Python async with BAC0.start() as bacnet: # Connect to a remote device and get a point dev = await BAC0.device("192.168.1.50:47808", 1234, bacnet, poll=0) av = dev["AV"] # Subscribe to COV notifications for 90 seconds await av.subscribe_cov(lifetime=90) ``` -------------------------------- ### BAC0 Installation and Verification Source: https://bac0.readthedocs.io/en/latest/index Instructions on how to install BAC0, either as a complete distribution or using pip, and how to verify the installation. ```bash # Installing a complete distribution (example command, actual command may vary) pip install bac0[complete] # Start using pip pip install bac0 # Check that BAC0 works (example Python code) import BAC0 bacnet_server = BAC0.lite() print(bacnet_server) ``` -------------------------------- ### Example: Two BAC0 Instances on Same Host Source: https://bac0.readthedocs.io/en/latest/_sources/connect Illustrates setting up two BAC0 instances on the same host, one acting as a local device and the other as a client. It shows how to specify different ports for each instance and how to explicitly address a device using its IP and port for communication, as broadcast discovery will not work across different BACnet networks (ports). ```python ADDRESS = '10.138.103.17/16' async with BAC0.start(ip=ADDRESS, deviceId=123) as bacnet: async with BAC0.start(ip=ADDRESS, port=47809, deviceId=456) as fake_device: # ... add local objects to fake_device ... # Explicitly point to ip:port to communicate dev = await BAC0.device(f"{ADDRESS}:47809", 456, bacnet) value = await dev['AI1'].value ``` -------------------------------- ### Manage BAC0 session lifecycle manually Source: https://bac0.readthedocs.io/en/latest/_sources/getstarted This Python example illustrates how to manually start, use, and disconnect from a BAC0 session using asyncio. It shows initializing BAC0, performing an operation like discovery, and ensuring proper cleanup with a finally block. ```python import BAC0, asyncio async def demo(): bacnet = BAC0.start() # or BAC0.connect(), BAC0.lite() try: # use bacnet await bacnet._discover(global_broadcast=True) finally: await bacnet._disconnect() # or: await bacnet.disconnect() asyncio.run(demo()) ``` -------------------------------- ### Minimal Async Example for COV Subscription (Python) Source: https://bac0.readthedocs.io/en/latest/cov Demonstrates a minimal asynchronous example of starting BAC0, connecting to a remote device, getting a specific point, and subscribing to its COV notifications for a set lifetime. ```Python async with BAC0.start() as bacnet: # Connect to a remote device and get a point dev = await BAC0.device("192.168.1.50:47808", 1234, bacnet, poll=0) av = dev["AV"] # Subscribe to COV notifications for 90 seconds await av.subscribe_cov(lifetime=90) ``` -------------------------------- ### Start BAC0 with Direct Assignment Source: https://bac0.readthedocs.io/en/latest/connect Illustrates initializing BAC0 by directly assigning the BAC0 object to a variable. This method requires manual disconnection to clean up resources. It also shows how to discover devices. ```Python import asyncio import BAC0 async defmain(): # create and start immediately bacnet = BAC0.start() # aliases: BAC0.connect(), BAC0.lite() try: # you can use bacnet right away await bacnet._discover(global_broadcast=True) finally: # when not using a context manager, disconnect explicitly await bacnet._disconnect() # or: await bacnet.disconnect() asyncio.run(main()) ``` -------------------------------- ### Start BAC0 with Custom Port Source: https://bac0.readthedocs.io/en/latest/_sources/connect Demonstrates how to start a BAC0 instance using a custom BACnet/IP port, which is necessary when running multiple instances on the same IP address to avoid port conflicts. This allows for explicit communication between devices on different ports. ```python BAC0.start(ip='192.168.1.10/24', port=47809) ``` -------------------------------- ### Configure Foreign Device Registration and Discover Source: https://bac0.readthedocs.io/en/latest/connect Provides an example of configuring BAC0 as a Foreign Device with BBMD details and then initiating network discovery. This ensures BAC0 can reach devices on other subnets via the BBMD. ```Python async with BAC0.start( ip="10.8.0.2/24", # your VPN/TUN interface bbmdAddress="192.168.1.2:47808", # BBMD on site bbmdTTL=900 # lifetime seconds ) as bacnet: await bacnet._discover(global_broadcast=True) ``` -------------------------------- ### Get BACnet Discovered Devices List Source: https://bac0.readthedocs.io/en/latest/_sources/connect Retrieves a list of discovered BACnet devices without printing a formatted table. This is an alternative to `await bacnet.devices` for programmatic access to the device list. ```python lst = await bacnet._devices(_return_list=True) ``` -------------------------------- ### Get BACnet Devices List Source: https://bac0.readthedocs.io/en/latest/connect Retrieves a list of discovered BACnet devices without printing a formatted table. This is a more efficient way to access device information for programmatic use. ```Python lst = await bacnet._devices(_return_list=True) ``` -------------------------------- ### Run Multiple BAC0 Instances (Custom Port) Source: https://bac0.readthedocs.io/en/latest/connect Demonstrates running two BAC0 instances on the same IP address but with different UDP ports. This is useful for explicit, point-to-point communication when broadcast discovery across ports is not required. It shows how to start instances and explicitly reference devices using their IP:port. ```python ADDRESS = '10.138.103.17/16' async with BAC0.start(ip=ADDRESS, deviceId=123) as bacnet: async with BAC0.start(ip=ADDRESS, port=47809, deviceId=456) as fake_device: # ... add local objects to fake_device ... # Explicitly point to ip:port to communicate dev = await BAC0.device(f"{ADDRESS}:47809", 456, bacnet) value = await dev['AI1'].value ``` -------------------------------- ### Start BAC0 with Device ID Source: https://bac0.readthedocs.io/en/latest/connect Shows how to set a specific device ID for the BAC0 instance during initialization. This is useful for uniquely identifying your BAC0 controller on the BACnet network. ```Python async with BAC0.start(ip='x.x.x.x/mask', deviceId=1234) as bacnet: ``` -------------------------------- ### InfluxDB Parameters Example .env file Source: https://bac0.readthedocs.io/en/latest/database This is an example of a .env file used by BAC0 to load InfluxDB connection parameters. It specifies the InfluxDB URL, organization, and token, along with commented-out optional parameters. ```INI # InfluxDB Params Example .env file INFLUXDB_V2_URL=http://192.168.1.10:8086 INFLUXDB_V2_ORG=my-org INFLUXDB_V2_TOKEN=123456789abcdefg # INFLUXDB_V2_TIMEOUT= # INFLUXDB_V2_VERIFY_SSL= # INFLUXDB_V2_SSL_CA_CERT= # INFLUXDB_V2_CONNECTION_POOL_MAXSIZE= # INFLUXDB_V2_AUTH_BASIC= # INFLUXDB_V2_PROFILERS= ``` -------------------------------- ### BAC0 Trends Module Setup Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/devices/Trends This snippet shows the initial setup for the BAC0 Trends module, including necessary imports from standard Python libraries, third-party modules like bacpypes3, and internal BAC0 utilities. It also demonstrates how to conditionally import pandas if available. ```Python #!/usr/bin/python # -*- coding: utf-8 -*- # # Copyright (C) 2015 by Christian Tremblay, P.Eng # Licensed under LGPLv3, see file LICENSE in this source tree. # # --- standard Python modules --- # --- 3rd party modules --- from collections import namedtuple from typing import Any, Dict, List, Optional, Tuple, Union from bacpypes3.primitivedata import Date, Time # --- this application's modules --- from..utils.notes import note_and_log from..utils.lookfordependency import pandas_if_available _PANDAS, pd, _, _ = pandas_if_available() ``` -------------------------------- ### Initiate Network Discovery Source: https://bac0.readthedocs.io/en/latest/_sources/connect Starts the BACnet device discovery process. This function can target specific networks or use 'known' networks. It also allows setting limits for the device instance range and controls whether global broadcasts are used. ```python bacnet.discover(networks=['listofnetworks'], limits=(0,4194303), global_broadcast=False) ``` -------------------------------- ### BAC0 Schedule Example Access Source: https://bac0.readthedocs.io/en/latest/_sources/schedules Demonstrates how to access predefined schedule examples in BAC0. These functions provide templates for different schedule types. ```Python bacnet.schedule_example_analog() bacnet.schedule_example_binary() bacnet.schedule_example_multistate() ``` -------------------------------- ### Minimal Asynchronous COV Example Source: https://bac0.readthedocs.io/en/latest/index A basic asynchronous example demonstrating the use of Change of Value (COV) notifications in BAC0. ```python import BAC0 import asyncio async def cov_example(): bacnet = BAC0.lite() device = bacnet.get_device('192.168.1.100', device_id=123) # Subscribe to COV for a specific point # Replace 'Analog Input 1' with the actual point name await device.cov_subscribe('Analog Input 1', callback=cov_callback) print("Subscribed to COV for Analog Input 1.") # Keep the script running to receive COV notifications await asyncio.sleep(60) # Run for 60 seconds # Unsubscribe from COV await device.cov_unsubscribe('Analog Input 1') print("Unsubscribed from COV.") bacnet.disconnect() def cov_callback(device, obj_name, value, **kwargs): print(f"COV received for {obj_name}: {value}") if __name__ == "__main__": asyncio.run(cov_example()) ``` -------------------------------- ### Start BAC0 as Foreign Device Source: https://bac0.readthedocs.io/en/latest/connect Illustrates how to configure BAC0 to act as a Foreign Device, enabling communication across different subnets by registering with a BBMD. This requires specifying the local IP, BBMD address, and Time-To-Live (TTL). ```Python my_ip = '10.8.0.2/24' bbmdIP = '192.168.1.2:47808' bbmdTTL = 900 # note the parameter name is bbmdAddress async with BAC0.start(ip=my_ip, bbmdAddress=bbmdIP, bbmdTTL=bbmdTTL) as bacnet: ... ``` -------------------------------- ### Start BACnet Stack Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/scripts/Base Initializes and starts the BACnet stack in a separate thread. Configures the local device, network port, and handles different operating modes (normal, bbmd, foreign). Includes error handling for socket operations. ```Python def start(self): """ Once defined, start the BACnet stack in its own thread. """ self.log("Create Local Device", level="debug") try: app_type = "BACnet/IP App" class config(defaultdict): """Simple class to mimic args dot retrieval""" def __init__(self, cfg): for k, v in cfg.items(): self[k] = v def __getattr__(self, key): return self[key] if self.bbmdAddress is not None: mode = "foreign" elif self.bdtable: mode = "bbmd" else: mode = "normal" cfg = { "BAC0": { "bbmdAddress": self.bbmdAddress, "bdt": self.bdtable, "ttl": self.bbmdTTL, }, "device": { "object-name": self.localObjName, "vendor-identifier": self.vendorId, "vendor-name": "Servisys inc.", "object-identifier": f"device,{self.Boid}", "object-list": [f"device,{self.Boid}", "network-port,1"], "model-name": self.modelName, }, "network-port": { "ip-address": str(self.localIPAddr), "ip-subnet-mask": str(self.localIPAddr.netmask), "bacnet-ip-udp-port": self.localIPAddr.addrPort, "network-number": None, "fd-bbmd-address": sequence_to_json(HostNPort(self.bbmdAddress)), "fd-subscription-lifetime": self.bbmdTTL, "bacnet-ip-mode": mode, }, } if mode == "bbmd": cfg["network-port"]["bbmdBroadcastDistributionTable"] = self.bdtable _cfg = config(cfg) self.this_application = BAC0Application( _cfg, self.localIPAddr, json_file=self.json_file ) if mode == "bbmd": self._log.info(f"Populating BDT with {self.bdtable}") self.this_application.populate_bdt() if mode == "foreign": self._log.info( f"Registering as a foreign device to host {self.bbmdAddress} for {self.bbmdTTL} seconds" ) self.this_application.register_as_foreign_device_to( host=self.bbmdAddress, lifetime=self.bbmdTTL ) self.log("Starting", level="debug") self._initialized = True try: Base._used_ips.add(self.localIPAddr) self.log(f"Registered as {app_type} | mode {mode}", level="info") self._started = True except OSError as error: self.log(f"Error opening socket: {error}", level="warning") raise InitializationError(f"Error opening socket: {error}") self.log("Running", level="debug") except OSError as error: self.log(f"an error has occurred: {error}", level="error") raise InitializationError(f"Error starting app: {error}") self.log("finally", level="debug") ``` -------------------------------- ### Configure BAC0 with Device ID Source: https://bac0.readthedocs.io/en/latest/_sources/connect Sets the device ID for a BAC0 instance during initialization. This is useful for uniquely identifying your BAC0 instance on the network. ```python async with BAC0.start(ip='x.x.x.x/mask', deviceId=1234) as bacnet: ``` -------------------------------- ### Start BAC0 and Discover Devices Source: https://bac0.readthedocs.io/en/latest/controller Initializes the BAC0 library, optionally specifying an IP address, and then discovers available BACnet devices on the network. The discovered devices are then listed. ```Python import BAC0 bacnet = BAC0.start() # or specify the IP you want to use / bacnet = BAC0.start(ip='192.168.1.10/24') # by default, it will attempt an internet connection and use the network adapter # connected to the internet. # Specifying the network mask will allow the usage of a local broadcast address # like 192.168.1.255 instead of the global broadcast address 255.255.255.255 # which could be blocked in some cases. # Query and display the list of devices seen on the network bacnet.discover() await bacnet.devices ``` -------------------------------- ### BAC0.core.io Module Contents Source: https://bac0.readthedocs.io/en/latest/_sources/BAC0.core.io Overview of the main BAC0.core.io module, listing its members, undocumented members, and inheritance. This serves as a general entry point to the I/O functionalities within BAC0. ```Python import BAC0.core.io # Accessing members (conceptual): # print(dir(BAC0.core.io)) # print(BAC0.core.io.some_function()) ``` -------------------------------- ### BAC0.core.io.Simulate Module Source: https://bac0.readthedocs.io/en/latest/_sources/BAC0.core.io Provides documentation for the BAC0.core.io.Simulate module, enabling the simulation of I/O operations. This is useful for testing and development without requiring actual hardware interaction. ```Python import BAC0.core.io.Simulate # Example usage (conceptual): # BAC0.core.io.Simulate.start_simulation() # print("Simulation started.") ``` -------------------------------- ### Get BAC0 Routing Table Source: https://bac0.readthedocs.io/en/latest/connect Retrieves the available routing information from BAC0. This is useful for understanding how BAC0 has discovered routes between networks. The output is a dictionary containing source network, address, destination networks, and path information. ```python await bacnet.routing_table ``` ```python await bacnet.routing_table {'192.168.211.3': Source Network: None | Address: 192.168.211.3 | Destination Networks: {303: 0} | Path: (1, 303)} ``` -------------------------------- ### Start BAC0 and Discover Devices Source: https://bac0.readthedocs.io/en/latest/_sources/controller Initializes the BAC0 library, optionally specifying an IP address for network connection. It then discovers all available BACnet devices on the network and retrieves the list of discovered devices. ```Python import BAC0 bacnet = BAC0.start() # or specify the IP you want to use / bacnet = BAC0.start(ip='192.168.1.10/24') # by default, it will attempt an internet connection and use the network adapter # connected to the internet. # Specifying the network mask will allow the usage of a local broadcast address # like 192.168.1.255 instead of the global broadcast address 255.255.255.255 # which could be blocked in some cases. # Query and display the list of devices seen on the network bacnet.discover() await bacnet.devices ``` -------------------------------- ### Manually Declare BACnet Router with Source Network Source: https://bac0.readthedocs.io/en/latest/_sources/connect Manually configures BAC0 to use a specific router for a destination network, while also specifying the source network number. This is useful for precise control over routing in complex network setups. ```python # Provide a specific source network number await bacnet.use_router(("192.168.1.2:47808", 3, 1)) ``` -------------------------------- ### Environment-Driven BACnet Device Setup (Python) Source: https://bac0.readthedocs.io/en/latest/_sources/local_objects Shows how to initialize a BACnet device using parameters read from environment variables (IP, PORT, MASK, DEVICEID, NAME). It then declares and registers several input objects, including analog inputs, binary inputs, and character strings. ```Python import os import asyncio from BAC0.core.devices.local.factory import analog_input, binary_input, character_string IP, PORT, MASK, DEVICEID, NAME = os.getenv("BAC0_IP"), os.getenv("BAC0_PORT"), os.getenv("BAC0_MASK"), os.getenv("BAC0_DEVICEID"), os.getenv("BAC0_OBJECTNAME") async def start_device(): dev = BAC0.lite(ip=IP, mask=MASK, port=PORT, deviceId=DEVICEID, localObjName=NAME) while not dev._initialized: await asyncio.sleep(0.01) analog_input(name="hg1_last_level", description="Level in meters", properties={"units": "meters"}) analog_input(name="Battery_Voltage", description="Voltage of battery", properties={"units": "volts"}) binary_input(name="NOAA_ALARM", description="Problem retrieving data") character_string(name="Application_Status", description="Health", presentValue="Normal") # Commandable config strings character_string(name="NOAA_USERNAME", description="Username", presentValue="", is_commandable=True) character_string(name="NOAA_PASSWORD", description="Password", presentValue="", is_commandable=True) character_string.add_objects_to_application(dev) return dev ``` -------------------------------- ### BAC0.tools Module Overview Source: https://bac0.readthedocs.io/en/latest/_sources/BAC0.tools Provides an overview of the entire BAC0.tools module, including its members, undocumented attributes, and inheritance. This serves as a general entry point for exploring the tools within the BAC0 package. ```Python import BAC0.tools # Access various tools and utilities provided by the BAC0.tools package # Example: BAC0.tools.some_utility_function() ``` -------------------------------- ### BAC0Application Class Initialization and Configuration Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/app/asyncApp Initializes the BAC0Application with configuration, sets up local IP address, BDT, and network port configurations. It also loads the BACnet application from a JSON configuration. ```Python importjson importos fromtypingimport Any, Dict, List, Optional, Set frombacpypes3.appimport Application frombacpypes3.basetypesimport BDTEntry, HostNPort from...core.utils.notesimport note_and_log [docs] @note_and_log classBAC0Application: _learnedNetworks: Set = set() _cfg: Optional[Dict[str, Any]] = None def__init__( self, cfg: Dict[str, Any], addr: str, json_file: Optional[str] = None ) -> None: self._cfg = cfg self.cfg: Dict[str, Any] = self.update_config(cfg, json_file) self.localIPAddr: str = addr self.bdt: List[str] = self._cfg["BAC0"]["bdt"] self.device_cfg, self.networkport_cfg = self.cfg["application"] self.log(f"Configuration sent to build application : {self.cfg}", level="debug") self.app: Application = Application.from_json(self.cfg["application"]) ``` -------------------------------- ### Create Device and Manage Connection State Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/devices/Device This asynchronous function creates a `Device` instance and immediately initiates a task to set its state to `DeviceDisconnected`. It returns the created device object after ensuring the initial state transition is complete. This is the standard way to instantiate and prepare a device for operation. ```Python async def device(*args: Any, **kwargs: Any) -> Device: dev = Device(*args, **kwargs) await dev.new_state(DeviceDisconnected) return dev ``` -------------------------------- ### Install influxdb-client (Bash) Source: https://bac0.readthedocs.io/en/latest/database Installs the necessary Python package for interacting with the InfluxDB API. This command ensures that the client library is available for BAC0 to use. ```Bash pip install ‘influxdb-client’ ``` -------------------------------- ### Create BACnet Device with Local Objects (Async) Source: https://bac0.readthedocs.io/en/latest/_sources/local_objects Demonstrates how to initialize a BACnet device using BAC0's lite mode and add various local objects like Analog Input, Binary Output, Multistate Value, and Character String. It shows how to declare objects with specific properties and update their values at runtime. ```python import asyncio import BAC0 from BAC0.core.devices.local.factory import ( analog_input, binary_output, multistate_value, character_string, make_state_text, ) async def main(): async with BAC0.lite(deviceId=1234, port=47808, localObjName="MyDevice") as dev: # Declare objects (units via property strings) analog_input(name="TW1", description="Water temperature 1", properties={"units": "degreesCelsius"}) binary_output(name="Night", description="Day/Night flag", properties={"inactiveText": "day", "activeText": "night"}) # State text for multistate lang_states = make_state_text(["en", "fr"]) multistate_value(name="Language", description="Language for requests", presentValue=1, properties={"stateText": lang_states}) # Commandable string character_string(name="Application_Status", description="Health/status", presentValue="Normal") # Push all declared objects into the running application # (call add_objects_to_application on any created model) _ = character_string # to emphasize any model can be used for the call _.add_objects_to_application(dev) # Update values at runtime dev["TW1"].presentValue = 21.5 dev["Night"].presentValue = False await asyncio.sleep(60) asyncio.run(main()) ``` -------------------------------- ### Install influxdb-client for BAC0 Source: https://bac0.readthedocs.io/en/latest/_sources/database Provides the command to install the necessary Python client library for interacting with InfluxDB. This package is required for BAC0 to send data to InfluxDB. ```bash pip install 'influxdb-client' ``` -------------------------------- ### Initialize Device from Database (Python) Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/devices/Device Initializes a device by loading its properties and points from a database. It handles potential errors during database lookup and raises a ValueError if the database name is missing or not found. ```Python async definitialize_device_from_db(self): self.log(f"Initializing DB for {self.properties.name}", level="info") # Save important properties for reuse if self.properties.db_name: dbname = self.properties.db_name try: self._props = self.read_dev_prop(self.properties.db_name) except ValueError: raise ValueError(f"Can't find {self.properties.db_name} on drive") else: self.log(f"Missing argument DB for {self.properties.name}", level="info") raise ValueError( f"Please provide db name using device.load_db('name') for {self.properties.name}" ) # network = self.properties.network pss = self.properties.pss self.points = [] for point in await self.points_from_sql(self.properties.db_name): try: self.points.append(OfflinePoint(self, point)) except RemovedPointException: continue self.properties = DeviceProperties() self.properties.db_name = dbname self.properties.address = self._props["address"] self.properties.device_id = self._props["device_id"] self.properties.network = None self.properties.pollDelay = self._props["pollDelay"] self.properties.name = self._props["name"] self.properties.objects_list = self._props["objects_list"] self.properties.pss = pss self.properties.serving_chart = {} self.properties.charts = [] self.properties.multistates = self._props["multistates"] self.properties.auto_save = self._props["auto_save"] self.properties.save_resampling = self._props["save_resampling"] self.properties.clear_history_on_save = self._props["clear_history_on_save"] self.properties.default_history_size = self._props["history_size"] self.log(f"{self.properties.name} restored from db", level="info") self.log( 'You can reconnect to network using : "device.connect(network=bacnet)"', level="info", ) ``` -------------------------------- ### BAC0 Weekly Schedule from Controller Example Source: https://bac0.readthedocs.io/en/latest/_sources/schedules An example of a weekly schedule object as retrieved from a BACnet controller. It includes additional metadata like object references and present value. ```Python {'object_references': [('multiStateValue', 59)], 'references_names': ['OCC-SCHEDULE'], 'states': {'Occupied': 1, 'UnOccupied': 2, 'Standby': 3, 'Not Set': 4}, 'reliability': 'noFaultDetected', 'priority': 15, 'presentValue': 'UnOccupied (2)', 'week': {'monday': [('01:00', 'Occupied'), ('17:00', 'UnOccupied')], 'tuesday': [('02:00', 'Occupied'), ('17:00', 'UnOccupied')], 'wednesday': [('03:00', 'Occupied'), ('17:00', 'UnOccupied')], 'thursday': [('04:00', 'Occupied'), ('17:00', 'UnOccupied')], 'friday': [('05:00', 'Occupied'), ('17:00', 'UnOccupied')], 'saturday': [('06:00', 'Occupied'), ('17:00', 'UnOccupied')], 'sunday': [('07:00', 'Occupied'), ('17:00', 'UnOccupied')]}} ``` -------------------------------- ### BAC0 DeviceFromDB Class Methods Source: https://bac0.readthedocs.io/en/latest/BAC0.core Describes methods for the DeviceFromDB class, used for initializing and interacting with devices loaded from a database. Includes polling and reading multiple points. ```python DeviceFromDB.connect() DeviceFromDB.initialize_device_from_db() DeviceFromDB.poll() DeviceFromDB.read_multiple() DeviceFromDB.to_excel() ``` -------------------------------- ### Python: Initialize Device from Database Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/devices/Device This method is intended to initialize the device using data stored in a database. It is currently not implemented and raises a NotImplementedError. ```Python def initialize_device_from_db(self) -> None: raise NotImplementedError() ``` -------------------------------- ### BAC0 Weekly Schedule Example (Modified) Source: https://bac0.readthedocs.io/en/latest/schedules An example of a modified weekly schedule dictionary, potentially used for writing back to a controller. It highlights the structure for daily events, including times and states. ```Python { 'monday': [('00:00', 'UnOccupied'),('07:00', 'Occupied'), ('17:00', 'UnOccupied')], 'tuesday': [('07:00', 'Occupied'), ('17:00', 'UnOccupied')], 'wednesday': [('07:00', 'Occupied'), ('17:00', 'UnOccupied')], 'thursday': [('07:00', 'Occupied'), ('17:00', 'UnOccupied')], 'friday': [('07:00', 'Occupied'), ('17:00', 'UnOccupied')], 'saturday': [], 'sunday': [] } ``` -------------------------------- ### Start BAC0 with Ping Disabled Source: https://bac0.readthedocs.io/en/latest/connect This code snippet demonstrates how to initialize BAC0 and disable the device pinging feature by setting the 'ping' parameter to False. This is useful if you do not want BAC0 to actively monitor device connectivity. ```Python bacnet = BAC0.start(ping=False) ``` -------------------------------- ### Python: Connect Device Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/devices/Device Initiates the connection of the device to the network. This method is a placeholder and must be implemented by subclasses. ```Python def connect(self) -> None: """ Connect the device to the network """ raise NotImplementedError() ``` -------------------------------- ### Base: Start BACnet Application Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/scripts/Base The startApp method is responsible for initiating the BACnet application services for the device. It defines the local device and its supported services, preparing it to handle network requests. ```Python defstartApp(self): """ Define the local device, including services supported. """ ``` -------------------------------- ### Start BAC0 with Ping Disabled Source: https://bac0.readthedocs.io/en/latest/_sources/connect Shows how to initialize BAC0 with the device ping feature disabled. By default, BAC0 continuously pings registered devices to monitor their online status and disconnect them when they go offline. Setting `ping=False` disables this monitoring. ```python bacnet = BAC0.start(ping=False) ``` -------------------------------- ### Creating a BACnet Device with Local Objects (Async) Source: https://bac0.readthedocs.io/en/latest/index A guide on how to create a BACnet device within BAC0 and add local objects to it asynchronously. ```python import BAC0 import asyncio async def create_local_device(): bacnet = BAC0.lite() # Create a local device with a specific device ID and IP address # Replace with your desired configuration local_device = bacnet.get_device(ip='192.168.1.150', device_id=500) # Add local objects to the device # Example: Adding an Analog Input object await local_device.add_local_object( obj_type='analogInput', obj_name='Local Temp Sensor', properties={ 'presentValue': 22.5, 'units': 'degreesCelsius', 'statusFlags': [False, False, False, False] } ) # Example: Adding a Binary Output object await local_device.add_local_object( obj_type='binaryOutput', obj_name='Local Light Switch', properties={ 'presentValue': 0, # 0 for Off, 1 for On 'reliability': 'noFault' } ) print(f"Local device created with objects: {local_device.points}") # Keep the device running await asyncio.sleep(60) bacnet.disconnect() if __name__ == "__main__": asyncio.run(create_local_device()) ``` -------------------------------- ### BAC0 Device Initialization from Database Source: https://bac0.readthedocs.io/en/latest/genindex Details methods for initializing devices from a database and checking if a device is initialized in BAC0. ```Python class Device: def initialize_device_from_db(self): pass initialized class DeviceFromDB: pass ``` -------------------------------- ### Example: Read presentValue of Analog Value Source: https://bac0.readthedocs.io/en/latest/_sources/read This example shows a practical application of reading the 'presentValue' property from an analog value object on a specific BACnet device. The format includes network, device ID, object type, instance, and property name. ```python await bacnet.read('303:9 analogValue 4410 presentValue') ``` -------------------------------- ### BAC0 ReadRange Example Usage in Python Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/io/Read This Python code snippet provides an example of how to use the `readRange` function in BAC0 to fetch log records from a BACnet device. It shows how to specify the device address, the trend log object, and how to use time-based range parameters to retrieve specific log entries. ```python import BAC0 from bacpypes.basetypes import Date, Time myIPAddr = '192.168.1.10/24' bacnet = BAC0.connect(ip=myIPAddr) log_records = bacnet.readRange('2:5 trendLog 1 logBuffer', range_params=('t', None, '2023-05-12', '12:00:00', 2)) for log_record in log_records: print(Date(log_record.timestamp.date), Time(log_record.timestamp.time), log_record.logDatum.realValue) log_records = bacnet.readRange('2:5 trendLog 1 logBuffer', range_params=('t', None, '2023-05-12', '12:00:00', -2)) for log_record in log_records: print(Date(log_record.timestamp.date), Time(log_record.timestamp.time), log_record.logDatum.realValue) ``` -------------------------------- ### Discover BACnet Devices Source: https://bac0.readthedocs.io/en/latest/connect Initiates an asynchronous discovery of BACnet devices on specified networks. It can use local or global broadcasts and allows bounding the device instance range. The function also attempts to learn the local network number. ```Python bacnet.discover(networks=['listofnetworks'], limits=(0,4194303), global_broadcast=False) ``` -------------------------------- ### Get Point BACnet Properties Source: https://bac0.readthedocs.io/en/latest/BAC0.core Retrieves the BACnet properties associated with the point. ```python _property_ bacnet_properties ``` -------------------------------- ### BAC0 DeviceLoad: Initialization Source: https://bac0.readthedocs.io/en/latest/_modules/BAC0/core/devices/Device The DeviceLoad class, inheriting from DeviceFromDB, is initialized with an optional filename. If a filename is provided, it initializes the Device with backup data; otherwise, it raises an Exception indicating that a backup file must be provided. ```Python class DeviceLoad(DeviceFromDB): def __init__(self, filename=None): if filename: Device.__init__(self, None, None, None, from_backup=filename) else: raise Exception("Please provide backup file as argument") ``` -------------------------------- ### Get Point Last Value Source: https://bac0.readthedocs.io/en/latest/BAC0.core Retrieves the last read value of a point. ```python _property_ lastValue ```