Skip to content

Commit

Permalink
Trying to migrate backend to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
GermanBluefox committed Sep 24, 2024
1 parent 13cb0e8 commit 674996a
Show file tree
Hide file tree
Showing 47 changed files with 8,943 additions and 63 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@alcalzone/release-script-plugin-license": "^3.7.0",
"@iobroker/build-tools": "^1.0.3",
"@iobroker/testing": "^5.0.0",
"@iobroker/types": "^6.0.11",
"@iobroker/vis-2-widgets-react-dev": "^4.0.3",
"@types/chai": "^4.3.19",
"@types/chai-as-promised": "^8.0.0",
Expand Down Expand Up @@ -70,6 +71,7 @@
"lint": "eslint",
"prepublishOnly": "node node_modules/gulp/bin/gulp --gulpfile tasks.js default",
"build": "node tasks",
"tsc": "tsc -p src/tsconfig.json",
"release": "release-script",
"release-patch": "release-script patch --yes",
"release-minor": "release-script minor --yes",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
7,331 changes: 7,331 additions & 0 deletions src-editor/package-lock.json

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
23 changes: 23 additions & 0 deletions src-editor/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": "./",
"types": ["@iobroker/types", "vite/client"]
},
"include": ["src"],
"exclude": ["node_modules", "build"]
}
File renamed without changes.
84 changes: 84 additions & 0 deletions src/cameras/eufy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const { getRtspSnapshot } = require('./rtsp');
const path = require('node:path');
const URL = require('node:url');

async function init(adapter, cam) {
adapter.__urlCameras = adapter.__urlCameras || {};
adapter.__urlCameras[cam.name] = true;

if (cam.useOid && !cam.oid) {
throw new Error(`Invalid object ID: "${cam.oid}"`);
}

// check parameters
if (!cam.useOid && (!cam.ip || typeof cam.ip !== 'string')) {
throw new Error(`Invalid IP: "${cam.ip}"`);
}

cam.settings = JSON.parse(JSON.stringify(cam));

if (cam.useOid) {
const url = await adapter.getForeignStateAsync(cam.oid);
const parts = cam.oid.split('.');
parts.pop();
parts.push('rtsp_stream');
const rtspEnabled = await adapter.getForeignStateAsync(parts.join('.'));
if (rtspEnabled && !rtspEnabled.val) {
await adapter.setForeignStateAsync(parts.join('.'), true);
}
if (url && url.val) {
const u = URL.parse(url.val);
cam.settings.ip = u.hostname;
cam.settings.port = u.port;
cam.settings.urlPath = u.pathname;
cam.settings.username = u.username;
cam.settings.decodedPassword = u.password;
cam.settings.timeout = parseInt(cam.timeout || adapter.config.defaultTimeout, 10) || 10000;
}
} else {
cam.settings.port = 80;
cam.settings.urlPath = '/live0';
}
}

function unload(adapter, cam) {
if (adapter.__urlCameras[cam.name]) {
delete adapter.__urlCameras[cam.name];
}
// after last unloading, all the resources must be cleared too
if (Object.keys(adapter.__urlCameras)) {
// unload
}

// do nothing
return Promise.resolve();
}

function process(adapter, cam) {
if (cam.runningRequest) {
return cam.runningRequest;
}

adapter.log.debug(`Requesting Eufy from ${cam.ip}...`);

const outputFileName = path.normalize(`${adapter.config.tempPath}/${cam.ip.replace(/[.:]/g, '_')}.jpg`);

cam.runningRequest = getRtspSnapshot(adapter.config.ffmpegPath, cam.settings, outputFileName, adapter)
.then(body => {
cam.runningRequest = null;
adapter.log.debug(`Eufy from ${cam.ip}. Done!`);

return {
body,
contentType: 'image/jpeg',
};
});

return cam.runningRequest;
}

module.exports = {
init,
process,
unload,
};
71 changes: 71 additions & 0 deletions src/cameras/hikam.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const { getRtspSnapshot, getRtspURL } = require('./rtsp');
const path = require('node:path');

// documentation https://www.wiwacam.com/de/mw1-minikamera-kurzanleitung-und-faq/
// https://support.hikam.de/support/solutions/articles/16000070656-zugriff-auf-kameras-der-2-generation-via-onvif-f%C3%BCr-s6-q8-a7-2-generation-

function init(adapter, cam) {
adapter.__urlCameras = adapter.__urlCameras || {};
adapter.__urlCameras[cam.name] = true;

// check parameters
if (!cam.ip || typeof cam.ip !== 'string') {
return Promise.reject(`Invalid IP: "${cam.ip}"`);
}

cam.decodedPassword = cam.password ? adapter.decrypt(cam.password) : '';

cam.settings = JSON.parse(JSON.stringify(cam));
cam.settings.port = 554;
cam.settings.urlPath = cam.quality === 'high' ? '/stream=0' : '/stream=1';
cam.settings.timeout = parseInt(cam.timeout || adapter.config.defaultTimeout, 10) || 2000;

return Promise.resolve();
}

function unload(adapter, cam) {
if (adapter.__urlCameras[cam.name]) {
delete adapter.__urlCameras[cam.name];
}
// after last unload, all the resources must be cleared too
if (Object.keys(adapter.__urlCameras)) {
// unload
}

// do nothing
return Promise.resolve();
}

function process(adapter, cam) {
if (cam.runningRequest) {
return cam.runningRequest;
}

adapter.log.debug(`Requesting HiKam from ${cam.ip}...`);

const outputFileName = path.normalize(`${adapter.config.tempPath}/${cam.ip.replace(/[.:]/g, '_')}.jpg`);

if (!cam.settings) {
return Promise.reject(`Invalid settings for ${JSON.stringify(cam)}`);
}

cam.runningRequest = getRtspSnapshot(adapter.config.ffmpegPath, cam.settings, outputFileName, adapter)
.then(body => {
cam.runningRequest = null;
adapter.log.debug(`HiKam from ${cam.ip}. Done!`);

return {
body,
contentType: 'image/jpeg',
};
});

return cam.runningRequest;
}

module.exports = {
init,
process,
unload,
getRtspURL,
};
70 changes: 70 additions & 0 deletions src/cameras/reolinkE1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const { getRtspSnapshot, getRtspURL } = require('./rtsp');
const path = require('node:path');

// documentation https://reolink.com/wp-content/uploads/2017/01/Reolink-CGI-command-v1.61.pdf

function init(adapter, cam) {
adapter.__urlCameras = adapter.__urlCameras || {};
adapter.__urlCameras[cam.name] = true;

// check parameters
if (!cam.ip || typeof cam.ip !== 'string') {
return Promise.reject(`Invalid IP: "${cam.ip}"`);
}

cam.decodedPassword = cam.password ? adapter.decrypt(cam.password) : '';

cam.settings = JSON.parse(JSON.stringify(cam));
cam.settings.port = 554;
cam.settings.urlPath = cam.quality === 'high' ? '/h264Preview_01_main' : '/h264Preview_01_sub';
cam.settings.timeout = parseInt(cam.timeout || adapter.config.defaultTimeout, 10) || 2000;

return Promise.resolve();
}

function unload(adapter, cam) {
if (adapter.__urlCameras[cam.name]) {
delete adapter.__urlCameras[cam.name];
}
// after last unload, all the resources must be cleared too
if (Object.keys(adapter.__urlCameras)) {
// unload
}

// do nothing
return Promise.resolve();
}

function process(adapter, cam) {
if (cam.runningRequest) {
return cam.runningRequest;
}

adapter.log.debug(`Requesting Reolink E1 from ${cam.ip}...`);

const outputFileName = path.normalize(`${adapter.config.tempPath}/${cam.ip.replace(/[.:]/g, '_')}.jpg`);

if (!cam.settings) {
return Promise.reject(`Invalid settings for ${JSON.stringify(cam)}`);
}

cam.runningRequest = getRtspSnapshot(adapter.config.ffmpegPath, cam.settings, outputFileName, adapter)
.then(body => {
cam.runningRequest = null;
adapter.log.debug(`Reolink E1 from ${cam.ip}. Done!`);

return {
body,
contentType: 'image/jpeg',
};
});

return cam.runningRequest;
}

module.exports = {
init,
process,
unload,
getRtspURL,
};
Loading

0 comments on commit 674996a

Please sign in to comment.