Skip to content

Commit

Permalink
Add ability to control USB Recorder (#26)
Browse files Browse the repository at this point in the history
Add two new entites
 - USB Filename (sensor)
 - USB tape stats  (select)

Some minor other cleanup
  • Loading branch information
wrodie authored Jan 26, 2024
1 parent 76ac85f commit 310c31d
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 13 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 - 2023 Joakim Sørensen @ludeeus
Copyright (c) 2023 - 2024 Warren Rodie

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ In addition to these 'fader' related variables, also provided is

- Current scene/snapshot number/index (Read/Write)
- Firmware (Read only)
- USB Filename (Read only)
- USB Player/Recorder status (Read/Write)

## Mixers Supported

Expand Down
22 changes: 16 additions & 6 deletions custom_components/ha_behringer_mixer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Platform.SWITCH,
Platform.NUMBER,
Platform.SENSOR,
Platform.SELECT,
]


Expand Down Expand Up @@ -61,17 +62,26 @@ async def async_migrate_entry(hass, config_entry: ConfigEntry):

if config_entry.version < 2:
"""Update Config data to include valid channels/bussses etc."""
client = BehringerMixerApiClient(mixer_ip=config_entry.data.get("MIXER_IP"), mixer_type=config_entry.data.get("MIXER_TYPE"))
client = BehringerMixerApiClient(
mixer_ip=config_entry.data.get("MIXER_IP"),
mixer_type=config_entry.data.get("MIXER_TYPE"),
)
await client.setup(test_connection_only=True)
await client.async_get_data()
await client.stop()
mixer_info = client.mixer_info()
new = {**config_entry.data}
new["CHANNEL_CONFIG"] = list(range(1, mixer_info.get('channel', {}).get("number") + 1))
new["BUS_CONFIG"] = list(range(1, mixer_info.get('bus', {}).get("number") + 1))
new["DCA_CONFIG"] = list(range(1, mixer_info.get('dca', {}).get("number") + 1))
new["MATRIX_CONFIG"] = list(range(1, mixer_info.get('matrix', {}).get("number") + 1))
new["AUXIN_CONFIG"] = list(range(1, mixer_info.get('auxin', {}).get("number") + 1))
new["CHANNEL_CONFIG"] = list(
range(1, mixer_info.get("channel", {}).get("number") + 1)
)
new["BUS_CONFIG"] = list(range(1, mixer_info.get("bus", {}).get("number") + 1))
new["DCA_CONFIG"] = list(range(1, mixer_info.get("dca", {}).get("number") + 1))
new["MATRIX_CONFIG"] = list(
range(1, mixer_info.get("matrix", {}).get("number") + 1)
)
new["AUXIN_CONFIG"] = list(
range(1, mixer_info.get("auxin", {}).get("number") + 1)
)
new["MAIN_CONFIG"] = True
new["CHANNELSENDS_CONFIG"] = False
new["BUSSENDS_CONFIG"] = False
Expand Down
5 changes: 4 additions & 1 deletion custom_components/ha_behringer_mixer/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import asyncio
from behringer_mixer import mixer_api


class BehringerMixerApiClientError(Exception):
"""Exception to indicate a general API error."""

Expand Down Expand Up @@ -77,8 +78,10 @@ async def load_scene(self, scene_number):
"""Change the scene."""
return await self._mixer.load_scene(scene_number)

def new_data_callback(self, data: dict): # pylint: disable=unused-argument
def new_data_callback(self, data: dict):
"""Handle the callback indicating new data has been received."""
if data.get("property").endswith("_db"):
return True
if self.coordinator:
self.coordinator.async_set_updated_data(self._get_data())
return True
Expand Down
19 changes: 18 additions & 1 deletion custom_components/ha_behringer_mixer/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(
logger=LOGGER,
name=DOMAIN,
)
self.sub_connected = False
self.sub_connected = True
self.entity_base_id = self.config_entry.data["NAME"]
self.entity_catalog = self.build_entity_catalog(self.client.mixer_info())

Expand All @@ -55,6 +55,7 @@ def build_entity_catalog(self, mixer_info):
"SENSOR": [],
"NUMBER": [],
"SWITCH": [],
"SELECT": [],
}
if self.config_entry.data.get("MAIN_CONFIG"):
self.fader_group(entities, "main", 0, "main/st")
Expand Down Expand Up @@ -107,6 +108,22 @@ def build_entity_catalog(self, mixer_info):
"default_name": "Firmware Version",
"base_address": "/firmware",
}
),
entities["SENSOR"].append(
{
"type": "generic",
"key": f"{self.entity_base_id}_usb_filename",
"default_name": "USB Filename",
"base_address": "/usb/file",
}
)
entities["SELECT"].append(
{
"type": "generic",
"key": f"{self.entity_base_id}_tape_state",
"default_name": "USB Tape State",
"base_address": "/usb/state",
}
)
return entities

Expand Down
4 changes: 2 additions & 2 deletions custom_components/ha_behringer_mixer/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def __init__(
"""Initialize the entity class."""
super().__init__(coordinator)
self.base_address = entity_setup.get("base_address")
self.default_name = entity_setup.get("default_name")
self.name_suffix = entity_setup.get("name_suffix")
self.default_name = entity_setup.get("default_name") or ""
self.name_suffix = entity_setup.get("name_suffix") or ""
key = entity_setup.get("key")
self._attr_unique_id = key
self._attr_entity_id = DOMAIN + "." + key
Expand Down
4 changes: 2 additions & 2 deletions custom_components/ha_behringer_mixer/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"iot_class": "local_push",
"issue_tracker": "https://github.com/wrodie/ha_behringer_mixer/issues",
"requirements": [
"behringer-mixer==0.4.2"
"behringer-mixer==0.4.3"
],
"version": "0.1.4"
"version": "0.1.5"
}
56 changes: 56 additions & 0 deletions custom_components/ha_behringer_mixer/select.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""Select entity platform for behringer_mixer."""
from __future__ import annotations

from homeassistant.components.select import SelectEntity, SelectEntityDescription

from .const import DOMAIN
from .entity import BehringerMixerEntity


async def async_setup_entry(hass, entry, async_add_devices):
"""Set up the sensor platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
devices_list = build_entities(coordinator)
async_add_devices(devices_list)


def build_entities(coordinator):
"""Build up the entities."""
entities = []
for entity in coordinator.entity_catalog.get("SELECT"):
entities.append(
BehringerMixerUSBState(
coordinator=coordinator,
entity_description=SelectEntityDescription(
key=entity.get("key"),
name=entity.get("default_name"),
),
entity_setup=entity,
)
)
return entities


class BehringerMixerUSBState(BehringerMixerEntity, SelectEntity):
"""Behringer_mixer select class."""

_attr_icon = "mdi:play-pause"
_attr_options = [
"STOP",
"PAUSE",
"PLAY",
"PAUSE_RECORD",
"RECORD",
"FAST_FORWARD",
"REWIND",
]

async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
await self.coordinator.client.async_set_value(self.base_address, option)
return True

@property
def current_option(self) -> str | None:
"""Return the current option."""
return self.coordinator.data[self.base_address]

0 comments on commit 310c31d

Please sign in to comment.