From aa90f43cfad59c9c0a1b0f2b113835dfbdc5175e Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 7 Nov 2023 15:55:21 +0100 Subject: [PATCH 01/13] chore: Remove trailing whitespace --- crypt.js | 2 +- pppp.js | 6 +++--- readme.md | 2 +- speaker.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crypt.js b/crypt.js index bff3866..1543b18 100644 --- a/crypt.js +++ b/crypt.js @@ -74,4 +74,4 @@ module.exports = { decrypt, dh, eh -} \ No newline at end of file +} diff --git a/pppp.js b/pppp.js index 3ccba7c..214ee75 100644 --- a/pppp.js +++ b/pppp.js @@ -25,7 +25,7 @@ TYPE_DICT[MSG_ALIVE_ACK] = 'MSG_ALIVE_ACK' TYPE_DICT[MSG_CLOSE] = 'MSG_CLOSE' class PPPP extends EventEmitter { - constructor(options) { + constructor(options) { super() this.socket = dgram.createSocket('udp4') @@ -43,7 +43,7 @@ class PPPP extends EventEmitter { this.isConnected = false this.punchCount = 0 - this.broadcastDestination=options.broadcastip, + this.broadcastDestination=options.broadcastip, this.myIpAddressToBind=options.thisip this.socket.on('error', (err) => { @@ -186,7 +186,7 @@ class PPPP extends EventEmitter { let bindOptions = {} if (this.myIpAddressToBind){ bindOptions.address = this.myIpAddressToBind - } + } console.log("bind options:"+bindOptions) this.socket.bind(bindOptions) } diff --git a/readme.md b/readme.md index 79015f2..c607095 100644 --- a/readme.md +++ b/readme.md @@ -21,4 +21,4 @@ The `run_with_audio.js` additionally plays audio using the npm plugin [speaker]( **If you have the "DGOC" prefix, you may need to change the boradcast address:** If your run.js dosent connect ('Broadcast message sent' line on screen that just repeats), use the option '-b 192.168.0.255'. -Replace the '192.168.0.' part with your own wifi ip range. \ No newline at end of file +Replace the '192.168.0.' part with your own wifi ip range. diff --git a/speaker.js b/speaker.js index 1cb8ab7..d59a9cb 100644 --- a/speaker.js +++ b/speaker.js @@ -5,4 +5,4 @@ const speaker = new Speaker({ sampleRate: 8000, // 44,100 Hz sample rate }); -module.exports = speaker; \ No newline at end of file +module.exports = speaker; From 243e52dfb856f23e720a91d031915db454f1db81 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 7 Nov 2023 16:08:05 +0100 Subject: [PATCH 02/13] feat: Add additional commands --- pppp.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/pppp.js b/pppp.js index 214ee75..c28a2a4 100644 --- a/pppp.js +++ b/pppp.js @@ -334,6 +334,60 @@ class PPPP extends EventEmitter { ) } + sendCMDGetWhiteLight() { + this.sendCMDPacket( + `{"pro":"get_whiteLight","cmd":305,"user":"admin","pwd":"6666"}` + ) + } + + sendCMDSetWhiteLight(isOn) { + this.sendCMDPacket( + `{"pro":"set_whiteLight","cmd":304,"user":"admin","pwd":"6666","status":${ + isOn ? 1 : 0 + }}` + ) + } + + sendCMDHeartBeat() { + this.sendCMDPacket( + `{"pro":"dev_control","cmd":102,"user":"admin","pwd":"6666","heart":1,"devmac":"0000"}` + ) + } + + sendCMDGetDeviceParameters() { + this.sendCMDPacket( + `{"pro":"get_parms","cmd":101,"user":"admin","pwd":"6666"}` + ) + /* returns e.g. + { + "cmd": 101, + "result": 0, + "tz": -8, + "time": 1699397280, + "icut": 0, + "batValue": 90, + "batStatus": 1, + "sysver": "HQLS_HK66_DP_20230802 20:08:13", + "mcuver": "1.1.1.1", + "isShow4KMenu": 0, + "isShowIcutAuto": 1, + "rotmir": 0, + "signal": 100, + "lamp": 0 +} + */ + } + + // direction == 0..7: + // 0 = start motor in A axis + // 1 = stop motor in A axis + // etc + sendCMDPtzControl(direction) { + this.sendCMDPacket( + `{"pro":"ptz_control","cmd":128,"parms":0,"value":${direction},"user":"admin","pwd":"6666"}` + ) + } + sendCMDReboot() { this.sendCMDPacket( `{"pro":"dev_control","cmd":102,"user":"admin","pwd":"6666","reboot":1,"devmac":"0000"}` From 8be983615b5b41a8a64f2840d40bcd0d9e35416a Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 7 Nov 2023 17:41:18 +0100 Subject: [PATCH 03/13] feat: Add get firmware/alarm commands --- pppp.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pppp.js b/pppp.js index c28a2a4..95aff80 100644 --- a/pppp.js +++ b/pppp.js @@ -378,6 +378,48 @@ class PPPP extends EventEmitter { */ } + + sendCMDGetDeviceFirmwareInfo() { + this.sendCMDPacket( + `{"pro":"get_cloudsupport","cmd":9000,"user":"admin","pwd":"6666"}` + ) + /* + the command name is a mis-nomer. this is more like TF card support, + firmware version and flashability. Returns something like: + { + "cmd": 9000, + "result": 0, + "flashOrTf": 1, + "uploadType": 0, + "isExistTf": 0, + "productName": "HQLS_HK66_DP230802", + "fwVer": 10000, + "supportNewUp": 1 + } + */ + } + + sendCMDGetAlarm() { + this.sendCMDPacket( + `{"pro":"get_alarm","cmd":107,"user":"admin","pwd":"6666"}` + ) + /* + Returns something like: + { + "cmd": 107, + "result": 0, + "pirenable": 0, + "pirsensitive": 3, + "pirvideo": 0, + "pirPush": 0, + "pirvideotime": 10, + "pirDelayTime": 120, + "AalarmInterval": 2, + "pirCloudUpCount": 50 + } + */ + } + // direction == 0..7: // 0 = start motor in A axis // 1 = stop motor in A axis From 5bdbde0ddd49c4045aac70fffb2746a1100486e8 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 7 Nov 2023 17:42:37 +0100 Subject: [PATCH 04/13] fix: sendCMDGetDeviceParameters was already implemented --- pppp.js | 43 ++++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/pppp.js b/pppp.js index 95aff80..ddb8e74 100644 --- a/pppp.js +++ b/pppp.js @@ -312,6 +312,24 @@ class PPPP extends EventEmitter { this.sendCMDPacket( `{"pro":"get_parms","cmd":101,"user":"admin","pwd":"6666","devmac":"0000"}` ) + /* returns e.g. + { + "cmd": 101, + "result": 0, + "tz": -8, + "time": 1699397280, + "icut": 0, + "batValue": 90, + "batStatus": 1, + "sysver": "HQLS_HK66_DP_20230802 20:08:13", + "mcuver": "1.1.1.1", + "isShow4KMenu": 0, + "isShowIcutAuto": 1, + "rotmir": 0, + "signal": 100, + "lamp": 0 +} + */ } sendCMDsetParams(changes) { @@ -354,31 +372,6 @@ class PPPP extends EventEmitter { ) } - sendCMDGetDeviceParameters() { - this.sendCMDPacket( - `{"pro":"get_parms","cmd":101,"user":"admin","pwd":"6666"}` - ) - /* returns e.g. - { - "cmd": 101, - "result": 0, - "tz": -8, - "time": 1699397280, - "icut": 0, - "batValue": 90, - "batStatus": 1, - "sysver": "HQLS_HK66_DP_20230802 20:08:13", - "mcuver": "1.1.1.1", - "isShow4KMenu": 0, - "isShowIcutAuto": 1, - "rotmir": 0, - "signal": 100, - "lamp": 0 -} - */ - } - - sendCMDGetDeviceFirmwareInfo() { this.sendCMDPacket( `{"pro":"get_cloudsupport","cmd":9000,"user":"admin","pwd":"6666"}` From 299ffc82ba5531f2f7c6b9641c322abbb849331d Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 7 Nov 2023 23:30:06 +0100 Subject: [PATCH 05/13] feat: add one more command and some documentation --- pppp.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pppp.js b/pppp.js index ddb8e74..0fdce65 100644 --- a/pppp.js +++ b/pppp.js @@ -352,6 +352,21 @@ class PPPP extends EventEmitter { ) } + sendCMDTalkSend() { + // it is unclear for me what this really does + this.sendCMDPacket( + `{"pro":"talk_send","cmd":300,"user":"admin","pwd":"6666","isSend":1}` + ) + /* + returns like: + { + "cmd": 300, + "result": 0 + } + */ + } + + sendCMDGetWhiteLight() { this.sendCMDPacket( `{"pro":"get_whiteLight","cmd":305,"user":"admin","pwd":"6666"}` @@ -390,6 +405,18 @@ class PPPP extends EventEmitter { "supportNewUp": 1 } */ + + /* incorrect password: + { + "cmd": 9000, + "result": -3 +}*/ + /* incorrect user name: (or password field missing) + { + "cmd": 9000, + "result": -1 +}*/ + } sendCMDGetAlarm() { From 7300e63b35db257273c07a3328c7ca035ffb1f0c Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 7 Nov 2023 23:51:04 +0100 Subject: [PATCH 06/13] refactor: Remove duplication when sending commands --- pppp.js | 115 ++++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 71 deletions(-) diff --git a/pppp.js b/pppp.js index 0fdce65..16f2660 100644 --- a/pppp.js +++ b/pppp.js @@ -263,56 +263,62 @@ class PPPP extends EventEmitter { this.sendEnc(buf) } + sendCommand(command_name, command_number, args) { + let fixed_data = { + user: 'admin', + pwd: '6666', + devmac:'0000' + } + + let data = { + pro: command_name, + cmd: command_number + } + + this.sendCMDPacket(JSON.stringify({ ...data, ...args, ...fixed_data})) + } + sendCMDCheckUser() { - this.sendCMDPacket( - `{"pro":"check_user","cmd":100,"devmac":"0000","user":"admin","pwd":"6666"}` - ) + this.sendCommand("check_user", 100); } sendCMDrequestVideo1() { //"1080p" "HD" with 640x480 - this.sendCMDPacket( - `{"pro":"stream","cmd":111,"video":1,"user":"admin","pwd":"6666","devmac":"0000"}` - ) + this.sendCommand("stream", 111, { video: 1 }); } sendCMDrequestVideo2() { //"720p" "HD" with 320x240 - this.sendCMDPacket( - `{"pro":"stream","cmd":111,"video":2,"user":"admin","pwd":"6666","devmac":"0000"}` - ) + this.sendCommand("stream", 111, { video: 2 }); } sendCMDrequestAudio() { //Strange ADPCM format - this.sendCMDPacket( - `{"pro":"stream","cmd":111,"audio":1,"user":"admin","pwd":"6666"}` - ) + this.sendCommand("stream", 111, { audio: 1 }); } sendCMDsetWifi(ssid, pw) { - this.sendCMDPacket( - `{"pro":"set_wifi","cmd":114,"user":"admin","pwd":"6666","wifissid":"${ssid}","wifipwd":"${pw}","encwifissid":"${ssid}","encwifipwd":"${pw}","encryption":1,"devmac":"0000"}` - ) + this.sendCommand("set_wifi", 114, + { wifissid: ssid, + encwifissid: ssid, + wifipwd: pw, + encwifipwd: pw, + encryption: 1 + }); } sendCMDscanWifi() { - this.sendCMDPacket( - `{"pro":"scan_wifi","cmd": 113,"user":"admin","pwd":"6666","devmac":"0000"}` - ) + this.sendCommand("scan_wifi", 113); } sendCMDgetWifi() { - this.sendCMDPacket( - `{"pro":"get_wifi","cmd": 112,"user":"admin","pwd":"6666","devmac":"0000"}` - ) + this.sendCommand("get_wifi", 112); } sendCMDgetParams() { - this.sendCMDPacket( - `{"pro":"get_parms","cmd":101,"user":"admin","pwd":"6666","devmac":"0000"}` - ) - /* returns e.g. + this.sendCommand("get_parms", 101); + + /* returns e.g. { "cmd": 101, "result": 0, @@ -332,31 +338,14 @@ class PPPP extends EventEmitter { */ } - sendCMDsetParams(changes) { - let data = { - pro: 'dev_control', - cmd: 102, - user: 'admin', - pwd: '6666', - devmac: '0000', - } - - this.sendCMDPacket(JSON.stringify({ ...data, ...changes })) - } - sendCMDIr(isOn) { - this.sendCMDPacket( - `{"pro":"dev_control","cmd":102,"user":"admin","pwd":"6666","icut":${ - isOn ? 1 : 0 - },"devmac":"0000"}` - ) + this.sendCommand("dev_control", 102, { icut: isOn ? 1 : 0}); } sendCMDTalkSend() { // it is unclear for me what this really does - this.sendCMDPacket( - `{"pro":"talk_send","cmd":300,"user":"admin","pwd":"6666","isSend":1}` - ) + this.sendCommand("talk_send", 300, { isSend: 1 }); + /* returns like: { @@ -368,29 +357,20 @@ class PPPP extends EventEmitter { sendCMDGetWhiteLight() { - this.sendCMDPacket( - `{"pro":"get_whiteLight","cmd":305,"user":"admin","pwd":"6666"}` - ) + this.sendCommand("get_whiteLight", 305); } sendCMDSetWhiteLight(isOn) { - this.sendCMDPacket( - `{"pro":"set_whiteLight","cmd":304,"user":"admin","pwd":"6666","status":${ - isOn ? 1 : 0 - }}` - ) + this.sendCommand("set_whiteLight", 304, { status: isOn ? 1 : 0}); } sendCMDHeartBeat() { - this.sendCMDPacket( - `{"pro":"dev_control","cmd":102,"user":"admin","pwd":"6666","heart":1,"devmac":"0000"}` - ) + this.sendCommand("dev_control", 102, { heart: 1 }); } sendCMDGetDeviceFirmwareInfo() { - this.sendCMDPacket( - `{"pro":"get_cloudsupport","cmd":9000,"user":"admin","pwd":"6666"}` - ) + this.sendCommand("get_cloudsupport", 9000); + /* the command name is a mis-nomer. this is more like TF card support, firmware version and flashability. Returns something like: @@ -420,9 +400,8 @@ class PPPP extends EventEmitter { } sendCMDGetAlarm() { - this.sendCMDPacket( - `{"pro":"get_alarm","cmd":107,"user":"admin","pwd":"6666"}` - ) + this.sendCommand("get_alarm", 107); + /* Returns something like: { @@ -445,21 +424,15 @@ class PPPP extends EventEmitter { // 1 = stop motor in A axis // etc sendCMDPtzControl(direction) { - this.sendCMDPacket( - `{"pro":"ptz_control","cmd":128,"parms":0,"value":${direction},"user":"admin","pwd":"6666"}` - ) + this.sendCommand("ptz_control", 128, { parms: 0, value: direction}); } sendCMDReboot() { - this.sendCMDPacket( - `{"pro":"dev_control","cmd":102,"user":"admin","pwd":"6666","reboot":1,"devmac":"0000"}` - ) + this.sendCommand("dev_control", 102, { reboot: 1}); } sendCMDReset() { - this.sendCMDPacket( - `{"pro":"dev_control","cmd":102,"user":"admin","pwd":"6666","reset":1,"devmac":"0000"}` - ) + this.sendCommand("dev_control", 102, { reset: 1}); } parsePacket(buff) { From baaef4a123e635fd900b012cf95475eda941fb6c Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 8 Nov 2023 00:10:17 +0100 Subject: [PATCH 07/13] refactor: Extract knowledge about commands into constants, and simplify code even more --- pppp.js | 73 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/pppp.js b/pppp.js index 16f2660..638f85f 100644 --- a/pppp.js +++ b/pppp.js @@ -24,6 +24,35 @@ TYPE_DICT[MSG_ALIVE] = 'MSG_ALIVE' TYPE_DICT[MSG_ALIVE_ACK] = 'MSG_ALIVE_ACK' TYPE_DICT[MSG_CLOSE] = 'MSG_CLOSE' +const CMD_CHECK_USER = 100 +const CMD_GET_PARMS = 101 +const CMD_DEV_CONTROL = 102 +const CMD_GET_ALARM = 107 +const CMD_STREAM = 111 +const CMD_GET_WIFI = 112 +const CMD_SCAN_WIFI = 113 +const CMD_SET_WIFI = 114 +const CMD_PTZ_CONTROL = 128 +const CMD_TALK_SEND = 300 +const CMD_SET_WHITELIGHT = 304 +const CMD_GET_WHITELIGHT = 305 +const CMD_GET_CLOUD_SUPPORT = 9000 + +const CMD_DICT = {} +CMD_DICT[CMD_CHECK_USER] = 'check_user' +CMD_DICT[CMD_GET_PARMS] = 'get_parms' +CMD_DICT[CMD_DEV_CONTROL] = 'dev_control' +CMD_DICT[CMD_GET_ALARM] = 'get_alarm' +CMD_DICT[CMD_STREAM] = 'stream' +CMD_DICT[CMD_GET_WIFI] = 'get_wifi' +CMD_DICT[CMD_SCAN_WIFI] = 'scan_wifi' +CMD_DICT[CMD_SET_WIFI] = 'set_wifi' +CMD_DICT[CMD_PTZ_CONTROL] = 'ptz_control' +CMD_DICT[CMD_TALK_SEND] = 'talk_send' +CMD_DICT[CMD_SET_WHITELIGHT] = 'set_whiteLight' +CMD_DICT[CMD_GET_WHITELIGHT] = 'get_whiteLight' +CMD_DICT[CMD_GET_CLOUD_SUPPORT] = 'get_cloudsupport' + class PPPP extends EventEmitter { constructor(options) { super() @@ -263,7 +292,7 @@ class PPPP extends EventEmitter { this.sendEnc(buf) } - sendCommand(command_name, command_number, args) { + sendCommand(command, args) { let fixed_data = { user: 'admin', pwd: '6666', @@ -271,35 +300,35 @@ class PPPP extends EventEmitter { } let data = { - pro: command_name, - cmd: command_number + pro: CMD_DICT[command], + cmd: command } this.sendCMDPacket(JSON.stringify({ ...data, ...args, ...fixed_data})) } sendCMDCheckUser() { - this.sendCommand("check_user", 100); + this.sendCommand(CMD_CHECK_USER); } sendCMDrequestVideo1() { //"1080p" "HD" with 640x480 - this.sendCommand("stream", 111, { video: 1 }); + this.sendCommand(CMD_STREAM, { video: 1 }); } sendCMDrequestVideo2() { //"720p" "HD" with 320x240 - this.sendCommand("stream", 111, { video: 2 }); + this.sendCommand(CMD_STREAM, { video: 2 }); } sendCMDrequestAudio() { //Strange ADPCM format - this.sendCommand("stream", 111, { audio: 1 }); + this.sendCommand(CMD_STREAM, { audio: 1 }); } sendCMDsetWifi(ssid, pw) { - this.sendCommand("set_wifi", 114, - { wifissid: ssid, + this.sendCommand(CMD_SET_WIFI, { + wifissid: ssid, encwifissid: ssid, wifipwd: pw, encwifipwd: pw, @@ -308,15 +337,15 @@ class PPPP extends EventEmitter { } sendCMDscanWifi() { - this.sendCommand("scan_wifi", 113); + this.sendCommand(CMD_SCAN_WIFI); } sendCMDgetWifi() { - this.sendCommand("get_wifi", 112); + this.sendCommand(CMD_GET_WIFI); } sendCMDgetParams() { - this.sendCommand("get_parms", 101); + this.sendCommand(CMD_GET_PARMS); /* returns e.g. { @@ -339,12 +368,12 @@ class PPPP extends EventEmitter { } sendCMDIr(isOn) { - this.sendCommand("dev_control", 102, { icut: isOn ? 1 : 0}); + this.sendCommand(CMD_DEV_CONTROL, { icut: isOn ? 1 : 0}); } sendCMDTalkSend() { // it is unclear for me what this really does - this.sendCommand("talk_send", 300, { isSend: 1 }); + this.sendCommand(CMD_TALK_SEND, { isSend: 1 }); /* returns like: @@ -357,19 +386,19 @@ class PPPP extends EventEmitter { sendCMDGetWhiteLight() { - this.sendCommand("get_whiteLight", 305); + this.sendCommand(CMD_GET_WHITELIGHT); } sendCMDSetWhiteLight(isOn) { - this.sendCommand("set_whiteLight", 304, { status: isOn ? 1 : 0}); + this.sendCommand(CMD_SET_WHITELIGHT, { status: isOn ? 1 : 0}); } sendCMDHeartBeat() { - this.sendCommand("dev_control", 102, { heart: 1 }); + this.sendCommand(CMD_DEV_CONTROL, { heart: 1 }); } sendCMDGetDeviceFirmwareInfo() { - this.sendCommand("get_cloudsupport", 9000); + this.sendCommand(CMD_GET_CLOUD_SUPPORT); /* the command name is a mis-nomer. this is more like TF card support, @@ -400,7 +429,7 @@ class PPPP extends EventEmitter { } sendCMDGetAlarm() { - this.sendCommand("get_alarm", 107); + this.sendCommand(CMD_GET_ALARM); /* Returns something like: @@ -424,15 +453,15 @@ class PPPP extends EventEmitter { // 1 = stop motor in A axis // etc sendCMDPtzControl(direction) { - this.sendCommand("ptz_control", 128, { parms: 0, value: direction}); + this.sendCommand(CMD_PTZ_CONTROL, { parms: 0, value: direction}); } sendCMDReboot() { - this.sendCommand("dev_control", 102, { reboot: 1}); + this.sendCommand(CMD_DEV_CONTROL, { reboot: 1}); } sendCMDReset() { - this.sendCommand("dev_control", 102, { reset: 1}); + this.sendCommand(CMD_DEV_CONTROL, { reset: 1}); } parsePacket(buff) { From fd20d75c0bcabe408d53412ff14b1dd2717e6955 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 8 Nov 2023 00:31:39 +0100 Subject: [PATCH 08/13] refactor: Move documentation to better place --- pppp.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/pppp.js b/pppp.js index 638f85f..b5e97d3 100644 --- a/pppp.js +++ b/pppp.js @@ -298,6 +298,19 @@ class PPPP extends EventEmitter { pwd: '6666', devmac:'0000' } + /* incorrect password: + { + "cmd": ..., + "result": -3 + } + + incorrect user name: (or password field missing): + { + "cmd": ..., + "result": -1 +}*/ + + let data = { pro: CMD_DICT[command], @@ -414,18 +427,6 @@ class PPPP extends EventEmitter { "supportNewUp": 1 } */ - - /* incorrect password: - { - "cmd": 9000, - "result": -3 -}*/ - /* incorrect user name: (or password field missing) - { - "cmd": 9000, - "result": -1 -}*/ - } sendCMDGetAlarm() { From 550009aeee77312cf7fed0f742bf41e2bd01ec62 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 8 Nov 2023 09:16:07 +0100 Subject: [PATCH 09/13] Add named constants for PTZ motor control --- pppp.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pppp.js b/pppp.js index b5e97d3..43467ef 100644 --- a/pppp.js +++ b/pppp.js @@ -53,6 +53,15 @@ CMD_DICT[CMD_SET_WHITELIGHT] = 'set_whiteLight' CMD_DICT[CMD_GET_WHITELIGHT] = 'get_whiteLight' CMD_DICT[CMD_GET_CLOUD_SUPPORT] = 'get_cloudsupport' +const PTZ_TILT_UP_START = 0 +const PTZ_TILT_UP_STOP = 1 +const PTZ_TILT_DOWN_START = 2 +const PTZ_TILT_DOWN_STOP = 3 +const PTZ_PAN_LEFT_START = 4 +const PTZ_PAN_LEFT_STOP = 5 +const PTZ_PAN_RIGHT_START = 6 +const PTZ_PAN_RIGHT_STOP = 7 + class PPPP extends EventEmitter { constructor(options) { super() @@ -449,10 +458,7 @@ class PPPP extends EventEmitter { */ } - // direction == 0..7: - // 0 = start motor in A axis - // 1 = stop motor in A axis - // etc + // For direction, use any of the PTZ_PAN/TILT constants sendCMDPtzControl(direction) { this.sendCommand(CMD_PTZ_CONTROL, { parms: 0, value: direction}); } From d28359dc0f20cb535576c30c0d7793171f6ac5aa Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 13 Nov 2023 20:50:42 +0100 Subject: [PATCH 10/13] Add new commands: set_cypush, edit_user, set_alarm, set_datetime and get_record_param --- pppp.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/pppp.js b/pppp.js index 43467ef..b54edb8 100644 --- a/pppp.js +++ b/pppp.js @@ -24,30 +24,40 @@ TYPE_DICT[MSG_ALIVE] = 'MSG_ALIVE' TYPE_DICT[MSG_ALIVE_ACK] = 'MSG_ALIVE_ACK' TYPE_DICT[MSG_CLOSE] = 'MSG_CLOSE' +const CMD_SET_CYPUSH = 1 const CMD_CHECK_USER = 100 const CMD_GET_PARMS = 101 const CMD_DEV_CONTROL = 102 +const CMD_EDIT_USER = 106 const CMD_GET_ALARM = 107 +const CMD_SET_ALARM = 108 const CMD_STREAM = 111 const CMD_GET_WIFI = 112 const CMD_SCAN_WIFI = 113 const CMD_SET_WIFI = 114 +const CMD_SET_DATETIME = 126 // returns result as cmd 128... const CMD_PTZ_CONTROL = 128 +const CMD_GET_RECORD_PARAM = 199 const CMD_TALK_SEND = 300 const CMD_SET_WHITELIGHT = 304 const CMD_GET_WHITELIGHT = 305 const CMD_GET_CLOUD_SUPPORT = 9000 const CMD_DICT = {} +CMD_DICT[CMD_SET_CYPUSH] = 'set_cypush' CMD_DICT[CMD_CHECK_USER] = 'check_user' CMD_DICT[CMD_GET_PARMS] = 'get_parms' CMD_DICT[CMD_DEV_CONTROL] = 'dev_control' +CMD_DICT[CMD_EDIT_USER] = 'edit_user' CMD_DICT[CMD_GET_ALARM] = 'get_alarm' +CMD_DICT[CMD_SET_ALARM] = 'set_alarm' CMD_DICT[CMD_STREAM] = 'stream' CMD_DICT[CMD_GET_WIFI] = 'get_wifi' CMD_DICT[CMD_SCAN_WIFI] = 'scan_wifi' CMD_DICT[CMD_SET_WIFI] = 'set_wifi' +CMD_DICT[CMD_SET_DATETIME] = 'set_datetime' CMD_DICT[CMD_PTZ_CONTROL] = 'ptz_control' +CMD_DICT[CMD_GET_RECORD_PARAM] = 'get_record_param' CMD_DICT[CMD_TALK_SEND] = 'talk_send' CMD_DICT[CMD_SET_WHITELIGHT] = 'set_whiteLight' CMD_DICT[CMD_GET_WHITELIGHT] = 'get_whiteLight' @@ -366,6 +376,10 @@ class PPPP extends EventEmitter { this.sendCommand(CMD_GET_WIFI); } + sendCMDgetRecordParam() { + this.sendCommand(CMD_GET_RECORD_PARAM); + } + sendCMDgetParams() { this.sendCommand(CMD_GET_PARMS); @@ -419,6 +433,69 @@ class PPPP extends EventEmitter { this.sendCommand(CMD_DEV_CONTROL, { heart: 1 }); } + /* + my_timezone_offset means: when the device interprets the timestamp, + adjust according to this offset. So if my_timezone_offset is -3600, + the device will add (not subtract!) 3600 seconds to the timestamp given, + before setting it. + + the timestamp is in seconds since epoch. + + this method do not set the local timezone of the device, as reported by + get_parms. (I don't know how to do that, if even possible) + */ + sendCMDsetDateTime(my_timezone_offset, timestamp) { + this.sendCommand(CMD_SET_DATETIME, { + tz: my_timezone_offset, + time: timestamp, + }); + } + + sendCMDsetPushServer() { + this.sendCommand(CMD_SET_CYPUSH, + { + "pushIp": "192.168.7.20", + "pushPort": 5432, + } + ); + var unused_args = { + "pushInterval": 30, + "isPushVideo": 0, + "isPushPic": 0, + "cyAdmin": "", + "cyPwd": "", + }; + } + + sendCMDsetAlarm() { + this.sendCommand(CMD_SET_ALARM, { + "pirPush": 1, + "pirenable": 1, + "pirsensitive": 2, + "pirDelayTime": 5, + "pirvideo": 0, + "pirvideotime": 0, + } + ); + + // "pirsensitive": 1, -- almost never triggers, 3 -- triggers most often + } + + sendCMDeditUser(userToEdit, newPwd, newUsername) { + this.sendCommand(CMD_EDIT_USER, { + "edituser" : userToEdit, + "newpwd" : newPwd, + "newuser" : newUsername, + } + ); + + /* additional reply: + { + "count": 1, + } + perhaps the number of times password has changed, nope, it is always 1 + */ + sendCMDGetDeviceFirmwareInfo() { this.sendCommand(CMD_GET_CLOUD_SUPPORT); @@ -463,6 +540,10 @@ class PPPP extends EventEmitter { this.sendCommand(CMD_PTZ_CONTROL, { parms: 0, value: direction}); } + sendCMDPtzReset() { + this.sendCommand(CMD_PTZ_CONTROL, { parms: 1, value: 132}); + } + sendCMDReboot() { this.sendCommand(CMD_DEV_CONTROL, { reboot: 1}); } From 6cc69ddb0db3c8f56335d99f7e539b20a2b92680 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 13 Nov 2023 20:51:03 +0100 Subject: [PATCH 11/13] fix: Only send close if we actually opened the connection --- pppp.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pppp.js b/pppp.js index b54edb8..8da802d 100644 --- a/pppp.js +++ b/pppp.js @@ -618,11 +618,11 @@ class PPPP extends EventEmitter { } destroy() { - this.sendEnc(Buffer.from([MCAM, MSG_CLOSE, 0, 0])) - this.sendEnc(Buffer.from([MCAM, MSG_CLOSE, 0, 0])) - this.sendEnc(Buffer.from([MCAM, MSG_CLOSE, 0, 0])) - - this.socket.unref() + if (this.isConnected) { + this.sendEnc(Buffer.from([MCAM, MSG_CLOSE, 0, 0])) + this.sendEnc(Buffer.from([MCAM, MSG_CLOSE, 0, 0])) + this.sendEnc(Buffer.from([MCAM, MSG_CLOSE, 0, 0])) + } } } From 4b95edac663d900fe6a70576b12c00f031a455d3 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 22 Nov 2023 10:22:32 +0100 Subject: [PATCH 12/13] Fix syntax error --- pppp.js | 1 + 1 file changed, 1 insertion(+) diff --git a/pppp.js b/pppp.js index 8da802d..bfc7635 100644 --- a/pppp.js +++ b/pppp.js @@ -495,6 +495,7 @@ class PPPP extends EventEmitter { } perhaps the number of times password has changed, nope, it is always 1 */ + } sendCMDGetDeviceFirmwareInfo() { this.sendCommand(CMD_GET_CLOUD_SUPPORT); From 7c433e0ab99078c1625afb88345c9c849464e299 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Wed, 22 Nov 2023 12:21:24 +0100 Subject: [PATCH 13/13] * Refactor: extract handlePacket() * Reply to MSG_CLOSE by MSG_ALIVE (multiple times) * Send more MSG_DRW_ACKs. --- pppp.js | 137 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 48 deletions(-) diff --git a/pppp.js b/pppp.js index bfc7635..d747362 100644 --- a/pppp.js +++ b/pppp.js @@ -115,6 +115,59 @@ class PPPP extends EventEmitter { } let p = this.parsePacket(d) + this.handlePacket(p, msg, rinfo) + + }) + + let bindOptions = {} + if (this.myIpAddressToBind){ + bindOptions.address = this.myIpAddressToBind + } + console.log("bind options:"+bindOptions) + this.socket.bind(bindOptions) + } + + setDebugIp(ip) { + this.IP_DEBUG_MSG = ip + } + + sendBroadcast() { + const message = Buffer.from('2cba5f5d', 'hex') + + this.socket.send(message, 32108, this.broadcastDestination) + console.log('broadcast Message sent.') + + if (!this.isConnected && this.punchCount == 0) { + setTimeout(this.sendBroadcast.bind(this), 100) + } + } + + sendEnc(msg) { + let message + if (msg instanceof Buffer) { + message = msg + } else { + message = Buffer.from(msg, 'hex') + } + + this.send(crypt.encrypt(message)) + } + + send(msg) { + let message + if (msg instanceof Buffer) { + message = msg + } else { + message = Buffer.from(msg, 'hex') + } + this.socket.send(message, this.PORT_CAM, this.IP_CAM) + + if (this.IP_DEBUG_MSG) { + this.socket.send(crypt.decrypt(message), 3301, this.IP_DEBUG_MSG) + } + } + + handlePacket(p, msg, rinfo) { //console.log(TYPE_DICT[p.type], p.size, p.channel, p.index) if (p.type == MSG_DRW) { this.emit( @@ -131,6 +184,7 @@ class PPPP extends EventEmitter { if (p.type == MSG_PUNCH) { if (this.punchCount++ < 5) { this.socket.send(msg, rinfo.port, rinfo.address) + this.emit('log', `Sent ${TYPE_DICT[MSG_PUNCH]}`) } } @@ -158,6 +212,32 @@ class PPPP extends EventEmitter { // this.send(crypt.encrypt(buf).toString("hex")) this.sendEnc(buf) + this.emit('log', `Sent ${TYPE_DICT[MSG_ALIVE_ACK]}`) + } + + // reply to MSG_CLOSE + if (p.type == MSG_CLOSE) { + let buf = Buffer.alloc(4) + buf.writeUint8(MCAM, 0) + buf.writeUInt8(MSG_ALIVE, 1) + buf.writeUint16BE(0, 2) + + // this.send(crypt.encrypt(buf).toString("hex")) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.sendEnc(buf) + this.emit('log', `Sent ${TYPE_DICT[MSG_ALIVE]}`) } //handle MSG_DRW @@ -174,6 +254,15 @@ class PPPP extends EventEmitter { this.send(crypt.encrypt(buf).toString('hex')) this.send(crypt.encrypt(buf).toString('hex')) + this.send(crypt.encrypt(buf).toString('hex')) + this.send(crypt.encrypt(buf).toString('hex')) + this.send(crypt.encrypt(buf).toString('hex')) + this.send(crypt.encrypt(buf).toString('hex')) + this.send(crypt.encrypt(buf).toString('hex')) + this.send(crypt.encrypt(buf).toString('hex')) + this.send(crypt.encrypt(buf).toString('hex')) + this.emit('log', `Sent ${TYPE_DICT[MSG_DRW_ACK]} x3`) + //handle CMD Response if (p.channel == 0) { @@ -229,55 +318,7 @@ class PPPP extends EventEmitter { } } } - }) - - let bindOptions = {} - if (this.myIpAddressToBind){ - bindOptions.address = this.myIpAddressToBind - } - console.log("bind options:"+bindOptions) - this.socket.bind(bindOptions) - } - - setDebugIp(ip) { - this.IP_DEBUG_MSG = ip - } - - sendBroadcast() { - const message = Buffer.from('2cba5f5d', 'hex') - - this.socket.send(message, 32108, this.broadcastDestination) - console.log('broadcast Message sent.') - - if (!this.isConnected && this.punchCount == 0) { - setTimeout(this.sendBroadcast.bind(this), 100) - } - } - - sendEnc(msg) { - let message - if (msg instanceof Buffer) { - message = msg - } else { - message = Buffer.from(msg, 'hex') - } - - this.send(crypt.encrypt(message)) - } - - send(msg) { - let message - if (msg instanceof Buffer) { - message = msg - } else { - message = Buffer.from(msg, 'hex') - } - this.socket.send(message, this.PORT_CAM, this.IP_CAM) - - if (this.IP_DEBUG_MSG) { - this.socket.send(crypt.decrypt(message), 3301, this.IP_DEBUG_MSG) } - } sendCMDPacket(msg) { let data