Skip to content

Commit d712c1a

Browse files
committed
fix: replace deprecated object_id with default_entity_id for HA 2026.4
Home Assistant 2026.4 removes support for the deprecated `object_id` field in MQTT discovery payloads. Replace with `default_entity_id` which includes the domain prefix (e.g. `light.kitchen_light` instead of just `kitchen_light`). Updated in haDiscovery, haBridgeDiagnostics, and staleDeviceDetector.
1 parent 9e4b0d8 commit d712c1a

7 files changed

Lines changed: 24 additions & 21 deletions

File tree

homeassistant-addon/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: "C-Gate Web Bridge"
2-
version: "1.6.1"
2+
version: "1.7.0"
33
slug: cgateweb
44
description: "Bridge between Clipsal C-Bus systems and MQTT/Home Assistant"
55
url: "https://github.com/dougrathbone/cgateweb"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cgateweb",
3-
"version": "1.6.1",
3+
"version": "1.7.0",
44
"description": "Node.js bridge connecting Clipsal C-Bus automation systems to MQTT for Home Assistant integration",
55
"keywords": [
66
"cbus",

src/haBridgeDiagnostics.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class HaBridgeDiagnostics {
7272
const payload = {
7373
name: entity.name,
7474
unique_id: `cgateweb_bridge_${entity.key}`,
75-
object_id: `cgateweb_bridge_${entity.key}`,
75+
default_entity_id: `${entity.component}.cgateweb_bridge_${entity.key}`,
7676
state_topic: stateTopic,
7777
availability_topic: MQTT_TOPIC_STATUS,
7878
payload_available: 'Online',

src/haDiscovery.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class HaDiscovery {
4949
* @param {Object} [labelData] - Optional label data object from LabelLoader.getLabelData()
5050
* @param {Map<string, string>} [labelData.labels] - Label overrides keyed by "network/app/group"
5151
* @param {Map<string, string>} [labelData.typeOverrides] - Type overrides ("cover"|"switch"|"light")
52-
* @param {Map<string, string>} [labelData.entityIds] - Entity ID hints (object_id for HA)
52+
* @param {Map<string, string>} [labelData.entityIds] - Entity ID hints (default_entity_id for HA)
5353
* @param {Set<string>} [labelData.exclude] - Addresses to skip during discovery
5454
*/
5555
constructor(settings, publishFn, sendCommandFn, labelData = null) {
@@ -406,7 +406,7 @@ class HaDiscovery {
406406
const payload = {
407407
name: null,
408408
unique_id: uniqueId,
409-
...(entityId && { object_id: entityId }),
409+
...(entityId && { default_entity_id: `${HA_COMPONENT_LIGHT}.${entityId}` }),
410410
state_topic: `${MQTT_TOPIC_PREFIX_READ}/${networkId}/${appId}/${groupId}/${MQTT_TOPIC_SUFFIX_STATE}`,
411411
command_topic: `${MQTT_TOPIC_PREFIX_WRITE}/${networkId}/${appId}/${groupId}/${MQTT_CMD_TYPE_RAMP}`,
412412
brightness_state_topic: `${MQTT_TOPIC_PREFIX_READ}/${networkId}/${appId}/${groupId}/${MQTT_TOPIC_SUFFIX_LEVEL}`,
@@ -518,7 +518,7 @@ class HaDiscovery {
518518
const payload = {
519519
name: null,
520520
unique_id: uniqueId,
521-
...(entityId && { object_id: entityId }),
521+
...(entityId && { default_entity_id: `${HA_COMPONENT_CLIMATE}.${entityId}` }),
522522

523523
// Current temperature: reported by C-Gate as a status level on this group.
524524
// Template converts 0-255 C-Bus level to 0-50°C (0.5°C resolution):
@@ -590,7 +590,7 @@ class HaDiscovery {
590590
const payload = {
591591
name: null,
592592
unique_id: uniqueId,
593-
...(entityId && { object_id: entityId }),
593+
...(entityId && { default_entity_id: `${config.component}.${entityId}` }),
594594
state_topic: stateTopic,
595595
...(!config.omitCommandTopic && { command_topic: `${MQTT_TOPIC_PREFIX_WRITE}/${networkId}/${appId}/${groupId}/${MQTT_CMD_TYPE_SWITCH}` }),
596596
...config.payloads,
@@ -653,7 +653,7 @@ class HaDiscovery {
653653
const payload = {
654654
name: null,
655655
unique_id: uniqueId,
656-
...(entityId && { object_id: `${entityId}_btn` }),
656+
...(entityId && { default_entity_id: `${HA_COMPONENT_BUTTON}.${entityId}_btn` }),
657657
command_topic: `${MQTT_TOPIC_PREFIX_WRITE}/${networkId}/${appId}/${groupId}/${MQTT_CMD_TYPE_TRIGGER}`,
658658
payload_press: MQTT_STATE_ON,
659659
qos: 0,
@@ -686,7 +686,7 @@ class HaDiscovery {
686686
const payload = {
687687
name: null,
688688
unique_id: uniqueId,
689-
...(entityId && { object_id: `${entityId}_scene` }),
689+
...(entityId && { default_entity_id: `${HA_COMPONENT_SCENE}.${entityId}_scene` }),
690690
command_topic: `${MQTT_TOPIC_PREFIX_WRITE}/${networkId}/${appId}/${groupId}/${MQTT_CMD_TYPE_SWITCH}`,
691691
payload_on: MQTT_STATE_ON,
692692
qos: 0,

src/labelLoader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ class LabelLoader extends EventEmitter {
229229
}
230230

231231
/**
232-
* @returns {Map<string, string>} Entity ID hints (address -> object_id for HA)
232+
* @returns {Map<string, string>} Entity ID hints (address -> default_entity_id for HA)
233233
*/
234234
getEntityIds() {
235235
return this._entityIds;

src/staleDeviceDetector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class StaleDeviceDetector {
143143
const payload = {
144144
name: 'C-Bus Stale Devices',
145145
unique_id: 'cgateweb_stale_devices',
146-
object_id: 'cgateweb_stale_devices',
146+
default_entity_id: 'sensor.cgateweb_stale_devices',
147147
state_topic: 'cbus/bridge/stale_devices',
148148
json_attributes_topic: 'cbus/bridge/stale_devices_detail',
149149
unit_of_measurement: 'devices',

tests/haDiscovery.test.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ describe('HaDiscovery', () => {
715715
expect(payload.device.name).toBe('Pond Pump');
716716
});
717717

718-
it('should inject object_id when entity_ids has an entry', () => {
718+
it('should inject default_entity_id with domain prefix when entity_ids has an entry', () => {
719719
const labelData = {
720720
labels: new Map([['254/56/10', 'Kitchen']]),
721721
typeOverrides: new Map(),
@@ -730,10 +730,11 @@ describe('HaDiscovery', () => {
730730
);
731731
expect(call).toBeDefined();
732732
const payload = JSON.parse(call[1]);
733-
expect(payload.object_id).toBe('kitchen_light');
733+
expect(payload.default_entity_id).toBe('light.kitchen_light');
734+
expect(payload.object_id).toBeUndefined();
734735
});
735736

736-
it('should not include object_id when no entity_id is configured', () => {
737+
it('should not include default_entity_id when no entity_id is configured', () => {
737738
const labelData = {
738739
labels: new Map(),
739740
typeOverrides: new Map(),
@@ -748,10 +749,10 @@ describe('HaDiscovery', () => {
748749
);
749750
expect(call).toBeDefined();
750751
const payload = JSON.parse(call[1]);
751-
expect(payload.object_id).toBeUndefined();
752+
expect(payload.default_entity_id).toBeUndefined();
752753
});
753754

754-
it('should inject object_id on type-overridden cover entities', () => {
755+
it('should inject default_entity_id with domain prefix on type-overridden cover entities', () => {
755756
const labelData = {
756757
labels: new Map([['254/56/10', 'Main Blind']]),
757758
typeOverrides: new Map([['254/56/10', 'cover']]),
@@ -766,7 +767,8 @@ describe('HaDiscovery', () => {
766767
);
767768
expect(coverCall).toBeDefined();
768769
const payload = JSON.parse(coverCall[1]);
769-
expect(payload.object_id).toBe('main_blind');
770+
expect(payload.default_entity_id).toBe('cover.main_blind');
771+
expect(payload.object_id).toBeUndefined();
770772
expect(payload.name).toBeNull();
771773
expect(payload.device.name).toBe('Main Blind');
772774
});
@@ -816,7 +818,7 @@ describe('HaDiscovery', () => {
816818
const payload = JSON.parse(extraCall[1]);
817819
expect(payload.name).toBeNull();
818820
expect(payload.device.name).toBe('Extra Group Not In Tree');
819-
expect(payload.object_id).toBe('extra_group');
821+
expect(payload.default_entity_id).toBe('light.extra_group');
820822

821823
const anotherCall = mockPublishFn.mock.calls.find(
822824
c => c[0] === 'testhomeassistant/light/cgateweb_254_56_201/config'
@@ -876,7 +878,7 @@ describe('HaDiscovery', () => {
876878
const payload = JSON.parse(coverCall[1]);
877879
expect(payload.name).toBeNull();
878880
expect(payload.device.name).toBe('Extra Blind');
879-
expect(payload.object_id).toBe('extra_blind');
881+
expect(payload.default_entity_id).toBe('cover.extra_blind');
880882
});
881883
});
882884

@@ -1373,7 +1375,7 @@ describe('HaDiscovery', () => {
13731375
expect(payload.device.name).toBe('Movie Mode');
13741376
});
13751377

1376-
it('should apply entity_id suffix to scene object_id when entity ID is configured', () => {
1378+
it('should apply entity_id suffix to scene default_entity_id when entity ID is configured', () => {
13771379
haDiscovery.updateLabels({
13781380
labels: new Map(),
13791381
typeOverrides: new Map(),
@@ -1388,7 +1390,8 @@ describe('HaDiscovery', () => {
13881390
);
13891391
expect(sceneCall).toBeDefined();
13901392
const payload = JSON.parse(sceneCall[1]);
1391-
expect(payload.object_id).toBe('entry_scene_scene');
1393+
expect(payload.default_entity_id).toBe('scene.entry_scene_scene');
1394+
expect(payload.object_id).toBeUndefined();
13921395
});
13931396
});
13941397
});

0 commit comments

Comments
 (0)