Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ jobs:
with: { path: zm-web }
- uses: actions/checkout@v7
with:
repository: SteveGilvarry/zm-api
repository: ZoneMinder/zm-api
path: zm_api
- uses: actions/setup-node@v7
with:
Expand Down
40 changes: 33 additions & 7 deletions e2e/seed/seed.sql
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,40 @@ VALUES
(9001, '/var/cache/zoneminder/events-e2e', 'e2e-events', 'local', NULL, NULL, 'Medium', 9001, 1, 1);

-- ---------------------------------------------------------------------------
-- PTZ control profile: a copy of the stock Ffmpeg/Pelco-D row (positional
-- VALUES, same column order as zm_create.sql.in) with our own id and name.
-- Positional, so every column ZoneMinder adds to Controls has to be added
-- here too, and every column it drops removed: Type went in 1.39.39 (ZoneMinder
-- 1043273, 2026-10-10), the four audio columns at the end are the newest.
-- PTZ control profile: a copy of the stock Pelco-D row (db/controls.sql)
-- with our own id and name.
-- Columns are named, so a column ZoneMinder adds (with a default) or drops
-- elsewhere in Controls does not break the load.
-- ---------------------------------------------------------------------------
INSERT INTO Controls VALUES
(9001,'e2e-PTZ Dome (Pelco-D)','PelcoD',1,1,0,0,1,1,0,0,1,NULL,NULL,NULL,NULL,1,0,3,1,1,0,0,1,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,1,1,0,1,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0,0,1,20,1,1,1,1,0,0,0,1,1,NULL,NULL,NULL,NULL,1,0,63,1,254,1,NULL,NULL,NULL,NULL,1,0,63,1,254,0,0,0,NULL,NULL,0);
INSERT INTO Controls
(Id, Name, Protocol, CanWake, CanSleep, CanReset, CanReboot, CanZoom,
CanAutoZoom, CanZoomAbs, CanZoomRel, CanZoomCon, MinZoomRange,
MaxZoomRange, MinZoomStep, MaxZoomStep, HasZoomSpeed, MinZoomSpeed,
MaxZoomSpeed, CanFocus, CanAutoFocus, CanFocusAbs, CanFocusRel,
CanFocusCon, MinFocusRange, MaxFocusRange, MinFocusStep, MaxFocusStep,
HasFocusSpeed, MinFocusSpeed, MaxFocusSpeed, CanIris, CanAutoIris,
CanIrisAbs, CanIrisRel, CanIrisCon, MinIrisRange, MaxIrisRange,
MinIrisStep, MaxIrisStep, HasIrisSpeed, MinIrisSpeed, MaxIrisSpeed,
CanGain, CanAutoGain, CanGainAbs, CanGainRel, CanGainCon, MinGainRange,
MaxGainRange, MinGainStep, MaxGainStep, HasGainSpeed, MinGainSpeed,
MaxGainSpeed, CanWhite, CanAutoWhite, CanWhiteAbs, CanWhiteRel,
CanWhiteCon, MinWhiteRange, MaxWhiteRange, MinWhiteStep, MaxWhiteStep,
HasWhiteSpeed, MinWhiteSpeed, MaxWhiteSpeed, CanLight, CanIndicatorLight,
HasPresets, NumPresets, HasHomePreset, CanSetPresets, CanMove,
CanMoveDiag, CanMoveMap, CanMoveAbs, CanMoveRel, CanMoveCon, CanPan,
MinPanRange, MaxPanRange, MinPanStep, MaxPanStep, HasPanSpeed,
MinPanSpeed, MaxPanSpeed, HasTurboPan, TurboPanSpeed, CanTilt,
MinTiltRange, MaxTiltRange, MinTiltStep, MaxTiltStep, HasTiltSpeed,
MinTiltSpeed, MaxTiltSpeed, HasTurboTilt, TurboTiltSpeed, CanAutoScan,
NumScanPaths, CanAudioPlay, MinAudioFile, MaxAudioFile, CanAudioVolume)
VALUES
(9001, 'e2e-PTZ Dome (Pelco-D)', 'PelcoD', 1, 1, 0, 0, 1, 1, 0, 0, 1, NULL,
NULL, NULL, NULL, 1, 0, 3, 1, 1, 0, 0, 1, NULL, NULL, NULL, NULL, 0,
NULL, NULL, 1, 1, 0, 1, 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, 0,
0, 0, 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 1, 1, 0, 1, 0, NULL,
NULL, NULL, NULL, 0, NULL, NULL, 0, 0, 1, 20, 1, 1, 1, 1, 0, 0, 0, 1, 1,
NULL, NULL, NULL, NULL, 1, 0, 63, 1, 254, 1, NULL, NULL, NULL, NULL, 1,
0, 63, 1, 254, 0, 0, 0, NULL, NULL, 0);

-- ---------------------------------------------------------------------------
-- Monitors. Four Ffmpeg cameras; 9002 is ROTATE_90 and 9003 is ROTATE_270 for
Expand Down
3 changes: 2 additions & 1 deletion src/api/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import type { PaginatedResponse } from '@/types';
export interface Control {
id: number;
name: string;
type: string;
/** Null from ZoneMinder 1.39.39 on, which dropped `Controls.Type`. */
type: string | null;
protocol?: string | null;

// Movement capabilities
Expand Down
14 changes: 14 additions & 0 deletions src/skins/modern/pages/settings.ptzControls.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ describe('PTZ controls page — editor and guards', () => {
expect(names()).toEqual(['Bravo']);
});

it('searches profiles that have no type, as ZoneMinder 1.39.39+ returns them', async () => {
seedControls([
{ id: 1, name: 'Pelco-D', type: null, protocol: 'PelcoD' },
{ id: 2, name: 'Axis', type: null, protocol: 'AxisV2' },
]);
const user = userEvent.setup();
renderPage();
await waitFor(() => expect(screen.getByText('Pelco-D')).toBeInTheDocument());
await user.type(screen.getByRole('searchbox', { name: /search control profiles/i }), 'pelco');
expect(screen.getByRole('row', { name: /Pelco-D/ })).toBeInTheDocument();
expect(screen.queryByRole('row', { name: /Axis/ })).not.toBeInTheDocument();
expect(screen.queryByText('Cannot reach the server.')).not.toBeInTheDocument();
});

it('Add profile opens the tabbed editor at ?id=new and POSTs every field', async () => {
seedControls([]);
let body: Record<string, unknown> | null = null;
Expand Down
Loading