mirror of
https://github.com/koush/scrypted.git
synced 2026-05-26 22:50:30 +01:00
Merge branch 'main' of github.com:koush/scrypted
This commit is contained in:
@@ -8,7 +8,7 @@ sc.exe stop scrypted.exe
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||
|
||||
# Install node.js
|
||||
choco upgrade -y nodejs-lts --version=18.14.0
|
||||
choco upgrade -y nodejs-lts --version=18.19.1
|
||||
|
||||
# Install Python
|
||||
choco upgrade -y python39
|
||||
|
||||
@@ -39,6 +39,8 @@ Each 'Channel' or (camera) Device attached to the NVR must be configured as sepa
|
||||
* `Snapshot URL Override` camera's IP address (preferred) or specific port number of NVR for that camera (may work). That is: `http://<camera IP address>/cgi-bin/snapshot.cgi` or `http://<NVR IP address>:<NVR port # for camera>/cgi-bin/snapshot.cgi`
|
||||
* `Channel Number Override` camera's channel number as known to DVR
|
||||
|
||||
## Dahua Lock/Unlock
|
||||
Dahua DTO video intercoms have built-in access control for locks/doors. If you have set the Amcrest plugin up with `Doorbell Type` set to `Dahua Doorbell`, you can enable support for remotely locking/unlocking by enabling/toggle the option `Enable Dahua Lock`.
|
||||
|
||||
# Troubleshooting
|
||||
## General
|
||||
|
||||
4
plugins/amcrest/package-lock.json
generated
4
plugins/amcrest/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.134",
|
||||
"version": "0.0.135",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.134",
|
||||
"version": "0.0.135",
|
||||
"license": "Apache",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/amcrest",
|
||||
"version": "0.0.134",
|
||||
"version": "0.0.135",
|
||||
"description": "Amcrest Plugin for Scrypted",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache",
|
||||
|
||||
@@ -125,4 +125,20 @@ export class AmcrestCameraClient {
|
||||
this.console.log(response.body);
|
||||
}
|
||||
}
|
||||
|
||||
async unlock(): Promise<boolean> {
|
||||
const response = await this.request({
|
||||
url: `http://${this.ip}/cgi-bin/accessControl.cgi?action=openDoor&channel=1&UserID=101&Type=Remote`,
|
||||
responseType: 'text',
|
||||
});
|
||||
return response.body.includes('OK');
|
||||
}
|
||||
|
||||
async lock(): Promise<boolean> {
|
||||
const response = await this.request({
|
||||
url: `http://${this.ip}/cgi-bin/accessControl.cgi?action=closeDoor&channel=1&UserID=101&Type=Remote`,
|
||||
responseType: 'text',
|
||||
});
|
||||
return response.body.includes('OK');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ffmpegLogInitialOutput } from '@scrypted/common/src/media-helpers';
|
||||
import { readLength } from "@scrypted/common/src/read-stream";
|
||||
import sdk, { Camera, DeviceCreatorSettings, DeviceInformation, FFmpegInput, Intercom, MediaObject, MediaStreamOptions, PictureOptions, Reboot, RequestPictureOptions, RequestRecordingStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, VideoCameraConfiguration, VideoRecorder } from "@scrypted/sdk";
|
||||
import sdk, { Camera, DeviceCreatorSettings, DeviceInformation, FFmpegInput, Intercom, Lock, MediaObject, MediaStreamOptions, Reboot, RequestPictureOptions, RequestRecordingStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, VideoCameraConfiguration, VideoRecorder } from "@scrypted/sdk";
|
||||
import child_process, { ChildProcess } from 'child_process';
|
||||
import { PassThrough, Readable, Stream } from "stream";
|
||||
import { OnvifIntercom } from "../../onvif/src/onvif-intercom";
|
||||
@@ -22,7 +22,7 @@ function findValue(blob: string, prefix: string, key: string) {
|
||||
return parts[1];
|
||||
}
|
||||
|
||||
class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration, Camera, Intercom, VideoRecorder, Reboot {
|
||||
class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration, Camera, Intercom, Lock, VideoRecorder, Reboot {
|
||||
eventStream: Stream;
|
||||
cp: ChildProcess;
|
||||
client: AmcrestCameraClient;
|
||||
@@ -270,6 +270,16 @@ class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration,
|
||||
|
||||
|
||||
if (doorbellType == DAHUA_DOORBELL_TYPE) {
|
||||
ret.push(
|
||||
{
|
||||
title: 'Enable Dahua Lock',
|
||||
key: 'enableDahuaLock',
|
||||
description: 'Some Dahua Doorbells have a built in lock/door access control.',
|
||||
type: 'boolean',
|
||||
value: (this.storage.getItem('enableDahuaLock') === 'true').toString(),
|
||||
}
|
||||
);
|
||||
|
||||
ret.push(
|
||||
{
|
||||
title: 'Multiple Call Buttons',
|
||||
@@ -462,6 +472,10 @@ class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration,
|
||||
if (isDoorbell || twoWayAudio) {
|
||||
interfaces.push(ScryptedInterface.Intercom);
|
||||
}
|
||||
const enableDahuaLock = this.storage.getItem('enableDahuaLock') === 'true';
|
||||
if (isDoorbell && doorbellType === DAHUA_DOORBELL_TYPE && enableDahuaLock) {
|
||||
interfaces.push(ScryptedInterface.Lock);
|
||||
}
|
||||
const continuousRecording = this.storage.getItem('continuousRecording') === 'true';
|
||||
if (continuousRecording)
|
||||
interfaces.push(ScryptedInterface.VideoRecorder);
|
||||
@@ -598,6 +612,18 @@ class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration,
|
||||
showRtspUrlOverride() {
|
||||
return false;
|
||||
}
|
||||
|
||||
async lock(): Promise<void> {
|
||||
if (!this.client.lock()) {
|
||||
this.console.error("Could not lock");
|
||||
}
|
||||
}
|
||||
|
||||
async unlock(): Promise<void> {
|
||||
if (!this.client.unlock()) {
|
||||
this.console.error("Could not unlock");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AmcrestProvider extends RtspProvider {
|
||||
|
||||
@@ -32,8 +32,10 @@ If recordings dont work, it's generally because of a few reasons, **follow the s
|
||||
|
||||
### HomeKit Discovery and Pairing Issues
|
||||
|
||||
If HomeKit is not discoverable, make sure LAN/WLAN multicast is enabled on your router.
|
||||
If HomeKit fails while pairing during a Docker install, ensure host networking is being used.
|
||||
* Ensure all your Home hubs are online and updated. Power cycling them is recommended in case one is stuck.
|
||||
* Ensure LAN/WLAN multicast is enabled on your router.
|
||||
* Ensure the iOS device you are using for pairing is on the same network (pairing will fail on cellular).
|
||||
* Ensure the Docker installation (if applicable) is using host networking. This configuration is the default if the official Scrypted Docker compose install script was used.
|
||||
|
||||
### HomeKit Live Streaming Timeout (Recordings may be working)
|
||||
|
||||
@@ -50,6 +52,9 @@ This almost always due to your camera bitrate being too high for remote streamin
|
||||
1) Use a lower bitrate substream for Remote Streaming.
|
||||
2) Enable Transcoding on Remote Streaming.
|
||||
|
||||
Other things to check:
|
||||
1) Ensure the Home app has cellular network permission.
|
||||
|
||||
|
||||
### mDNS Advertiser Options
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { bindCharacteristic } from "../common";
|
||||
import { Accessory, Characteristic, CharacteristicEventTypes, Service, uuid } from '../hap';
|
||||
import type { HomeKitPlugin } from "../main";
|
||||
import { getService as getOnOffService } from "./onoff-base";
|
||||
import { HOMEKIT_MIXIN } from "../homekit-mixin";
|
||||
|
||||
const { deviceManager, systemManager } = sdk;
|
||||
|
||||
@@ -201,7 +202,7 @@ export function mergeOnOffDevicesByType(device: ScryptedDevice & DeviceProvider,
|
||||
const children = getChildDevices(device);
|
||||
const mergedDevices = [];
|
||||
const services = children.map((child: ScryptedDevice & OnOff) => {
|
||||
if (child.type !== type || !child.interfaces.includes(ScryptedInterface.OnOff))
|
||||
if (child.type !== type || !child.interfaces.includes(ScryptedInterface.OnOff) || !child.interfaces.includes(HOMEKIT_MIXIN))
|
||||
return undefined;
|
||||
|
||||
const onOffService = getOnOffService(child, accessory, Service.Switch)
|
||||
|
||||
Reference in New Issue
Block a user