From 4eff06bdbcee31be51bff82686c4513c2f2717b3 Mon Sep 17 00:00:00 2001 From: GravySeal Date: Tue, 9 Jan 2024 08:17:53 +0100 Subject: [PATCH] Dev small update. config has emtpy list now so it won't fail. retrying entity list if it fails because of API --- .devcontainer.json | 2 +- README.md | 2 +- bacnetinterface_dev/CHANGELOG.md | 2 +- bacnetinterface_dev/DOCS.md | 6 +- bacnetinterface_dev/Dockerfile | 3 +- bacnetinterface_dev/README.md | 2 + bacnetinterface_dev/config.yaml | 3 +- .../rootfs/usr/bin/BACnetIOHandler.py | 58 +++++++++++++------ bacnetinterface_dev/rootfs/usr/bin/main.py | 8 ++- bacnetinterface_dev/rootfs/usr/bin/webAPI.py | 4 +- repository.yaml | 2 +- 11 files changed, 60 insertions(+), 32 deletions(-) diff --git a/.devcontainer.json b/.devcontainer.json index c40b0c2c..a7c67a50 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -1,5 +1,5 @@ { - "name": "bepacom repository", + "name": "Bepacom Add-on Repository", "image": "ghcr.io/home-assistant/devcontainer:addons", "appPort": ["7123:8123", "7357:4357"], "postStartCommand": "bash devcontainer_bootstrap", diff --git a/README.md b/README.md index af14d978..53cc9765 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository contains all of Bepacom B.V.'s developed add-ons for Home Assist Add-on documentation: -[![Open your Home Assistant instance and show the add add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https://github.com/GravySeal/bepacom-repo) +[![Open your Home Assistant instance and show the add add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https://github.com/Bepacom-Raalte/bepacom-HA-Addons) ## Add-ons diff --git a/bacnetinterface_dev/CHANGELOG.md b/bacnetinterface_dev/CHANGELOG.md index f1fc642d..019edf96 100644 --- a/bacnetinterface_dev/CHANGELOG.md +++ b/bacnetinterface_dev/CHANGELOG.md @@ -11,7 +11,7 @@ Happy new year everyone! - Using Home Assistant API to fetch data from entities. - "No segmentation supported" way for reading object list added. - maxApduLenghtAccepted and maxSegmentsAccepted back in configuration as unused options. -- Added name and description to the Subscriptions configuration option. +- Added name and description to the Subscriptions configuration option. - WebUI components like .css should now always be served through https. ## Fixed diff --git a/bacnetinterface_dev/DOCS.md b/bacnetinterface_dev/DOCS.md index dcb60b3d..a984628f 100644 --- a/bacnetinterface_dev/DOCS.md +++ b/bacnetinterface_dev/DOCS.md @@ -1,6 +1,6 @@ -# Bepacom EcoPanel BACnet/IP interface +# Bepacom BACnet/IP interface -The Bepacom EcoPanel BACnet/IP interface add-on is intended to be a bridge between the BACnet/IP network and Home Assistant. +The Bepacom BACnet/IP interface add-on is intended to be a bridge between the BACnet/IP network and Home Assistant. The goal of this add-on is to add BACnet functionality to Home Assistant so these devices can be displayed on the dashboard. @@ -17,7 +17,7 @@ Created and maintained by [Bepacom B.V. Raalte](https://www.bepacom.nl/) [![Open this add-on in your Home Assistant instance.][addon-badge]][addon] 1. Click the "Install" button to install the add-on. -1. Start the "Bepacom EcoPanel BACnet/IP Interface" add-on. +1. Start the "Bepacom BACnet/IP Interface" add-on. 1. Check the logs of the "Bepacom EcoPanel BACnet/IP Interface" add-on to see if everything went well. 1. Now your Home Assistant host is a virtual BACnet/IP device! diff --git a/bacnetinterface_dev/Dockerfile b/bacnetinterface_dev/Dockerfile index e8aef289..53cb5dff 100644 --- a/bacnetinterface_dev/Dockerfile +++ b/bacnetinterface_dev/Dockerfile @@ -18,7 +18,8 @@ RUN \ 'uvicorn<=0.25.0' \ 'websockets<=12.0' \ 'python-multipart<=0.0.6' \ - 'requests<=2.31.0 ' + 'requests<=2.31.0 ' \ + 'backoff<=2.2.1' WORKDIR / diff --git a/bacnetinterface_dev/README.md b/bacnetinterface_dev/README.md index c7e0495a..c8a9d1aa 100644 --- a/bacnetinterface_dev/README.md +++ b/bacnetinterface_dev/README.md @@ -10,6 +10,8 @@ The accompanying integration can be found on Bepacom's Custom Component Componen If you have any issues, please check the logs and contact the add-on developer at the GitHub repository. +## [Bepacom Add-on Repository](https://github.com/Bepacom-Raalte/bepacom-HA-Addons) + ![Supports aarch64 Architecture][aarch64-shield] ![Supports amd64 Architecture][amd64-shield] ![Supports armhf Architecture][armhf-shield] diff --git a/bacnetinterface_dev/config.yaml b/bacnetinterface_dev/config.yaml index f152f067..fd83cb38 100644 --- a/bacnetinterface_dev/config.yaml +++ b/bacnetinterface_dev/config.yaml @@ -2,7 +2,7 @@ name: Bepacom BACnet/IP Interface Development Version version: "1.3.0" slug: bacnetinterface_dev -description: Bepacom BACnet/IP interface for the Bepacom EcoPanel. Allows BACnet devices to be available to Home Assistant through an API +description: Bepacom BACnet/IP interface for the Bepacom EcoPanel. Allows BACnet/IP devices to be available to Home Assistant through an API. url: "https://github.com/Bepacom-Raalte/bepacom-HA-Addons/tree/main/bacnetinterface" arch: - armhf @@ -42,6 +42,7 @@ options: multiStateInput: true multiStateOutput: true multiStateValue: true + entity_list: [] loglevel: WARNING segmentation: segmentedBoth schema: diff --git a/bacnetinterface_dev/rootfs/usr/bin/BACnetIOHandler.py b/bacnetinterface_dev/rootfs/usr/bin/BACnetIOHandler.py index 92a87651..ece3e481 100644 --- a/bacnetinterface_dev/rootfs/usr/bin/BACnetIOHandler.py +++ b/bacnetinterface_dev/rootfs/usr/bin/BACnetIOHandler.py @@ -1,31 +1,34 @@ import asyncio +import json import logging import traceback -import json -import requests -import websockets from math import isinf, isnan from typing import Any, Dict, TypeVar +import backoff +import requests +import websockets from bacpypes3.apdu import (AbortPDU, ConfirmedCOVNotificationRequest, - ErrorPDU, ErrorRejectAbortNack, ReadPropertyACK, - ReadPropertyRequest, RejectPDU, SimpleAckPDU, - SubscribeCOVRequest, WritePropertyRequest) + ErrorPDU, ErrorRejectAbortNack, ReadPropertyACK, + ReadPropertyRequest, RejectPDU, SimpleAckPDU, + SubscribeCOVRequest, WritePropertyRequest) from bacpypes3.basetypes import (BinaryPV, DeviceStatus, EngineeringUnits, - ErrorType, EventState, PropertyIdentifier, - Reliability) + ErrorType, EventState, PropertyIdentifier, + Reliability) from bacpypes3.constructeddata import AnyAtomic, Array, List, SequenceOf from bacpypes3.errors import * from bacpypes3.ipv4.app import ForeignApplication, NormalApplication +from bacpypes3.local.analog import AnalogInputObject, AnalogValueObject +from bacpypes3.local.binary import BinaryInputObject, BinaryValueObject from bacpypes3.local.device import DeviceObject -from bacpypes3.local.binary import BinaryValueObject, BinaryInputObject -from bacpypes3.local.analog import AnalogValueObject, AnalogInputObject -from bacpypes3.object import get_vendor_info, MultiStateInputObject, MultiStateValueObject, CharacterStringValueObject +from bacpypes3.object import (CharacterStringValueObject, + MultiStateInputObject, MultiStateValueObject, + get_vendor_info) from bacpypes3.pdu import Address from bacpypes3.primitivedata import (BitString, Date, Null, ObjectIdentifier, - ObjectType, Time, Unsigned) + ObjectType, Time, Unsigned) from const import (device_properties_to_read, object_properties_to_read_once, - object_properties_to_read_periodically) + object_properties_to_read_periodically) KeyType = TypeVar("KeyType") @@ -710,8 +713,6 @@ async def do_ReadPropertyRequest(self, apdu: ReadPropertyRequest) -> None: async def do_WritePropertyRequest(self, apdu: WritePropertyRequest): try: - # await super().do_WritePropertyRequest(apdu) - obj_id = apdu.objectIdentifier obj = self.get_object_id(obj_id) @@ -838,8 +839,17 @@ def __init__(self, app: BACnetIOHandler, api_token: str, entity_list: list = Non self.data_write_task() ) - + @backoff.on_exception(backoff.expo, Exception, max_time=60) def process_entity_list(self, entity_list: list) -> None: + """Fill bacnet object list""" + self.binary_val_entity_ids = [] + self.binary_in_entity_ids = [] + self.analog_val_entity_ids = [] + self.analog_in_entity_ids = [] + self.multi_state_val_entity_ids = [] + self.multi_state_in_entity_ids = [] + self.char_string_val_entity_ids = [] + for entity in entity_list: split_entity = entity.split(".") @@ -884,7 +894,7 @@ def process_entity_list(self, entity_list: list) -> None: # self.multi_state_in_entity_ids.append(entity) state else: - logging.error(f"Entity {entity} can't be turned into an object as it's not supported!") + logging.warning(f"Entity {entity} can't be turned into an object as it's not supported!") def entity_to_obj(self, entity): @@ -910,7 +920,7 @@ def entity_to_obj(self, entity): def fetch_entity_data(self, entity_id): """Fetch data from API.""" - url = f"http://supervisor/core/api/states/{entity_id}" #http://supervisor/discovery post laat onze eigen service maken... GEBRUIKEN VOOR INTEGRATION? + url = f"http://supervisor/core/api/states/{entity_id}" headers = { "Authorization": f"Bearer {self.api_token}", "content-type": "application/json", @@ -1079,6 +1089,18 @@ def determine_units(self, unit): bacnetUnits = EngineeringUnits("kilowattHours") elif unit == "W": bacnetUnits = EngineeringUnits("watts") + elif unit == "km/h": + bacnetUnits = EngineeringUnits("kilometersPerHour") + elif unit == "m/s": + bacnetUnits = EngineeringUnits("metersPerSecond") + elif unit == "mph": + bacnetUnits = EngineeringUnits("milesPerHour") + elif unit == "ft/s": + bacnetUnits = EngineeringUnits("feetPerSecond") + elif unit == "\u0057\u002f\u006d\u00b2": + bacnetUnits = EngineeringUnits("wattsPerSquareMeter") + elif unit == "lx": + bacnetUnits = EngineeringUnits("luxes") else: bacnetUnits = None return bacnetUnits diff --git a/bacnetinterface_dev/rootfs/usr/bin/main.py b/bacnetinterface_dev/rootfs/usr/bin/main.py index 529b98f0..7d6730f5 100644 --- a/bacnetinterface_dev/rootfs/usr/bin/main.py +++ b/bacnetinterface_dev/rootfs/usr/bin/main.py @@ -192,11 +192,13 @@ async def main(): ttl=config.get("BACpypes", "foreignTTL"), update_event=webAPI.events.val_updated_event, ) - + with open("/usr/bin/auth_token.ini", "r") as auth_token: token = auth_token.read() - - object_manager = ObjectManager(app=app, entity_list=options.get('entity_list'), api_token=token) + + object_manager = ObjectManager( + app=app, entity_list=options.get("entity_list"), api_token=token + ) app.asap.maxApduLengthAccepted = int( config.get("BACpypes", "maxApduLengthAccepted") diff --git a/bacnetinterface_dev/rootfs/usr/bin/webAPI.py b/bacnetinterface_dev/rootfs/usr/bin/webAPI.py index c22a01cb..b88b1c0e 100644 --- a/bacnetinterface_dev/rootfs/usr/bin/webAPI.py +++ b/bacnetinterface_dev/rootfs/usr/bin/webAPI.py @@ -84,7 +84,7 @@ async def lifespan(app: FastAPI): description = """ -The Bepacom EcoPanel BACnet/IP Interface API +# Bepacom BACnet/IP Interface API ## Use @@ -130,7 +130,7 @@ def get_ingress_url() -> str: app = FastAPI( lifespan=lifespan, - title="Bepacom EcoPanel BACnet/IP Interface API", + title="Bepacom BACnet/IP Interface API", description=description, version="1.3.0", contact={ diff --git a/repository.yaml b/repository.yaml index 8d673d48..96b0b1c3 100644 --- a/repository.yaml +++ b/repository.yaml @@ -1,4 +1,4 @@ # https://developers.home-assistant.io/docs/add-ons/repository#repository-configuration name: Bepacom Add-on Repository url: 'https://github.com/Bepacom-Raalte/bepacom-HA-Addons' -maintainer: Bepacom \ No newline at end of file +maintainer: Bepacom B.V. \ No newline at end of file