DS-KD8003 - DS-KV8113 - DS-KV8213 - DS-KV6113 - DS-KV8413 and .... integration Hikvision HikConnect Video intercom doorbell

great! but how can we use it then? with HA app? or what do you want to build?
Its qiute easy to start twoway audio, just 2 commands
but we need an app or something to make the actual talk also?

the implementation I have been using is to pass the SDK data from HA to Scrypted, whcih integrates the entire video doorbell into the iOS homekit app with recording using Homekit Secure Video.

ah ok, and what do you want to make?
i dont have applye/homekit :slight_smile:

remember, when someone presses the doorbell, if you then activate twoway audio, it doesnt work
i think its because the speaker was already in use

have you tested it?
i need to hangup/decline call first

I did not consider that, Hikvision definitely does not make it easy for third party integrators.

yeah, but i can be wrong, but you can test with hikconnect app
if you make a doorbell call, and the just let it ring, then start twoway audio manually, in my case that doesnt work

That screenshot, is that the app scrypted? ot what is it?
not sure why you are using scrypted? i dont know that? but isnt it just a streaming service? why dont you use HA for streaming cams?

It is the iOS Homekit app. Scrypted is a server that takes video feeds and transforms them into HKSV compatible feeds.

Ah ok, well, let me know how it goes…
You want to enable two way audio on scrypted?

correct - even if I am only able to enable two way audio on an open video feed and cannot utilize the doorbell calling answer ability

What I do, I use Synology surveillance for starting two way audio, but before I enable two way audio, I send the answer command first…
How are you going to implement it in scrypted? The two way audio part?

I plan to add the PUT command (ISAPI) to the code:

import AxiosDigestAuth from '@koush/axios-digest-auth';
import { EventEmitter } from "stream";

function getChannel(channel: string) {
    return channel || '101';
}

export enum HikVisionCameraEvent {
    MotionDetected = "<eventType>VMD</eventType>",
    VideoLoss = "<eventType>videoloss</eventType>",
    // <eventType>linedetection</eventType>
    // <eventState>active</eventState>
    // <eventType>linedetection</eventType>
    // <eventState>inactive</eventState>
    LineDetection = "<eventType>linedetection</eventType>",
    // <eventType>fielddetection</eventType>
    // <eventState>active</eventState>
    // <eventType>fielddetection</eventType>
    // <eventState>inactive</eventState>
    FieldDetection = "<eventType>fielddetection</eventType>",
}


export interface HikVisionCameraStreamSetup {
    videoCodecType: string;
    audioCodecType: string;
}

export class HikVisionCameraAPI {
    digestAuth: AxiosDigestAuth;
    deviceModel: Promise<string>;
    listenerPromise: Promise<EventEmitter>;

    constructor(public ip: string, username: string, password: string, public console: Console) {
        this.digestAuth = new AxiosDigestAuth({
            username,
            password,
        });
    }

    async checkDeviceModel(): Promise<string> {
        if (!this.deviceModel) {
            this.deviceModel = new Promise(async (resolve, reject) => {
                try {
                    const response = await this.digestAuth.request({
                        method: "GET",
                        responseType: 'text',
                        url: `http://${this.ip}/ISAPI/System/deviceInfo`,
                    });
                    const deviceModel = response.data.match(/>(.*?)<\/model>/)?.[1];
                    resolve(deviceModel);
                } catch (e) {
                    this.console.error('error checking NVR model', e);
                    resolve(undefined);
                }
            });
        }
        return await this.deviceModel;
    }

    async checkIsOldModel() {
        // The old Hikvision DS-7608NI-E2 doesn't support channel capability checks, and the requests cause errors
        const model = await this.checkDeviceModel();
        if (!model)
            return;
        return !!model?.match(/DS-7608NI-E2/);
    }

    async checkStreamSetup(channel: string, isOld: boolean): Promise<HikVisionCameraStreamSetup> {
        if (isOld) {
            this.console.error('NVR is old version.  Defaulting camera capabilities to H.264/AAC');
            return {
                videoCodecType: "H.264",
                audioCodecType: "AAC",
            }
        }

        const response = await this.digestAuth.request({
            method: "GET",
            responseType: 'text',
            url: `http://${this.ip}/ISAPI/Streaming/channels/${getChannel(channel)}/capabilities`,
        });

        // this is bad:
        // <videoCodecType opt="H.264,H.265">H.265</videoCodecType>
        const vcodec = response.data.match(/>(.*?)<\/videoCodecType>/);
        const acodec = response.data.match(/>(.*?)<\/audioCompressionType>/);

        return {
            videoCodecType: vcodec?.[1],
            audioCodecType: acodec?.[1],
        }
    }

    async jpegSnapshot(channel: string): Promise<Buffer> {
        const url = `http://${this.ip}/ISAPI/Streaming/channels/${getChannel(channel)}/picture?snapShotImageType=JPEG`

        const response = await this.digestAuth.request({
            method: "GET",
            responseType: 'arraybuffer',
            url: url,
        });

        return Buffer.from(response.data);
    }

    async listenEvents() {
        // support multiple cameras listening to a single single stream 
        if (!this.listenerPromise) {
            this.listenerPromise = new Promise(async (resolve, reject) => {
                const url = `http://${this.ip}/ISAPI/Event/notification/alertStream`;
                this.console.log('listener url', url);

                const response = await this.digestAuth.request({
                    method: "GET",
                    url,
                    responseType: 'stream',
                });
                const stream = response.data as Readable;

                stream.on('data', (buffer: Buffer) => {
                    const data = buffer.toString();
                    // this.console.log(data);
                    for (const event of Object.values(HikVisionCameraEvent)) {
                        if (data.indexOf(event) !== -1) {
                            const cameraNumber = data.match(/<channelID>(.*?)</)?.[1] || data.match(/<dynChannelID>(.*?)</)?.[1];
                            stream.emit('event', event, cameraNumber);
                        }
                    }
                });
                resolve(stream);
            });
        }

        const eventSource = await this.listenerPromise;
        return eventSource;
    }
}

Let me know how it goes , very interested in this project… Gonna have a look at the code

is this pushed out through the github repository yet?

Yes, but you need to uninstall and reinstall, not sure yet how to work with releases… all new to me also;-)

First addon ever :slight_smile:

I own a DS-KV8113-WME1(B). I’ve just update the firmware to V2.2.53 build 220108. Using curl I was able to open the lock before and after firmware update using command [1] below. However, it looks like the curl command that supposed to get the status (one of: {idle, ring, onCall}) is always returning idle.

Is the DS-KV8113-WME1(B) with the latest firmware supposed to correctly return the status?

Command I used to open the lock

# command 1
curl -i --digest -u admin:xxx -X PUT -d '<RemoteControlDoor><cmd>open</cmd></RemoteControlDoor>' http://192.168.0.xxx/ISAPI/AccessControl/RemoteControl/door/1

How I verified the status

  1. I’ve run command below (on a linux based system - my terminal on HA).
  2. I’ve left to the gate and push the ring button
  3. Wait for about 5 seconds
  4. Answer the call and keep it open for 5 more seconds
  5. run cat out.txt | tee status and see that the status is always idle.
# command 2
# basically calls curl every second and prints output to terminal and also in the file out.txt. 
# this allows me time to interact with the device and also eliminates probability to configuration errors.
for i in {1..200}; curl --digest -u admin:xxx http://192.168.0.xxx/ISAPI/VideoIntercom/callStatus?format=json; sleep 1; echo $i; done | tee out.txt

Note, before firmware update there was a similar behavior for both interaction with the door-bell/lock. Initially the firmware was V2.2.11 build 201126.

1 Like

have you tried command below, for 8003 system, i also need this one:

curl -i --digest -u admin:xxxx http://192.168.0.70/ISAPI/VideoIntercom/callStatus?format=json&channelType=tripartitePlatform

Hello all,

I see thousands of messages in here, and just wanted to ask few questions about DS-KD8003:

Just wanted to know if anyone know if the DS-KD8003 integrates the back light button and IR turned on during night periods and not just when people presses the button.
Also if the SIP config can be changed, so that I can integrate a different SIP server, or add different SIP clients
And last thing, is DS-KD8003 compatible with home assistant without the need of internet access to their hikvision cloud?

Kind regards