diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index 75a084f..3bbc4ae 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,3 +1,3 @@ -pip==20.3.3 -pre-commit==2.9.3 -nox==2020.12.31 +pip==22.2.2 +pre-commit==2.20.0 +nox==2022.8.7 diff --git a/.github/workflows/hassfest.yaml b/.github/workflows/hassfest.yaml index 862840e..1ee9922 100644 --- a/.github/workflows/hassfest.yaml +++ b/.github/workflows/hassfest.yaml @@ -1,7 +1,6 @@ ---- - name: Validate with hassfest +# yamllint disable-line rule:truthy on: push: pull_request: @@ -12,5 +11,5 @@ jobs: validate: runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v2" + - uses: "actions/checkout@v3.1.0" - uses: home-assistant/actions/hassfest@master diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 9e43ce8..b0e3f19 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -1,42 +1,15 @@ -name: Linting +name: pre-commit +# yamllint disable-line rule:truthy on: - push: - branches: - - main - - master - - dev pull_request: + push: + branches: [master] jobs: pre-commit: runs-on: ubuntu-latest - name: pre-commit steps: - - uses: actions/checkout@v2.3.4 - - uses: actions/setup-python@v2.2.1 - with: - python-version: "3.9" - - run: | - pip install --constraint=.github/workflows/constraints.txt pip - pip install --constraint=.github/workflows/constraints.txt pre-commit - - name: Compute cache key prefix - if: matrix.os != 'windows-latest' - id: cache_key_prefix - shell: python - run: | - import hashlib - import sys - python = "py{}.{}".format(*sys.version_info[:2]) - payload = sys.version.encode() + sys.executable.encode() - digest = hashlib.sha256(payload).hexdigest() - result = "${{ runner.os }}-{}-{}-pre-commit".format(python, digest) - print("::set-output name=result::{}".format(result)) - - uses: actions/cache@v2.1.3 - if: matrix.os != 'windows-latest' - with: - path: ~/.cache/pre-commit - key: ${{ steps.cache_key_prefix.outputs.result }}-${{ hashFiles('.pre-commit-config.yaml') }} - restore-keys: | - ${{ steps.cache_key_prefix.outputs.result }}- - - run: pre-commit run --all-files --show-diff-on-failure --color=always + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e6f41e8..9efca2f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,21 +1,18 @@ ---- - repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.32.1 + rev: v3.15.0 hooks: - id: pyupgrade - args: [ --py39 ] + args: [--py39-plus] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 23.12.1 hooks: - id: black args: - - --safe - --quiet - files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$ + files: ^((custom_components)/.+)?[^/]+\.py$ - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.2.6 hooks: - id: codespell args: @@ -23,41 +20,54 @@ repos: - --skip="./.*,*.csv,*.json" - --quiet-level=2 exclude_types: [csv, json] - exclude: ^tests/fixtures/ - - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 + - repo: https://github.com/PyCQA/autoflake + rev: v2.2.1 + hooks: + - id: autoflake + args: + - --in-place + - --remove-all-unused-imports + - repo: https://github.com/PyCQA/flake8 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: - - flake8-docstrings==1.5.0 - - pydocstyle==5.1.1 - files: ^(homeassistant|script|tests)/.+\.py$ + - pycodestyle>=2.10.0 + - pyflakes>=3.0.1 + # - flake8-docstrings==1.6.0 + # - pydocstyle==6.2.3 + - flake8-comprehensions>=3.10.1 + - flake8-noqa>=1.3.0 + - mccabe>=0.7.0 + files: ^(custom_components)/.+\.py$ - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 + rev: 1.7.6 hooks: - id: bandit args: - --quiet - --format=custom - - --configfile=tests/bandit.yaml - files: ^(homeassistant|script|tests)/.+\.py$ + - --configfile=bandit.yaml + files: ^(custom_components)/.+\.py$ - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 + rev: v4.5.0 hooks: - - id: check-executables-have-shebangs - stages: [manual] - id: check-json exclude: (.vscode|.devcontainer) - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - id: check-added-large-files + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.33.0 + hooks: + - id: yamllint + exclude: (.yamllint) - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.6.1 + rev: v3.0.3 hooks: - id: prettier - stages: [manual] diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..c2f877a --- /dev/null +++ b/.yamllint @@ -0,0 +1,61 @@ +ignore: | + azure-*.yml +rules: + braces: + level: error + min-spaces-inside: 0 + max-spaces-inside: 1 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + brackets: + level: error + min-spaces-inside: 0 + max-spaces-inside: 0 + min-spaces-inside-empty: -1 + max-spaces-inside-empty: -1 + colons: + level: error + max-spaces-before: 0 + max-spaces-after: 1 + commas: + level: error + max-spaces-before: 0 + min-spaces-after: 1 + max-spaces-after: 1 + comments: + level: error + require-starting-space: true + min-spaces-from-content: 2 + comments-indentation: + level: error + document-end: + level: error + present: false + document-start: + level: error + present: false + empty-lines: + level: error + max: 1 + max-start: 0 + max-end: 1 + hyphens: + level: error + max-spaces-after: 1 + indentation: + level: error + spaces: 2 + indent-sequences: true + check-multi-line-strings: false + key-duplicates: + level: error + line-length: disable + new-line-at-end-of-file: + level: error + new-lines: + level: error + type: unix + trailing-spaces: + level: error + truthy: + level: error diff --git a/CHANGELOG.md b/CHANGELOG.md index a2ff1c4..4e31b79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.0.16 + +- Update ConfigEntry to support HA v2024.1.0b0 and above [Issue #218](https://github.com/elad-bar/ha-blueiris/issues/218) +- Update pre-commit package and configuration files (updated packages) +- Set minimum version of HA to be supported by HACS as 2024.1.0b0 +- Re-order manifest property order to support hassfest validation + ## 1.0.13 - Device and Entity registry - `async_get_registry` is deprecated, change to `async_get` [\#170](https://github.com/elad-bar/ha-blueiris/issues/170) @@ -26,7 +33,7 @@ ## 1.0.8 -- Fix for 2021.9.0 Breaking Change: Custom integrations: Cameras* [\#127](https://github.com/elad-bar/ha-blueiris/issues/127) +- Fix for 2021.9.0 Breaking Change: Custom integrations: Cameras\* [\#127](https://github.com/elad-bar/ha-blueiris/issues/127) - Fixed Info logging message when setting profile and schedule ## 1.0.7 @@ -36,17 +43,20 @@ ## 2021-07-31 (1.0.6) **Fixed bugs:** -- Cannot import MQTT Message (HA Core Breaking Change) >=2021.8.* [\#120](https://github.com/elad-bar/ha-blueiris/issues/120) + +- Cannot import MQTT Message (HA Core Breaking Change) >=2021.8.\* [\#120](https://github.com/elad-bar/ha-blueiris/issues/120) ## 2021-07-31 (1.0.6b2) **Fixed bugs:** -- Cannot import MQTT Message (HA Core Breaking Change) >=2021.8.* [\#120](https://github.com/elad-bar/ha-blueiris/issues/120) + +- Cannot import MQTT Message (HA Core Breaking Change) >=2021.8.\* [\#120](https://github.com/elad-bar/ha-blueiris/issues/120) ## 2021-07-30 (1.0.6b1) **Fixed bugs:** -- Cannot import MQTT Message (HA Core Breaking Change) >=2021.8.* [\#120](https://github.com/elad-bar/ha-blueiris/issues/120) + +- Cannot import MQTT Message (HA Core Breaking Change) >=2021.8.\* [\#120](https://github.com/elad-bar/ha-blueiris/issues/120) ## 2021-02-16 @@ -111,6 +121,7 @@ - Improved generate configuration file process **Fixed bugs:** + - Fixed - Generate configuration files ## 2020-07-17 @@ -251,9 +262,9 @@ **Fixed bugs:** - Fix issue [\#37](https://github.com/elad-bar/ha-blueiris/issues/37) - Restart of HASS causes all entities to be renamed to defaults
- improving the way the component is loading, unloading and discover new entities (sensors, camera and switch).
- the main issue as reported in the past was that once changing the entity_id / name it will return to the original after restart.
- another issue that caused by the way it was handled, upon changing the options (settings) - it took few seconds to present the new entities and sometimes it happened only after restart.
+ improving the way the component is loading, unloading and discover new entities (sensors, camera and switch).
+ the main issue as reported in the past was that once changing the entity_id / name it will return to the original after restart.
+ another issue that caused by the way it was handled, upon changing the options (settings) - it took few seconds to present the new entities and sometimes it happened only after restart.
In that version, the entity_id, name will remain as manually set and changes of options will take place immediately ## 2020-02-28 @@ -265,14 +276,12 @@ - Fix issue [\#27](https://github.com/elad-bar/ha-blueiris/issues/27) - when changing switch it doesn't work smoothly and after restart - Resources (strings) fixed - **Implemented enhancements:** - Username and password are now optional, if not set, will not create profile's switches - Added validation for host, port and SSL state in configuration, if URL is not accessible, will throw an error - Validate administrator username and password, in case entered wrong credentials, will throw an error - ## 2020-02-07 - v2.0.0 - Breaking change!!! **Implemented enhancements:** diff --git a/README.md b/README.md index 80e064e..0455c78 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,16 @@ Integration with Blue Iris Video Security Software. Creates the following components: -* Camera - per-camera defined. -* MQTT Binary Sensors (MOTION, AUDIO, WATCHDOG) - per-camera defined. -* Switch (Arm / Unarmed) - only when profiles and admin username and password are provided. -* Support HLS Streams instead of H264. -* Support SSL with self-signed certificate. +- Camera - per-camera defined. +- MQTT Binary Sensors (MOTION, AUDIO, WATCHDOG) - per-camera defined. +- Switch (Arm / Unarmed) - only when profiles and admin username and password are provided. +- Support HLS Streams instead of H264. +- Support SSL with self-signed certificate. [Changelog](https://github.com/elad-bar/ha-blueiris/blob/master/CHANGELOG.md) ## Component is no longer being maintained by elad-bar + I switched to Shinobi Video, if there is an issue, feel free to report, suggest PR and I will approve it kramttocs is working to maintain it but any assistance or PRs are welcome @@ -20,43 +21,48 @@ kramttocs is working to maintain it but any assistance or PRs are welcome ## How to #### Requirements + - BlueIris Server available with a user - To control profiles, user must have 'admin' level permissions - MQTT Integration is optional - it will allow listening to BlueIris events - Read the [BlueIris manual](https://github.com/elad-bar/ha-blueiris/blob/master/docs/blueiris-server.md) for this component #### Installations via HACS + Look for "Blue Iris NVR" and install #### Integration settings + ###### Basic configuration (Configuration -> Integrations -> Add BlueIris) -Fields name | Type | Required | Default | Description ---- | --- | --- | --- | --- | -Host | Texbox | + | None | Hostname or IP address of the BlueIris server -Port | Textbox | + | 0 | HTTP Port to access BlueIris server -SSL | Check-box | + | Unchecked | Is SSL supported? -Username | Textbox | - | | Username of admin user for BlueIris server -Password | Textbox | - | | Password of admin user for BlueIris server + +| Fields name | Type | Required | Default | Description | +| ----------- | --------- | -------- | --------- | --------------------------------------------- | +| Host | Texbox | + | None | Hostname or IP address of the BlueIris server | +| Port | Textbox | + | 0 | HTTP Port to access BlueIris server | +| SSL | Check-box | + | Unchecked | Is SSL supported? | +| Username | Textbox | - | | Username of admin user for BlueIris server | +| Password | Textbox | - | | Password of admin user for BlueIris server | ###### Integration options (Configuration -> Integrations -> BlueIris Integration -> Options) -Fields name | Type | Required | Default | Description ---- | --- | --- | --- | --- | -Host | Texbox | + | Last stored hostname | Hostname or IP address of the BlueIris server -Port | Textbox | + | Last stored port | HTTP Port to access BlueIris server -SSL | Check-box | + | Last stored SSL flag | Is SSL supported? -Username | Textbox | - | Last stored username | Username of admin user for BlueIris server -Password | Textbox | - | Last stored password | Password of admin user for BlueIris server -Clear credentials | Check-box | + | Unchecked | Workaround to clear the username & password since there is not support for optional fields (Not being stored under options) -Generate configurations | Check-box | + | Unchecked | Will take generate store and configuration for HA, more details below (Not being stored under options) -Log level | Drop-down | + | Default | Changes component's log level (more details below) -Reset components settings to default | Check-box | + | Unchecked | Will reset drown-downs of componet's creation to their default (Not being stored under options) -Camera components | Drop-down | - | All camera | Will create camera for each of the chosen camera -Motion sensors | Drop-down | - | All non-system camera | Will create binary sensor for each of the chosen camera -Connectivity sensors | Drop-down | - | All non-system camera | Will create connectivity binary sensor for each of the chosen camera -Audio sensors | Drop-down | - | All audio supported non-system camera | Will create audio binary sensor for each of the chosen camera -Profile switches | Drop-down | - | All profiles | Will create switch for each of the chosen profiles -Stream type | Drop-down | - | H264 | Defines the stream type H264 / MJPG -Stream support | Check-box | - | False | Defines whether to use `Stream` component for preview camera, requires restart to affect + +| Fields name | Type | Required | Default | Description | +| ------------------------------------ | --------- | -------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| Host | Texbox | + | Last stored hostname | Hostname or IP address of the BlueIris server | +| Port | Textbox | + | Last stored port | HTTP Port to access BlueIris server | +| SSL | Check-box | + | Last stored SSL flag | Is SSL supported? | +| Username | Textbox | - | Last stored username | Username of admin user for BlueIris server | +| Password | Textbox | - | Last stored password | Password of admin user for BlueIris server | +| Clear credentials | Check-box | + | Unchecked | Workaround to clear the username & password since there is not support for optional fields (Not being stored under options) | +| Generate configurations | Check-box | + | Unchecked | Will take generate store and configuration for HA, more details below (Not being stored under options) | +| Log level | Drop-down | + | Default | Changes component's log level (more details below) | +| Reset components settings to default | Check-box | + | Unchecked | Will reset drown-downs of componet's creation to their default (Not being stored under options) | +| Camera components | Drop-down | - | All camera | Will create camera for each of the chosen camera | +| Motion sensors | Drop-down | - | All non-system camera | Will create binary sensor for each of the chosen camera | +| Connectivity sensors | Drop-down | - | All non-system camera | Will create connectivity binary sensor for each of the chosen camera | +| Audio sensors | Drop-down | - | All audio supported non-system camera | Will create audio binary sensor for each of the chosen camera | +| Profile switches | Drop-down | - | All profiles | Will create switch for each of the chosen profiles | +| Stream type | Drop-down | - | H264 | Defines the stream type H264 / MJPG | +| Stream support | Check-box | - | False | Defines whether to use `Stream` component for preview camera, requires restart to affect | **Integration's title** Title will be extracted from BlueIris server's configuration, it will be set upon adding the server, and after every Option's change @@ -68,7 +74,7 @@ New feature to set the log level for the component without need to set log_level Upon startup or integration's option update, based on the value chosen, the component will make a service call to `logger.set_level` for that component with the desired value, - In case `Default` option is chosen the service call will not happen. Therefore after changing from any other option to `Default` a restart is required. +In case `Default` option is chosen the service call will not happen. Therefore after changing from any other option to `Default` a restart is required. **Control component's creation** New feature to control which of the components will be created: @@ -81,24 +87,29 @@ New feature to control which of the components will be created: - To restore defaults which allows automatically adding new camera, check the check-box of Reset components settings to default ###### Auto-generating configurations files: + Will create YAML with all the configurations in the config directory under blueiris.advanced_configurations.yaml: + - Input select (drop-downs) - Script to cast based on the selection - UI of all the components created by BlueIris based on the description above [Example of configuration output](https://github.com/elad-bar/ha-blueiris/blob/master/docs/configs/casting/configuration.yaml) - ###### Configuration validations + After submitting the form either for a new integration instance or updating options, the component will try to login to the BlueIris server to verify the new settings. The following errors can appear: + - BlueIris integration ({host}) already configured - Invalid administrator credentials - credentials are invalid or user is not an admin - Invalid server details - Cannot reach the server ###### Encryption key got corrupted + If a persistent notification popped up with the following message: + ``` Encryption key got corrupted, please remove the integration and re-add it ``` @@ -108,67 +119,77 @@ It means that the encryption key was modified from outside the code and the inte ## Components ###### Binary Sensor - Alerts + Represents whether there is an active alert or not -Attributes | ---- | -Active alerts # | -System name | -Version | -License | -Support expiration | -Logged in User | -Latitude | -Longitude | +| Attributes | +| ------------------ | +| Active alerts # | +| System name | +| Version | +| License | +| Support expiration | +| Logged in User | +| Latitude | +| Longitude | ###### Binary Sensor - Connectivity - Non-system-camera + Represents whether the camera is online or not (based on MQTT message) ###### Binary Sensor - Audio - Non-system-camera and camera supports audio + Represents whether the camera is triggered for noise or not (based on MQTT message) ###### Binary Sensor - Motion - Non-system-camera + Represents whether the camera is triggered for motion or not (based on MQTT message) ###### Binary Sensor - DIO - Non-system-camera + Represents whether the camera is triggered for digital I/O event or not (based on MQTT message) ###### Binary Sensor - External - Non-system-camera + Represents whether the camera is triggered for external / ONVIF event or not (based on MQTT message) ###### Camera -State: Idle -Attributes | ---- | -FPS | -Audio support | -Width | -Height | -Is Online | -Is Recording | -Issue (Camera is yellow) | -Alerts # | -Triggers # | -Clips # | -No Signal # | -Error | -Group Cameras (list of camera names if a group) | +State: Idle +| Attributes | +| ----------------------------------------------- | +| FPS | +| Audio support | +| Width | +| Height | +| Is Online | +| Is Recording | +| Issue (Camera is yellow) | +| Alerts # | +| Triggers # | +| Clips # | +| No Signal # | +| Error | +| Group Cameras (list of camera names if a group) | ###### Switch - Profile (Per profile) + Allows setting the active profile, only one of the profile switches can be turned on at a time. If you turn off one of the switches it will behave as follows: -* Profile #1 is turned off, it will turn on Profile #0 -* Any of the other profiles are turned off, it will turn on Profile #1 + +- Profile #1 is turned off, it will turn on Profile #0 +- Any of the other profiles are turned off, it will turn on Profile #1 ###### Services + Trigger Camera: Provides the ability to manually trigger a camera or camera group Move to Preset: Provides the ability to move a camera to a specified preset ## Lovelace UI Configuration + [Example of UI layout](https://github.com/elad-bar/ha-blueiris/blob/master/docs/configs/casting/configuration.yaml) ## Casting diff --git a/bandit.yaml b/bandit.yaml new file mode 100644 index 0000000..46566cc --- /dev/null +++ b/bandit.yaml @@ -0,0 +1,20 @@ +# https://bandit.readthedocs.io/en/latest/config.html + +tests: + - B103 + - B108 + - B306 + - B307 + - B313 + - B314 + - B315 + - B316 + - B317 + - B318 + - B319 + - B320 + - B601 + - B602 + - B604 + - B608 + - B609 diff --git a/blueiris.json b/blueiris.json index 535fcc5..e79ee7c 100644 --- a/blueiris.json +++ b/blueiris.json @@ -1,20 +1,20 @@ { - "blueiris": { - "version": "2.0.0", - "local_location": "/custom_components/blueiris/__init__.py", - "remote_location": "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/__init__.py", - "visit_repo": "https://github.com/elad-bar/ha-blueiris", - "changelog": "https://github.com/elad-bar/ha-blueiris/releases/latest", - "resources": [ - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/binary_sensor.py", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/blue_iris_api.py", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/blue_iris_data.py", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/camera.py", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/const.py", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/home_assistant.py", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/services.yaml", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/switch.py", - "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/manifest.json" - ] - } + "blueiris": { + "version": "2.0.0", + "local_location": "/custom_components/blueiris/__init__.py", + "remote_location": "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/__init__.py", + "visit_repo": "https://github.com/elad-bar/ha-blueiris", + "changelog": "https://github.com/elad-bar/ha-blueiris/releases/latest", + "resources": [ + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/binary_sensor.py", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/blue_iris_api.py", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/blue_iris_data.py", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/camera.py", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/const.py", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/home_assistant.py", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/services.yaml", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/switch.py", + "https://raw.githubusercontent.com/elad-bar/ha-blueiris/master/custom_components/blueiris/manifest.json" + ] + } } diff --git a/custom_components/blueiris/api/blue_iris_api.py b/custom_components/blueiris/api/blue_iris_api.py index 003d18d..45482bf 100644 --- a/custom_components/blueiris/api/blue_iris_api.py +++ b/custom_components/blueiris/api/blue_iris_api.py @@ -82,7 +82,7 @@ async def async_post(self, data): try: async with self.session.post( - self.url, data=json.dumps(data), ssl=False + self.url, data=json.dumps(data), ssl=False ) as response: _LOGGER.debug(f"Status of {self.url}: {response.status}") @@ -139,7 +139,9 @@ async def initialize(self): ) async def async_update(self): - _LOGGER.info(f"Updating data from BI Server ({self.config_manager.config_entry.title})") + _LOGGER.info( + f"Updating data from BI Server ({self.config_manager.config_entry.title})" + ) await self.load_camera() await self.load_status() @@ -296,7 +298,7 @@ async def trigger_camera(self, camera_short_name): request_data = { "cmd": "trigger", "session": self.session_id, - "camera": camera_short_name + "camera": camera_short_name, } await self.async_verified_post(request_data) @@ -307,6 +309,6 @@ async def move_to_preset(self, camera_short_name, preset): "cmd": "ptz", "session": self.session_id, "camera": camera_short_name, - "button": preset_value + "button": preset_value, } await self.async_verified_post(request_data) diff --git a/custom_components/blueiris/camera.py b/custom_components/blueiris/camera.py index 62d1d88..2185c7c 100644 --- a/custom_components/blueiris/camera.py +++ b/custom_components/blueiris/camera.py @@ -34,23 +34,22 @@ async def async_setup_entry(hass, config_entry, async_add_devices): """Set up the BlueIris Camera.""" await async_setup_base_entry( hass, config_entry, async_add_devices, CURRENT_DOMAIN, get_camera - ) + ) platform = entity_platform.current_platform.get() platform.async_register_entity_service( - SERVICE_TRIGGER_CAMERA, - {}, - SERVICE_TRIGGER_CAMERA, + SERVICE_TRIGGER_CAMERA, + {}, + SERVICE_TRIGGER_CAMERA, ) platform.async_register_entity_service( - SERVICE_MOVE_TO_PRESET, - { - vol.Required('preset'): cv.positive_int, - }, - SERVICE_MOVE_TO_PRESET, + SERVICE_MOVE_TO_PRESET, + { + vol.Required("preset"): cv.positive_int, + }, + SERVICE_MOVE_TO_PRESET, ) - async def async_unload_entry(hass, config_entry): _LOGGER.info(f"async_unload_entry {CURRENT_DOMAIN}: {config_entry}") @@ -67,7 +66,7 @@ def get_camera(hass: HomeAssistant, host: str, entity: EntityData): class BlueIrisCamera(Camera, BlueIrisEntity, ABC): - """ BlueIris Camera """ + """BlueIris Camera""" def __init__(self, hass, device_info): super().__init__() @@ -102,7 +101,6 @@ def __init__(self, hass, device_info): self._last_url = None self._last_image = None - def _immediate_update(self, previous_state: bool): if previous_state != self.entity.state: _LOGGER.debug( @@ -125,13 +123,17 @@ def frame_interval(self): """Return the interval between frames of the mjpeg stream.""" return self._frame_interval - def camera_image(self, width: Optional[int] = None, height: Optional[int] = None) -> Optional[bytes]: + def camera_image( + self, width: Optional[int] = None, height: Optional[int] = None + ) -> Optional[bytes]: """Return bytes of camera image.""" return asyncio.run_coroutine_threadsafe( self.async_camera_image(), self.hass.loop ).result() - async def async_camera_image(self, width: Optional[int] = None, height: Optional[int] = None) -> Optional[bytes]: + async def async_camera_image( + self, width: Optional[int] = None, height: Optional[int] = None + ) -> Optional[bytes]: """Return a still image response from the camera.""" try: url = self._still_image_url.async_render() diff --git a/custom_components/blueiris/helpers/__init__.py b/custom_components/blueiris/helpers/__init__.py index 59c7977..4b73c2b 100644 --- a/custom_components/blueiris/helpers/__init__.py +++ b/custom_components/blueiris/helpers/__init__.py @@ -13,13 +13,13 @@ def clear_ha(hass: HomeAssistant, entry_id): if DATA_BLUEIRIS not in hass.data: - hass.data[DATA_BLUEIRIS] = dict() + hass.data[DATA_BLUEIRIS] = {} del hass.data[DATA_BLUEIRIS][entry_id] def get_ha(hass: HomeAssistant, entry_id): - ha_data = hass.data.get(DATA_BLUEIRIS, dict()) + ha_data = hass.data.get(DATA_BLUEIRIS, {}) ha = ha_data.get(entry_id) return ha @@ -28,7 +28,7 @@ def get_ha(hass: HomeAssistant, entry_id): async def async_set_ha(hass: HomeAssistant, entry: ConfigEntry): try: if DATA_BLUEIRIS not in hass.data: - hass.data[DATA_BLUEIRIS] = dict() + hass.data[DATA_BLUEIRIS] = {} if PASSWORD_MANAGER_BLUEIRIS not in hass.data: hass.data[PASSWORD_MANAGER_BLUEIRIS] = PasswordManager(hass) @@ -56,10 +56,12 @@ async def handle_log_level(hass: HomeAssistant, entry: ConfigEntry): log_level_data = {f"custom_components.{DOMAIN}": log_level.lower()} try: - await hass.services.async_call(DOMAIN_LOGGER, SERVICE_SET_LEVEL, log_level_data) + await hass.services.async_call(DOMAIN_LOGGER, SERVICE_SET_LEVEL, log_level_data) except Exception as ex: exc_type, exc_obj, tb = sys.exc_info() line_number = tb.tb_lineno - _LOGGER.error(f"Failed to set log level. Ensure you have logging enabled in configuration.yaml., error: {ex}, line: {line_number}") + _LOGGER.error( + f"Failed to set log level. Ensure you have logging enabled in configuration.yaml., error: {ex}, line: {line_number}" + ) diff --git a/custom_components/blueiris/helpers/const.py b/custom_components/blueiris/helpers/const.py index df9e19f..a1c8091 100644 --- a/custom_components/blueiris/helpers/const.py +++ b/custom_components/blueiris/helpers/const.py @@ -4,7 +4,6 @@ https://home-assistant.io/components/switch.blueiris/ """ from datetime import timedelta -from http.client import NOT_ACCEPTABLE import voluptuous as vol @@ -44,7 +43,14 @@ BI_ATTR_GROUP = "group" BI_ATTR_TYPE = "type" -BI_NON_GENERIC_ATTRIBUTES = [BI_ATTR_NAME, BI_ATTR_ID, BI_ATTR_AUDIO, BI_ATTR_IS_ONLINE, BI_ATTR_GROUP, BI_ATTR_TYPE] +BI_NON_GENERIC_ATTRIBUTES = [ + BI_ATTR_NAME, + BI_ATTR_ID, + BI_ATTR_AUDIO, + BI_ATTR_IS_ONLINE, + BI_ATTR_GROUP, + BI_ATTR_TYPE, +] CAMERA_HAS_AUDIO = "has_audio" CAMERA_IS_ONLINE = "is_online" @@ -195,7 +201,7 @@ BI_CAMERA_TYPE_NETWORK_IP: BI_CAMERA_TYPE_NETWORK_IP_LABEL, BI_CAMERA_TYPE_BROADCAST: BI_CAMERA_TYPE_BROADCAST_LABEL, BI_CAMERA_TYPE_SCREEN_CAPTURE: BI_CAMERA_TYPE_SCREEN_CAPTURE_LABEL, - BI_CAMERA_TYPE_USB_FIREWIRE_ANALOG: BI_CAMERA_TYPE_USB_FIREWIRE_ANALOG_LABEL + BI_CAMERA_TYPE_USB_FIREWIRE_ANALOG: BI_CAMERA_TYPE_USB_FIREWIRE_ANALOG_LABEL, } ATTR_BLUE_IRIS_CAMERA = { diff --git a/custom_components/blueiris/managers/config_flow_manager.py b/custom_components/blueiris/managers/config_flow_manager.py index 256a163..19e8517 100644 --- a/custom_components/blueiris/managers/config_flow_manager.py +++ b/custom_components/blueiris/managers/config_flow_manager.py @@ -237,7 +237,15 @@ def get_default_options(self) -> vol.Schema: async def _update_entry(self): try: - entry = ConfigEntry(0, "", "", self._data, "", options=self._options) + entry = ConfigEntry( + version=0, + minor_version=0, + domain="", + title="", + data=self._data, + source="", + options=self._options, + ) await self._config_manager.update(entry) except InvalidToken: @@ -245,7 +253,15 @@ async def _update_entry(self): del self._data[CONF_PASSWORD] - entry = ConfigEntry(0, "", "", self._data, "", options=self._options) + entry = ConfigEntry( + version=0, + minor_version=0, + domain="", + title="", + data=self._data, + source="", + options=self._options, + ) await self._config_manager.update(entry) diff --git a/custom_components/blueiris/managers/configuration_manager.py b/custom_components/blueiris/managers/configuration_manager.py index 2a6090f..f6539f8 100644 --- a/custom_components/blueiris/managers/configuration_manager.py +++ b/custom_components/blueiris/managers/configuration_manager.py @@ -44,7 +44,9 @@ async def update(self, config_entry: ConfigEntry): ) result.allowed_profile = self._get_allowed_option(CONF_ALLOWED_PROFILE, options) - result.allowed_schedule = self._get_allowed_option(CONF_ALLOWED_SCHEDULE, options) + result.allowed_schedule = self._get_allowed_option( + CONF_ALLOWED_SCHEDULE, options + ) result.stream_type = options.get(CONF_STREAM_TYPE, DEFAULT_STREAM_TYPE) diff --git a/custom_components/blueiris/managers/entity_manager.py b/custom_components/blueiris/managers/entity_manager.py index f7a713c..fb523e0 100644 --- a/custom_components/blueiris/managers/entity_manager.py +++ b/custom_components/blueiris/managers/entity_manager.py @@ -1,6 +1,6 @@ import logging import sys -from typing import Dict, List, Optional +from typing import Optional from homeassistant.components.camera import DEFAULT_CONTENT_TYPE from homeassistant.components.stream import DOMAIN as DOMAIN_STREAM @@ -156,12 +156,18 @@ def create_components(self): allowed_schedule = config_data.allowed_schedule system_device_name = self.system_device_name - if is_admin and (allowed_profile is None or len(allowed_profile) > 0) and (allowed_schedule is None or len(allowed_schedule) > 0) : + if ( + is_admin + and (allowed_profile is None or len(allowed_profile) > 0) + and (allowed_schedule is None or len(allowed_schedule) > 0) + ): for profile_name in available_profiles: profile_id = available_profiles.index(profile_name) if allowed_profile is None or str(profile_id) in allowed_profile: - self.generate_profile_switch(profile_id, profile_name, system_device_name) + self.generate_profile_switch( + profile_id, profile_name, system_device_name + ) for schedule_name in available_schedules: schedule_id = available_schedules.index(schedule_name) @@ -271,7 +277,9 @@ async def _async_update(self): except Exception as ex: self.log_exception(ex, f"Failed to update, step: {step}") - def get_profile_switch(self, profile_id, profile_name, system_device_name) -> EntityData: + def get_profile_switch( + self, profile_id, profile_name, system_device_name + ) -> EntityData: entity = None try: @@ -304,7 +312,9 @@ def get_profile_switch(self, profile_id, profile_name, system_device_name) -> En def generate_profile_switch(self, profile_id, profile_name, system_device_name): try: - entity = self.get_profile_switch(profile_id, profile_name, system_device_name) + entity = self.get_profile_switch( + profile_id, profile_name, system_device_name + ) entity_name = entity.name self.set_entity(DOMAIN_SWITCH, entity_name, entity) @@ -338,9 +348,7 @@ def get_schedule_switch(self, schedule_name, system_device_name) -> EntityData: entity.icon = SCHEDULE_ICON entity.device_name = system_device_name except Exception as ex: - self.log_exception( - ex, f"Failed to get schedule switch {schedule_name}" - ) + self.log_exception(ex, f"Failed to get schedule switch {schedule_name}") return entity @@ -415,7 +423,9 @@ def generate_main_binary_sensor(self): except Exception as ex: self.log_exception(ex, "Failed to generate main binary sensor") - def get_camera_entity(self, camera: CameraData, sensor_type_name, camera_device_name) -> EntityData: + def get_camera_entity( + self, camera: CameraData, sensor_type_name, camera_device_name + ) -> EntityData: entity = None try: @@ -459,7 +469,9 @@ def generate_camera_binary_sensors(self, camera: CameraData): camera_device_name = self.device_manager.get_camera_device_name(camera) for sensor_type_name in CAMERA_SENSORS.keys(): if self.config_manager.is_allowed_sensor(camera, sensor_type_name): - entity = self.get_camera_entity(camera, sensor_type_name, camera_device_name) + entity = self.get_camera_entity( + camera, sensor_type_name, camera_device_name + ) entities.append(entity) for entity in entities: diff --git a/custom_components/blueiris/manifest.json b/custom_components/blueiris/manifest.json index 6307009..f686d5f 100644 --- a/custom_components/blueiris/manifest.json +++ b/custom_components/blueiris/manifest.json @@ -1,19 +1,13 @@ { - "domain": "blueiris", - "name": "Blue Iris NVR", - "documentation": "https://github.com/elad-bar/ha-blueiris", - "after_dependencies": [ - "mqtt" - ], - "dependencies": [ - "camera" - ], - "codeowners": [ - "@elad-bar", - "@kramttocs" - ], - "requirements": [], - "config_flow": true, - "version": "1.0.15", - "iot_class": "local_polling" - } + "domain": "blueiris", + "name": "Blue Iris NVR", + "after_dependencies": ["mqtt"], + "codeowners": ["@elad-bar", "@kramttocs"], + "config_flow": true, + "dependencies": ["camera"], + "documentation": "https://github.com/elad-bar/ha-blueiris", + "iot_class": "local_polling", + "issue_tracker": "https://github.com/elad-bar/ha-blueiris/issues", + "requirements": [], + "version": "1.0.16" +} diff --git a/custom_components/blueiris/models/base_entity.py b/custom_components/blueiris/models/base_entity.py index 1d9b17e..e8ee7c7 100644 --- a/custom_components/blueiris/models/base_entity.py +++ b/custom_components/blueiris/models/base_entity.py @@ -21,7 +21,6 @@ async def async_setup_base_entry( domain: str, component: Callable[[HomeAssistant, Any, EntityData], Any], ): - """Set up BlueIris based off an entry.""" _LOGGER.debug(f"Starting async_setup_entry {domain}") diff --git a/custom_components/blueiris/models/camera_data.py b/custom_components/blueiris/models/camera_data.py index ed73f8a..51df58f 100644 --- a/custom_components/blueiris/models/camera_data.py +++ b/custom_components/blueiris/models/camera_data.py @@ -18,7 +18,7 @@ def __init__(self, camera): self.is_online = camera.get(BI_ATTR_IS_ONLINE, False) self.has_audio = camera.get(BI_ATTR_AUDIO, False) self.data = camera - self.is_group = True if(camera.get(BI_ATTR_GROUP) is not None) else False + self.is_group = True if (camera.get(BI_ATTR_GROUP) is not None) else False if self.is_group: self.group_cameras = camera.get(BI_ATTR_GROUP) self.is_system = self.id in SYSTEM_CAMERA_ID @@ -35,7 +35,6 @@ def __repr__(self): CAMERA_DATA: self.data, CAMERA_GROUP_CAMERAS: self.group_cameras, CAMERA_TYPE: self.type, - } to_string = f"{obj}" diff --git a/custom_components/blueiris/services.yaml b/custom_components/blueiris/services.yaml index 217e437..d103802 100644 --- a/custom_components/blueiris/services.yaml +++ b/custom_components/blueiris/services.yaml @@ -2,19 +2,19 @@ trigger_camera: name: Trigger Camera description: Triggers a camera target: - entity: - integration: blueiris - domain: camera + entity: + integration: blueiris + domain: camera move_to_preset: name: Move to Preset description: Moves the selected camera to the specified preset target: - entity: - integration: blueiris - domain: camera + entity: + integration: blueiris + domain: camera fields: - preset: + preset: name: Preset description: Desired preset required: true diff --git a/custom_components/blueiris/strings.json b/custom_components/blueiris/strings.json index 10eea0f..0cd6862 100644 --- a/custom_components/blueiris/strings.json +++ b/custom_components/blueiris/strings.json @@ -20,37 +20,37 @@ } }, "options": { - "step": { - "blue_iris_additional_settings": { - "title": "Options for BlueIris.", - "description": "Set up username and password to control profiles / exclude system camera.", - "data": { - "host": "Host", - "port": "Port", - "ssl": "Is SSL", - "username": "Username", - "password": "Password", - "clear-credentials": "Clear credentials", - "log_level": "Log level", - "generate-config-files": "Generate configuration files", - "allowed_camera": "Camera components", - "allowed_profile": "Profile switches", - "allowed_schedule": "Schedule switches", - "allowed_motion_sensor": "Motion sensors", - "allowed_audio_sensor": "Audio sensors", - "allowed_connectivity_sensor": "Connectivity sensors", - "allowed_dio_sensor": "DIO sensors", - "allowed_external_sensor": "External sensors", - "reset-components-settings": "Reset components settings to default", - "stream-type": "Stream type", - "support_stream": "Support stream component (Requires restart)" - } - } - }, - "error": { - "invalid_admin_credentials": "Invalid administrator credentials", - "invalid_server_details": "Invalid server details", - "already_configured": "BlueIris integration already configured with the name" + "step": { + "blue_iris_additional_settings": { + "title": "Options for BlueIris.", + "description": "Set up username and password to control profiles / exclude system camera.", + "data": { + "host": "Host", + "port": "Port", + "ssl": "Is SSL", + "username": "Username", + "password": "Password", + "clear-credentials": "Clear credentials", + "log_level": "Log level", + "generate-config-files": "Generate configuration files", + "allowed_camera": "Camera components", + "allowed_profile": "Profile switches", + "allowed_schedule": "Schedule switches", + "allowed_motion_sensor": "Motion sensors", + "allowed_audio_sensor": "Audio sensors", + "allowed_connectivity_sensor": "Connectivity sensors", + "allowed_dio_sensor": "DIO sensors", + "allowed_external_sensor": "External sensors", + "reset-components-settings": "Reset components settings to default", + "stream-type": "Stream type", + "support_stream": "Support stream component (Requires restart)" + } } + }, + "error": { + "invalid_admin_credentials": "Invalid administrator credentials", + "invalid_server_details": "Invalid server details", + "already_configured": "BlueIris integration already configured with the name" + } } } diff --git a/custom_components/blueiris/translations/en.json b/custom_components/blueiris/translations/en.json index 10eea0f..0cd6862 100644 --- a/custom_components/blueiris/translations/en.json +++ b/custom_components/blueiris/translations/en.json @@ -20,37 +20,37 @@ } }, "options": { - "step": { - "blue_iris_additional_settings": { - "title": "Options for BlueIris.", - "description": "Set up username and password to control profiles / exclude system camera.", - "data": { - "host": "Host", - "port": "Port", - "ssl": "Is SSL", - "username": "Username", - "password": "Password", - "clear-credentials": "Clear credentials", - "log_level": "Log level", - "generate-config-files": "Generate configuration files", - "allowed_camera": "Camera components", - "allowed_profile": "Profile switches", - "allowed_schedule": "Schedule switches", - "allowed_motion_sensor": "Motion sensors", - "allowed_audio_sensor": "Audio sensors", - "allowed_connectivity_sensor": "Connectivity sensors", - "allowed_dio_sensor": "DIO sensors", - "allowed_external_sensor": "External sensors", - "reset-components-settings": "Reset components settings to default", - "stream-type": "Stream type", - "support_stream": "Support stream component (Requires restart)" - } - } - }, - "error": { - "invalid_admin_credentials": "Invalid administrator credentials", - "invalid_server_details": "Invalid server details", - "already_configured": "BlueIris integration already configured with the name" + "step": { + "blue_iris_additional_settings": { + "title": "Options for BlueIris.", + "description": "Set up username and password to control profiles / exclude system camera.", + "data": { + "host": "Host", + "port": "Port", + "ssl": "Is SSL", + "username": "Username", + "password": "Password", + "clear-credentials": "Clear credentials", + "log_level": "Log level", + "generate-config-files": "Generate configuration files", + "allowed_camera": "Camera components", + "allowed_profile": "Profile switches", + "allowed_schedule": "Schedule switches", + "allowed_motion_sensor": "Motion sensors", + "allowed_audio_sensor": "Audio sensors", + "allowed_connectivity_sensor": "Connectivity sensors", + "allowed_dio_sensor": "DIO sensors", + "allowed_external_sensor": "External sensors", + "reset-components-settings": "Reset components settings to default", + "stream-type": "Stream type", + "support_stream": "Support stream component (Requires restart)" + } } + }, + "error": { + "invalid_admin_credentials": "Invalid administrator credentials", + "invalid_server_details": "Invalid server details", + "already_configured": "BlueIris integration already configured with the name" + } } } diff --git a/docs/blueiris-server.md b/docs/blueiris-server.md index 484f055..0adb8f5 100644 --- a/docs/blueiris-server.md +++ b/docs/blueiris-server.md @@ -1,6 +1,7 @@ # BlueIris Server Settings #### User + If you intent to use any of the Blue Iris REST API commands (such as profile switching), it's recommended you create a separate Administrator user for Home Assistant to connect to, and limit access to LAN only. @@ -12,7 +13,8 @@ This keeps any accesses or limitations you may wish to set on Home Assistant sep ![Blue Iris Edit User](https://github.com/elad-bar/ha-blueiris/blob/master/docs/images/bi-edit_user.png) #### Web Server -Enable the Blue Iris Web Server. Select the `Advanced...` button to proceed to the next step. + +Enable the Blue Iris Web Server. Select the `Advanced...` button to proceed to the next step. ![Blue Iris Web Server](https://github.com/elad-bar/ha-blueiris/blob/master/docs/images/bi-web_server.png) @@ -48,20 +50,22 @@ In the Blue Iris Options panel, on the `Digital IO and IoT` tab under `MQTT`, se ###### Troubleshooting -* Do you have a MQTT broker set up and configured? It is recommend to use the [Mosquitto MQTT broker](https://www.home-assistant.io/addons/mosquitto/) add-on, instead of the HA embedded broker - Mosquitto appears to be much more robust. Check that the broker is starting up clean and the topics are coming in without pitching errors. -* Do you have the [MQTT Integration configured](https://www.home-assistant.io/addons/mosquitto/#home-assistant-configuration)? It's not sufficient to just install/start the broker. Make sure to check the `Enable discovery` box when you configure the integration. +- Do you have a MQTT broker set up and configured? It is recommend to use the [Mosquitto MQTT broker](https://www.home-assistant.io/addons/mosquitto/) add-on, instead of the HA embedded broker - Mosquitto appears to be much more robust. Check that the broker is starting up clean and the topics are coming in without pitching errors. +- Do you have the [MQTT Integration configured](https://www.home-assistant.io/addons/mosquitto/#home-assistant-configuration)? It's not sufficient to just install/start the broker. Make sure to check the `Enable discovery` box when you configure the integration. ![Integrations MQTT](https://github.com/elad-bar/ha-blueiris/blob/master/docs/images/ha-integrations_mqtt.png) ![Integrations MQTT Configure](https://github.com/elad-bar/ha-blueiris/blob/master/docs/images/ha-integrations_mqtt_configure.png) - #### Event triggers + For each camera you wish to monitor, select `"Camera properties..."` and on the `Alerts` tab, check `"Post to a web address or MQTT server"` and then select `"Configure..."`. Binary sensors for motion, external, DIO, audio and watchdog (connectivity) per camera, In order to configure it in BlueIris you will need to go to: + ##### Motion / External / DIO + Camera settings -> Alerts: Fire when: This camera is triggered @@ -76,6 +80,7 @@ Action section: Click on `On alert`, in the popup window, create new (or modify) alert for MQTT with the following settings: + ``` Topic - BlueIris/&CAM/Status Payload - { "type": "&TYPE", "trigger": "ON" } @@ -84,7 +89,6 @@ Payload - { "type": "&TYPE", "trigger": "ON" } for `On reset` do the same with payload: `{ "type": "&TYPE", "trigger": "OFF" }` - The alert should be sent for the profile you would like it to trigger. Note: Triggering the camera manually in BlueIris sends a different &TYPE and will not trigger the motion sensor. Motion must be detected on the camera for the sensor change to be detected. @@ -95,6 +99,7 @@ Note: Triggering the camera manually in BlueIris sends a different &TYPE and wil ![Blue Iris MQTT Alert](https://github.com/elad-bar/ha-blueiris/blob/master/docs/images/bi-alerts-settings.png) ##### Audio + Camera settings -> Audio -> Options:
Check the `Trigger the camera during profiles` and mark all profiles you would like it to trigger
Check the `Use 1 second average intensity` and set the sensitivity level to the desired level
@@ -104,9 +109,11 @@ Payloads will be sent according to the definition in the Alert's section defined ![Blue Iris Alerts](https://github.com/elad-bar/ha-blueiris/blob/master/docs/images/bi-audio-alerts.png) ##### Watchdog (Connectivity) + Camera settings -> Watchdog
in the action's section click on `On loss of signal`,
then in the popup window, create new (or modify) alert for MQTT with the following settings: + ``` Topic - BlueIris/&CAM/Status Payload - { "type": "Connectivity", "trigger": "OFF" } diff --git a/docs/configs/casting/configuration.yaml b/docs/configs/casting/configuration.yaml index b1fd73f..fd8c118 100644 --- a/docs/configs/casting/configuration.yaml +++ b/docs/configs/casting/configuration.yaml @@ -46,4 +46,4 @@ script: {% elif is_state('input_select.camera_dropdown', 'All Cameras') %} http://192.168.0.10:8081/mjpg/index?/video.mjpg {% endif %} - media_content_type: 'image/jpg' + media_content_type: "image/jpg" diff --git a/docs/configs/casting/ui-lovelace.yaml b/docs/configs/casting/ui-lovelace.yaml index 3e90bd2..199c5a8 100644 --- a/docs/configs/casting/ui-lovelace.yaml +++ b/docs/configs/casting/ui-lovelace.yaml @@ -1,8 +1,8 @@ # Example ui-lovelace.yaml view entry - - type: entities - title: Cast Camera to Screen - show_header_toggle: false - entities: - - entity: input_select.camera_dropdown - - entity: input_select.cast_to_screen_dropdown - - entity: script.execute_cast_dropdown +- type: entities + title: Cast Camera to Screen + show_header_toggle: false + entities: + - entity: input_select.camera_dropdown + - entity: input_select.cast_to_screen_dropdown + - entity: script.execute_cast_dropdown diff --git a/hacs.json b/hacs.json index 23316fc..bf0486c 100644 --- a/hacs.json +++ b/hacs.json @@ -1,5 +1,5 @@ { "name": "BlueIris NVR", "iot_class": "Local Polling", - "homeassistant": "2021.12.0" + "homeassistant": "2024.1.0b0" } diff --git a/info.md b/info.md index b9d47f1..a681b7f 100644 --- a/info.md +++ b/info.md @@ -4,54 +4,59 @@ Integration with Blue Iris Video Security Software. Creates the following components: -* Camera - per-camera defined. -* MQTT Binary Sensors (MOTION, AUDIO, WATCHDOG) - per-camera defined. -* Switch (Arm / Unarmed) - only when profiles and admin username and password are provided. -* Support HLS Streams instead of H264. -* Support SSL with self-signed certificate. +- Camera - per-camera defined. +- MQTT Binary Sensors (MOTION, AUDIO, WATCHDOG) - per-camera defined. +- Switch (Arm / Unarmed) - only when profiles and admin username and password are provided. +- Support HLS Streams instead of H264. +- Support SSL with self-signed certificate. [Changelog](https://github.com/elad-bar/ha-blueiris/blob/master/CHANGELOG.md) ## How to #### Requirements + - BlueIris Server available with a user - To control profiles, user must have 'admin' level permissions - MQTT Integration is optional - it will allow to listen to BlueIris event - Read the [BlueIris manual](https://github.com/elad-bar/ha-blueiris/blob/master/docs/blueiris-server.md) for this component #### Installations via HACS + Look for "Blue Iris NVR" and install #### Integration settings + ###### Basic configuration (Configuration -> Integrations -> Add BlueIris) -Fields name | Type | Required | Default | Description ---- | --- | --- | --- | --- | -Host | Texbox | + | None | Hostname or IP address of the BlueIris server -Port | Textbox | + | 0 | HTTP Port to access BlueIris server -SSL | Check-box | + | Unchecked | Is SSL supported? -Username | Textbox | - | | Username of admin user for BlueIris server -Password | Textbox | - | | Password of admin user for BlueIris server + +| Fields name | Type | Required | Default | Description | +| ----------- | --------- | -------- | --------- | --------------------------------------------- | +| Host | Texbox | + | None | Hostname or IP address of the BlueIris server | +| Port | Textbox | + | 0 | HTTP Port to access BlueIris server | +| SSL | Check-box | + | Unchecked | Is SSL supported? | +| Username | Textbox | - | | Username of admin user for BlueIris server | +| Password | Textbox | - | | Password of admin user for BlueIris server | ###### Integration options (Configuration -> Integrations -> BlueIris Integration -> Options) -Fields name | Type | Required | Default | Description ---- | --- | --- | --- | --- | -Host | Texbox | + | ast stored hostname | Hostname or IP address of the BlueIris server -Port | Textbox | + | 0ast stored port | HTTP Port to access BlueIris server -SSL | Check-box | + | Last stored SSL flag | Is SSL supported? -Username | Textbox | - | Last stored username | Username of admin user for BlueIris server -Password | Textbox | - | Last stored password | Password of admin user for BlueIris server -Clear credentials | Check-box | + | Unchecked | Workaround to clear the username & password since there is not support for optional fields (Not being stored under options) -Generate configurations | Check-box | + | Unchecked | Will take generate store and configuration for HA, more details below (Not being stored under options) -Log level | Drop-down | + | Default | Changes component's log level (more details below) -Reset components settings to default | Check-box | + | Unchecked | Will reset drown-downs of componet's creation to their default (Not being stored under options) -Camera components | Drop-down | - | All camera | Will create camera for each of the chosen camera -Motion sensors | Drop-down | - | All non-system camera | Will create binary sensor for each of the chosen camera -Connectivity sensors | Drop-down | - | All non-system camera | Will create connectivity binary sensor for each of the chosen camera -Audio sensors | Drop-down | - | All audio supported non-system camera | Will create audio binary sensor for each of the chosen camera -Profile switches | Drop-down | - | All profiles | Will create switch for each of the chosen profiles -Stream type | Drop-down | - | H264 | Defines the stream type H264 / MJPG -Stream support | Check-box | - | False | Defines whether to use `Stream` component for preview camera, requires restart to affect + +| Fields name | Type | Required | Default | Description | +| ------------------------------------ | --------- | -------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| Host | Texbox | + | ast stored hostname | Hostname or IP address of the BlueIris server | +| Port | Textbox | + | 0ast stored port | HTTP Port to access BlueIris server | +| SSL | Check-box | + | Last stored SSL flag | Is SSL supported? | +| Username | Textbox | - | Last stored username | Username of admin user for BlueIris server | +| Password | Textbox | - | Last stored password | Password of admin user for BlueIris server | +| Clear credentials | Check-box | + | Unchecked | Workaround to clear the username & password since there is not support for optional fields (Not being stored under options) | +| Generate configurations | Check-box | + | Unchecked | Will take generate store and configuration for HA, more details below (Not being stored under options) | +| Log level | Drop-down | + | Default | Changes component's log level (more details below) | +| Reset components settings to default | Check-box | + | Unchecked | Will reset drown-downs of componet's creation to their default (Not being stored under options) | +| Camera components | Drop-down | - | All camera | Will create camera for each of the chosen camera | +| Motion sensors | Drop-down | - | All non-system camera | Will create binary sensor for each of the chosen camera | +| Connectivity sensors | Drop-down | - | All non-system camera | Will create connectivity binary sensor for each of the chosen camera | +| Audio sensors | Drop-down | - | All audio supported non-system camera | Will create audio binary sensor for each of the chosen camera | +| Profile switches | Drop-down | - | All profiles | Will create switch for each of the chosen profiles | +| Stream type | Drop-down | - | H264 | Defines the stream type H264 / MJPG | +| Stream support | Check-box | - | False | Defines whether to use `Stream` component for preview camera, requires restart to affect | **Integration's title** Title will be extracted from BlueIris server's configuration, it will be set upon adding the server, and after every Option's change @@ -76,24 +81,29 @@ New feature to control which of the components will be created: - To restore defaults which allows automatically adding new camera, check the check-box of Reset components settings to default ###### Auto-generating configurations files: + Will create YAML with all the configurations in the config directory under blueiris.advanced_configurations.yaml: + - Input select (drop-downs) - Script to cast based on the selection - UI of all the components created by BlueIris based on the description above [Example of configuration output](https://github.com/elad-bar/ha-blueiris/blob/master/docs/configs/casting/configuration.yaml) - ###### Configuration validations + Upon submitting the form of creating an integration or updating options, Component will try to login to the BlueIris server to verify new settings, following errors can appear: + - BlueIris integration ({host}) already configured - Invalid administrator credentials - credentials are invalid or user is not an admin - Invalid server details - Cannot reach the server ###### Encryption key got corrupted + If a persistent notification popped up with the following message: + ``` Encryption key got corrupted, please remove the integration and re-add it ``` @@ -104,53 +114,61 @@ Please remove the integration and re-add it to make it work again. ## Components ###### Binary Sensor - Alerts + Represents whether there is an active alert or not -Attributes | ---- | -Active alerts # | -System name | -Version | -License | -Support expiration | -Logged in User | -Latitude | -Longitude | +| Attributes | +| ------------------ | +| Active alerts # | +| System name | +| Version | +| License | +| Support expiration | +| Logged in User | +| Latitude | +| Longitude | ###### Binary Sensor - Connectivity - Non-system-camera + Represents whether the camera is online or not (based on MQTT message) ###### Binary Sensor - Audio - Non-system-camera and camera supports audio + Represents whether the camera is triggered for noise or not (based on MQTT message) ###### Binary Sensor - Motion - Non-system-camera + Represents whether the camera is triggered for motion or not (based on MQTT message) ###### Binary Sensor - DIO - Non-system-camera + Represents whether the camera is triggered for digital I/O event or not (based on MQTT message) ###### Binary Sensor - External - Non-system-camera + Represents whether the camera is triggered for external / ONVIF event or not (based on MQTT message) ###### Camera + State: Idle -Attributes | ---- | -FPS | -Audio support | -Width | -Height | -Is Online | -Is Recording | -Issue (Camera is yellow) | -Alerts # | -Triggers # | -Clips # | -No Signal # | -Error | +| Attributes | +| ------------------------ | +| FPS | +| Audio support | +| Width | +| Height | +| Is Online | +| Is Recording | +| Issue (Camera is yellow) | +| Alerts # | +| Triggers # | +| Clips # | +| No Signal # | +| Error | ###### Switch - Profile (Per profile) + Allows to set the active profile, only one of the profile switches can be turned on at a time If you are turning off one of the switch it will work according to the following order: @@ -158,6 +176,7 @@ Profile #1 turned off, will turn on Profile #0 All the other profiles upon turning off, will turn on Profile #1 ## Lovelace UI Configuration + [Example of UI layout](https://github.com/elad-bar/ha-blueiris/blob/master/docs/configs/casting/configuration.yaml) ## Casting