iobroker.agent-dvr 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.de.md +33 -12
- package/README.md +32 -11
- package/build/main.js +71 -7
- package/build/main.js.map +2 -2
- package/io-package.json +14 -14
- package/package.json +1 -1
- package/www/index.html +7693 -38
- package/www/flv.min.js +0 -7534
package/build/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts"],
|
|
4
|
-
"sourcesContent": ["import * as utils from '@iobroker/adapter-core';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\nimport { getWidgetLabels, type WidgetLabels } from './lib/widget-i18n';\n\n// =====================================================================\n// Agent DVR -> ioBroker Adapter\n// API reference: https://ispysoftware.github.io/Agent_API/ (v7.5)\n// =====================================================================\n\n// ---- Types ----\n\ninterface ApiResult {\n\tok: boolean;\n\tdata?: string;\n\terror?: string;\n}\n\ninterface AgentDvrEvent {\n\tfn?: string;\n\ttg?: string;\n\tc?: number;\n\td?: number | string;\n\tsb?: number;\n\t[key: string]: unknown;\n}\n\ninterface Device {\n\toid: number | string;\n\tot: number;\n\tname: string;\n\traw: Record<string, unknown>;\n}\n\ntype RegistryKind = 'cam' | 'sys' | 'ptz' | 'ptzHold' | 'push' | 'setProfile' | 'snapshotB64';\n\ninterface RegistryEntry {\n\tkind: RegistryKind;\n\tpath?: string | null;\n\tparams?: string[];\n\toid?: number | string;\n\tot?: number;\n\tdir?: number;\n\tfid?: string;\n}\n\n// ---- Commands ----\n\nconst CAM_COMMANDS = [\n\t{ id: 'record', path: '/command/record', params: ['oid', 'ot'], name: 'Start recording' },\n\t{ id: 'recordStop', path: '/command/recordStop', params: ['oid', 'ot'], name: 'Stop recording' },\n\t{ id: 'recordRestart', path: '/command/recordRestart', params: ['oid', 'ot'], name: 'Restart recording' },\n\t{ id: 'triggerRecord', path: '/command/triggerRecord', params: ['oid', 'ot'], name: 'Trigger recording (timeout)' },\n\t{ id: 'snapshot', path: '/command/snapshot', params: ['oid'], name: 'Take snapshot' },\n\t{ id: 'detect', path: '/command/detect', params: ['oid', 'ot'], name: 'Trigger motion detection' },\n\t{ id: 'alertOn', path: '/command/alertOn', params: ['oid', 'ot'], name: 'Arm alerts' },\n\t{ id: 'alertOff', path: '/command/alertOff', params: ['oid', 'ot'], name: 'Disarm alerts' },\n\t{ id: 'switchOn', path: '/command/switchOn', params: ['oid', 'ot'], name: 'Switch device on' },\n\t{ id: 'switchOff', path: '/command/switchOff', params: ['oid', 'ot'], name: 'Switch device off' },\n\t{ id: 'objectDetectOn', path: '/command/objectdetecton', params: ['oid', 'ot'], name: 'Enable object detection' },\n\t{\n\t\tid: 'objectDetectOff',\n\t\tpath: '/command/objectdetectoff',\n\t\tparams: ['oid', 'ot'],\n\t\tname: 'Disable object detection',\n\t},\n\t{ id: 'recOnAlert', path: '/command/recordOnAlertOn', params: ['oid', 'ot'], name: 'Record on alert: on' },\n\t{ id: 'recOnDetect', path: '/command/recordOnDetectOn', params: ['oid', 'ot'], name: 'Record on detect: on' },\n\t{ id: 'purge', path: '/command/purge', params: ['oid', 'ot'], name: 'Purge folder (caution!)' },\n] as const;\n\nconst SYS_COMMANDS = [\n\t{ id: 'arm', path: '/command/arm', name: 'Arm system' },\n\t{ id: 'disarm', path: '/command/disarm', name: 'Disarm system' },\n\t{ id: 'allOn', path: '/command/allOn', name: 'All devices on' },\n\t{ id: 'allOff', path: '/command/allOff', name: 'All devices off' },\n\t{ id: 'reloadConfig', path: '/command/reloadConfig', name: 'Reload config' },\n\t{ id: 'reloadObjects', path: '/command/reloadObjects', name: 'Reload objects' },\n\t{ id: 'runStorageMgmt', path: '/command/runStorageMgmt', name: 'Run storage management' },\n\t{ id: 'blockExternal', path: '/command/blockExternal', name: 'Block external access' },\n\t{ id: 'unblockExternal', path: '/command/unblockExternal', name: 'Unblock external access' },\n\t{ id: 'restart', path: '/command/restart', name: 'Restart Agent DVR' },\n\t{ id: 'refresh', path: null, name: 'Refresh data now' },\n] as const;\n\nconst PTZ_DIRS = [\n\t{ id: 'left', dir: 1, hold: true },\n\t{ id: 'upLeft', dir: 2, hold: true },\n\t{ id: 'up', dir: 3, hold: true },\n\t{ id: 'upRight', dir: 4, hold: true },\n\t{ id: 'right', dir: 5, hold: true },\n\t{ id: 'downRight', dir: 6, hold: true },\n\t{ id: 'down', dir: 7, hold: true },\n\t{ id: 'downLeft', dir: 8, hold: true },\n\t{ id: 'zoomIn', dir: 9, hold: true },\n\t{ id: 'zoomOut', dir: 10, hold: true },\n\t{ id: 'stop', dir: 11, hold: false },\n\t{ id: 'center', dir: 0, hold: false },\n] as const;\n\nconst SKIP_KEYS = ['icons', 'image', 'thumbnail', 'base64'];\n\n// ---- Module-level helpers ----\n\nfunction sanitize(s: unknown): string {\n\treturn (\n\t\tString(s)\n\t\t\t.replace(/[\\s.[\\]*?\"'`,;:/\\\\]+/g, '_')\n\t\t\t.replace(/[^A-Za-z0-9_-]/g, '_')\n\t\t\t.replace(/_+/g, '_')\n\t\t\t.replace(/^_+|_+$/g, '') || 'x'\n\t);\n}\n\nfunction asJson(data: unknown): Record<string, unknown> | null {\n\tif (data == null) {\n\t\treturn null;\n\t}\n\tif (typeof data === 'object') {\n\t\treturn data as Record<string, unknown>;\n\t}\n\tif (typeof data === 'string') {\n\t\ttry {\n\t\t\treturn JSON.parse(data) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction toStr(v: unknown): string {\n\tif (v == null) {\n\t\treturn '';\n\t}\n\tif (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n\t\treturn String(v);\n\t}\n\treturn Object.prototype.toString.call(v);\n}\n\nfunction escHtml(s: unknown): string {\n\treturn toStr(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction parseSizeGb(s: unknown): number | null {\n\tif (s == null) {\n\t\treturn null;\n\t}\n\tconst m = toStr(s)\n\t\t.trim()\n\t\t.match(/([\\d.,]+)\\s*([KMGT]?B)?/i);\n\tif (!m) {\n\t\treturn null;\n\t}\n\tlet v = parseFloat(m[1].replace(',', '.'));\n\tif (isNaN(v)) {\n\t\treturn null;\n\t}\n\tconst u = (m[2] || 'GB').toUpperCase();\n\tif (u === 'TB') {\n\t\tv *= 1024;\n\t} else if (u === 'MB') {\n\t\tv /= 1024;\n\t} else if (u === 'KB') {\n\t\tv /= 1048576;\n\t} else if (u === 'B') {\n\t\tv /= 1073741824;\n\t}\n\treturn Math.round(v * 100) / 100;\n}\n\nfunction findWH(obj: unknown, depth: number): [number, number] | null {\n\tif (!obj || typeof obj !== 'object' || depth > 5) {\n\t\treturn null;\n\t}\n\tconst o = obj as Record<string, unknown>;\n\tfor (const [kw, kh] of [\n\t\t['width', 'height'],\n\t\t['w', 'h'],\n\t\t['sourceWidth', 'sourceHeight'],\n\t\t['videoWidth', 'videoHeight'],\n\t\t['imageWidth', 'imageHeight'],\n\t]) {\n\t\tconst w = o[kw],\n\t\t\th = o[kh];\n\t\tif (typeof w === 'number' && typeof h === 'number' && w >= 100 && h >= 100 && w <= 12000 && h <= 12000) {\n\t\t\tconst r = w / h;\n\t\t\tif (r >= 0.3 && r <= 4) {\n\t\t\t\treturn [w, h];\n\t\t\t}\n\t\t}\n\t}\n\tfor (const k of Object.keys(o)) {\n\t\tconst g = findWH(o[k], depth + 1);\n\t\tif (g) {\n\t\t\treturn g;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction detectOt(elem: Record<string, unknown>): number {\n\tconst v = elem.typeID ?? elem.ot ?? elem.objectTypeID ?? elem.type;\n\treturn v === 1 || v === 2 ? v : 2;\n}\n\nfunction findDevices(json: Record<string, unknown>): Device[] {\n\tconst list = Array.isArray(json.objectList) ? json.objectList : [];\n\tconst out: Device[] = [];\n\tfor (const e of list) {\n\t\tif (!e || typeof e !== 'object') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst el = e as Record<string, unknown>;\n\t\tconst rawId = el.id ?? el.oid;\n\t\tif (rawId === undefined || rawId === null) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = rawId as number | string;\n\t\tconst name = typeof el.name === 'string' ? el.name : `obj_${id}`;\n\t\tout.push({ oid: id, ot: detectOt(el), name, raw: el });\n\t}\n\treturn out;\n}\n\n// ---- HTML/CSS gallery helpers ----\n\ninterface WidgetColors {\n\tcardBg?: string;\n\ttagBg?: string;\n\ttagText?: string;\n\taccent?: string;\n\tmodalBg?: string;\n\tradius?: number;\n}\n\nfunction advCssVars(c?: WidgetColors): string {\n\tconst cardBg = c?.cardBg || 'rgba(127,127,127,.15)';\n\tconst tagBg = c?.tagBg || 'rgba(0,0,0,.55)';\n\tconst tagText = c?.tagText || '#fff';\n\tconst accent = c?.accent || '#8ab4f8';\n\tconst modalBg = c?.modalBg || '#1c1c1e';\n\tconst radius = c?.radius != null ? `${c.radius}px` : '8px';\n\treturn `--adv-card-bg:${cardBg};--adv-tag-bg:${tagBg};--adv-tag-color:${tagText};--adv-accent:${accent};--adv-modal-bg:${modalBg};--adv-radius:${radius};`;\n}\n\nfunction galleryCss(minCol: number, maxW: number, compact = false, colors?: WidgetColors): string {\n\tconst gap = compact ? 6 : 12;\n\treturn (\n\t\t`.advgrid{${advCssVars(colors)}display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:${gap}px;max-width:100%}` +\n\t\t`.advgrid .advlb{display:none}` +\n\t\t`.advcell{display:flex;flex-direction:column;cursor:pointer;text-decoration:none;color:inherit;font-family:inherit}` +\n\t\t`.advimg{position:relative;display:block;border-radius:var(--adv-radius);overflow:hidden;background:var(--adv-card-bg)}` +\n\t\t`.advimg img{width:100%;height:auto;display:block}` +\n\t\t`.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtag{position:absolute;background:var(--adv-tag-bg);color:var(--adv-tag-color);font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplay::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcell:hover .advplay{opacity:1}` +\n\t\t`.advcap{font-size:${compact ? '.65rem' : '.72rem'};margin-top:${compact ? 2 : 4}px;line-height:1.25;opacity:.85}` +\n\t\t`.advmodal{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}` +\n\t\t`.advgrid .advlb:checked + .advthumb + .advmodal{display:flex}` +\n\t\t`.advbackdrop{position:absolute;inset:0;background:transparent;cursor:pointer}` +\n\t\t`.advbox{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,${maxW}px);background:var(--adv-modal-bg);padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}` +\n\t\t`.advvideo{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}` +\n\t\t`.advclose{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}` +\n\t\t`.advinfo{color:#fff;font-size:.8rem;text-align:center}` +\n\t\t`.advinfo a{color:var(--adv-accent)}` +\n\t\t`.advempty{padding:24px;text-align:center;opacity:.7;font-family:inherit}`\n\t);\n}\n\nfunction galleryCssJs(minCol: number, compact = false, colors?: WidgetColors): string {\n\tconst gap = compact ? 6 : 12;\n\treturn (\n\t\t`.advroot{${advCssVars(colors)}font-family:inherit;color:inherit}` +\n\t\t`.advbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px}` +\n\t\t`.advsearchjs{flex:1 1 160px;min-width:120px;padding:6px 10px;border-radius:8px;border:1px solid rgba(127,127,127,.4);background:rgba(127,127,127,.08);color:inherit;font:inherit}` +\n\t\t`.advtagsjs{display:flex;flex-wrap:wrap;gap:6px}` +\n\t\t`.advtagbtn{padding:4px 10px;border-radius:999px;border:1px solid rgba(127,127,127,.4);background:transparent;color:inherit;cursor:pointer;font:inherit;font-size:.8rem}` +\n\t\t`.advtagbtn.on{background:var(--adv-accent);color:#fff;border-color:var(--adv-accent)}` +\n\t\t`.advgridjs{display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:${gap}px}` +\n\t\t`.advcelljs{display:flex;flex-direction:column;cursor:pointer}` +\n\t\t`.advimgjs{position:relative;display:block;border-radius:var(--adv-radius);overflow:hidden;background:var(--adv-card-bg)}` +\n\t\t`.advimgjs img{width:100%;height:auto;display:block}` +\n\t\t`.advimgjs.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtagjs{position:absolute;background:var(--adv-tag-bg);color:var(--adv-tag-color);font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplayjs{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplayjs::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcelljs:hover .advplayjs{opacity:1}` +\n\t\t`.advcapjs{font-size:${compact ? '.65rem' : '.72rem'};margin-top:${compact ? 2 : 4}px;line-height:1.25;opacity:.85}` +\n\t\t`.advemptyjs{padding:24px;text-align:center;opacity:.7}`\n\t);\n}\n\n// Client-side browser code for the JS widget variant.\n// Stored as a string: TypeScript never type-checks browser code running in DOM context.\nconst ADV_CLIENT_CODE = `\n(function(){\nfunction esc(s){return String(s==null?'':s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"');}\nvar MODAL_CSS='.advmodaljs{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}.advbackdropjs{position:absolute;inset:0;background:transparent;cursor:pointer}.advboxjs{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,900px);background:#1c1c1e;padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}.advvideojs{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}.advclosejs{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}.advinfojs{color:#fff;font-size:.8rem;text-align:center}';\nvar modalEl=null,modalVideo=null,modalInfo=null,modalBox=null;\nfunction getModal(){\n if(modalEl&&document.body.contains(modalEl))return modalEl;\n if(!document.getElementById('advmodalcss')){var st=document.createElement('style');st.id='advmodalcss';st.textContent=MODAL_CSS;document.head.appendChild(st);}\n modalEl=document.createElement('div');modalEl.className='advmodaljs';\n var bd=document.createElement('div');bd.className='advbackdropjs';\n modalBox=document.createElement('div');modalBox.className='advboxjs';\n var cl=document.createElement('span');cl.className='advclosejs';cl.textContent='\u2715';\n modalVideo=document.createElement('video');modalVideo.className='advvideojs';\n modalVideo.setAttribute('controls','');modalVideo.setAttribute('preload','none');modalVideo.setAttribute('playsinline','');\n modalInfo=document.createElement('div');modalInfo.className='advinfojs';\n modalBox.appendChild(cl);modalBox.appendChild(modalVideo);modalBox.appendChild(modalInfo);\n modalEl.appendChild(bd);modalEl.appendChild(modalBox);\n document.body.appendChild(modalEl);\n bd.addEventListener('click',closeModal);cl.addEventListener('click',closeModal);\n return modalEl;\n}\nfunction openSrc(src,label,maxW){\n var m=getModal();\n if(maxW)modalBox.style.maxWidth='min(92vw,'+maxW+'px)';\n modalVideo.setAttribute('src',src);modalInfo.textContent=label;m.style.display='flex';\n}\nfunction closeModal(){\n if(!modalEl)return;\n try{modalVideo.pause();}catch(e){}\n modalVideo.removeAttribute('src');try{modalVideo.load();}catch(e){}\n modalEl.style.display='none';\n}\ndocument.addEventListener('keydown',function(e){if(e.key==='Escape'||e.keyCode===27)closeModal();});\nfunction initRoot(root){\n var dataEl=root.querySelector('script.advdata');\n if(!dataEl)return;\n var D;try{D=JSON.parse(dataEl.textContent);}catch(e){return;}\n var cfg=D.cfg||{},items=D.items||[],live=D.live||null;\n var grid=root.querySelector('.advgridjs'),search=root.querySelector('.advsearchjs'),tagsBox=root.querySelector('.advtagsjs');\n var state={q:'',tag:cfg.default_tag||''};\n var tagset={};\n items.forEach(function(it){String(it.tag||'').split(/[,\\\\s]+/).forEach(function(t){if(t)tagset[t]=1;});});\n var tags=Object.keys(tagset);\n if(cfg.show_tags&&tags.length){\n var mk=function(label,val){\n var b=document.createElement('button');b.className='advtagbtn';b.textContent=label;b.setAttribute('data-tag',val);\n b.addEventListener('click',function(){state.tag=state.tag===val?'':val;updateTagBtns();render();});\n tagsBox.appendChild(b);\n };\n mk(cfg.labels&&cfg.labels.all||'All','');tags.forEach(function(t){mk(t,t);});\n }\n function updateTagBtns(){var bs=tagsBox.querySelectorAll('.advtagbtn');for(var i=0;i<bs.length;i++)bs[i].classList.toggle('on',bs[i].getAttribute('data-tag')===state.tag);}\n updateTagBtns();\n if(search)search.addEventListener('input',function(){state.q=this.value.toLowerCase();render();});\n function badge(it){if(!(cfg.show_tags&&it.tag))return '';var pos=String(cfg.tag_position||'bottom-left').split('-');return '<span class=\"advtagjs\" style=\"'+pos[0]+':5px;'+pos[1]+':5px\">'+esc(it.tag)+'</span>';}\n function render(){\n var html='';\n if(live){var ar=cfg.live_aspect||'',arStyle=ar?' style=\"aspect-ratio:'+ar.replace('/',' / ')+'\"':'',arCls=ar?' advimgfix':'';\n html+='<div class=\"advcelljs\" data-live=\"1\"><span class=\"advimgjs'+arCls+'\"'+arStyle+'><img loading=\"lazy\" src=\"'+esc(live.thumb)+'\"><span class=\"advtagjs\" style=\"top:5px;left:5px\">● '+(cfg.labels&&cfg.labels.live||'LIVE')+'</span><span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(live.name)+'</span></div>';}\n items.forEach(function(it,i){\n if(state.tag&&String(it.tag||'').toLowerCase().indexOf(state.tag.toLowerCase())<0)return;\n if(state.q){var hay=((it.date||'')+' '+(it.time||'')+' '+(it.tag||'')).toLowerCase();if(hay.indexOf(state.q)<0)return;}\n html+='<div class=\"advcelljs\" data-i=\"'+i+'\"><span class=\"advimgjs\"><img loading=\"lazy\" src=\"'+esc(it.thumb)+'\">'+badge(it)+'<span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(it.date)+' '+esc(it.time)+'<br>'+esc(it.dur)+'s · '+esc(it.size)+' MB</span></div>';\n });\n grid.innerHTML=html||'<div class=\"advemptyjs\">'+(cfg.labels&&cfg.labels.noRecordings||'No recordings')+'</div>';\n var cells=grid.querySelectorAll('.advcelljs');\n for(var k=0;k<cells.length;k++)(function(cell){\n cell.addEventListener('click',function(){\n if(cell.getAttribute('data-live')==='1'){openSrc(live.video,(live.name||'')+' \u00B7 Live',cfg.max_modal_width);return;}\n var it=items[parseInt(cell.getAttribute('data-i'),10)],maxW=Number(cfg.max_modal_width)||900;\n if(cfg.player_url){var u=cfg.player_url.replace(/{video}/g,encodeURIComponent(it.video)).replace(/{videoRaw}/g,it.video).replace(/{fn}/g,encodeURIComponent(it.fn||'')).replace(/{date}/g,encodeURIComponent(it.date)).replace(/{time}/g,encodeURIComponent(it.time)).replace(/{duration}/g,encodeURIComponent(it.dur)).replace(/{size}/g,encodeURIComponent(it.size)).replace(/{tags}/g,encodeURIComponent(it.tag));window.open(u,'_blank');}\n else{openSrc(it.video,esc(it.date)+' '+esc(it.time)+(it.dur!=null?' \u00B7 '+it.dur+'s':'')+(it.size!=null?' \u00B7 '+it.size+' MB':'')+(it.tag?' \u00B7 '+it.tag:''),maxW);}\n });\n })(cells[k]);\n }\n render();\n}\nfunction scan(){var roots=document.querySelectorAll('.advroot');for(var i=0;i<roots.length;i++)if(!roots[i].__adv){roots[i].__adv=1;initRoot(roots[i]);}}\nwindow.ADVscan=scan;scan();\n})();\n`.trim();\n\n// ---- Adapter class ----\n\nclass AgentDvr extends utils.Adapter {\n\tprivate pollTimer: ioBroker.Interval | undefined = undefined;\n\tprivate pollBusy = false;\n\tprivate refreshTimer: ioBroker.Timeout | undefined = undefined;\n\tprivate authHeader: string | null = null;\n\tprivate baseUrl = '';\n\tprivate wt: WidgetLabels = getWidgetLabels('en');\n\n\tprivate readonly ensuredFolders = new Set<string>();\n\tprivate readonly registry = new Map<string, RegistryEntry>();\n\tprivate readonly ptzActive = new Map<string | number, string>();\n\tprivate readonly widgetSig: Record<string, string> = {};\n\tprivate profileSig = '';\n\tprivate lastCamNames: { key: string; name: string }[] = [];\n\tprivate readonly lastEventFn: Record<string | number, string> = {};\n\tprivate readonly camAspect: Record<string | number, string> = {};\n\tprivate readonly devById = new Map<string | number, Device>();\n\tprivate readonly eventBusy: Record<string | number, boolean> = {};\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({ ...options, name: 'agent-dvr' });\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\tthis.on('message', this.onMessage.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\t// ---- lifecycle ----\n\n\tprivate async ensureWebInstance(): Promise<void> {\n\t\tconst instanceId = `system.adapter.${this.namespace}`;\n\t\tconst obj = await this.getForeignObjectAsync(instanceId);\n\t\tif (obj && !obj.native?.webInstance) {\n\t\t\tawait this.extendForeignObjectAsync(instanceId, { native: { webInstance: '*' } });\n\t\t\tthis.log.info('webInstance set \u2014 web adapter will reload the extension');\n\t\t}\n\t}\n\n\tprivate async onReady(): Promise<void> {\n\t\tvoid this.setState('info.connection', false, true);\n\t\tawait this.ensureWebInstance();\n\n\t\tconst sysConfig = await this.getForeignObjectAsync('system.config');\n\t\tconst rawLang = (sysConfig?.common as unknown as { language?: string } | undefined)?.language;\n\t\tthis.wt = getWidgetLabels(rawLang ?? 'en');\n\n\t\tconst pollSeconds = Math.max(5, Math.min(3600, this.config.pollSeconds || 30));\n\t\tthis.baseUrl = `http://${this.config.ip}:${this.config.port || 8090}`;\n\n\t\tif (this.config.user || this.config.pass) {\n\t\t\tthis.authHeader = `Basic ${Buffer.from(`${this.config.user}:${this.config.pass}`).toString('base64')}`;\n\t\t}\n\n\t\tawait this.buildSystem();\n\t\ttry {\n\t\t\tawait this.poll();\n\t\t} catch (e) {\n\t\t\tthis.log.warn(`First poll error: ${(e as Error).message}`);\n\t\t}\n\n\t\tthis.pollTimer = this.setInterval(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Poll error: ${(e as Error).message}`)),\n\t\t\tpollSeconds * 1000,\n\t\t);\n\n\t\tthis.subscribeStates('*');\n\t\tthis.log.info(`Agent DVR adapter ready. Polling ${this.baseUrl} every ${pollSeconds}s.`);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tif (this.pollTimer !== undefined) {\n\t\t\t\tthis.clearInterval(this.pollTimer);\n\t\t\t\tthis.pollTimer = undefined;\n\t\t\t}\n\t\t\tif (this.refreshTimer !== undefined) {\n\t\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\t\tthis.refreshTimer = undefined;\n\t\t\t}\n\t\t} catch {\n\t\t\t/* ignore */\n\t\t}\n\t\tcallback();\n\t}\n\n\tprivate onMessage(obj: ioBroker.Message): void {\n\t\tif (!obj) {\n\t\t\treturn;\n\t\t}\n\t\tif (obj.command === 'getGo2rtcStreams') {\n\t\t\tconst overrideUrl =\n\t\t\t\ttypeof obj.message === 'object' && obj.message !== null\n\t\t\t\t\t? (obj.message.url as string | undefined)\n\t\t\t\t\t: undefined;\n\t\t\tvoid this.fetchGo2rtcStreams(overrideUrl).then(result => {\n\t\t\t\tthis.sendTo(obj.from, obj.command, result, obj.callback);\n\t\t\t});\n\t\t} else if (obj.command === 'getAgentDvrCameras') {\n\t\t\tthis.sendTo(obj.from, obj.command, { cameras: this.lastCamNames }, obj.callback);\n\t\t} else if (obj.command === 'getAvailableSources') {\n\t\t\tvoid this.fetchAvailableSources().then(result => {\n\t\t\t\tthis.sendTo(obj.from, obj.command, result, obj.callback);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async fetchAvailableSources(): Promise<{ result: { source: string; name: string }[] }> {\n\t\tconst deadline = new Promise<{ result: { source: string; name: string }[] }>(res =>\n\t\t\tthis.setTimeout(() => res({ result: [{ source: '!', name: 'Timeout' }] }), 5000),\n\t\t);\n\t\treturn Promise.race([this._doFetchAvailableSources(), deadline]);\n\t}\n\n\tprivate async _doFetchAvailableSources(): Promise<{ result: { source: string; name: string }[] }> {\n\t\tconst rows: { source: string; name: string }[] = [];\n\t\tfor (const c of this.lastCamNames) {\n\t\t\trows.push({ source: 'AgentDVR', name: `${c.name} (${c.key})` });\n\t\t}\n\t\tconst { streams } = await this.fetchGo2rtcStreams();\n\t\tfor (const s of streams) {\n\t\t\trows.push({ source: 'go2rtc', name: s });\n\t\t}\n\t\tif (!rows.length) {\n\t\t\trows.push({ source: '\u2014', name: 'No sources found (adapter has not polled yet)' });\n\t\t}\n\t\treturn { result: rows };\n\t}\n\n\tprivate fetchGo2rtcStreams(overrideUrl?: string): Promise<{ streams: string[]; error?: string }> {\n\t\t// go2rtc only accepts plain HTTP; force https:// \u2192 http://\n\t\tconst url = (overrideUrl || this.config.go2rtcUrl || '').replace(/^https:\\/\\//i, 'http://');\n\t\tif (!url) {\n\t\t\treturn Promise.resolve({ streams: [], error: 'go2rtcUrl not configured' });\n\t\t}\n\t\tlet target: URL;\n\t\ttry {\n\t\t\ttarget = new URL('/api/streams', url);\n\t\t} catch {\n\t\t\treturn Promise.resolve({ streams: [], error: `Invalid URL: ${url}` });\n\t\t}\n\t\tlet httpReq: ReturnType<typeof http.get> | undefined;\n\t\tconst fetch = new Promise<{ streams: string[]; error?: string }>(resolve => {\n\t\t\tconst mod = target.protocol === 'https:' ? https : http;\n\t\t\thttpReq = mod.get(target.toString(), res => {\n\t\t\t\tlet body = '';\n\t\t\t\tres.on('data', (c: Buffer) => {\n\t\t\t\t\tbody += c.toString();\n\t\t\t\t});\n\t\t\t\tres.on('end', () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst parsed = JSON.parse(body);\n\t\t\t\t\t\tconst streams = Object.keys(parsed || {});\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tstreams,\n\t\t\t\t\t\t\terror: streams.length === 0 ? 'go2rtc reachable but no streams configured' : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tstreams: [],\n\t\t\t\t\t\t\terror: `Invalid JSON response from go2rtc (HTTP ${res.statusCode})`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tres.on('error', (e: Error) => resolve({ streams: [], error: `Stream error: ${e.message}` }));\n\t\t\t});\n\t\t\thttpReq.on('error', (e: Error) => resolve({ streams: [], error: `Connection error: ${e.message}` }));\n\t\t});\n\t\tconst timeout = new Promise<{ streams: string[]; error?: string }>(resolve =>\n\t\t\tthis.setTimeout(() => {\n\t\t\t\thttpReq?.destroy();\n\t\t\t\tresolve({ streams: [], error: `Timeout fetching ${target.toString()}` });\n\t\t\t}, 3000),\n\t\t);\n\t\treturn Promise.race([fetch, timeout]);\n\t}\n\n\tprivate onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n\t\tif (!state || state.ack !== false) {\n\t\t\treturn;\n\t\t}\n\t\tconst relId = this.getRelId(id);\n\t\tconst entry = this.registry.get(relId);\n\t\tif (entry) {\n\t\t\tthis.runCommand(relId, entry, state.val).catch(e =>\n\t\t\t\tthis.log.warn(`Command error: ${(e as Error).message}`),\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- helpers ----\n\n\tprivate getRelId(fullId: string): string {\n\t\treturn fullId.startsWith(`${this.namespace}.`) ? fullId.slice(this.namespace.length + 1) : fullId;\n\t}\n\n\tprivate apiGet(path: string): Promise<ApiResult> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tlet data = '';\n\t\t\t\t\tres.on('data', (c: Buffer) => {\n\t\t\t\t\t\tdata += c.toString();\n\t\t\t\t\t});\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate apiGetBuffer(path: string): Promise<{ ok: boolean; data?: Buffer; error?: string }> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tconst chunks: Buffer[] = [];\n\t\t\t\t\tres.on('data', (c: Buffer) => chunks.push(c));\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data: Buffer.concat(chunks) });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async ensureFolder(id: string, name: string, type: 'device' | 'channel' = 'channel'): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setObjectNotExistsAsync(id, { type, common: { name }, native: {} });\n\t\tthis.ensuredFolders.add(id);\n\t}\n\n\tprivate async ensurePath(fullId: string): Promise<void> {\n\t\tconst parts = fullId.split('.');\n\t\tlet acc = parts[0];\n\t\tfor (let i = 1; i < parts.length - 1; i++) {\n\t\t\tacc += `.${parts[i]}`;\n\t\t\tif (!this.ensuredFolders.has(acc)) {\n\t\t\t\tawait this.setObjectNotExistsAsync(acc, { type: 'channel', common: { name: parts[i] }, native: {} });\n\t\t\t\tthis.ensuredFolders.add(acc);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate guessRole(id: string, val: unknown): ioBroker.CommonType {\n\t\tif (typeof val === 'string' && /^https?:\\/\\//i.test(val)) {\n\t\t\treturn 'string';\n\t\t}\n\t\treturn 'string';\n\t}\n\n\tprivate async writeLeaf(id: string, val: unknown): Promise<void> {\n\t\tconst t = typeof val;\n\t\tlet common: ioBroker.StateCommon;\n\t\tif (t === 'boolean') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'boolean', role: 'indicator', read: true, write: false };\n\t\t} else if (t === 'number') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'number', role: 'value', read: true, write: false };\n\t\t} else {\n\t\t\tconst role = typeof val === 'string' && /^https?:\\/\\//i.test(val) ? 'text.url' : 'text';\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'string', role, read: true, write: false };\n\t\t}\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, { type: 'state', common, native: {} });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tawait this.setStateAsync(id, { val: (val === undefined ? null : val) as ioBroker.StateValue, ack: true });\n\t}\n\n\tprivate async flattenWrite(obj: unknown, prefix: string, depth: number): Promise<void> {\n\t\tconst maxDepth = Math.max(1, Math.min(10, this.config.maxDepth || 6));\n\t\tconst maxArray = Math.max(1, Math.min(500, this.config.maxArray || 30));\n\t\tif (depth > maxDepth) {\n\t\t\treturn;\n\t\t}\n\t\tif (obj === null || obj === undefined) {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof obj === 'object') {\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\tif (obj.length > maxArray) {\n\t\t\t\t\tawait this.writeLeaf(`${prefix}.count`, obj.length);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\t\t\tawait this.flattenWrite(obj[i], `${prefix}.${i}`, depth + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const k of Object.keys(obj)) {\n\t\t\t\t\tif (SKIP_KEYS.includes(k)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.flattenWrite((obj as Record<string, unknown>)[k], `${prefix}.${sanitize(k)}`, depth + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t}\n\t}\n\n\tprivate async ensureControl(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\trole: 'button' | 'switch',\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'boolean', role, read: role === 'switch', write: true, def: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate ensureButton(id: string, name: string, entry: RegistryEntry): Promise<void> {\n\t\treturn this.ensureControl(id, name, entry, 'button');\n\t}\n\n\tprivate async ensureSelector(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\tstates: Record<number, string>,\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'number', role: 'level', read: true, write: true, states },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: 0, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate async fetchSnapshotB64(oid: number | string, snapId: string): Promise<void> {\n\t\tconst imgRes = await this.apiGetBuffer(`/photo.jpg?oid=${oid}`);\n\t\tif (imgRes.ok && imgRes.data) {\n\t\t\tawait this.setStateAsync(snapId, {\n\t\t\t\tval: `data:image/jpeg;base64,${imgRes.data.toString('base64')}`,\n\t\t\t\tack: true,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async ensureFlag(id: string, name: string): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.ensurePath(id);\n\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\ttype: 'state',\n\t\t\tcommon: { name, type: 'boolean', role: 'indicator', read: true, write: false, def: false },\n\t\t\tnative: {},\n\t\t});\n\t\tthis.ensuredFolders.add(id);\n\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t}\n\n\tprivate async pulse(id: string): Promise<void> {\n\t\tawait this.setStateAsync(id, { val: true, ack: true });\n\t\tthis.setTimeout(() => this.setStateAsync(id, { val: false, ack: true }).catch(() => {}), 1500);\n\t}\n\n\t// ---- system structure ----\n\n\tprivate async buildSystem(): Promise<void> {\n\t\tawait this.ensureFolder('system', 'System', 'channel');\n\t\tawait this.writeLeaf('system.online', false);\n\t\tawait this.writeLeaf('system.lastUpdate', '');\n\t\tawait this.writeLeaf('system.lastPoll', 0);\n\t\tawait this.writeLeaf('system.cameraCount', 0);\n\n\t\tif (this.config.enableSystemControls) {\n\t\t\tawait this.ensureFolder('system.control', 'Control', 'channel');\n\t\t\tfor (const c of SYS_COMMANDS) {\n\t\t\t\tawait this.ensureButton(`system.control.${c.id}`, c.name, { kind: 'sys', path: c.path });\n\t\t\t}\n\t\t\tawait this.ensureFolder('system.profile', 'Profile', 'channel');\n\t\t\tawait this.ensureSelector(\n\t\t\t\t'system.profile.selector',\n\t\t\t\t'Active profile',\n\t\t\t\t{ kind: 'setProfile' },\n\t\t\t\t{ 0: 'Home', 1: 'Away', 2: 'Night' },\n\t\t\t);\n\t\t\tif (!this.ensuredFolders.has('system.profile.list')) {\n\t\t\t\tawait this.setObjectNotExistsAsync('system.profile.list', {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Available profiles (JSON)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'json',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tthis.ensuredFolders.add('system.profile.list');\n\t\t\t\tawait this.setStateAsync('system.profile.list', { val: '[]', ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---- camera aspect detection ----\n\n\tprivate async detectAspect(d: Device): Promise<void> {\n\t\tif (this.camAspect[d.oid] !== undefined) {\n\t\t\treturn;\n\t\t}\n\t\tlet wh = findWH(d.raw, 0);\n\t\tif (!wh) {\n\t\t\tconst res = await this.apiGet(`/command/getObject?oid=${d.oid}&ot=2`);\n\t\t\tconst j = asJson(res.data);\n\t\t\tif (j) {\n\t\t\t\twh = findWH(j, 0);\n\t\t\t}\n\t\t}\n\t\tthis.camAspect[d.oid] = wh ? `${wh[0]}/${wh[1]}` : '';\n\t\tif (wh) {\n\t\t\tthis.log.debug(`cam ${d.oid} resolution ${wh[0]}x${wh[1]} -> AR ${this.camAspect[d.oid]}`);\n\t\t}\n\t}\n\n\t// ---- device folder name ----\n\n\tprivate deviceFolder(d: Device): string {\n\t\treturn `${d.ot === 1 ? 'mic' : 'cam'}_${sanitize(d.oid)}_${sanitize(d.name)}`;\n\t}\n\n\t// ---- device status data points ----\n\n\tprivate readonly STATUS_DPS = [\n\t\t{ key: 'recording', role: 'indicator.working', name: 'Active recording' },\n\t\t{ key: 'online', role: 'indicator.reachable', name: 'Online' },\n\t\t{ key: 'connected', role: 'indicator.connected', name: 'Stream connected' },\n\t\t{ key: 'detected', role: 'indicator', name: 'Motion detected' },\n\t\t{ key: 'alerted', role: 'indicator.alarm', name: 'Alert active' },\n\t] as const;\n\n\tprivate async writeStatusDps(d: Device, fid: string): Promise<void> {\n\t\tconst data = d.raw.data as Record<string, unknown> | undefined;\n\t\tif (!data || typeof data !== 'object') {\n\t\t\treturn;\n\t\t}\n\t\tconst sfid = `${fid}.status`;\n\t\tif (!this.ensuredFolders.has(sfid)) {\n\t\t\tawait this.ensureFolder(sfid, 'Status', 'channel');\n\t\t}\n\t\tfor (const dp of this.STATUS_DPS) {\n\t\t\tif (!(dp.key in data)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = `${sfid}.${dp.key}`;\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: dp.name, type: 'boolean', role: dp.role, read: true, write: false, def: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: !!data[dp.key], ack: true });\n\t\t}\n\t}\n\n\t// ---- build device data points ----\n\n\tprivate async buildDevice(d: Device): Promise<void> {\n\t\tconst fid = this.deviceFolder(d);\n\t\tthis.devById.set(d.oid, d);\n\n\t\tawait this.ensureFolder(fid, d.name, 'device');\n\t\tif (d.ot === 2) {\n\t\t\tawait this.detectAspect(d);\n\t\t}\n\t\tawait this.flattenWrite(d.raw, fid, 0);\n\t\tawait this.writeStatusDps(d, fid);\n\n\t\tawait this.ensureFolder(`${fid}.control`, 'Control', 'channel');\n\t\tfor (const c of CAM_COMMANDS) {\n\t\t\tif (c.id === 'snapshot' && d.ot !== 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.${c.id}`, c.name, {\n\t\t\t\tkind: 'cam',\n\t\t\t\tpath: c.path,\n\t\t\t\tparams: [...c.params],\n\t\t\t\toid: d.oid,\n\t\t\t\tot: d.ot,\n\t\t\t});\n\t\t}\n\n\t\tif (this.config.enablePtz && d.ot === 2) {\n\t\t\tawait this.ensureFolder(`${fid}.control.ptz`, 'PTZ', 'channel');\n\t\t\tfor (const p of PTZ_DIRS) {\n\t\t\t\tconst cid = `${fid}.control.ptz.${p.id}`;\n\t\t\t\tif (p.hold) {\n\t\t\t\t\tawait this.ensureControl(\n\t\t\t\t\t\tcid,\n\t\t\t\t\t\t`PTZ ${p.id} (hold)`,\n\t\t\t\t\t\t{ kind: 'ptzHold', oid: d.oid, dir: p.dir },\n\t\t\t\t\t\t'switch',\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.ensureButton(cid, `PTZ ${p.id}`, { kind: 'ptz', oid: d.oid, dir: p.dir });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.config.enableUrls && d.ot === 2) {\n\t\t\tawait this.ensureFolder(`${fid}.urls`, 'URLs', 'channel');\n\t\t\tawait this.writeLeaf(`${fid}.urls.snapshot`, `${this.baseUrl}/grab.jpg?oid=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.photo`, `${this.baseUrl}/photo.jpg?oid=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.mjpeg`, `${this.baseUrl}/video.mjpg?oids=${d.oid}`);\n\t\t\tawait this.writeLeaf(`${fid}.urls.mp4`, `${this.baseUrl}/video.mp4?oids=${d.oid}`);\n\t\t}\n\n\t\tif (d.ot === 2) {\n\t\t\tconst snapId = `${fid}.snapshot_b64`;\n\t\t\tif (!this.ensuredFolders.has(snapId)) {\n\t\t\t\tawait this.ensurePath(snapId);\n\t\t\t\tawait this.setObjectNotExistsAsync(snapId, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Snapshot (Base64)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'state',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(snapId, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(snapId);\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.refreshSnapshotB64`, 'Refresh snapshot (Base64)', {\n\t\t\t\tkind: 'snapshotB64',\n\t\t\t\toid: d.oid,\n\t\t\t\tfid,\n\t\t\t});\n\t\t\tif (this.config.enableSnapshotB64) {\n\t\t\t\tawait this.fetchSnapshotB64(d.oid, snapId);\n\t\t\t}\n\t\t}\n\n\t\tawait this.updateCameraEvents(d, fid);\n\t}\n\n\t// ---- event formatting ----\n\n\tprivate fmtEvent(\n\t\tev: Record<string, unknown>,\n\t\toid: number | string,\n\t): {\n\t\tfn: string;\n\t\tsizeMB: number;\n\t\tdur: string;\n\t\ttag: string;\n\t\tdate: string;\n\t\ttime: string;\n\t\tthumb: string;\n\t\tvideo: string;\n\t} {\n\t\tconst e = ev as AgentDvrEvent;\n\t\tconst fn = e.fn ?? '';\n\t\tconst dot = fn.lastIndexOf('.');\n\t\tconst jpg = `${dot > 0 ? fn.slice(0, dot) : fn}_large.jpg`;\n\t\tconst sizeMB = e.sb ? Math.round((Number(e.sb) / 1048576) * 100) / 100 : 0;\n\t\tconst dur = e.d != null ? String(e.d) : '';\n\t\tconst tag = e.tg ?? '';\n\t\tconst ms = (parseFloat(String(e.c ?? 0)) - 621355968000000000) / 10000;\n\t\tconst dt = new Date(ms);\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst date = `${two(dt.getDate())}.${two(dt.getMonth() + 1)}.`;\n\t\tconst time = `${two(dt.getHours())}:${two(dt.getMinutes())}`;\n\t\tconst thumb = `${this.baseUrl}/fileThumb.jpg?oid=${oid}&fn=${encodeURIComponent(jpg)}`;\n\t\tconst video = `${this.baseUrl}/streamFile.cgi?oid=${oid}&ot=2&fn=${encodeURIComponent(fn)}`;\n\t\treturn { fn, sizeMB, dur, tag, date, time, thumb, video };\n\t}\n\n\t// ---- gallery HTML builders ----\n\n\tprivate effectiveMinCol(): number {\n\t\tconst sizeMap: Record<string, number> = { small: 120, medium: 180, large: 240 };\n\t\tconst ts = this.config.widgetThumbSize;\n\t\treturn ts && sizeMap[ts] ? sizeMap[ts] : this.config.widgetMinCol || 150;\n\t}\n\n\tprivate async pruneStaleDevices(activeFolders: Set<string>): Promise<void> {\n\t\tconst allObjs = await this.getAdapterObjectsAsync();\n\t\tconst stale: string[] = [];\n\t\tfor (const fullId of Object.keys(allObjs)) {\n\t\t\tconst obj = allObjs[fullId];\n\t\t\tif (obj.type !== 'device') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst rel = fullId.slice(this.namespace.length + 1);\n\t\t\tif (/^(cam|mic)_/.test(rel) && !activeFolders.has(rel)) {\n\t\t\t\tstale.push(rel);\n\t\t\t}\n\t\t}\n\t\tfor (const rel of stale) {\n\t\t\tthis.log.info(`[agent-dvr] removing stale device: ${rel}`);\n\t\t\tawait this.delObjectAsync(rel, { recursive: true });\n\t\t\t// clean up internal cache\n\t\t\tfor (const [oid, d] of this.devById) {\n\t\t\t\tif (this.deviceFolder(d) === rel) {\n\t\t\t\t\tthis.devById.delete(oid);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sortedEvents(events: Record<string, unknown>[]): Record<string, unknown>[] {\n\t\t// newest-first by default; widgetSortNewest=false reverses to oldest-first\n\t\treturn this.config.widgetSortNewest === false ? [...events].reverse() : events;\n\t}\n\n\tprivate buildGalleryHtml(d: Device, events: Record<string, unknown>[]): string {\n\t\treturn (this.config.widgetMode || 'nojs') === 'js'\n\t\t\t? this.buildGalleryHtmlJs(d, events)\n\t\t\t: this.buildGalleryHtmlNojs(d, events);\n\t}\n\n\tprivate buildGalleryHtmlNojs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.effectiveMinCol();\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst showTags = this.config.widgetShowTags;\n\t\tconst pos = (this.config.widgetTagPosition || 'bottom-left').split('-');\n\t\tconst tagStyle = `${pos[0]}:5px;${pos[1]}:5px`;\n\t\tconst playerUrl = (this.config.widgetPlayerUrl || '').trim();\n\t\tconst compact = !!this.config.widgetCompact;\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\n\t\tconst items = this.sortedEvents(events)\n\t\t\t.map((ev, i) => {\n\t\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\t\tconst id = `adv${sanitize(oid)}_${i}`;\n\t\t\t\tconst badge =\n\t\t\t\t\tshowTags && p.tag ? `<span class=\"advtag\" style=\"${tagStyle}\">${escHtml(p.tag)}</span>` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg\"><img src=\"${p.thumb}\" loading=\"lazy\" alt=\"\">${badge}<span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${escHtml(p.date)} ${escHtml(p.time)}<br>${escHtml(p.dur)}s · ${escHtml(p.sizeMB)} MB</span>`;\n\t\t\t\tif (playerUrl) {\n\t\t\t\t\tconst href = playerUrl\n\t\t\t\t\t\t.replace(/{video}/g, encodeURIComponent(p.video))\n\t\t\t\t\t\t.replace(/{videoRaw}/g, p.video)\n\t\t\t\t\t\t.replace(/{fn}/g, encodeURIComponent(p.fn))\n\t\t\t\t\t\t.replace(/{date}/g, encodeURIComponent(p.date))\n\t\t\t\t\t\t.replace(/{time}/g, encodeURIComponent(p.time))\n\t\t\t\t\t\t.replace(/{duration}/g, encodeURIComponent(p.dur))\n\t\t\t\t\t\t.replace(/{size}/g, encodeURIComponent(String(p.sizeMB)))\n\t\t\t\t\t\t.replace(/{tags}/g, encodeURIComponent(p.tag));\n\t\t\t\t\treturn `<a class=\"advcell\" href=\"${escHtml(href)}\" target=\"_blank\" rel=\"noopener\">${inner}</a>`;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">✕</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${p.video}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${escHtml(p.date)} ${escHtml(p.time)} · ${escHtml(p.dur)}s · ${escHtml(p.sizeMB)} MB${\n\t\t\t\t\t\tp.tag ? ` · ${escHtml(p.tag)}` : ''\n\t\t\t\t\t} · <a href=\"${p.video}\" download target=\"_blank\">${this.wt.download}</a></div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\n\t\tconst gridClass = compact ? 'advgrid advcompact' : 'advgrid';\n\t\tconst grid = items\n\t\t\t? `<div class=\"${gridClass}\">${items}</div>`\n\t\t\t: `<div class=\"advempty\">${this.wt.noRecordings}</div>`;\n\t\tconst colors: WidgetColors = {\n\t\t\tcardBg: this.config.widgetColorCardBg || undefined,\n\t\t\ttagBg: this.config.widgetColorTagBg || undefined,\n\t\t\ttagText: this.config.widgetColorTagText || undefined,\n\t\t\taccent: this.config.widgetColorAccent || undefined,\n\t\t\tmodalBg: this.config.widgetColorModalBg || undefined,\n\t\t\tradius: this.config.widgetBorderRadius,\n\t\t};\n\t\treturn `<style>${galleryCss(minCol, maxW, compact, colors)}</style>${grid}`;\n\t}\n\n\tprivate buildGalleryHtmlJs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.effectiveMinCol();\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst showSearch = this.config.widgetShowSearch !== false;\n\t\tconst compact = !!this.config.widgetCompact;\n\t\tconst defaultTag = (this.config.widgetDefaultTag || '').trim();\n\t\tconst items = this.sortedEvents(events).map(ev => {\n\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\treturn {\n\t\t\t\tfn: p.fn,\n\t\t\t\tdate: p.date,\n\t\t\t\ttime: p.time,\n\t\t\t\tdur: p.dur,\n\t\t\t\tsize: p.sizeMB,\n\t\t\t\ttag: p.tag,\n\t\t\t\tthumb: p.thumb,\n\t\t\t\tvideo: p.video,\n\t\t\t};\n\t\t});\n\t\tconst cfg = {\n\t\t\tmin_col: minCol,\n\t\t\tshow_tags: !!this.config.widgetShowTags,\n\t\t\tmax_modal_width: maxW,\n\t\t\tlive_aspect: this.camAspect[oid] || this.config.widgetLiveAspect || '',\n\t\t\tplayer_url: (this.config.widgetPlayerUrl || '').trim(),\n\t\t\ttag_position: this.config.widgetTagPosition || 'bottom-left',\n\t\t\tcompact,\n\t\t\tdefault_tag: defaultTag,\n\t\t\tlabels: { noRecordings: this.wt.noRecordings, all: this.wt.all, live: this.wt.live },\n\t\t};\n\t\tconst data = JSON.stringify({ items, live: null, cfg }).replace(/</g, '\\\\u003c');\n\t\tconst boot = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';\n\t\tconst searchHtml = showSearch\n\t\t\t? `<input class=\"advsearchjs\" type=\"text\" placeholder=\"${escHtml(this.wt.search)}\">`\n\t\t\t: '';\n\t\tconst colors: WidgetColors = {\n\t\t\tcardBg: this.config.widgetColorCardBg || undefined,\n\t\t\ttagBg: this.config.widgetColorTagBg || undefined,\n\t\t\ttagText: this.config.widgetColorTagText || undefined,\n\t\t\taccent: this.config.widgetColorAccent || undefined,\n\t\t\tmodalBg: this.config.widgetColorModalBg || undefined,\n\t\t\tradius: this.config.widgetBorderRadius,\n\t\t};\n\t\treturn (\n\t\t\t`<style>${galleryCssJs(minCol, compact, colors)}</style>` +\n\t\t\t`<div class=\"advroot\"><script type=\"application/json\" class=\"advdata\">${data}</script>` +\n\t\t\t`<div class=\"advbar\">${searchHtml}<div class=\"advtagsjs\"></div></div>` +\n\t\t\t`<div class=\"advgridjs\"></div></div>` +\n\t\t\t`<script type=\"text/plain\" class=\"advcode\">${ADV_CLIENT_CODE}</script>` +\n\t\t\t`<img alt=\"\" src=\"${boot}\" style=\"display:none\" onload=\"(function(){if(window.ADVscan){window.ADVscan();return;}var c=document.querySelector('script.advcode');if(!c)return;var s=document.createElement('script');s.textContent=c.textContent;document.body.appendChild(s);})()\">`\n\t\t);\n\t}\n\n\tprivate buildOverviewHtml(cams: Device[]): string {\n\t\tconst ts = Date.now();\n\t\tconst minCol = this.config.widgetMinCol || 150;\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\t\tconst tiles = cams\n\t\t\t.map(d => {\n\t\t\t\tconst oid = d.oid;\n\t\t\t\tconst id = `advlive${sanitize(oid)}`;\n\t\t\t\tconst grab = `${this.baseUrl}/grab.jpg?oid=${oid}&ot=2&maintainAR=1&ts=${ts}`;\n\t\t\t\tconst webm = `${this.baseUrl}/video.webm?oid=${oid}&ot=2`;\n\t\t\t\tconst name = escHtml(d.name || `Camera ${oid}`);\n\t\t\t\tconst arRaw = this.camAspect[oid] || this.config.widgetLiveAspect || '';\n\t\t\t\tconst ar = arRaw ? String(arRaw).replace('/', ' / ') : '';\n\t\t\t\tconst fix = ar ? ' advimgfix' : '';\n\t\t\t\tconst arStyle = ar ? ` style=\"aspect-ratio:${ar}\"` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg${fix}\"${arStyle}><img src=\"${grab}\" loading=\"lazy\" alt=\"\">` +\n\t\t\t\t\t`<span class=\"advtag\" style=\"top:5px;left:5px\">● ${escHtml(this.wt.live)}</span><span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${name}</span>`;\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">✕</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${webm}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${name} · Live</div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\t\tconst grid = tiles ? `<div class=\"advgrid\">${tiles}</div>` : `<div class=\"advempty\">No cameras</div>`;\n\t\treturn `<style>${galleryCss(minCol, maxW)}</style>${grid}`;\n\t}\n\n\t// ---- event data points ----\n\n\tprivate async writeEventDps(d: Device, fid: string, events: Record<string, unknown>[]): Promise<void> {\n\t\tconst oid = d.oid;\n\t\tawait this.ensureFolder(`${fid}.events`, 'Events', 'channel');\n\t\tawait this.ensureFolder(`${fid}.events.last`, 'Last event', 'channel');\n\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst now = new Date();\n\t\tconst td = `${two(now.getDate())}.${two(now.getMonth() + 1)}.`;\n\t\tconst todayCount = events.filter(ev => this.fmtEvent(ev, oid).date === td).length;\n\n\t\tawait this.writeLeaf(`${fid}.events.count`, events.length);\n\t\tawait this.writeLeaf(`${fid}.events.today`, todayCount);\n\n\t\tif (events.length) {\n\t\t\tconst p = this.fmtEvent(events[0], oid);\n\t\t\tconst tsMs = (parseFloat(String((events[0] as AgentDvrEvent).c ?? 0)) - 621355968000000000) / 10000;\n\t\t\tawait this.writeLeaf(`${fid}.events.last.time`, `${p.date} ${p.time}`);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.timestamp`, Math.round(tsMs));\n\t\t\tawait this.writeLeaf(`${fid}.events.last.tag`, p.tag);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.duration`, p.dur ? parseFloat(p.dur) : 0);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.size_mb`, p.sizeMB);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.thumb`, p.thumb);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.video`, p.video);\n\t\t}\n\n\t\t// JSON list for web UI \u2014 browser never needs to talk to AgentDVR for recordings\n\t\tconst jsonId = `${fid}.events.json`;\n\t\tif (!this.ensuredFolders.has(jsonId)) {\n\t\t\tawait this.ensurePath(jsonId);\n\t\t\tawait this.setObjectNotExistsAsync(jsonId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: 'Recordings list (web UI)', type: 'string', role: 'json', read: true, write: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tthis.ensuredFolders.add(jsonId);\n\t\t}\n\t\tawait this.setStateAsync(jsonId, {\n\t\t\tval: JSON.stringify(\n\t\t\t\tevents.slice(0, Math.max(1, this.config.widgetAnzahl || 50)).map(ev => {\n\t\t\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdate: p.date,\n\t\t\t\t\t\ttime: p.time,\n\t\t\t\t\t\tdur: p.dur,\n\t\t\t\t\t\tsize: p.sizeMB,\n\t\t\t\t\t\ttag: p.tag,\n\t\t\t\t\t\tthumb: p.thumb,\n\t\t\t\t\t\tvideo: p.video,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t),\n\t\t\tack: true,\n\t\t});\n\n\t\tawait this.ensureFlag(`${fid}.events.new`, 'New event');\n\n\t\tif (this.config.enablePush) {\n\t\t\tconst pid = `${fid}.events.pushTrigger`;\n\t\t\tif (!this.ensuredFolders.has(pid)) {\n\t\t\t\tawait this.ensurePath(pid);\n\t\t\t\tawait this.setObjectNotExistsAsync(pid, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Push trigger (AgentDVR action)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'text',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\tdef: '',\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(pid, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(pid);\n\t\t\t}\n\t\t\tthis.registry.set(pid, { kind: 'push', oid, fid });\n\t\t}\n\n\t\tconst ignore = (this.config.eventTagsIgnore || 'detected')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim().toLowerCase())\n\t\t\t.filter(Boolean);\n\t\tconst tokensOf = (s: string): string[] =>\n\t\t\ts\n\t\t\t\t.toLowerCase()\n\t\t\t\t.split(/[,\\s]+/)\n\t\t\t\t.filter(Boolean);\n\n\t\tfor (const kw of (this.config.eventTags || '')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim())\n\t\t\t.filter(Boolean)) {\n\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(kw)}`, `Detected: ${kw}`);\n\t\t}\n\n\t\tif (this.config.eventTagsDynamic) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const ev of events) {\n\t\t\t\ttokensOf((ev as AgentDvrEvent).tg ?? '').forEach(t => seen.add(t));\n\t\t\t}\n\t\t\tfor (const t of seen) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(t)}`, `Detected: ${t}`);\n\t\t\t}\n\t\t}\n\n\t\tlet newCount = 0;\n\t\tif (events.length) {\n\t\t\tconst prev = this.lastEventFn[oid];\n\t\t\tif (prev !== undefined) {\n\t\t\t\tconst i = events.findIndex(e => (e as AgentDvrEvent).fn === prev);\n\t\t\t\tnewCount = i === -1 ? events.length : i;\n\t\t\t}\n\t\t\tthis.lastEventFn[oid] = (events[0] as AgentDvrEvent).fn ?? '';\n\t\t}\n\n\t\tif (newCount > 0) {\n\t\t\tawait this.pulse(`${fid}.events.new`);\n\t\t\tconst tags = new Set<string>();\n\t\t\tfor (let i = 0; i < newCount && i < events.length; i++) {\n\t\t\t\ttokensOf((events[i] as AgentDvrEvent).tg ?? '').forEach(t => tags.add(t));\n\t\t\t}\n\t\t\tfor (const t of tags) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst tid = `${fid}.events.detected_${sanitize(t)}`;\n\t\t\t\tawait this.ensureFlag(tid, `Detected: ${t}`);\n\t\t\t\tawait this.pulse(tid);\n\t\t\t}\n\t\t\tthis.log.debug(`${newCount} new event(s) cam ${oid} [${[...tags].join(',')}]`);\n\t\t}\n\t}\n\n\t// ---- camera events + widget ----\n\n\tprivate async updateCameraEvents(d: Device, fid: string): Promise<void> {\n\t\tif (d.ot !== 2) {\n\t\t\treturn;\n\t\t}\n\t\tif (!this.config.enableWidget && !this.config.enableEventDps) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.eventBusy[d.oid]) {\n\t\t\treturn;\n\t\t}\n\t\tthis.eventBusy[d.oid] = true;\n\t\ttry {\n\t\t\tconst evRes = await this.apiGet(`/q/getEvents?oid=${d.oid}&ot=2`);\n\t\t\tconst evJson = asJson(evRes.data);\n\t\t\tif (!evJson) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst events = (\n\t\t\t\tArray.isArray(evJson.events) ? evJson.events : Array.isArray(evJson) ? evJson : []\n\t\t\t) as Record<string, unknown>[];\n\n\t\t\tif (this.config.enableEventDps) {\n\t\t\t\tawait this.writeEventDps(d, fid, events);\n\t\t\t}\n\n\t\t\tif (this.config.enableWidget) {\n\t\t\t\tconst wId = `${fid}.widget`;\n\t\t\t\tif (!this.ensuredFolders.has(wId)) {\n\t\t\t\t\tawait this.ensurePath(wId);\n\t\t\t\t\tawait this.setObjectNotExistsAsync(wId, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'HTML gallery widget',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\tdef: '',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tthis.ensuredFolders.add(wId);\n\t\t\t\t}\n\t\t\t\tconst ev = events.slice(0, Math.max(1, this.config.widgetAnzahl || 50));\n\t\t\t\tconst f = (ev[0] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst l = (ev[ev.length - 1] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst sig = `${ev.length}|${f.fn ?? ''}|${l.fn ?? ''}`;\n\t\t\t\tif (this.widgetSig[wId] !== sig) {\n\t\t\t\t\tawait this.setStateAsync(wId, { val: this.buildGalleryHtml(d, ev), ack: true });\n\t\t\t\t\tthis.widgetSig[wId] = sig;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.eventBusy[d.oid] = false;\n\t\t}\n\t}\n\n\tprivate pushRefresh(oid: number | string): void {\n\t\tconst d = this.devById.get(oid);\n\t\tif (!d) {\n\t\t\tthis.log.warn(`Push: camera ${oid} unknown (available after first poll)`);\n\t\t\treturn;\n\t\t}\n\t\tconst fid = this.deviceFolder(d);\n\t\tfor (const ms of [0, 1500, 3500, 6000]) {\n\t\t\tthis.setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\tthis.updateCameraEvents(d, fid).catch(e =>\n\t\t\t\t\t\tthis.log.warn(`Push refresh error: ${(e as Error).message}`),\n\t\t\t\t\t),\n\t\t\t\tms,\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- main poll ----\n\n\tprivate async poll(): Promise<void> {\n\t\tif (this.pollBusy) {\n\t\t\tthis.log.debug('poll() skipped \u2014 previous run still in progress');\n\t\t\treturn;\n\t\t}\n\t\tthis.pollBusy = true;\n\t\ttry {\n\t\t\tconst res = await this.apiGet('/command/getObjects');\n\t\t\tconst json = asJson(res.data);\n\n\t\t\tif (!res.ok || !json) {\n\t\t\t\tawait this.setStateAsync('info.connection', false, true);\n\t\t\t\tawait this.setStateAsync('system.online', { val: false, ack: true });\n\t\t\t\tthis.log.warn(`AgentDVR unreachable: ${res.error || 'invalid response'}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait this.setStateAsync('info.connection', true, true);\n\t\t\tawait this.setStateAsync('system.online', { val: true, ack: true });\n\n\t\t\tif (json.settings) {\n\t\t\t\tawait this.flattenWrite(json.settings, 'system.settings', 0);\n\t\t\t}\n\n\t\t\tif (this.config.storeRawJson) {\n\t\t\t\tconst clean: Record<string, unknown> = { ...json };\n\t\t\t\tdelete clean.icons;\n\t\t\t\tawait this.writeLeaf('system.raw_getObjects', JSON.stringify(clean).slice(0, 60000));\n\t\t\t}\n\n\t\t\tconst devices = findDevices(json);\n\t\t\tthis.lastCamNames = devices.filter(d => d.ot === 2).map(d => ({ key: this.deviceFolder(d), name: d.name }));\n\t\t\tawait this.setStateAsync('system.cameraCount', { val: devices.filter(d => d.ot === 2).length, ack: true });\n\n\t\t\tconst activeFolders = new Set(devices.map(d => this.deviceFolder(d)));\n\t\t\tfor (const d of devices) {\n\t\t\t\tawait this.buildDevice(d);\n\t\t\t}\n\t\t\tawait this.pruneStaleDevices(activeFolders);\n\n\t\t\tconst stats = asJson((await this.apiGet('/command/getSystemStats')).data);\n\t\t\tif (stats) {\n\t\t\t\tawait this.flattenWrite(stats, 'system.stats', 0);\n\t\t\t\tconst gb = parseSizeGb(stats.disk_free);\n\t\t\t\tif (gb !== null) {\n\t\t\t\t\tawait this.writeLeaf('system.disk_free_gb', gb);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst status = asJson((await this.apiGet('/command/getStatus')).data);\n\t\t\tif (status) {\n\t\t\t\tawait this.flattenWrite(status, 'system.status', 0);\n\t\t\t}\n\n\t\t\tif (this.config.enableSystemControls && Array.isArray(json.profiles)) {\n\t\t\t\tconst states: Record<number, string> = {};\n\t\t\t\tlet activeInd: number | null = null;\n\t\t\t\tfor (const p of json.profiles) {\n\t\t\t\t\tif (p && typeof p === 'object') {\n\t\t\t\t\t\tconst po = p as Record<string, unknown>;\n\t\t\t\t\t\tconst ind = po.id ?? po.ind ?? po.index;\n\t\t\t\t\t\tconst pname = po.name;\n\t\t\t\t\t\tif (typeof ind === 'number' && (typeof pname === 'string' || typeof pname === 'number')) {\n\t\t\t\t\t\t\tstates[ind] = String(pname);\n\t\t\t\t\t\t\tif (po.active === true) {\n\t\t\t\t\t\t\t\tactiveInd = ind;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(states).length > 0) {\n\t\t\t\t\tconst sig = JSON.stringify(states);\n\t\t\t\t\tif (sig !== this.profileSig) {\n\t\t\t\t\t\tthis.profileSig = sig;\n\t\t\t\t\t\tawait this.extendObjectAsync('system.profile.selector', { common: { states } });\n\t\t\t\t\t\tawait this.setStateAsync('system.profile.list', { val: sig, ack: true });\n\t\t\t\t\t}\n\t\t\t\t\tif (activeInd !== null) {\n\t\t\t\t\t\tawait this.setStateAsync('system.profile.selector', { val: activeInd, ack: true });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.config.enableOverview) {\n\t\t\t\tconst cams = devices.filter(d => d.ot === 2);\n\t\t\t\tconst ovId = 'overview';\n\t\t\t\tif (!this.ensuredFolders.has(ovId)) {\n\t\t\t\t\tawait this.setObjectNotExistsAsync(ovId, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'Overview (all cameras)',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\tdef: '',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tthis.ensuredFolders.add(ovId);\n\t\t\t\t}\n\t\t\t\tawait this.setStateAsync(ovId, { val: this.buildOverviewHtml(cams), ack: true });\n\t\t\t}\n\n\t\t\tawait this.setStateAsync('system.lastUpdate', { val: new Date().toISOString(), ack: true });\n\t\t\tawait this.setStateAsync('system.lastPoll', { val: Date.now(), ack: true });\n\t\t} finally {\n\t\t\tthis.pollBusy = false;\n\t\t}\n\t}\n\n\tprivate scheduleRefresh(): void {\n\t\tif (this.refreshTimer !== undefined) {\n\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = undefined;\n\t\t}\n\t\tthis.refreshTimer = this.setTimeout(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Refresh error: ${(e as Error).message}`)),\n\t\t\t1500,\n\t\t);\n\t}\n\n\t// ---- command execution ----\n\n\tprivate ptzUrl(oid: number | string, dir: number): string {\n\t\treturn `/ptz.cgi?oid=${encodeURIComponent(String(oid))}&dir=${dir}`;\n\t}\n\n\tprivate buildCommandUrl(entry: RegistryEntry): string {\n\t\tif (entry.kind === 'ptz') {\n\t\t\treturn this.ptzUrl(entry.oid!, entry.dir!);\n\t\t}\n\t\tif (entry.kind === 'sys') {\n\t\t\treturn entry.path as string;\n\t\t}\n\t\tconst qs: string[] = [];\n\t\tfor (const p of entry.params || []) {\n\t\t\tif (p === 'oid') {\n\t\t\t\tqs.push(`oid=${encodeURIComponent(String(entry.oid))}`);\n\t\t\t} else if (p === 'ot') {\n\t\t\t\tqs.push(`ot=${encodeURIComponent(String(entry.ot))}`);\n\t\t\t}\n\t\t}\n\t\treturn (entry.path || '') + (qs.length ? `?${qs.join('&')}` : '');\n\t}\n\n\tprivate async clearPtzSiblings(stateId: string): Promise<void> {\n\t\tconst prefix = stateId.slice(0, stateId.lastIndexOf('.') + 1);\n\t\tfor (const p of PTZ_DIRS) {\n\t\t\tif (!p.hold) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst sid = prefix + p.id;\n\t\t\tif (sid !== stateId) {\n\t\t\t\tawait this.setStateAsync(sid, { val: false, ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async runCommand(relId: string, entry: RegistryEntry, val: ioBroker.StateValue): Promise<void> {\n\t\tif (entry.kind === 'setProfile') {\n\t\t\tconst ind = typeof val === 'number' ? val : parseInt(String(val ?? ''), 10);\n\t\t\tif (!isNaN(ind)) {\n\t\t\t\tconst url = `/command/setProfile?ind=${ind}`;\n\t\t\t\tconst cmdRes = await this.apiGet(url);\n\t\t\t\tif (cmdRes.ok) {\n\t\t\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t\t\t\tawait this.setStateAsync(relId, { val: ind, ack: true });\n\t\t\t\t} else {\n\t\t\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t\t\t}\n\t\t\t\tthis.scheduleRefresh();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'snapshotB64') {\n\t\t\tconst snapId = `${entry.fid}.snapshot_b64`;\n\t\t\tawait this.fetchSnapshotB64(entry.oid!, snapId);\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'push') {\n\t\t\tthis.log.info(`Push trigger cam ${entry.oid}`);\n\t\t\tawait this.setStateAsync(relId, { val: '', ack: true });\n\t\t\tthis.pushRefresh(entry.oid!);\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'ptzHold') {\n\t\t\tconst oid = entry.oid!;\n\t\t\tconst startMove = async (): Promise<void> => {\n\t\t\t\tawait this.clearPtzSiblings(relId);\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, entry.dir!));\n\t\t\t\tthis.ptzActive.set(oid, relId);\n\t\t\t\tawait this.setStateAsync(relId, { val: true, ack: true });\n\t\t\t};\n\t\t\tconst stopMove = async (): Promise<void> => {\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, 11));\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tthis.ptzActive.delete(oid);\n\t\t\t\t}\n\t\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\t};\n\t\t\tif (val) {\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tawait stopMove();\n\t\t\t\t} else {\n\t\t\t\t\tawait startMove();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait stopMove();\n\t\t\t}\n\t\t\tthis.scheduleRefresh();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!val) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'sys' && entry.path === null) {\n\t\t\tawait this.poll().catch(e => this.log.warn(`Manual refresh error: ${(e as Error).message}`));\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = this.buildCommandUrl(entry);\n\t\tconst cmdRes = await this.apiGet(url);\n\t\tif (cmdRes.ok) {\n\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t} else {\n\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t}\n\n\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\tthis.scheduleRefresh();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AgentDvr(options);\n} else {\n\t(() => new AgentDvr())();\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import * as utils from '@iobroker/adapter-core';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\nimport { getWidgetLabels, type WidgetLabels } from './lib/widget-i18n';\n\n// =====================================================================\n// Agent DVR -> ioBroker Adapter\n// API reference: https://ispysoftware.github.io/Agent_API/ (v7.5)\n// =====================================================================\n\n// ---- Types ----\n\ninterface ApiResult {\n\tok: boolean;\n\tdata?: string;\n\terror?: string;\n}\n\ninterface AgentDvrEvent {\n\tfn?: string;\n\ttg?: string;\n\tc?: number;\n\td?: number | string;\n\tsb?: number;\n\t[key: string]: unknown;\n}\n\ninterface Device {\n\toid: number | string;\n\tot: number;\n\tname: string;\n\traw: Record<string, unknown>;\n}\n\ntype RegistryKind = 'cam' | 'sys' | 'ptz' | 'ptzHold' | 'push' | 'setProfile' | 'snapshotB64' | 'levelCmd';\n\ninterface RegistryEntry {\n\tkind: RegistryKind;\n\tpath?: string | null;\n\tparams?: string[];\n\toid?: number | string;\n\tot?: number;\n\tdir?: number;\n\tfid?: string;\n\tvalueParam?: string;\n}\n\n// ---- Commands ----\n\nconst CAM_COMMANDS = [\n\t{ id: 'record', path: '/command/record', params: ['oid', 'ot'], name: 'Start recording' },\n\t{ id: 'recordStop', path: '/command/recordStop', params: ['oid', 'ot'], name: 'Stop recording' },\n\t{ id: 'recordRestart', path: '/command/recordRestart', params: ['oid', 'ot'], name: 'Restart recording' },\n\t{ id: 'triggerRecord', path: '/command/triggerRecord', params: ['oid', 'ot'], name: 'Trigger recording (timeout)' },\n\t{ id: 'snapshot', path: '/command/snapshot', params: ['oid'], name: 'Take snapshot' },\n\t{ id: 'detect', path: '/command/detect', params: ['oid', 'ot'], name: 'Trigger motion detection' },\n\t{ id: 'alertOn', path: '/command/alertOn', params: ['oid', 'ot'], name: 'Arm alerts' },\n\t{ id: 'alertOff', path: '/command/alertOff', params: ['oid', 'ot'], name: 'Disarm alerts' },\n\t{ id: 'switchOn', path: '/command/switchOn', params: ['oid', 'ot'], name: 'Switch device on' },\n\t{ id: 'switchOff', path: '/command/switchOff', params: ['oid', 'ot'], name: 'Switch device off' },\n\t{ id: 'objectDetectOn', path: '/command/objectdetecton', params: ['oid', 'ot'], name: 'Enable object detection' },\n\t{\n\t\tid: 'objectDetectOff',\n\t\tpath: '/command/objectdetectoff',\n\t\tparams: ['oid', 'ot'],\n\t\tname: 'Disable object detection',\n\t},\n\t{ id: 'recOnAlert', path: '/command/recordOnAlertOn', params: ['oid', 'ot'], name: 'Record on alert: on' },\n\t{ id: 'recOnDetect', path: '/command/recordOnDetectOn', params: ['oid', 'ot'], name: 'Record on detect: on' },\n\t{ id: 'scheduleOn', path: '/command/scheduleOn', params: ['oid', 'ot'], name: 'Enable schedule' },\n\t{ id: 'scheduleOff', path: '/command/scheduleOff', params: ['oid', 'ot'], name: 'Disable schedule' },\n\t{ id: 'detectorOn', path: '/command/switchDetector?on=true', params: ['oid', 'ot'], name: 'Enable detector' },\n\t{ id: 'detectorOff', path: '/command/switchDetector?on=false', params: ['oid', 'ot'], name: 'Disable detector' },\n\t{ id: 'purge', path: '/command/purge', params: ['oid', 'ot'], name: 'Purge folder (caution!)' },\n] as const;\n\nconst SYS_COMMANDS = [\n\t{ id: 'arm', path: '/command/arm', name: 'Arm system' },\n\t{ id: 'disarm', path: '/command/disarm', name: 'Disarm system' },\n\t{ id: 'allOn', path: '/command/allOn', name: 'All devices on' },\n\t{ id: 'allOff', path: '/command/allOff', name: 'All devices off' },\n\t{ id: 'reloadConfig', path: '/command/reloadConfig', name: 'Reload config' },\n\t{ id: 'reloadObjects', path: '/command/reloadObjects', name: 'Reload objects' },\n\t{ id: 'runStorageMgmt', path: '/command/runStorageMgmt', name: 'Run storage management' },\n\t{ id: 'blockExternal', path: '/command/blockExternal', name: 'Block external access' },\n\t{ id: 'unblockExternal', path: '/command/unblockExternal', name: 'Unblock external access' },\n\t{ id: 'restart', path: '/command/restart', name: 'Restart Agent DVR' },\n\t{ id: 'refresh', path: null, name: 'Refresh data now' },\n] as const;\n\nconst PTZ_DIRS = [\n\t{ id: 'left', dir: 1, hold: true },\n\t{ id: 'upLeft', dir: 2, hold: true },\n\t{ id: 'up', dir: 3, hold: true },\n\t{ id: 'upRight', dir: 4, hold: true },\n\t{ id: 'right', dir: 5, hold: true },\n\t{ id: 'downRight', dir: 6, hold: true },\n\t{ id: 'down', dir: 7, hold: true },\n\t{ id: 'downLeft', dir: 8, hold: true },\n\t{ id: 'zoomIn', dir: 9, hold: true },\n\t{ id: 'zoomOut', dir: 10, hold: true },\n\t{ id: 'stop', dir: 11, hold: false },\n\t{ id: 'center', dir: 0, hold: false },\n] as const;\n\nconst SKIP_KEYS = ['icons', 'image', 'thumbnail', 'base64'];\n\n// ---- Module-level helpers ----\n\nfunction sanitize(s: unknown): string {\n\treturn (\n\t\tString(s)\n\t\t\t.replace(/[\\s.[\\]*?\"'`,;:/\\\\]+/g, '_')\n\t\t\t.replace(/[^A-Za-z0-9_-]/g, '_')\n\t\t\t.replace(/_+/g, '_')\n\t\t\t.replace(/^_+|_+$/g, '') || 'x'\n\t);\n}\n\nfunction asJson(data: unknown): Record<string, unknown> | null {\n\tif (data == null) {\n\t\treturn null;\n\t}\n\tif (typeof data === 'object') {\n\t\treturn data as Record<string, unknown>;\n\t}\n\tif (typeof data === 'string') {\n\t\ttry {\n\t\t\treturn JSON.parse(data) as Record<string, unknown>;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction toStr(v: unknown): string {\n\tif (v == null) {\n\t\treturn '';\n\t}\n\tif (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n\t\treturn String(v);\n\t}\n\treturn Object.prototype.toString.call(v);\n}\n\nfunction escHtml(s: unknown): string {\n\treturn toStr(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction parseSizeGb(s: unknown): number | null {\n\tif (s == null) {\n\t\treturn null;\n\t}\n\tconst m = toStr(s)\n\t\t.trim()\n\t\t.match(/([\\d.,]+)\\s*([KMGT]?B)?/i);\n\tif (!m) {\n\t\treturn null;\n\t}\n\tlet v = parseFloat(m[1].replace(',', '.'));\n\tif (isNaN(v)) {\n\t\treturn null;\n\t}\n\tconst u = (m[2] || 'GB').toUpperCase();\n\tif (u === 'TB') {\n\t\tv *= 1024;\n\t} else if (u === 'MB') {\n\t\tv /= 1024;\n\t} else if (u === 'KB') {\n\t\tv /= 1048576;\n\t} else if (u === 'B') {\n\t\tv /= 1073741824;\n\t}\n\treturn Math.round(v * 100) / 100;\n}\n\nfunction findWH(obj: unknown, depth: number): [number, number] | null {\n\tif (!obj || typeof obj !== 'object' || depth > 5) {\n\t\treturn null;\n\t}\n\tconst o = obj as Record<string, unknown>;\n\tfor (const [kw, kh] of [\n\t\t['width', 'height'],\n\t\t['w', 'h'],\n\t\t['sourceWidth', 'sourceHeight'],\n\t\t['videoWidth', 'videoHeight'],\n\t\t['imageWidth', 'imageHeight'],\n\t]) {\n\t\tconst w = o[kw],\n\t\t\th = o[kh];\n\t\tif (typeof w === 'number' && typeof h === 'number' && w >= 100 && h >= 100 && w <= 12000 && h <= 12000) {\n\t\t\tconst r = w / h;\n\t\t\tif (r >= 0.3 && r <= 4) {\n\t\t\t\treturn [w, h];\n\t\t\t}\n\t\t}\n\t}\n\tfor (const k of Object.keys(o)) {\n\t\tconst g = findWH(o[k], depth + 1);\n\t\tif (g) {\n\t\t\treturn g;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction detectOt(elem: Record<string, unknown>): number {\n\tconst v = elem.typeID ?? elem.ot ?? elem.objectTypeID ?? elem.type;\n\treturn v === 1 || v === 2 ? v : 2;\n}\n\nfunction findDevices(json: Record<string, unknown>): Device[] {\n\tconst list = Array.isArray(json.objectList) ? json.objectList : [];\n\tconst out: Device[] = [];\n\tfor (const e of list) {\n\t\tif (!e || typeof e !== 'object') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst el = e as Record<string, unknown>;\n\t\tconst rawId = el.id ?? el.oid;\n\t\tif (rawId === undefined || rawId === null) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst id = rawId as number | string;\n\t\tconst name = typeof el.name === 'string' ? el.name : `obj_${id}`;\n\t\tout.push({ oid: id, ot: detectOt(el), name, raw: el });\n\t}\n\treturn out;\n}\n\n// ---- HTML/CSS gallery helpers ----\n\ninterface WidgetColors {\n\tcardBg?: string;\n\ttagBg?: string;\n\ttagText?: string;\n\taccent?: string;\n\tmodalBg?: string;\n\tradius?: number;\n}\n\nfunction advCssVars(c?: WidgetColors): string {\n\tconst cardBg = c?.cardBg || 'rgba(127,127,127,.15)';\n\tconst tagBg = c?.tagBg || 'rgba(0,0,0,.55)';\n\tconst tagText = c?.tagText || '#fff';\n\tconst accent = c?.accent || '#8ab4f8';\n\tconst modalBg = c?.modalBg || '#1c1c1e';\n\tconst radius = c?.radius != null ? `${c.radius}px` : '8px';\n\treturn `--adv-card-bg:${cardBg};--adv-tag-bg:${tagBg};--adv-tag-color:${tagText};--adv-accent:${accent};--adv-modal-bg:${modalBg};--adv-radius:${radius};`;\n}\n\nfunction galleryCss(minCol: number, maxW: number, compact = false, colors?: WidgetColors): string {\n\tconst gap = compact ? 6 : 12;\n\treturn (\n\t\t`.advgrid{${advCssVars(colors)}display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:${gap}px;max-width:100%}` +\n\t\t`.advgrid .advlb{display:none}` +\n\t\t`.advcell{display:flex;flex-direction:column;cursor:pointer;text-decoration:none;color:inherit;font-family:inherit}` +\n\t\t`.advimg{position:relative;display:block;border-radius:var(--adv-radius);overflow:hidden;background:var(--adv-card-bg)}` +\n\t\t`.advimg img{width:100%;height:auto;display:block}` +\n\t\t`.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtag{position:absolute;background:var(--adv-tag-bg);color:var(--adv-tag-color);font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplay::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcell:hover .advplay{opacity:1}` +\n\t\t`.advcap{font-size:${compact ? '.65rem' : '.72rem'};margin-top:${compact ? 2 : 4}px;line-height:1.25;opacity:.85}` +\n\t\t`.advmodal{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}` +\n\t\t`.advgrid .advlb:checked + .advthumb + .advmodal{display:flex}` +\n\t\t`.advbackdrop{position:absolute;inset:0;background:transparent;cursor:pointer}` +\n\t\t`.advbox{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,${maxW}px);background:var(--adv-modal-bg);padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}` +\n\t\t`.advvideo{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}` +\n\t\t`.advclose{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}` +\n\t\t`.advinfo{color:#fff;font-size:.8rem;text-align:center}` +\n\t\t`.advinfo a{color:var(--adv-accent)}` +\n\t\t`.advempty{padding:24px;text-align:center;opacity:.7;font-family:inherit}`\n\t);\n}\n\nfunction galleryCssJs(minCol: number, compact = false, colors?: WidgetColors): string {\n\tconst gap = compact ? 6 : 12;\n\treturn (\n\t\t`.advroot{${advCssVars(colors)}font-family:inherit;color:inherit}` +\n\t\t`.advbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:10px}` +\n\t\t`.advsearchjs{flex:1 1 160px;min-width:120px;padding:6px 10px;border-radius:8px;border:1px solid rgba(127,127,127,.4);background:rgba(127,127,127,.08);color:inherit;font:inherit}` +\n\t\t`.advtagsjs{display:flex;flex-wrap:wrap;gap:6px}` +\n\t\t`.advtagbtn{padding:4px 10px;border-radius:999px;border:1px solid rgba(127,127,127,.4);background:transparent;color:inherit;cursor:pointer;font:inherit;font-size:.8rem}` +\n\t\t`.advtagbtn.on{background:var(--adv-accent);color:#fff;border-color:var(--adv-accent)}` +\n\t\t`.advgridjs{display:grid;grid-template-columns:repeat(auto-fill,minmax(${minCol}px,1fr));gap:${gap}px}` +\n\t\t`.advcelljs{display:flex;flex-direction:column;cursor:pointer}` +\n\t\t`.advimgjs{position:relative;display:block;border-radius:var(--adv-radius);overflow:hidden;background:var(--adv-card-bg)}` +\n\t\t`.advimgjs img{width:100%;height:auto;display:block}` +\n\t\t`.advimgjs.advimgfix img{height:100%;object-fit:cover}` +\n\t\t`.advtagjs{position:absolute;background:var(--adv-tag-bg);color:var(--adv-tag-color);font-size:.6rem;padding:2px 4px;border-radius:3px;line-height:1;max-width:85%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}` +\n\t\t`.advplayjs{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s;background:rgba(0,0,0,.2)}` +\n\t\t`.advplayjs::before{content:\"\";border-style:solid;border-width:11px 0 11px 18px;border-color:transparent transparent transparent #fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}` +\n\t\t`.advcelljs:hover .advplayjs{opacity:1}` +\n\t\t`.advcapjs{font-size:${compact ? '.65rem' : '.72rem'};margin-top:${compact ? 2 : 4}px;line-height:1.25;opacity:.85}` +\n\t\t`.advemptyjs{padding:24px;text-align:center;opacity:.7}`\n\t);\n}\n\n// Client-side browser code for the JS widget variant.\n// Stored as a string: TypeScript never type-checks browser code running in DOM context.\nconst ADV_CLIENT_CODE = `\n(function(){\nfunction esc(s){return String(s==null?'':s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"');}\nvar MODAL_CSS='.advmodaljs{display:none;position:fixed;inset:0;z-index:99999;align-items:center;justify-content:center}.advbackdropjs{position:absolute;inset:0;background:transparent;cursor:pointer}.advboxjs{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;max-width:min(92vw,900px);background:#1c1c1e;padding:12px;border-radius:14px;box-shadow:0 16px 48px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.08)}.advvideojs{width:100%;max-height:80vh;border-radius:8px;background:#000;display:block}.advclosejs{position:absolute;top:18px;right:18px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,.65);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:15px;z-index:2;border:2px solid rgba(255,255,255,.35)}.advinfojs{color:#fff;font-size:.8rem;text-align:center}';\nvar modalEl=null,modalVideo=null,modalInfo=null,modalBox=null;\nfunction getModal(){\n if(modalEl&&document.body.contains(modalEl))return modalEl;\n if(!document.getElementById('advmodalcss')){var st=document.createElement('style');st.id='advmodalcss';st.textContent=MODAL_CSS;document.head.appendChild(st);}\n modalEl=document.createElement('div');modalEl.className='advmodaljs';\n var bd=document.createElement('div');bd.className='advbackdropjs';\n modalBox=document.createElement('div');modalBox.className='advboxjs';\n var cl=document.createElement('span');cl.className='advclosejs';cl.textContent='\u2715';\n modalVideo=document.createElement('video');modalVideo.className='advvideojs';\n modalVideo.setAttribute('controls','');modalVideo.setAttribute('preload','none');modalVideo.setAttribute('playsinline','');\n modalInfo=document.createElement('div');modalInfo.className='advinfojs';\n modalBox.appendChild(cl);modalBox.appendChild(modalVideo);modalBox.appendChild(modalInfo);\n modalEl.appendChild(bd);modalEl.appendChild(modalBox);\n document.body.appendChild(modalEl);\n bd.addEventListener('click',closeModal);cl.addEventListener('click',closeModal);\n return modalEl;\n}\nfunction openSrc(src,label,maxW){\n var m=getModal();\n if(maxW)modalBox.style.maxWidth='min(92vw,'+maxW+'px)';\n modalVideo.setAttribute('src',src);modalInfo.textContent=label;m.style.display='flex';\n}\nfunction closeModal(){\n if(!modalEl)return;\n try{modalVideo.pause();}catch(e){}\n modalVideo.removeAttribute('src');try{modalVideo.load();}catch(e){}\n modalEl.style.display='none';\n}\ndocument.addEventListener('keydown',function(e){if(e.key==='Escape'||e.keyCode===27)closeModal();});\nfunction initRoot(root){\n var dataEl=root.querySelector('script.advdata');\n if(!dataEl)return;\n var D;try{D=JSON.parse(dataEl.textContent);}catch(e){return;}\n var cfg=D.cfg||{},items=D.items||[],live=D.live||null;\n var grid=root.querySelector('.advgridjs'),search=root.querySelector('.advsearchjs'),tagsBox=root.querySelector('.advtagsjs');\n var state={q:'',tag:cfg.default_tag||''};\n var tagset={};\n items.forEach(function(it){String(it.tag||'').split(/[,\\\\s]+/).forEach(function(t){if(t)tagset[t]=1;});});\n var tags=Object.keys(tagset);\n if(cfg.show_tags&&tags.length){\n var mk=function(label,val){\n var b=document.createElement('button');b.className='advtagbtn';b.textContent=label;b.setAttribute('data-tag',val);\n b.addEventListener('click',function(){state.tag=state.tag===val?'':val;updateTagBtns();render();});\n tagsBox.appendChild(b);\n };\n mk(cfg.labels&&cfg.labels.all||'All','');tags.forEach(function(t){mk(t,t);});\n }\n function updateTagBtns(){var bs=tagsBox.querySelectorAll('.advtagbtn');for(var i=0;i<bs.length;i++)bs[i].classList.toggle('on',bs[i].getAttribute('data-tag')===state.tag);}\n updateTagBtns();\n if(search)search.addEventListener('input',function(){state.q=this.value.toLowerCase();render();});\n function badge(it){if(!(cfg.show_tags&&it.tag))return '';var pos=String(cfg.tag_position||'bottom-left').split('-');return '<span class=\"advtagjs\" style=\"'+pos[0]+':5px;'+pos[1]+':5px\">'+esc(it.tag)+'</span>';}\n function render(){\n var html='';\n if(live){var ar=cfg.live_aspect||'',arStyle=ar?' style=\"aspect-ratio:'+ar.replace('/',' / ')+'\"':'',arCls=ar?' advimgfix':'';\n html+='<div class=\"advcelljs\" data-live=\"1\"><span class=\"advimgjs'+arCls+'\"'+arStyle+'><img loading=\"lazy\" src=\"'+esc(live.thumb)+'\"><span class=\"advtagjs\" style=\"top:5px;left:5px\">● '+(cfg.labels&&cfg.labels.live||'LIVE')+'</span><span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(live.name)+'</span></div>';}\n items.forEach(function(it,i){\n if(state.tag&&String(it.tag||'').toLowerCase().indexOf(state.tag.toLowerCase())<0)return;\n if(state.q){var hay=((it.date||'')+' '+(it.time||'')+' '+(it.tag||'')).toLowerCase();if(hay.indexOf(state.q)<0)return;}\n html+='<div class=\"advcelljs\" data-i=\"'+i+'\"><span class=\"advimgjs\"><img loading=\"lazy\" src=\"'+esc(it.thumb)+'\">'+badge(it)+'<span class=\"advplayjs\"></span></span><span class=\"advcapjs\">'+esc(it.date)+' '+esc(it.time)+'<br>'+esc(it.dur)+'s · '+esc(it.size)+' MB</span></div>';\n });\n grid.innerHTML=html||'<div class=\"advemptyjs\">'+(cfg.labels&&cfg.labels.noRecordings||'No recordings')+'</div>';\n var cells=grid.querySelectorAll('.advcelljs');\n for(var k=0;k<cells.length;k++)(function(cell){\n cell.addEventListener('click',function(){\n if(cell.getAttribute('data-live')==='1'){openSrc(live.video,(live.name||'')+' \u00B7 Live',cfg.max_modal_width);return;}\n var it=items[parseInt(cell.getAttribute('data-i'),10)],maxW=Number(cfg.max_modal_width)||900;\n if(cfg.player_url){var u=cfg.player_url.replace(/{video}/g,encodeURIComponent(it.video)).replace(/{videoRaw}/g,it.video).replace(/{fn}/g,encodeURIComponent(it.fn||'')).replace(/{date}/g,encodeURIComponent(it.date)).replace(/{time}/g,encodeURIComponent(it.time)).replace(/{duration}/g,encodeURIComponent(it.dur)).replace(/{size}/g,encodeURIComponent(it.size)).replace(/{tags}/g,encodeURIComponent(it.tag));window.open(u,'_blank');}\n else{openSrc(it.video,esc(it.date)+' '+esc(it.time)+(it.dur!=null?' \u00B7 '+it.dur+'s':'')+(it.size!=null?' \u00B7 '+it.size+' MB':'')+(it.tag?' \u00B7 '+it.tag:''),maxW);}\n });\n })(cells[k]);\n }\n render();\n}\nfunction scan(){var roots=document.querySelectorAll('.advroot');for(var i=0;i<roots.length;i++)if(!roots[i].__adv){roots[i].__adv=1;initRoot(roots[i]);}}\nwindow.ADVscan=scan;scan();\n})();\n`.trim();\n\n// ---- Adapter class ----\n\nclass AgentDvr extends utils.Adapter {\n\tprivate pollTimer: ioBroker.Interval | undefined = undefined;\n\tprivate pollBusy = false;\n\tprivate refreshTimer: ioBroker.Timeout | undefined = undefined;\n\tprivate authHeader: string | null = null;\n\tprivate baseUrl = '';\n\tprivate wt: WidgetLabels = getWidgetLabels('en');\n\n\tprivate readonly ensuredFolders = new Set<string>();\n\tprivate readonly registry = new Map<string, RegistryEntry>();\n\tprivate readonly ptzActive = new Map<string | number, string>();\n\tprivate readonly widgetSig: Record<string, string> = {};\n\tprivate profileSig = '';\n\tprivate lastCamNames: { key: string; name: string }[] = [];\n\tprivate readonly lastEventFn: Record<string | number, string> = {};\n\tprivate readonly camAspect: Record<string | number, string> = {};\n\tprivate readonly devById = new Map<string | number, Device>();\n\tprivate readonly eventBusy: Record<string | number, boolean> = {};\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({ ...options, name: 'agent-dvr' });\n\t\tthis.on('ready', this.onReady.bind(this));\n\t\tthis.on('stateChange', this.onStateChange.bind(this));\n\t\tthis.on('message', this.onMessage.bind(this));\n\t\tthis.on('unload', this.onUnload.bind(this));\n\t}\n\n\t// ---- lifecycle ----\n\n\tprivate async ensureWebInstance(): Promise<void> {\n\t\tconst instanceId = `system.adapter.${this.namespace}`;\n\t\tconst obj = await this.getForeignObjectAsync(instanceId);\n\t\tif (obj && !obj.native?.webInstance) {\n\t\t\tawait this.extendForeignObjectAsync(instanceId, { native: { webInstance: '*' } });\n\t\t\tthis.log.info('webInstance set \u2014 web adapter will reload the extension');\n\t\t}\n\t}\n\n\tprivate async onReady(): Promise<void> {\n\t\tvoid this.setState('info.connection', false, true);\n\t\tawait this.ensureWebInstance();\n\n\t\tconst sysConfig = await this.getForeignObjectAsync('system.config');\n\t\tconst rawLang = (sysConfig?.common as unknown as { language?: string } | undefined)?.language;\n\t\tthis.wt = getWidgetLabels(rawLang ?? 'en');\n\n\t\tconst pollSeconds = Math.max(5, Math.min(3600, this.config.pollSeconds || 30));\n\t\tthis.baseUrl = `http://${this.config.ip}:${this.config.port || 8090}`;\n\n\t\tif (this.config.user || this.config.pass) {\n\t\t\tthis.authHeader = `Basic ${Buffer.from(`${this.config.user}:${this.config.pass}`).toString('base64')}`;\n\t\t}\n\n\t\tawait this.buildSystem();\n\t\ttry {\n\t\t\tawait this.poll();\n\t\t} catch (e) {\n\t\t\tthis.log.warn(`First poll error: ${(e as Error).message}`);\n\t\t}\n\n\t\tthis.pollTimer = this.setInterval(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Poll error: ${(e as Error).message}`)),\n\t\t\tpollSeconds * 1000,\n\t\t);\n\n\t\tthis.subscribeStates('*');\n\t\tthis.log.info(`Agent DVR adapter ready. Polling ${this.baseUrl} every ${pollSeconds}s.`);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\ttry {\n\t\t\tif (this.pollTimer !== undefined) {\n\t\t\t\tthis.clearInterval(this.pollTimer);\n\t\t\t\tthis.pollTimer = undefined;\n\t\t\t}\n\t\t\tif (this.refreshTimer !== undefined) {\n\t\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\t\tthis.refreshTimer = undefined;\n\t\t\t}\n\t\t} catch {\n\t\t\t/* ignore */\n\t\t}\n\t\tcallback();\n\t}\n\n\tprivate onMessage(obj: ioBroker.Message): void {\n\t\tif (!obj) {\n\t\t\treturn;\n\t\t}\n\t\tif (obj.command === 'getGo2rtcStreams') {\n\t\t\tconst overrideUrl =\n\t\t\t\ttypeof obj.message === 'object' && obj.message !== null\n\t\t\t\t\t? (obj.message.url as string | undefined)\n\t\t\t\t\t: undefined;\n\t\t\tvoid this.fetchGo2rtcStreams(overrideUrl).then(result => {\n\t\t\t\tthis.sendTo(obj.from, obj.command, result, obj.callback);\n\t\t\t});\n\t\t} else if (obj.command === 'getAgentDvrCameras') {\n\t\t\tthis.sendTo(obj.from, obj.command, { cameras: this.lastCamNames }, obj.callback);\n\t\t} else if (obj.command === 'getAvailableSources') {\n\t\t\tvoid this.fetchAvailableSources().then(result => {\n\t\t\t\tthis.sendTo(obj.from, obj.command, result, obj.callback);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async fetchAvailableSources(): Promise<{ result: { source: string; name: string }[] }> {\n\t\tconst deadline = new Promise<{ result: { source: string; name: string }[] }>(res =>\n\t\t\tthis.setTimeout(() => res({ result: [{ source: '!', name: 'Timeout' }] }), 5000),\n\t\t);\n\t\treturn Promise.race([this._doFetchAvailableSources(), deadline]);\n\t}\n\n\tprivate async _doFetchAvailableSources(): Promise<{ result: { source: string; name: string }[] }> {\n\t\tconst rows: { source: string; name: string }[] = [];\n\t\tfor (const c of this.lastCamNames) {\n\t\t\trows.push({ source: 'AgentDVR', name: `${c.name} (${c.key})` });\n\t\t}\n\t\tconst { streams } = await this.fetchGo2rtcStreams();\n\t\tfor (const s of streams) {\n\t\t\trows.push({ source: 'go2rtc', name: s });\n\t\t}\n\t\tif (!rows.length) {\n\t\t\trows.push({ source: '\u2014', name: 'No sources found (adapter has not polled yet)' });\n\t\t}\n\t\treturn { result: rows };\n\t}\n\n\tprivate fetchGo2rtcStreams(overrideUrl?: string): Promise<{ streams: string[]; error?: string }> {\n\t\t// go2rtc only accepts plain HTTP; force https:// \u2192 http://\n\t\tconst url = (overrideUrl || this.config.go2rtcUrl || '').replace(/^https:\\/\\//i, 'http://');\n\t\tif (!url) {\n\t\t\treturn Promise.resolve({ streams: [], error: 'go2rtcUrl not configured' });\n\t\t}\n\t\tlet target: URL;\n\t\ttry {\n\t\t\ttarget = new URL('/api/streams', url);\n\t\t} catch {\n\t\t\treturn Promise.resolve({ streams: [], error: `Invalid URL: ${url}` });\n\t\t}\n\t\tlet httpReq: ReturnType<typeof http.get> | undefined;\n\t\tconst fetch = new Promise<{ streams: string[]; error?: string }>(resolve => {\n\t\t\tconst mod = target.protocol === 'https:' ? https : http;\n\t\t\thttpReq = mod.get(target.toString(), res => {\n\t\t\t\tlet body = '';\n\t\t\t\tres.on('data', (c: Buffer) => {\n\t\t\t\t\tbody += c.toString();\n\t\t\t\t});\n\t\t\t\tres.on('end', () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst parsed = JSON.parse(body);\n\t\t\t\t\t\tconst streams = Object.keys(parsed || {});\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tstreams,\n\t\t\t\t\t\t\terror: streams.length === 0 ? 'go2rtc reachable but no streams configured' : undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tstreams: [],\n\t\t\t\t\t\t\terror: `Invalid JSON response from go2rtc (HTTP ${res.statusCode})`,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tres.on('error', (e: Error) => resolve({ streams: [], error: `Stream error: ${e.message}` }));\n\t\t\t});\n\t\t\thttpReq.on('error', (e: Error) => resolve({ streams: [], error: `Connection error: ${e.message}` }));\n\t\t});\n\t\tconst timeout = new Promise<{ streams: string[]; error?: string }>(resolve =>\n\t\t\tthis.setTimeout(() => {\n\t\t\t\thttpReq?.destroy();\n\t\t\t\tresolve({ streams: [], error: `Timeout fetching ${target.toString()}` });\n\t\t\t}, 3000),\n\t\t);\n\t\treturn Promise.race([fetch, timeout]);\n\t}\n\n\tprivate onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n\t\tif (!state || state.ack !== false) {\n\t\t\treturn;\n\t\t}\n\t\tconst relId = this.getRelId(id);\n\t\tconst entry = this.registry.get(relId);\n\t\tif (entry) {\n\t\t\tthis.runCommand(relId, entry, state.val).catch(e =>\n\t\t\t\tthis.log.warn(`Command error: ${(e as Error).message}`),\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- helpers ----\n\n\tprivate getRelId(fullId: string): string {\n\t\treturn fullId.startsWith(`${this.namespace}.`) ? fullId.slice(this.namespace.length + 1) : fullId;\n\t}\n\n\tprivate apiGet(path: string): Promise<ApiResult> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tlet data = '';\n\t\t\t\t\tres.on('data', (c: Buffer) => {\n\t\t\t\t\t\tdata += c.toString();\n\t\t\t\t\t});\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate apiGetBuffer(path: string): Promise<{ ok: boolean; data?: Buffer; error?: string }> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst timeout = Math.max(1000, Math.min(30000, this.config.httpTimeoutMs || 8000));\n\t\t\tconst opts: http.RequestOptions = {\n\t\t\t\thostname: this.config.ip,\n\t\t\t\tport: this.config.port || 8090,\n\t\t\t\tpath,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout,\n\t\t\t};\n\t\t\tif (this.authHeader) {\n\t\t\t\topts.headers = { Authorization: this.authHeader };\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst req = http.request(opts, res => {\n\t\t\t\t\tconst chunks: Buffer[] = [];\n\t\t\t\t\tres.on('data', (c: Buffer) => chunks.push(c));\n\t\t\t\t\tres.on('end', () => {\n\t\t\t\t\t\tif (res.statusCode && res.statusCode >= 400) {\n\t\t\t\t\t\t\tresolve({ ok: false, error: `HTTP ${res.statusCode}` });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve({ ok: true, data: Buffer.concat(chunks) });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tres.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\t});\n\t\t\t\treq.on('error', (e: Error) => resolve({ ok: false, error: e.message }));\n\t\t\t\treq.on('timeout', () => {\n\t\t\t\t\treq.destroy();\n\t\t\t\t\tresolve({ ok: false, error: 'timeout' });\n\t\t\t\t});\n\t\t\t\treq.end();\n\t\t\t} catch (e) {\n\t\t\t\tresolve({ ok: false, error: String((e as Error).message || e) });\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate async ensureFolder(id: string, name: string, type: 'device' | 'channel' = 'channel'): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setObjectNotExistsAsync(id, { type, common: { name }, native: {} });\n\t\tthis.ensuredFolders.add(id);\n\t}\n\n\tprivate async ensurePath(fullId: string): Promise<void> {\n\t\tconst parts = fullId.split('.');\n\t\tlet acc = parts[0];\n\t\tfor (let i = 1; i < parts.length - 1; i++) {\n\t\t\tacc += `.${parts[i]}`;\n\t\t\tif (!this.ensuredFolders.has(acc)) {\n\t\t\t\tawait this.setObjectNotExistsAsync(acc, { type: 'channel', common: { name: parts[i] }, native: {} });\n\t\t\t\tthis.ensuredFolders.add(acc);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate guessRole(id: string, val: unknown): ioBroker.CommonType {\n\t\tif (typeof val === 'string' && /^https?:\\/\\//i.test(val)) {\n\t\t\treturn 'string';\n\t\t}\n\t\treturn 'string';\n\t}\n\n\tprivate async writeLeaf(id: string, val: unknown): Promise<void> {\n\t\tconst t = typeof val;\n\t\tlet common: ioBroker.StateCommon;\n\t\tif (t === 'boolean') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'boolean', role: 'indicator', read: true, write: false };\n\t\t} else if (t === 'number') {\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'number', role: 'value', read: true, write: false };\n\t\t} else {\n\t\t\tconst role = typeof val === 'string' && /^https?:\\/\\//i.test(val) ? 'text.url' : 'text';\n\t\t\tcommon = { name: id.split('.').pop() || id, type: 'string', role, read: true, write: false };\n\t\t}\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, { type: 'state', common, native: {} });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tawait this.setStateAsync(id, { val: (val === undefined ? null : val) as ioBroker.StateValue, ack: true });\n\t}\n\n\tprivate async flattenWrite(obj: unknown, prefix: string, depth: number): Promise<void> {\n\t\tconst maxDepth = Math.max(1, Math.min(10, this.config.maxDepth || 6));\n\t\tconst maxArray = Math.max(1, Math.min(500, this.config.maxArray || 30));\n\t\tif (depth > maxDepth) {\n\t\t\treturn;\n\t\t}\n\t\tif (obj === null || obj === undefined) {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t\treturn;\n\t\t}\n\t\tif (typeof obj === 'object') {\n\t\t\tif (Array.isArray(obj)) {\n\t\t\t\tif (obj.length > maxArray) {\n\t\t\t\t\tawait this.writeLeaf(`${prefix}.count`, obj.length);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\t\t\tawait this.flattenWrite(obj[i], `${prefix}.${i}`, depth + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const k of Object.keys(obj)) {\n\t\t\t\t\tif (SKIP_KEYS.includes(k)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.flattenWrite((obj as Record<string, unknown>)[k], `${prefix}.${sanitize(k)}`, depth + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tawait this.writeLeaf(prefix, obj);\n\t\t}\n\t}\n\n\tprivate async ensureControl(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\trole: 'button' | 'switch',\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'boolean', role, read: role === 'switch', write: true, def: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate ensureButton(id: string, name: string, entry: RegistryEntry): Promise<void> {\n\t\treturn this.ensureControl(id, name, entry, 'button');\n\t}\n\n\tprivate async ensureLevel(id: string, name: string, entry: RegistryEntry, min: number, max: number): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'number', role: 'level', read: true, write: true, min, max },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: 0, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate async ensureSelector(\n\t\tid: string,\n\t\tname: string,\n\t\tentry: RegistryEntry,\n\t\tstates: Record<number, string>,\n\t): Promise<void> {\n\t\tif (!this.ensuredFolders.has(id)) {\n\t\t\tawait this.ensurePath(id);\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name, type: 'number', role: 'level', read: true, write: true, states },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: 0, ack: true });\n\t\t\tthis.ensuredFolders.add(id);\n\t\t}\n\t\tthis.registry.set(id, entry);\n\t}\n\n\tprivate async fetchSnapshotB64(oid: number | string, snapId: string): Promise<void> {\n\t\tconst imgRes = await this.apiGetBuffer(`/photo.jpg?oid=${oid}`);\n\t\tif (imgRes.ok && imgRes.data) {\n\t\t\tawait this.setStateAsync(snapId, {\n\t\t\t\tval: `data:image/jpeg;base64,${imgRes.data.toString('base64')}`,\n\t\t\t\tack: true,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async ensureFlag(id: string, name: string): Promise<void> {\n\t\tif (this.ensuredFolders.has(id)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.ensurePath(id);\n\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\ttype: 'state',\n\t\t\tcommon: { name, type: 'boolean', role: 'indicator', read: true, write: false, def: false },\n\t\t\tnative: {},\n\t\t});\n\t\tthis.ensuredFolders.add(id);\n\t\tawait this.setStateAsync(id, { val: false, ack: true });\n\t}\n\n\tprivate async pulse(id: string): Promise<void> {\n\t\tawait this.setStateAsync(id, { val: true, ack: true });\n\t\tthis.setTimeout(() => this.setStateAsync(id, { val: false, ack: true }).catch(() => {}), 1500);\n\t}\n\n\t// ---- system structure ----\n\n\tprivate async buildSystem(): Promise<void> {\n\t\tawait this.ensureFolder('system', 'System', 'channel');\n\t\tawait this.writeLeaf('system.online', false);\n\t\tawait this.writeLeaf('system.lastUpdate', '');\n\t\tawait this.writeLeaf('system.lastPoll', 0);\n\t\tawait this.writeLeaf('system.cameraCount', 0);\n\n\t\tif (this.config.enableSystemControls) {\n\t\t\tawait this.ensureFolder('system.control', 'Control', 'channel');\n\t\t\tfor (const c of SYS_COMMANDS) {\n\t\t\t\tawait this.ensureButton(`system.control.${c.id}`, c.name, { kind: 'sys', path: c.path });\n\t\t\t}\n\t\t\tawait this.ensureFolder('system.profile', 'Profile', 'channel');\n\t\t\tawait this.ensureSelector(\n\t\t\t\t'system.profile.selector',\n\t\t\t\t'Active profile',\n\t\t\t\t{ kind: 'setProfile' },\n\t\t\t\t{ 0: 'Home', 1: 'Away', 2: 'Night' },\n\t\t\t);\n\t\t\tif (!this.ensuredFolders.has('system.profile.list')) {\n\t\t\t\tawait this.setObjectNotExistsAsync('system.profile.list', {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Available profiles (JSON)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'json',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tthis.ensuredFolders.add('system.profile.list');\n\t\t\t\tawait this.setStateAsync('system.profile.list', { val: '[]', ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\t// ---- camera aspect detection ----\n\n\tprivate async detectAspect(d: Device): Promise<void> {\n\t\tif (this.camAspect[d.oid] !== undefined) {\n\t\t\treturn;\n\t\t}\n\t\tlet wh = findWH(d.raw, 0);\n\t\tif (!wh) {\n\t\t\tconst res = await this.apiGet(`/command/getObject?oid=${d.oid}&ot=2`);\n\t\t\tconst j = asJson(res.data);\n\t\t\tif (j) {\n\t\t\t\twh = findWH(j, 0);\n\t\t\t}\n\t\t}\n\t\tthis.camAspect[d.oid] = wh ? `${wh[0]}/${wh[1]}` : '';\n\t\tif (wh) {\n\t\t\tthis.log.debug(`cam ${d.oid} resolution ${wh[0]}x${wh[1]} -> AR ${this.camAspect[d.oid]}`);\n\t\t}\n\t}\n\n\t// ---- device folder name ----\n\n\tprivate deviceFolder(d: Device): string {\n\t\treturn `${d.ot === 1 ? 'mic' : 'cam'}_${sanitize(d.oid)}_${sanitize(d.name)}`;\n\t}\n\n\t// ---- device status data points ----\n\n\tprivate readonly STATUS_DPS = [\n\t\t{ key: 'recording', role: 'indicator.working', name: 'Active recording' },\n\t\t{ key: 'online', role: 'indicator.reachable', name: 'Online' },\n\t\t{ key: 'connected', role: 'indicator.connected', name: 'Stream connected' },\n\t\t{ key: 'detected', role: 'indicator', name: 'Motion detected' },\n\t\t{ key: 'alerted', role: 'indicator.alarm', name: 'Alert active' },\n\t] as const;\n\n\tprivate async writeStatusDps(d: Device, fid: string): Promise<void> {\n\t\tconst data = d.raw.data as Record<string, unknown> | undefined;\n\t\tif (!data || typeof data !== 'object') {\n\t\t\treturn;\n\t\t}\n\t\tconst sfid = `${fid}.status`;\n\t\tif (!this.ensuredFolders.has(sfid)) {\n\t\t\tawait this.ensureFolder(sfid, 'Status', 'channel');\n\t\t}\n\t\tfor (const dp of this.STATUS_DPS) {\n\t\t\tif (!(dp.key in data)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = `${sfid}.${dp.key}`;\n\t\t\tawait this.setObjectNotExistsAsync(id, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: dp.name, type: 'boolean', role: dp.role, read: true, write: false, def: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tawait this.setStateAsync(id, { val: !!data[dp.key], ack: true });\n\t\t}\n\t}\n\n\t// ---- build device data points ----\n\n\tprivate async buildDevice(d: Device): Promise<void> {\n\t\tconst fid = this.deviceFolder(d);\n\t\tthis.devById.set(d.oid, d);\n\n\t\tawait this.ensureFolder(fid, d.name, 'device');\n\t\tif (d.ot === 2) {\n\t\t\tawait this.detectAspect(d);\n\t\t}\n\t\tawait this.flattenWrite(d.raw, fid, 0);\n\t\tawait this.writeStatusDps(d, fid);\n\n\t\tawait this.ensureFolder(`${fid}.control`, 'Control', 'channel');\n\t\tconst CAM_ONLY = new Set(['snapshot', 'objectDetectOn', 'objectDetectOff']);\n\t\tfor (const c of CAM_COMMANDS) {\n\t\t\tif (CAM_ONLY.has(c.id) && d.ot !== 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.${c.id}`, c.name, {\n\t\t\t\tkind: 'cam',\n\t\t\t\tpath: c.path,\n\t\t\t\tparams: [...c.params],\n\t\t\t\toid: d.oid,\n\t\t\t\tot: d.ot,\n\t\t\t});\n\t\t}\n\n\t\tif (this.config.enablePtz && d.ot === 2) {\n\t\t\tawait this.ensureFolder(`${fid}.control.ptz`, 'PTZ', 'channel');\n\t\t\tfor (const p of PTZ_DIRS) {\n\t\t\t\tconst cid = `${fid}.control.ptz.${p.id}`;\n\t\t\t\tif (p.hold) {\n\t\t\t\t\tawait this.ensureControl(\n\t\t\t\t\t\tcid,\n\t\t\t\t\t\t`PTZ ${p.id} (hold)`,\n\t\t\t\t\t\t{ kind: 'ptzHold', oid: d.oid, dir: p.dir },\n\t\t\t\t\t\t'switch',\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.ensureButton(cid, `PTZ ${p.id}`, { kind: 'ptz', oid: d.oid, dir: p.dir });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (d.ot === 2) {\n\t\t\tconst sfx = { kind: 'levelCmd' as const, path: '/command/setSensitivity', oid: d.oid, ot: d.ot };\n\t\t\tawait this.ensureLevel(\n\t\t\t\t`${fid}.control.sensitivityMin`,\n\t\t\t\t'Sensitivity min (0-100)',\n\t\t\t\t{ ...sfx, valueParam: 'min' },\n\t\t\t\t0,\n\t\t\t\t100,\n\t\t\t);\n\t\t\tawait this.ensureLevel(\n\t\t\t\t`${fid}.control.sensitivityMax`,\n\t\t\t\t'Sensitivity max (0-100)',\n\t\t\t\t{ ...sfx, valueParam: 'max' },\n\t\t\t\t0,\n\t\t\t\t100,\n\t\t\t);\n\t\t\tawait this.ensureLevel(\n\t\t\t\t`${fid}.control.sensitivityGain`,\n\t\t\t\t'Sensitivity gain (0-100)',\n\t\t\t\t{ ...sfx, valueParam: 'gain' },\n\t\t\t\t0,\n\t\t\t\t100,\n\t\t\t);\n\t\t}\n\n\t\tif (this.config.enableUrls) {\n\t\t\tawait this.ensureFolder(`${fid}.urls`, 'URLs', 'channel');\n\t\t\tif (d.ot === 2) {\n\t\t\t\tawait this.writeLeaf(`${fid}.urls.snapshot`, `${this.baseUrl}/grab.jpg?oid=${d.oid}`);\n\t\t\t\tawait this.writeLeaf(`${fid}.urls.photo`, `${this.baseUrl}/photo.jpg?oid=${d.oid}`);\n\t\t\t\tawait this.writeLeaf(`${fid}.urls.mjpeg`, `${this.baseUrl}/video.mjpg?oids=${d.oid}`);\n\t\t\t\tawait this.writeLeaf(`${fid}.urls.mp4`, `${this.baseUrl}/video.mp4?oids=${d.oid}`);\n\t\t\t} else if (d.ot === 1) {\n\t\t\t\tawait this.writeLeaf(`${fid}.urls.audio_mp3`, `${this.baseUrl}/audio.mp3?oid=${d.oid}`);\n\t\t\t\tawait this.writeLeaf(`${fid}.urls.audio_ogg`, `${this.baseUrl}/audio.ogg?oid=${d.oid}`);\n\t\t\t}\n\t\t}\n\n\t\tif (d.ot === 2) {\n\t\t\tconst snapId = `${fid}.snapshot_b64`;\n\t\t\tif (!this.ensuredFolders.has(snapId)) {\n\t\t\t\tawait this.ensurePath(snapId);\n\t\t\t\tawait this.setObjectNotExistsAsync(snapId, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Snapshot (Base64)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'state',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: false,\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(snapId, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(snapId);\n\t\t\t}\n\t\t\tawait this.ensureButton(`${fid}.control.refreshSnapshotB64`, 'Refresh snapshot (Base64)', {\n\t\t\t\tkind: 'snapshotB64',\n\t\t\t\toid: d.oid,\n\t\t\t\tfid,\n\t\t\t});\n\t\t\tif (this.config.enableSnapshotB64) {\n\t\t\t\tawait this.fetchSnapshotB64(d.oid, snapId);\n\t\t\t}\n\t\t}\n\n\t\tawait this.updateCameraEvents(d, fid);\n\t}\n\n\t// ---- event formatting ----\n\n\tprivate fmtEvent(\n\t\tev: Record<string, unknown>,\n\t\toid: number | string,\n\t): {\n\t\tfn: string;\n\t\tsizeMB: number;\n\t\tdur: string;\n\t\ttag: string;\n\t\tdate: string;\n\t\ttime: string;\n\t\tthumb: string;\n\t\tvideo: string;\n\t} {\n\t\tconst e = ev as AgentDvrEvent;\n\t\tconst fn = e.fn ?? '';\n\t\tconst dot = fn.lastIndexOf('.');\n\t\tconst jpg = `${dot > 0 ? fn.slice(0, dot) : fn}_large.jpg`;\n\t\tconst sizeMB = e.sb ? Math.round((Number(e.sb) / 1048576) * 100) / 100 : 0;\n\t\tconst dur = e.d != null ? String(e.d) : '';\n\t\tconst tag = e.tg ?? '';\n\t\tconst ms = (parseFloat(String(e.c ?? 0)) - 621355968000000000) / 10000;\n\t\tconst dt = new Date(ms);\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst date = `${two(dt.getDate())}.${two(dt.getMonth() + 1)}.`;\n\t\tconst time = `${two(dt.getHours())}:${two(dt.getMinutes())}`;\n\t\tconst thumb = `${this.baseUrl}/fileThumb.jpg?oid=${oid}&fn=${encodeURIComponent(jpg)}`;\n\t\tconst video = `${this.baseUrl}/streamFile.cgi?oid=${oid}&ot=2&fn=${encodeURIComponent(fn)}`;\n\t\treturn { fn, sizeMB, dur, tag, date, time, thumb, video };\n\t}\n\n\t// ---- gallery HTML builders ----\n\n\tprivate effectiveMinCol(): number {\n\t\tconst sizeMap: Record<string, number> = { small: 120, medium: 180, large: 240 };\n\t\tconst ts = this.config.widgetThumbSize;\n\t\treturn ts && sizeMap[ts] ? sizeMap[ts] : this.config.widgetMinCol || 150;\n\t}\n\n\tprivate async pruneStaleDevices(activeFolders: Set<string>): Promise<void> {\n\t\tconst allObjs = await this.getAdapterObjectsAsync();\n\t\tconst stale: string[] = [];\n\t\tfor (const fullId of Object.keys(allObjs)) {\n\t\t\tconst obj = allObjs[fullId];\n\t\t\tif (obj.type !== 'device') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst rel = fullId.slice(this.namespace.length + 1);\n\t\t\tif (/^(cam|mic)_/.test(rel) && !activeFolders.has(rel)) {\n\t\t\t\tstale.push(rel);\n\t\t\t}\n\t\t}\n\t\tfor (const rel of stale) {\n\t\t\tthis.log.info(`[agent-dvr] removing stale device: ${rel}`);\n\t\t\tawait this.delObjectAsync(rel, { recursive: true });\n\t\t\t// clean up internal cache\n\t\t\tfor (const [oid, d] of this.devById) {\n\t\t\t\tif (this.deviceFolder(d) === rel) {\n\t\t\t\t\tthis.devById.delete(oid);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sortedEvents(events: Record<string, unknown>[]): Record<string, unknown>[] {\n\t\t// newest-first by default; widgetSortNewest=false reverses to oldest-first\n\t\treturn this.config.widgetSortNewest === false ? [...events].reverse() : events;\n\t}\n\n\tprivate buildGalleryHtml(d: Device, events: Record<string, unknown>[]): string {\n\t\treturn (this.config.widgetMode || 'nojs') === 'js'\n\t\t\t? this.buildGalleryHtmlJs(d, events)\n\t\t\t: this.buildGalleryHtmlNojs(d, events);\n\t}\n\n\tprivate buildGalleryHtmlNojs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.effectiveMinCol();\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst showTags = this.config.widgetShowTags;\n\t\tconst pos = (this.config.widgetTagPosition || 'bottom-left').split('-');\n\t\tconst tagStyle = `${pos[0]}:5px;${pos[1]}:5px`;\n\t\tconst playerUrl = (this.config.widgetPlayerUrl || '').trim();\n\t\tconst compact = !!this.config.widgetCompact;\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\n\t\tconst items = this.sortedEvents(events)\n\t\t\t.map((ev, i) => {\n\t\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\t\tconst id = `adv${sanitize(oid)}_${i}`;\n\t\t\t\tconst badge =\n\t\t\t\t\tshowTags && p.tag ? `<span class=\"advtag\" style=\"${tagStyle}\">${escHtml(p.tag)}</span>` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg\"><img src=\"${p.thumb}\" loading=\"lazy\" alt=\"\">${badge}<span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${escHtml(p.date)} ${escHtml(p.time)}<br>${escHtml(p.dur)}s · ${escHtml(p.sizeMB)} MB</span>`;\n\t\t\t\tif (playerUrl) {\n\t\t\t\t\tconst href = playerUrl\n\t\t\t\t\t\t.replace(/{video}/g, encodeURIComponent(p.video))\n\t\t\t\t\t\t.replace(/{videoRaw}/g, p.video)\n\t\t\t\t\t\t.replace(/{fn}/g, encodeURIComponent(p.fn))\n\t\t\t\t\t\t.replace(/{date}/g, encodeURIComponent(p.date))\n\t\t\t\t\t\t.replace(/{time}/g, encodeURIComponent(p.time))\n\t\t\t\t\t\t.replace(/{duration}/g, encodeURIComponent(p.dur))\n\t\t\t\t\t\t.replace(/{size}/g, encodeURIComponent(String(p.sizeMB)))\n\t\t\t\t\t\t.replace(/{tags}/g, encodeURIComponent(p.tag));\n\t\t\t\t\treturn `<a class=\"advcell\" href=\"${escHtml(href)}\" target=\"_blank\" rel=\"noopener\">${inner}</a>`;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">✕</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${p.video}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${escHtml(p.date)} ${escHtml(p.time)} · ${escHtml(p.dur)}s · ${escHtml(p.sizeMB)} MB${\n\t\t\t\t\t\tp.tag ? ` · ${escHtml(p.tag)}` : ''\n\t\t\t\t\t} · <a href=\"${p.video}\" download target=\"_blank\">${this.wt.download}</a></div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\n\t\tconst gridClass = compact ? 'advgrid advcompact' : 'advgrid';\n\t\tconst grid = items\n\t\t\t? `<div class=\"${gridClass}\">${items}</div>`\n\t\t\t: `<div class=\"advempty\">${this.wt.noRecordings}</div>`;\n\t\tconst colors: WidgetColors = {\n\t\t\tcardBg: this.config.widgetColorCardBg || undefined,\n\t\t\ttagBg: this.config.widgetColorTagBg || undefined,\n\t\t\ttagText: this.config.widgetColorTagText || undefined,\n\t\t\taccent: this.config.widgetColorAccent || undefined,\n\t\t\tmodalBg: this.config.widgetColorModalBg || undefined,\n\t\t\tradius: this.config.widgetBorderRadius,\n\t\t};\n\t\treturn `<style>${galleryCss(minCol, maxW, compact, colors)}</style>${grid}`;\n\t}\n\n\tprivate buildGalleryHtmlJs(d: Device, events: Record<string, unknown>[]): string {\n\t\tconst oid = d.oid;\n\t\tconst minCol = this.effectiveMinCol();\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst showSearch = this.config.widgetShowSearch !== false;\n\t\tconst compact = !!this.config.widgetCompact;\n\t\tconst defaultTag = (this.config.widgetDefaultTag || '').trim();\n\t\tconst items = this.sortedEvents(events).map(ev => {\n\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\treturn {\n\t\t\t\tfn: p.fn,\n\t\t\t\tdate: p.date,\n\t\t\t\ttime: p.time,\n\t\t\t\tdur: p.dur,\n\t\t\t\tsize: p.sizeMB,\n\t\t\t\ttag: p.tag,\n\t\t\t\tthumb: p.thumb,\n\t\t\t\tvideo: p.video,\n\t\t\t};\n\t\t});\n\t\tconst cfg = {\n\t\t\tmin_col: minCol,\n\t\t\tshow_tags: !!this.config.widgetShowTags,\n\t\t\tmax_modal_width: maxW,\n\t\t\tlive_aspect: this.camAspect[oid] || this.config.widgetLiveAspect || '',\n\t\t\tplayer_url: (this.config.widgetPlayerUrl || '').trim(),\n\t\t\ttag_position: this.config.widgetTagPosition || 'bottom-left',\n\t\t\tcompact,\n\t\t\tdefault_tag: defaultTag,\n\t\t\tlabels: { noRecordings: this.wt.noRecordings, all: this.wt.all, live: this.wt.live },\n\t\t};\n\t\tconst data = JSON.stringify({ items, live: null, cfg }).replace(/</g, '\\\\u003c');\n\t\tconst boot = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';\n\t\tconst searchHtml = showSearch\n\t\t\t? `<input class=\"advsearchjs\" type=\"text\" placeholder=\"${escHtml(this.wt.search)}\">`\n\t\t\t: '';\n\t\tconst colors: WidgetColors = {\n\t\t\tcardBg: this.config.widgetColorCardBg || undefined,\n\t\t\ttagBg: this.config.widgetColorTagBg || undefined,\n\t\t\ttagText: this.config.widgetColorTagText || undefined,\n\t\t\taccent: this.config.widgetColorAccent || undefined,\n\t\t\tmodalBg: this.config.widgetColorModalBg || undefined,\n\t\t\tradius: this.config.widgetBorderRadius,\n\t\t};\n\t\treturn (\n\t\t\t`<style>${galleryCssJs(minCol, compact, colors)}</style>` +\n\t\t\t`<div class=\"advroot\"><script type=\"application/json\" class=\"advdata\">${data}</script>` +\n\t\t\t`<div class=\"advbar\">${searchHtml}<div class=\"advtagsjs\"></div></div>` +\n\t\t\t`<div class=\"advgridjs\"></div></div>` +\n\t\t\t`<script type=\"text/plain\" class=\"advcode\">${ADV_CLIENT_CODE}</script>` +\n\t\t\t`<img alt=\"\" src=\"${boot}\" style=\"display:none\" onload=\"(function(){if(window.ADVscan){window.ADVscan();return;}var c=document.querySelector('script.advcode');if(!c)return;var s=document.createElement('script');s.textContent=c.textContent;document.body.appendChild(s);})()\">`\n\t\t);\n\t}\n\n\tprivate buildOverviewHtml(cams: Device[]): string {\n\t\tconst ts = Date.now();\n\t\tconst minCol = this.config.widgetMinCol || 150;\n\t\tconst maxW = this.config.widgetMaxModalWidth || 900;\n\t\tconst PAUSE_ATTR = ` onchange=\"if(!this.checked){var m=this.nextElementSibling.nextElementSibling,v=m&&m.querySelector('video');if(v){v.pause();}}\"`;\n\t\tconst tiles = cams\n\t\t\t.map(d => {\n\t\t\t\tconst oid = d.oid;\n\t\t\t\tconst id = `advlive${sanitize(oid)}`;\n\t\t\t\tconst grab = `${this.baseUrl}/grab.jpg?oid=${oid}&ot=2&maintainAR=1&ts=${ts}`;\n\t\t\t\tconst webm = `${this.baseUrl}/video.webm?oid=${oid}&ot=2`;\n\t\t\t\tconst name = escHtml(d.name || `Camera ${oid}`);\n\t\t\t\tconst arRaw = this.camAspect[oid] || this.config.widgetLiveAspect || '';\n\t\t\t\tconst ar = arRaw ? String(arRaw).replace('/', ' / ') : '';\n\t\t\t\tconst fix = ar ? ' advimgfix' : '';\n\t\t\t\tconst arStyle = ar ? ` style=\"aspect-ratio:${ar}\"` : '';\n\t\t\t\tconst inner =\n\t\t\t\t\t`<span class=\"advimg${fix}\"${arStyle}><img src=\"${grab}\" loading=\"lazy\" alt=\"\">` +\n\t\t\t\t\t`<span class=\"advtag\" style=\"top:5px;left:5px\">● ${escHtml(this.wt.live)}</span><span class=\"advplay\"></span></span>` +\n\t\t\t\t\t`<span class=\"advcap\">${name}</span>`;\n\t\t\t\treturn (\n\t\t\t\t\t`<input class=\"advlb\" type=\"checkbox\" id=\"${id}\"${PAUSE_ATTR}>` +\n\t\t\t\t\t`<label class=\"advcell advthumb\" for=\"${id}\">${inner}</label>` +\n\t\t\t\t\t`<div class=\"advmodal\"><label class=\"advbackdrop\" for=\"${id}\"></label>` +\n\t\t\t\t\t`<div class=\"advbox\"><label class=\"advclose\" for=\"${id}\">✕</label>` +\n\t\t\t\t\t`<video class=\"advvideo\" controls preload=\"none\" playsinline src=\"${webm}\"></video>` +\n\t\t\t\t\t`<div class=\"advinfo\">${name} · Live</div></div></div>`\n\t\t\t\t);\n\t\t\t})\n\t\t\t.join('');\n\t\tconst grid = tiles ? `<div class=\"advgrid\">${tiles}</div>` : `<div class=\"advempty\">No cameras</div>`;\n\t\treturn `<style>${galleryCss(minCol, maxW)}</style>${grid}`;\n\t}\n\n\t// ---- event data points ----\n\n\tprivate async writeEventDps(d: Device, fid: string, events: Record<string, unknown>[]): Promise<void> {\n\t\tconst oid = d.oid;\n\t\tawait this.ensureFolder(`${fid}.events`, 'Events', 'channel');\n\t\tawait this.ensureFolder(`${fid}.events.last`, 'Last event', 'channel');\n\n\t\tconst two = (n: number): string => String(n).padStart(2, '0');\n\t\tconst now = new Date();\n\t\tconst td = `${two(now.getDate())}.${two(now.getMonth() + 1)}.`;\n\t\tconst todayCount = events.filter(ev => this.fmtEvent(ev, oid).date === td).length;\n\n\t\tawait this.writeLeaf(`${fid}.events.count`, events.length);\n\t\tawait this.writeLeaf(`${fid}.events.today`, todayCount);\n\n\t\tif (events.length) {\n\t\t\tconst p = this.fmtEvent(events[0], oid);\n\t\t\tconst tsMs = (parseFloat(String((events[0] as AgentDvrEvent).c ?? 0)) - 621355968000000000) / 10000;\n\t\t\tawait this.writeLeaf(`${fid}.events.last.time`, `${p.date} ${p.time}`);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.timestamp`, Math.round(tsMs));\n\t\t\tawait this.writeLeaf(`${fid}.events.last.tag`, p.tag);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.duration`, p.dur ? parseFloat(p.dur) : 0);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.size_mb`, p.sizeMB);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.thumb`, p.thumb);\n\t\t\tawait this.writeLeaf(`${fid}.events.last.video`, p.video);\n\t\t}\n\n\t\t// JSON list for web UI \u2014 browser never needs to talk to AgentDVR for recordings\n\t\tconst jsonId = `${fid}.events.json`;\n\t\tif (!this.ensuredFolders.has(jsonId)) {\n\t\t\tawait this.ensurePath(jsonId);\n\t\t\tawait this.setObjectNotExistsAsync(jsonId, {\n\t\t\t\ttype: 'state',\n\t\t\t\tcommon: { name: 'Recordings list (web UI)', type: 'string', role: 'json', read: true, write: false },\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t\tthis.ensuredFolders.add(jsonId);\n\t\t}\n\t\tawait this.setStateAsync(jsonId, {\n\t\t\tval: JSON.stringify(\n\t\t\t\tevents.slice(0, Math.max(1, this.config.widgetAnzahl || 50)).map(ev => {\n\t\t\t\t\tconst p = this.fmtEvent(ev, oid);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdate: p.date,\n\t\t\t\t\t\ttime: p.time,\n\t\t\t\t\t\tdur: p.dur,\n\t\t\t\t\t\tsize: p.sizeMB,\n\t\t\t\t\t\ttag: p.tag,\n\t\t\t\t\t\tthumb: p.thumb,\n\t\t\t\t\t\tvideo: p.video,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t),\n\t\t\tack: true,\n\t\t});\n\n\t\tawait this.ensureFlag(`${fid}.events.new`, 'New event');\n\n\t\tif (this.config.enablePush) {\n\t\t\tconst pid = `${fid}.events.pushTrigger`;\n\t\t\tif (!this.ensuredFolders.has(pid)) {\n\t\t\t\tawait this.ensurePath(pid);\n\t\t\t\tawait this.setObjectNotExistsAsync(pid, {\n\t\t\t\t\ttype: 'state',\n\t\t\t\t\tcommon: {\n\t\t\t\t\t\tname: 'Push trigger (AgentDVR action)',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\trole: 'text',\n\t\t\t\t\t\tread: true,\n\t\t\t\t\t\twrite: true,\n\t\t\t\t\t\tdef: '',\n\t\t\t\t\t},\n\t\t\t\t\tnative: {},\n\t\t\t\t});\n\t\t\t\tawait this.setStateAsync(pid, { val: '', ack: true });\n\t\t\t\tthis.ensuredFolders.add(pid);\n\t\t\t}\n\t\t\tthis.registry.set(pid, { kind: 'push', oid, fid });\n\t\t}\n\n\t\tconst ignore = (this.config.eventTagsIgnore || 'detected')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim().toLowerCase())\n\t\t\t.filter(Boolean);\n\t\tconst tokensOf = (s: string): string[] =>\n\t\t\ts\n\t\t\t\t.toLowerCase()\n\t\t\t\t.split(/[,\\s]+/)\n\t\t\t\t.filter(Boolean);\n\n\t\tfor (const kw of (this.config.eventTags || '')\n\t\t\t.split(',')\n\t\t\t.map(s => s.trim())\n\t\t\t.filter(Boolean)) {\n\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(kw)}`, `Detected: ${kw}`);\n\t\t}\n\n\t\tif (this.config.eventTagsDynamic) {\n\t\t\tconst seen = new Set<string>();\n\t\t\tfor (const ev of events) {\n\t\t\t\ttokensOf((ev as AgentDvrEvent).tg ?? '').forEach(t => seen.add(t));\n\t\t\t}\n\t\t\tfor (const t of seen) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait this.ensureFlag(`${fid}.events.detected_${sanitize(t)}`, `Detected: ${t}`);\n\t\t\t}\n\t\t}\n\n\t\tlet newCount = 0;\n\t\tif (events.length) {\n\t\t\tconst prev = this.lastEventFn[oid];\n\t\t\tif (prev !== undefined) {\n\t\t\t\tconst i = events.findIndex(e => (e as AgentDvrEvent).fn === prev);\n\t\t\t\tnewCount = i === -1 ? events.length : i;\n\t\t\t}\n\t\t\tthis.lastEventFn[oid] = (events[0] as AgentDvrEvent).fn ?? '';\n\t\t}\n\n\t\tif (newCount > 0) {\n\t\t\tawait this.pulse(`${fid}.events.new`);\n\t\t\tconst tags = new Set<string>();\n\t\t\tfor (let i = 0; i < newCount && i < events.length; i++) {\n\t\t\t\ttokensOf((events[i] as AgentDvrEvent).tg ?? '').forEach(t => tags.add(t));\n\t\t\t}\n\t\t\tfor (const t of tags) {\n\t\t\t\tif (ignore.includes(t)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst tid = `${fid}.events.detected_${sanitize(t)}`;\n\t\t\t\tawait this.ensureFlag(tid, `Detected: ${t}`);\n\t\t\t\tawait this.pulse(tid);\n\t\t\t}\n\t\t\tthis.log.debug(`${newCount} new event(s) cam ${oid} [${[...tags].join(',')}]`);\n\t\t}\n\t}\n\n\t// ---- camera events + widget ----\n\n\tprivate async updateCameraEvents(d: Device, fid: string): Promise<void> {\n\t\tif (d.ot !== 2) {\n\t\t\treturn;\n\t\t}\n\t\tif (!this.config.enableWidget && !this.config.enableEventDps) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.eventBusy[d.oid]) {\n\t\t\treturn;\n\t\t}\n\t\tthis.eventBusy[d.oid] = true;\n\t\ttry {\n\t\t\tconst evRes = await this.apiGet(`/q/getEvents?oid=${d.oid}&ot=2`);\n\t\t\tconst evJson = asJson(evRes.data);\n\t\t\tif (!evJson) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst events = (\n\t\t\t\tArray.isArray(evJson.events) ? evJson.events : Array.isArray(evJson) ? evJson : []\n\t\t\t) as Record<string, unknown>[];\n\n\t\t\tif (this.config.enableEventDps) {\n\t\t\t\tawait this.writeEventDps(d, fid, events);\n\t\t\t}\n\n\t\t\tif (this.config.enableWidget) {\n\t\t\t\tconst wId = `${fid}.widget`;\n\t\t\t\tif (!this.ensuredFolders.has(wId)) {\n\t\t\t\t\tawait this.ensurePath(wId);\n\t\t\t\t\tawait this.setObjectNotExistsAsync(wId, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'HTML gallery widget',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\tdef: '',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tthis.ensuredFolders.add(wId);\n\t\t\t\t}\n\t\t\t\tconst ev = events.slice(0, Math.max(1, this.config.widgetAnzahl || 50));\n\t\t\t\tconst f = (ev[0] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst l = (ev[ev.length - 1] ?? {}) as AgentDvrEvent;\n\t\t\t\tconst sig = `${ev.length}|${f.fn ?? ''}|${l.fn ?? ''}`;\n\t\t\t\tif (this.widgetSig[wId] !== sig) {\n\t\t\t\t\tawait this.setStateAsync(wId, { val: this.buildGalleryHtml(d, ev), ack: true });\n\t\t\t\t\tthis.widgetSig[wId] = sig;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.eventBusy[d.oid] = false;\n\t\t}\n\t}\n\n\tprivate pushRefresh(oid: number | string): void {\n\t\tconst d = this.devById.get(oid);\n\t\tif (!d) {\n\t\t\tthis.log.warn(`Push: camera ${oid} unknown (available after first poll)`);\n\t\t\treturn;\n\t\t}\n\t\tconst fid = this.deviceFolder(d);\n\t\tfor (const ms of [0, 1500, 3500, 6000]) {\n\t\t\tthis.setTimeout(\n\t\t\t\t() =>\n\t\t\t\t\tthis.updateCameraEvents(d, fid).catch(e =>\n\t\t\t\t\t\tthis.log.warn(`Push refresh error: ${(e as Error).message}`),\n\t\t\t\t\t),\n\t\t\t\tms,\n\t\t\t);\n\t\t}\n\t}\n\n\t// ---- main poll ----\n\n\tprivate async poll(): Promise<void> {\n\t\tif (this.pollBusy) {\n\t\t\tthis.log.debug('poll() skipped \u2014 previous run still in progress');\n\t\t\treturn;\n\t\t}\n\t\tthis.pollBusy = true;\n\t\ttry {\n\t\t\tconst res = await this.apiGet('/command/getObjects');\n\t\t\tconst json = asJson(res.data);\n\n\t\t\tif (!res.ok || !json) {\n\t\t\t\tawait this.setStateAsync('info.connection', false, true);\n\t\t\t\tawait this.setStateAsync('system.online', { val: false, ack: true });\n\t\t\t\tthis.log.warn(`AgentDVR unreachable: ${res.error || 'invalid response'}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait this.setStateAsync('info.connection', true, true);\n\t\t\tawait this.setStateAsync('system.online', { val: true, ack: true });\n\n\t\t\tif (json.settings) {\n\t\t\t\tawait this.flattenWrite(json.settings, 'system.settings', 0);\n\t\t\t}\n\n\t\t\tif (this.config.storeRawJson) {\n\t\t\t\tconst clean: Record<string, unknown> = { ...json };\n\t\t\t\tdelete clean.icons;\n\t\t\t\tawait this.writeLeaf('system.raw_getObjects', JSON.stringify(clean).slice(0, 60000));\n\t\t\t}\n\n\t\t\tconst devices = findDevices(json);\n\t\t\tthis.lastCamNames = devices.filter(d => d.ot === 2).map(d => ({ key: this.deviceFolder(d), name: d.name }));\n\t\t\tawait this.setStateAsync('system.cameraCount', { val: devices.filter(d => d.ot === 2).length, ack: true });\n\n\t\t\tconst activeFolders = new Set(devices.map(d => this.deviceFolder(d)));\n\t\t\tfor (const d of devices) {\n\t\t\t\tawait this.buildDevice(d);\n\t\t\t}\n\t\t\tawait this.pruneStaleDevices(activeFolders);\n\n\t\t\tconst stats = asJson((await this.apiGet('/command/getSystemStats')).data);\n\t\t\tif (stats) {\n\t\t\t\tawait this.flattenWrite(stats, 'system.stats', 0);\n\t\t\t\tconst gb = parseSizeGb(stats.disk_free);\n\t\t\t\tif (gb !== null) {\n\t\t\t\t\tawait this.writeLeaf('system.disk_free_gb', gb);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst status = asJson((await this.apiGet('/command/getStatus')).data);\n\t\t\tif (status) {\n\t\t\t\tawait this.flattenWrite(status, 'system.status', 0);\n\t\t\t}\n\n\t\t\tif (this.config.enableSystemControls && Array.isArray(json.profiles)) {\n\t\t\t\tconst states: Record<number, string> = {};\n\t\t\t\tlet activeInd: number | null = null;\n\t\t\t\tfor (const p of json.profiles) {\n\t\t\t\t\tif (p && typeof p === 'object') {\n\t\t\t\t\t\tconst po = p as Record<string, unknown>;\n\t\t\t\t\t\tconst ind = po.id ?? po.ind ?? po.index;\n\t\t\t\t\t\tconst pname = po.name;\n\t\t\t\t\t\tif (typeof ind === 'number' && (typeof pname === 'string' || typeof pname === 'number')) {\n\t\t\t\t\t\t\tstates[ind] = String(pname);\n\t\t\t\t\t\t\tif (po.active === true) {\n\t\t\t\t\t\t\t\tactiveInd = ind;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(states).length > 0) {\n\t\t\t\t\tconst sig = JSON.stringify(states);\n\t\t\t\t\tif (sig !== this.profileSig) {\n\t\t\t\t\t\tthis.profileSig = sig;\n\t\t\t\t\t\tawait this.extendObjectAsync('system.profile.selector', { common: { states } });\n\t\t\t\t\t\tawait this.setStateAsync('system.profile.list', { val: sig, ack: true });\n\t\t\t\t\t}\n\t\t\t\t\tif (activeInd !== null) {\n\t\t\t\t\t\tawait this.setStateAsync('system.profile.selector', { val: activeInd, ack: true });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.config.enableOverview) {\n\t\t\t\tconst cams = devices.filter(d => d.ot === 2);\n\t\t\t\tconst ovId = 'overview';\n\t\t\t\tif (!this.ensuredFolders.has(ovId)) {\n\t\t\t\t\tawait this.setObjectNotExistsAsync(ovId, {\n\t\t\t\t\t\ttype: 'state',\n\t\t\t\t\t\tcommon: {\n\t\t\t\t\t\t\tname: 'Overview (all cameras)',\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\trole: 'html',\n\t\t\t\t\t\t\tread: true,\n\t\t\t\t\t\t\twrite: false,\n\t\t\t\t\t\t\tdef: '',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnative: {},\n\t\t\t\t\t});\n\t\t\t\t\tthis.ensuredFolders.add(ovId);\n\t\t\t\t}\n\t\t\t\tawait this.setStateAsync(ovId, { val: this.buildOverviewHtml(cams), ack: true });\n\t\t\t}\n\n\t\t\tawait this.setStateAsync('system.lastUpdate', { val: new Date().toISOString(), ack: true });\n\t\t\tawait this.setStateAsync('system.lastPoll', { val: Date.now(), ack: true });\n\t\t} finally {\n\t\t\tthis.pollBusy = false;\n\t\t}\n\t}\n\n\tprivate scheduleRefresh(): void {\n\t\tif (this.refreshTimer !== undefined) {\n\t\t\tthis.clearTimeout(this.refreshTimer);\n\t\t\tthis.refreshTimer = undefined;\n\t\t}\n\t\tthis.refreshTimer = this.setTimeout(\n\t\t\t() => this.poll().catch(e => this.log.warn(`Refresh error: ${(e as Error).message}`)),\n\t\t\t1500,\n\t\t);\n\t}\n\n\t// ---- command execution ----\n\n\tprivate ptzUrl(oid: number | string, dir: number): string {\n\t\treturn `/ptz.cgi?oid=${encodeURIComponent(String(oid))}&dir=${dir}`;\n\t}\n\n\tprivate buildCommandUrl(entry: RegistryEntry): string {\n\t\tif (entry.kind === 'ptz') {\n\t\t\treturn this.ptzUrl(entry.oid!, entry.dir!);\n\t\t}\n\t\tif (entry.kind === 'sys') {\n\t\t\treturn entry.path as string;\n\t\t}\n\t\tconst qs: string[] = [];\n\t\tfor (const p of entry.params || []) {\n\t\t\tif (p === 'oid') {\n\t\t\t\tqs.push(`oid=${encodeURIComponent(String(entry.oid))}`);\n\t\t\t} else if (p === 'ot') {\n\t\t\t\tqs.push(`ot=${encodeURIComponent(String(entry.ot))}`);\n\t\t\t}\n\t\t}\n\t\tconst base = entry.path || '';\n\t\tconst sep = base.includes('?') ? '&' : '?';\n\t\treturn base + (qs.length ? `${sep}${qs.join('&')}` : '');\n\t}\n\n\tprivate async clearPtzSiblings(stateId: string): Promise<void> {\n\t\tconst prefix = stateId.slice(0, stateId.lastIndexOf('.') + 1);\n\t\tfor (const p of PTZ_DIRS) {\n\t\t\tif (!p.hold) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst sid = prefix + p.id;\n\t\t\tif (sid !== stateId) {\n\t\t\t\tawait this.setStateAsync(sid, { val: false, ack: true });\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async runCommand(relId: string, entry: RegistryEntry, val: ioBroker.StateValue): Promise<void> {\n\t\tif (entry.kind === 'setProfile') {\n\t\t\tconst ind = typeof val === 'number' ? val : parseInt(String(val ?? ''), 10);\n\t\t\tif (!isNaN(ind)) {\n\t\t\t\tconst url = `/command/setProfile?ind=${ind}`;\n\t\t\t\tconst cmdRes = await this.apiGet(url);\n\t\t\t\tif (cmdRes.ok) {\n\t\t\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t\t\t\tawait this.setStateAsync(relId, { val: ind, ack: true });\n\t\t\t\t} else {\n\t\t\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t\t\t}\n\t\t\t\tthis.scheduleRefresh();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'levelCmd') {\n\t\t\tconst num = typeof val === 'number' ? val : parseFloat(String(val ?? ''));\n\t\t\tif (!isNaN(num)) {\n\t\t\t\tconst url = `${entry.path}?oid=${encodeURIComponent(String(entry.oid))}&ot=${encodeURIComponent(String(entry.ot))}&${entry.valueParam}=${Math.round(num)}`;\n\t\t\t\tconst cmdRes = await this.apiGet(url);\n\t\t\t\tif (cmdRes.ok) {\n\t\t\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t\t\t\tawait this.setStateAsync(relId, { val: Math.round(num), ack: true });\n\t\t\t\t} else {\n\t\t\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t\t\t}\n\t\t\t\tthis.scheduleRefresh();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'snapshotB64') {\n\t\t\tconst snapId = `${entry.fid}.snapshot_b64`;\n\t\t\tawait this.fetchSnapshotB64(entry.oid!, snapId);\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'push') {\n\t\t\tthis.log.info(`Push trigger cam ${entry.oid}`);\n\t\t\tawait this.setStateAsync(relId, { val: '', ack: true });\n\t\t\tthis.pushRefresh(entry.oid!);\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'ptzHold') {\n\t\t\tconst oid = entry.oid!;\n\t\t\tconst startMove = async (): Promise<void> => {\n\t\t\t\tawait this.clearPtzSiblings(relId);\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, entry.dir!));\n\t\t\t\tthis.ptzActive.set(oid, relId);\n\t\t\t\tawait this.setStateAsync(relId, { val: true, ack: true });\n\t\t\t};\n\t\t\tconst stopMove = async (): Promise<void> => {\n\t\t\t\tawait this.apiGet(this.ptzUrl(oid, 11));\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tthis.ptzActive.delete(oid);\n\t\t\t\t}\n\t\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\t};\n\t\t\tif (val) {\n\t\t\t\tif (this.ptzActive.get(oid) === relId) {\n\t\t\t\t\tawait stopMove();\n\t\t\t\t} else {\n\t\t\t\t\tawait startMove();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait stopMove();\n\t\t\t}\n\t\t\tthis.scheduleRefresh();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!val) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (entry.kind === 'sys' && entry.path === null) {\n\t\t\tawait this.poll().catch(e => this.log.warn(`Manual refresh error: ${(e as Error).message}`));\n\t\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = this.buildCommandUrl(entry);\n\t\tconst cmdRes = await this.apiGet(url);\n\t\tif (cmdRes.ok) {\n\t\t\tthis.log.debug(`OK: ${url}`);\n\t\t} else {\n\t\t\tthis.log.warn(`Command failed (${url}): ${cmdRes.error}`);\n\t\t}\n\n\t\tawait this.setStateAsync(relId, { val: false, ack: true });\n\t\tthis.scheduleRefresh();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AgentDvr(options);\n} else {\n\t(() => new AgentDvr())();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["url", "cmdRes"]
|
|
7
7
|
}
|