fix: Reolink Trackmix cameras should be detected correctly (#2264)
- Closes: #2254
This commit is contained in:
@@ -104,9 +104,7 @@ export class ReolinkCamera extends EntityCamera {
|
|||||||
// and must only be taken from the user config instead.
|
// and must only be taken from the user config instead.
|
||||||
|
|
||||||
const match = uniqueID
|
const match = uniqueID
|
||||||
? String(uniqueID).match(
|
? String(uniqueID).match(/^(?<hostid>[^_]+)_(?<channel_or_uid>[^_]+)_/)
|
||||||
/^(?<hostid>[A-Za-z0-9]+)_(?<channel_or_uid>[A-Za-z0-9]+)_/,
|
|
||||||
)
|
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const hostid = match?.groups?.hostid ?? null;
|
const hostid = match?.groups?.hostid ?? null;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import { ReolinkCamera } from '../../../src/camera-manager/reolink/camera';
|
|||||||
import { CameraProxyConfig } from '../../../src/camera-manager/types';
|
import { CameraProxyConfig } from '../../../src/camera-manager/types';
|
||||||
import { ActionsExecutor } from '../../../src/card-controller/actions/types';
|
import { ActionsExecutor } from '../../../src/card-controller/actions/types';
|
||||||
import { StateWatcher } from '../../../src/card-controller/hass/state-watcher';
|
import { StateWatcher } from '../../../src/card-controller/hass/state-watcher';
|
||||||
import { EntityRegistryManagerLive } from '../../../src/ha/registry/entity';
|
|
||||||
import { DeviceRegistryManager } from '../../../src/ha/registry/device';
|
import { DeviceRegistryManager } from '../../../src/ha/registry/device';
|
||||||
|
import { EntityRegistryManagerLive } from '../../../src/ha/registry/entity';
|
||||||
import { EntityRegistryManagerMock } from '../../ha/registry/entity/mock';
|
import { EntityRegistryManagerMock } from '../../ha/registry/entity/mock';
|
||||||
import {
|
import {
|
||||||
createCameraConfig,
|
createCameraConfig,
|
||||||
@@ -122,6 +122,7 @@ describe('ReolinkCamera', () => {
|
|||||||
await camera.initialize({
|
await camera.initialize({
|
||||||
hass: createHASS(),
|
hass: createHASS(),
|
||||||
entityRegistryManager,
|
entityRegistryManager,
|
||||||
|
deviceRegistryManager: mock<DeviceRegistryManager>(),
|
||||||
stateWatcher: mock<StateWatcher>(),
|
stateWatcher: mock<StateWatcher>(),
|
||||||
}),
|
}),
|
||||||
).rejects.toThrowError('Could not initialize Reolink camera');
|
).rejects.toThrowError('Could not initialize Reolink camera');
|
||||||
@@ -151,29 +152,6 @@ describe('ReolinkCamera', () => {
|
|||||||
).rejects.toThrowError('Could not initialize Reolink camera');
|
).rejects.toThrowError('Could not initialize Reolink camera');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('successfully with an NVR-connected camera without user-specified channel', async () => {
|
|
||||||
const config = createCameraConfig({
|
|
||||||
camera_entity: 'camera.office_reolink',
|
|
||||||
});
|
|
||||||
const camera = new ReolinkCamera(config, mock<CameraManagerEngine>());
|
|
||||||
const entityRegistryManager = new EntityRegistryManagerMock([
|
|
||||||
createRegistryEntity({
|
|
||||||
entity_id: 'camera.office_reolink',
|
|
||||||
unique_id: '9527000HXU4V1VHZ_9527000I7E5F1GYU_main',
|
|
||||||
platform: 'reolink',
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
await camera.initialize({
|
|
||||||
hass: createHASS(),
|
|
||||||
entityRegistryManager,
|
|
||||||
deviceRegistryManager: mock<DeviceRegistryManager>(),
|
|
||||||
stateWatcher: mock<StateWatcher>(),
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(camera.getChannel()).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('successfully with a directly connected camera', async () => {
|
it('successfully with a directly connected camera', async () => {
|
||||||
const config = createCameraConfig({
|
const config = createCameraConfig({
|
||||||
camera_entity: 'camera.office_reolink',
|
camera_entity: 'camera.office_reolink',
|
||||||
@@ -223,6 +201,75 @@ describe('ReolinkCamera', () => {
|
|||||||
expect(camera.getChannel()).toBe(3);
|
expect(camera.getChannel()).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('successfully with hyphenated host id', async () => {
|
||||||
|
const config = createCameraConfig({
|
||||||
|
camera_entity: 'camera.office_reolink',
|
||||||
|
});
|
||||||
|
const camera = new ReolinkCamera(config, mock<CameraManagerEngine>());
|
||||||
|
const entityRegistryManager = new EntityRegistryManagerMock([
|
||||||
|
createRegistryEntity({
|
||||||
|
entity_id: 'camera.office_reolink',
|
||||||
|
unique_id: 'host-id_7_main',
|
||||||
|
platform: 'reolink',
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await camera.initialize({
|
||||||
|
hass: createHASS(),
|
||||||
|
entityRegistryManager,
|
||||||
|
deviceRegistryManager: mock<DeviceRegistryManager>(),
|
||||||
|
stateWatcher: mock<StateWatcher>(),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(camera.getChannel()).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('successfully with a default fallback channel', async () => {
|
||||||
|
const config = createCameraConfig({
|
||||||
|
camera_entity: 'camera.office_reolink',
|
||||||
|
});
|
||||||
|
const camera = new ReolinkCamera(config, mock<CameraManagerEngine>());
|
||||||
|
const entityRegistryManager = new EntityRegistryManagerMock([
|
||||||
|
createRegistryEntity({
|
||||||
|
entity_id: 'camera.office_reolink',
|
||||||
|
unique_id: 'hostid_channel-uid_main',
|
||||||
|
platform: 'reolink',
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await camera.initialize({
|
||||||
|
hass: createHASS(),
|
||||||
|
entityRegistryManager,
|
||||||
|
deviceRegistryManager: mock<DeviceRegistryManager>(),
|
||||||
|
stateWatcher: mock<StateWatcher>(),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(camera.getChannel()).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('successfully with colon in host id', async () => {
|
||||||
|
const config = createCameraConfig({
|
||||||
|
camera_entity: 'camera.office_reolink',
|
||||||
|
});
|
||||||
|
const camera = new ReolinkCamera(config, mock<CameraManagerEngine>());
|
||||||
|
const entityRegistryManager = new EntityRegistryManagerMock([
|
||||||
|
createRegistryEntity({
|
||||||
|
entity_id: 'camera.office_reolink',
|
||||||
|
unique_id: 'host:id_7_main',
|
||||||
|
platform: 'reolink',
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await camera.initialize({
|
||||||
|
hass: createHASS(),
|
||||||
|
entityRegistryManager,
|
||||||
|
deviceRegistryManager: mock<DeviceRegistryManager>(),
|
||||||
|
stateWatcher: mock<StateWatcher>(),
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(camera.getChannel()).toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
describe('should detect channel from configuration URL', () => {
|
describe('should detect channel from configuration URL', () => {
|
||||||
it('should return null if device_id is missing', async () => {
|
it('should return null if device_id is missing', async () => {
|
||||||
const config = createCameraConfig({
|
const config = createCameraConfig({
|
||||||
|
|||||||
Reference in New Issue
Block a user