starkillerOG/reolink_aio

I can help you if you need some help about reolink command

mnpg opened this issue ยท 48 comments

mnpg commented

Hi @starkillerOG,
If you need some help about the reolink commands, i can help you if you will.
i made an unofficial documentation for the Reolink Cameras (it concerns only the 5MP cams, i ain't got some latest ones) that you can find on my Github channel : https://github.com/mnpg/Reolink_api_documentations

Sorry, all the unofficial documentations are in French but easy to google translate them.

Regards

@mnpg any help is always apreciated, you can just make PRs to this library and/or the HomeAssistant integration and I will review them and help you out if you get stuck.

Yes I already found your documentation library, very helpfull!
I found at least the new doorbell quick reply commands there.

Do you have any other particular commands/features that you would like to see added?

mnpg commented

Hi @starkillerOG, for a feature, i think the calibration one. It's easy to include it but i don't know if you have already added it.
here the commands i use to do that : PtzCheck and GetPtzCheckState.

In the command below, change #IP# to the IP address of the cam and #username# and #password# (an admin account credentials) by your own values and also the channel #X# of the camera (0 if the camera is a standalone cam). The URL is in https, change it to http if it doesn't work

  • For the first one, it start the calibration of the camera (PtzCheck) :

curl -s -k -X POST -H "Content-Type : application/json" -d '[{\"cmd\":\"PtzCheck\",\"action\":0,\"param\":{\"channel\":#X#}}]' "https://#IP#/cgi-bin/api.cgi?user=#USERNAME#&password=#PASSWORD#"

  • For the second one : you have the status of the calibration (GetPtzCheckState):

curl -s -k -X POST -H "Content-Type : application/json" -d '[{\"cmd\":\"GetPtzCheckState\",\"action\":0,\"value\":{\"channel\":#X#}}]' "https://#IP#/cgi-bin/api.cgi?user=#USERNAME#&password=#PASSWORD#"

return status (field PtzCheckState):
0 : calibration is required
1 : calibration is running
2 : calibration done

IMPORTANT : This feature depends on the Abitity "supportPtzCheck" of the camera

Regards

mnpg commented

just for my information : which camera(s) to do have?
and also which commands you need some informations?

FYI : i really want help you but python isn't easy for me.

@mnpg yes the callibration using PtzCheck has already been included as a button entity.
I did not include the GetPtzCheckState, but I don't think that status will really be that helpfull in HomeAssistant, what do you think?

I have:

  • NVR RLN8-410
  • Reolink doorbell PoE
  • RLC-811A
  • E1 zoom
  • Reolink TrackMix PoE (on its way, in shipping)

But I have good contacts with Reolink, so if there is a particular model which is causing difficult issues, I can ask for that model for testing. Thats also why the TrackMix is on its way, not going to use it myself, but it has slightly diffrent API, so I am going to test and programm with it.

@mnpg At this moment I would like a command to trigger the doorbell quick replay message, but reolink already confirmed to me it is not yet included in there firmware API.
I would also like a command to set the absolute Pan/Tilt position, but have not found it yet and think it is not yet included in the API.

mnpg commented

@mnpg At this moment I would like a command to trigger the doorbell quick replay message, but reolink already confirmed to me it is not yet included in there firmware API.

i confime you that it's not possible to do this except to choose the reply message. It's seems like the 2-way audio feature that we cannot use through API.

I would also like a command to set the absolute Pan/Tilt position, but have not found it yet and think it is not yet included in the API.

For which camera?

For which camera?

I am not programming for myself, but for all 15.000 current users of the reolink homeassistant integration.
So for all camera's that support PTZ basically, hopefully (and probably) the command will be the same in all models if the firmware supports it.

mnpg commented

@mnpg yes the callibration using PtzCheck has already been included as a button entity.
I did not include the GetPtzCheckState, but I don't think that status will really be that helpfull in HomeAssistant, what do you think?

It's a good thing to have it. When you have the status at 0 of the GetPtzCheckState status field (PtzCheckState), you can automate through HA to launch the calibration.

@mnpg when will it become 0 (required)?
Does that often happen, and have you experianced that?

mnpg commented

when you reboot the camera, the calibration is required

mnpg commented

beware, the E1Zoom (not the AI version) have also the calibration BUT there are no PTZCheck or GetPtzCheckState commands in there firmware. These commands appear with the AI cameras.

mnpg commented

So for all camera's that support PTZ basically, hopefully (and probably) the command will be the same in all models if the firmware supports it.

For the Ptz, i've found some difference with the oldest cameras, in particular with some movements or zoom and focus.

mnpg commented

If you have a E1-Zoom, i invite you to take a look a my github wiki page. This camera have a easter egg : the patrol mode :
https://github.com/mnpg/Reolink_api_documentations/wiki/Easter-Egg-dans-la-Reolink-E1-Zoom-:-le-mode-Patrol

@mnpg nice find the Patrol mode in the E1 zoom ๐Ÿ‘

mnpg commented

Hi @starkillerOG
for the Get/Set3DPos command, take a look at the RLC-823A_16X firmware (unpak the firmware with the command 'binwalk -e -M "pak"'), and you find the answer in the file ViewPtz3DLocation.js (in repositoy _IPC_523SD10.1646_22122622.RLC-823A-16X.IMX415.8MP.PTZ.REOLINK.pak.extracted/ubifs-root/2101463492/app/www/js/modules)
NB: the firmware is available in the download center of Reolink (https://reolink.com/fr/download-center/)
Regards

@mnpg Thanks for the info, but I have never used binwalk.
Could you maybe have a look at it for me and post the Set/Get3DPos commands (which parameters they take and what I schould expect for response?)

mnpg commented

sure, no pb.
it's seeems that for Get3DPos, you will seen these parameters :

            channel: e
        }, function (t) {
            d === e && (t = t["3d_pos"], w = {
                    [EnumStreamType.CLEAR]: {
                        width: t.mainStream.width,
                        height: t.mainStream.height
                    },
                    [EnumStreamType.FLUENT]: {
                        width: t.subStream.width,
                        height: t.subStream.height
                    },
                    [EnumStreamType.BALANCED]: {
                        width: t.extStream.width,
                        height: t.extStream.height
                    }
                })

For the Set3PPos, here the parameters to set :

 iX: Math.floor(e * h / r.width),
                iY: Math.floor(i * n / r.height),
                iWidth: Math.floor(e * o / r.width),
                iHeight: Math.floor(i * a / r.height)
            }, CGI.sendCommand("Set3DPos", {
                "3DPos": {
                    channel: t,
                    posX: h.iX,
                    posY: h.iY,
                    posWidth: h.iWidth,
                    posHeight: h.iHeight,
                    speed: function () {
                        let t = 20;
                        var e = window.localStorage.getItem("/ptz/speed");
                        return t = e && !isNaN(parseFloat(e)) ? Math.max(1, Math.min(64, parseFloat(e))) : t
                    }
                    (),
                    width: e,
                    height: i
                }
for the Set3DPos, there are several parameters : 

- channel (it's normal -NVR or standalone-)
- posX
- posY
- posWidth
- posHeight
- width
- height
- speed

mnpg commented

For the Set command, I don't know how to use this command and parameters (Set3DPos)
I ain't got a RLC-823_16X
Sorry.

Thank you very much for the information, so actually the Set3DPos seems to consern some display/image setting and not the Pan/Tilt position I was hoping for, but still very usefull to know.

mnpg commented

The Get/Set3DPos command this feature in particular with this version of firmware of the RLC-823_16X

mnpg commented

Hi @starkillerOG,
You're right, it's another feature (the 3D Zoom feature) introducted with the firmware 3.1.0.1646 of the RLC-823_16X
As i know about the Reolink cameras and about the Get/Set3DPos, i'm not sure but by experience with these cameras, here are, i suppose, how the parameters are defined for the feature 3D Zoom

mnpg commented

for the Set3DPos, there are several parameters :

  • channel (it's normal -NVR or standalone-)
  • posX
  • posY
  • posWidth
  • posHeight
  • width
  • height
  • speed

Get-Set3DPOS parameters

mnpg commented

For the speed parameter, it's seems to be the time (in seconds or mseconds) to go the the 3D Zoom zone.
It's my opinion, i'm not quite sure. We must wait more infos about this command as soon as they release a newer upgrade of the official Reolink API documentation.
Regards

mnpg commented

not the Pan/Tilt position I was hoping for, but still very usefull to know.

hi @starkillerOG, for which camera?

mnpg commented

@starkillerOG : waiting for your answer

I was looking for the Trackmix and/or E1 Zoom, I have figured out the GetPtzCurPos gives me the pan position on the Trackmix, still looking for a way to set the position

mnpg commented

Hi @starkillerOG, since the latest firmware from the E1-Zoom (I have one too), there will be no commands to tilt/pan the camera, they always add new commands on newer cameras. I think that it's probably in the TrackMix firmware, you'll find some informations. As always, we can't wait more information from the Reolink api guide, It's depends in our experience.

mnpg commented

@starkillerOG : which features you want to add in your "plugin" ? privacy mask, surveillance scheduler? Detection zone ?

@mnpg No privacy mask, schedule and detection zone will be too difficult and not used that many to implement.

I would really love to have the triggering of a quick reply message for the Reolink doorbell.
New firmware for the doorbell was published a week ago.
Could you by any change look if that new firmware included a command to trigger the quick reply message?

mnpg commented

@starkillerOG, taken from the latest firmware of the Doorbell i've found new commands or parameters, here there are (not sure they 'll working with this firmware because these commands aren't included in the cgiserver.cgi file of the firmware):

  • ExportAudioFile :

{"cmd"="ExportAudioFile", "param":{"AudioFile":{"id":id of the audio reply file,"channel":X}}

also, from the command GetAudioCfg/SetAudioCfg, a new parameter appears (visitorLoudspeaker):

SetAudioCfg : {"cmd":"SetAudioCfg","param":{"AudioCfg":{"visitorLoudspeaker":0->100 (??), "channel":X}}

In this firmware, there were also included 2 new commands for the FishEye Camera :

  • GetFishEye/SetFishEye :

SetFishEye : {"cmd":"SetFishEye","param":{"FishEye": {"channel": X, "installType": ???, "imageType": ???, "rotationAngle": ???}}

EDIT : i can't see any manual trigger reply command in the files of the firmware. Perhaps, do a test with the command AudioAlarmPlay

The visitorLoudspeaker parameter is 0 or 1, to enable/disable the sound of the doorbell itself (not the chime).
I already included this in reolink-aio and HA in PR: home-assistant/home-assistant.io#26791

The FishEye commands are certainly interesting, thanks for those, I would need one of these cameras to figure out what the parameter range is, but this is already helpfull!

The ExportAudioFile is (I think) for downloading the audio file from the doorbell, but will not play the sound.

mnpg commented

hi @starkillerOG, based with the @jasonk rl-api bash script (for linux) -FYI, its an awesome script-, i've created several examples of scripts when you can't define or configure some parameters (or features) through your Home Automation Solution. I regroup them on my github repo > Folder Bash-scripts

EDIT: these examples concern PrivacyMask, DetectionZone and VideoClip. I think there is a way to adapt these codes to HA.

mnpg commented

Hi @starkillerOG, i've win recently a reolink fish camera from Reolink contest.
When i receive it, i will come back to you with more infos or commands about it
Regards

mnpg commented

hi @starkillerOG, based with the @jasonk rl-api bash script (for linux) -FYI, its an awesome script-, i've created several examples of scripts when you can't define or configure some parameters (or features) through your Home Automation Solution. I regroup them on my github repo > Folder Bash-scripts

EDIT: these examples concern PrivacyMask, DetectionZone and VideoClip. I think there is a way to adapt these codes to HA.

New scripts are available :

  • synchronize ntp manually
  • manual/repeat mode of the siren

More will come :

  • manage schedulers for all surveillance modes
  • the mode patrol -taken from my post "easter egg in the E1-Zoom- that's works and tested with E1-Zoom, E1-Outdoor and TrackMix

NB : I suppose they can be adapted to HA plugin

Regards

Thanks for the info

@mnpg there is a new firmware version of the reolink doorbell available on AT0myks/reolink-fw-archive@ffa16f3

https://home-cdn.reolink.us/wp-content/uploads/2024/03/010147201709257640.8976.zip

Could you perhaps take a look if you can find a command to trigger playback of a quickreplay message in this new firmware?

mnpg commented

hi @starkillerOG,
Here the first infos i've got from the Doorbell's firmware :


QuickReplyPlay COMMAND

  • TypeCommand : SET Command
  • Command : QuickReplyPlay

NO INFO ABOUT IT

NB : Probably, not sure, it seems to work like the reboot command.
Test this command : [{"cmd":"QuickReplyPlay","action":0,"param":{}}]


DingDong COMMANDS

###########################
"supportDingDongCtrl" => getAbilityChnBy("supportDingDongCtrl")
###########################

DingDongCtrl

  • TypeCommand : SET Command
  • Command : DingDongCtrl
  • Parameters :

DingDong :

{
channel: this.index,
modeCtrl: e.ctrl
}

EDIT :
It seems that this command is used to enter/exit in the pairing mode.

  • if modeCtrl : 1 => enterPairingMode
  • if modeCtrl : 0 => exitPairingMode

GetDingDongList

  • TypeCommand : GET Command
  • Command : GetDingDongList
  • Parameters :

{
channel: this.index
}

=> return Values

{
channel: this.index,
maxPairNumber: i.maxPairNumber, # <--- 5 or 10 max ? #
size: a.length,
dingDong: a
}

DingDongOpt (dingDongManualRing)

  • TypeCommand : SET Command
  • Command : DingDongOpt
  • Parameters :

DingDong:

{
channel: this.index,
option: 4,
id: e.identifier.dingDongId,
musicId: e.musicId
}

INFO :
dingDongAudioBasenameMap => new Map([[0, "dingdong_001.mp3"], [1, "dingdong_002.mp3"], [2, "dingdong_003.mp3"], [3, "dingdong_004.mp3"], [4, "dingdong_005.mp3"], [5, "dingdong_006.mp3"], [6, "dingdong_007.mp3"], [7, "dingdong_008.mp3"], [8, "dingdong_009.mp3"], [9, "dingdong_010.mp3"]])

DingDongOpt (dingDongPair)

  • TypeCommand : SET Command
  • Command : DingDongOpt
  • Parameters :

DingDong:

{
channel: this.index,
option: 0,
id: e
}

DingDongOpt (dingDongUnpair)

  • TypeCommand : SET Command
  • Command : DingDongOpt
  • Parameters :

DingDong:

{
channel: this.index,
option: 1,
id: e
}

DingDongOpt (getDingDongOption)

  • TypeCommand : SET(GET??) Command
  • Command : DingDongOpt
  • Parameters :

DingDong:

{
channel: this.index,
option: 2,
id: t
}

=> return Values

{
dingDongId: t,
volume:

{
defaultLevel: r.volLevel,
level: r.volLevel,
levelOptions: a
ledState: r.ledState,
name: r.name
}

DingDongOpt (setDingDongOption)

  • TypeCommand : SET Command
  • Command : DingDongOpt
  • Parameters :

DingDong:

{
channel: this.index,
option: 3,
id: e.dingDongId,
name: e.name,
volLevel: e.volume.level,
ledState: e.ledState
}

GetDingDongCfg (getDingDongAudioInfo)

  • TypeCommand : GET Command
  • Command : GetDingDongCfg
  • Parameters :

{
channel: this.index
}

=> return Values

{ ?? }

SetDingDongCfg (setDingDongAudioInfo)

  • TypeCommand : SET Command
  • Command : SetDingDongCfg
  • Parameters :

DingDongCfg:

{
channel: this.index,
ringId: e,
type: Object(y["a"])({}, i,

{
switch : n.enable,
musicId: n.musicId
}
)

}

I will send you another commands soon

Regards

mnpg commented

Hi again,

in this post, it concerns a command of the NVRs and the long-awaited commands for Webhook

  • NVR

like the command GetDevInfo for a single camera, here a new command i've found for the NVR (probably you already know it) :


GetChnTypeInfo (getChannelVersion)

  • TypeCommand : GET Command
  • Command : GetChnTypeInfo
  • Parameters :

{
channel: this.index
}

=> return Values

{
cName: "",
cType: s.typeInfo,
cSerialNo: "",
cBuildDay: "",
cHardwareVer: "",
cCfgVer: "",
cFirmwareVer: s.firmVer,
cPakSuffix: s.pakSuffix,
cDetail: "",
cCC3200Ver: "",
cSpVer: ""
}

  • Webhook

Here i've found these commands in the firmware :

Webhook COMMANDS

###########################
"supportWebhook" => getAbilityChnBy("supportWebhook")
###########################

GetWebHook

  • TypeCommand : GET Command
  • Command : GetWebHook
  • Parameters :

{
channel: this.index
}

=> return Values

{
index: o.index,
indexEnable: o.indexEnable,
hookUrl: o.hookUrl,
bodyCustom: o.bCustom,
hookBody: D["a"].recover2Str(o.hookBody, !1)
}


SetWebHook

  • TypeCommand : SET Command
  • Command : SetWebHook
  • Parameters :

WebHook:

{
channel: this.index,
index: e.index,
indexEnable: e.indexEnable,
hookUrl: e.hookUrl,
bCustom: e.bodyCustom,
hookBody: D["a"].transform(e.hookBody, !1)
}


TestWebHook

  • TypeCommand : SET Command
  • Command : TestWebHook
  • Parameters :

WebHook:

{
alarmChannel: this.index,
type: 3,
source: "hook",
hookUrl: e.hookUrl,
bCustom: e.bodyCustom,
hookBody: D["a"].transform(e.hookBody, !1)
}

@mnpg Thank you soooo much!!!

The command: body = [{"cmd":"QuickReplyPlay","action":0,"param":{"id": 1}}] works and plays the quick reply message.
I already implemented it in the reolink-aio library :)

On the new firmware:

          "supportDingDongCtrl": {
            "permit": 0,
            "ver": 0
          },

So I think the dingDong commands are not fully working yet.

GetDingDongList gives:
[{'cmd': 'GetDingDongList', 'code': 1, 'error': {'detail': 'rcv failed', 'rspCode': -17}}]

[{"cmd": "DingDongOpt", "action": 0, "param": {"channel": 0, "option": 4, "id": 0, "musicId": 1}}] gives:
[{'cmd': 'DingDongOpt', 'code': 1, 'error': {'detail': 'rcv failed', 'rspCode': -17}}]

[{'cmd': 'DingDongOpt', 'action': 0, 'param': {'channel': 0, 'option': 2, 'id': 0}}] gives:
[{'cmd': 'DingDongOpt', 'code': 1, 'error': {'detail': 'rcv failed', 'rspCode': -17}}]

GetDingDongCfg gives a intresting response:
Seems like they are developing more advanced chimes that can be controlled through the API:

[
   {
      "cmd":"GetDingDongCfg",
      "code":0,
      "value":{
         "DingDongCfg":{
            "pairedlist":[
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               },
               {
                  "ringId":-1,
                  "ringName":"Reolink Chime",
                  "type":{
                     "md":{
                        "musicId":0,
                        "switch":0
                     },
                     "people":{
                        "musicId":0,
                        "switch":0
                     },
                     "visitor":{
                        "musicId":0,
                        "switch":1
                     }
                  }
               }
            ]
         }
      }
   }
]

I have already been using the GetChnTypeInfo for some time. I really hope they will add the hardware version to this command!

GetWebHook, SetWebHook and TestWebHook were already implemented in the reolink-aio library.
They work but are not too usefull, there is not so much info in the webhook calls and they are coupled to the push settings, making them very messy.
ONVIF WS base subscription is a better option in my opinion.

@mnpg thank you very very much for these additional commands, very usefull.

I am especially thrilled about the QuickReplyPlay command.
And the GetDingDongCfg is certainly interesting since it looks like some new chimes are comming.

mnpg commented

The command: body = [{"cmd":"QuickReplyPlay","action":0,"param":{"id": 1}}] works and plays the quick reply message. I already implemented it in the reolink-aio library :)

@starkillerOG, in the command QuickReplyPlay, does the id parameter correspond to the response number (id parameter for the AudioFileList) we would like to hear?

The command: body = [{"cmd":"QuickReplyPlay","action":0,"param":{"id": 1}}] works and plays the quick reply message. I already implemented it in the reolink-aio library :)

@starkillerOG, in the command QuickReplyPlay, does the id parameter correspond to the response number (id parameter for the AudioFileList) we would like to hear?

Yes exactly. The ID equals the file_id.

@mnpg do you know how the SetAudioFileList command works for the doorbell?
Does it allow you to upload a quick replay audio file directly?

mnpg commented

Hi @starkillerOG , sorry to reply you late i was on holidays. I will take a look.

mnpg commented

hi @starkillerOG, here the only infos i found about SetAudioFileList :


{
AudioFileList: {
                      id: n.identity,
                      fileName: n.cFileName,
                      channel: this.index
                      }
}

Does it allow you to upload a quick replay audio file directly?

I don't know, no easy to understand their js file

Sorry for the noise. You guys are fabulous. Thank you very much.