pyalarmdotcom / alarmdotcom

Custom component to allow Home Assistant to interface with Alarm.com
MIT License
114 stars 35 forks source link

Camera Feed Help #386

Open kmcrawford opened 4 months ago

kmcrawford commented 4 months ago

I'm looking at the camera feeds (ADC-V610PT & ADC-V521IR) and there are urls with a token on them. Assuming we can figure out the token and what it means and how to create it, having the camera live view may not be so difficult.

https://legacyvideostream-na01.devicetask.com/ProxyLiveVideoMobile.ashx?token=<token>

The token does not look to be standard jwt.io there are only 2 sections delimited by a . Example of first section base64 decoded: (yes looks like incomplete json data)

{"ui":<int>,"di":<int>,"li":<int>,"uha":"<camera ip>","ico":false,"iee":false,"su":

The second part after the . decoded I can base64 decode it, but I don't think it's correct in ASCII I see a lot of ???)Ū( characters. So it is the second part I fear that will be hard, especially if it is signed with a secret key server-side.

kmcrawford commented 3 months ago

I took some time to look into this more.

There is an api called to get all devices, which I'm sure this project already uses. https://www.alarm.com/web/api/systems/systems/<accountCode?>

Then call https://www.alarm.com/web/api/video/videoSources/liveVideoSources/

This will return the proxyUrl to get the video:

"data": {
    "id": "<device-id>",
    "type": "video/videoSources/liveVideoSource",
    "attributes": {
      "errorEnum": 0,
      "isMjpeg": true,
      "urlEncoded": false,
      "proxyStreamTimeoutTime": 180,
      "proxyUrl": "https://legacyvideostream-na01.devicetask.com/ProxyLiveVideoMobile.ashx?token=<token>",
      "janusGatewayUrl": null,
kmcrawford commented 3 months ago

I created a PR that calls the api to get the proxyUrl from the above api: https://github.com/pyalarmdotcom/pyalarmdotcomajax/pull/140

elahd commented 3 months ago

Amazing work, thanks for this! I'll work the changes back into v0.6.0, being tested here.

A few questions about consuming the feed:

  1. Is there audio?
  2. Is the token all that's required to authenticate, or are ADC authentication cookies required, as well?
  3. Is the proxyStreamTimeoutTime for the token's life or is it how long the client should wait for the HTTP connection to establish?
  4. Within the web/api/systems/systems/ response, do you see any values in the camera's manufacturer or device_model attributes that can be used to identify your camera models? Do you know whether this response format works for camera models beyond the two that you own?
  5. How does this appear in the systems endpoint? Is it a standalone device with the type "video/videoSources/liveVideoSource", or is listed as a relationship of a "video/camera"?

Thanks again.

elahd commented 3 months ago

Looks like 5 is answered in my own post in #101 🤦‍♂️, along with a helpful comment by @ifeign.

kmcrawford commented 3 months ago

Example of my browser (not showing full url or video for privacy)

image

1.) There is no Audio, at least my camera's don't support audio 2.) Just the url in the proxyUrl is required to view the live stream, the token does expire at some point so will need to be refreshed. 3.) I'm not sure about this one, it does time out after some time 4.) I included the device payload below, deviceModel does exist, but not make. 5.) See payload below

id's and ip addresses obfuscated

{
  "data": [
    {
      "id": "32323432234-2050",
      "type": "video/devices/camera",
      "attributes": {
        "supportsSnapShot": false,
        "canTakeSnapshot": true,
        "supportsRecording": true,
        "canRequestRecording": true,
        "canUploadClips": true,
        "maxSvrClipDownloadDurationSec": 900,
        "maxSvrClipUploadDurationSec": 300,
        "username": null,
        "hasSvrSchedule": false,
        "onvifParentId": null,
        "excludedFromVisualVerification": false,
        "excludedFromEscalatedEvents": false,
        "liveViewHdToggleEnabled": true,
        "supportsEndToEndWebRTCStreaming": false,
        "supports4MPStreaming": false,
        "supportsSiren": false,
        "canSirenBeActivatedByLogin": false,
        "isWarningReactionEnabled": false,
        "isSirenPlaying": false,
        "supportsLight": false,
        "osdOverlayEnabled": false,
        "isOnvifCamera": false,
        "canPanTilt": false,
        "maxPanTiltLevel": 0,
        "canZoom": false,
        "maxZoomLevel": 0,
        "minZoomLevelForPanTilt": 0,
        "panTiltPresets": [],
        "preferredPanTiltPreset": null,
        "isUnreachable": false,
        "lastSuccessfulSupervision": null,
        "lastOperatorViewedTime": null,
        "doorbellChimeType": 1,
        "supportedDoorbellWedgeOptions": null,
        "doorbellWedgeType": 0,
        "supportsWedgeYesNo": false,
        "supportsWedgeGIF": false,
        "supportsVmdSchedules": false,
        "deviceImagePath": "/web/webimages/camera_images/SkyBellHD_64px.png?v=2",
        "deviceMake": null,
        "deviceModel": "SKYBELLHD",
        "macAddress": "33234323",
        "firmwareVersion": "5042",
        "thirdPartySerialNumber": "2932498340",
        "publicIp": null,
        "privateIp": null,
        "port": null,
        "httpsPort": null,
        "shouldUseEntireImageForSnapshot": false,
        "hasDdnsed": false,
        "usageProtocolMapping": {
          "6": 1,
          "9": 1,
          "10": 1,
          "18": 3,
          "20": 3
        },
        "isVirtualCamera": false,
        "isDigitalFovCamera": false,
        "isVarifocalCamera": false,
        "hasSdRecordingSchedule": false,
        "usingGatewayForBackendAccess": false,
        "isFirmwareUpToDate": true,
        "streamUsageToScrubberThumbnailsMapping": null,
        "lastDdnsUpdateTime": "2024-03-19T13:52:36.9955058Z",
        "supportsLiveView": false,
        "isLiveViewDisplayable": true,
        "forcedAspectRatio": null,
        "isTwoWayAudioEnabled": false,
        "isRecordedAudioEnabled": false,
        "hasFirmwareForTwoWayAudio": false,
        "canUpgradeFirmware": true,
        "hasUpstreamAudioUrl": false,
        "supportsVideoClipUpload": false,
        "canBeSaved": false,
        "canChangeDescription": false,
        "description": "Front Door Skybell",
        "deviceModelId": 0,
        "canConfirmStateChange": false,
        "canReceiveCommands": false,
        "remoteCommandsEnabled": false,
        "hasPermissionToChangeState": false,
        "deviceIcon": {
          "icon": 27
        },
        "batteryLevelNull": null,
        "lowBattery": false,
        "criticalBattery": false
      },
      "relationships": {
        "videoEvents": {
          "data": [],
          "meta": {
            "count": "0"
          }
        },
        "password": {
          "data": {
            "id": "4564566-2050",
            "type": "video/cameraPassword"
          }
        },
        "videoSource": {
          "data": {
            "id": "1231223-2050",
            "type": "video/videoSources/liveVideoSource"
          }
        },
        "videoSourceHd": {
          "data": {
            "id": "2323432-2050",
            "type": "video/videoSources/liveVideoHighestResSource"
          }
        },
        "svrVideoSource": {
          "data": {
            "id": "23423-2050",
            "type": "video/videoSources/svrVideoSource"
          }
        },
        "svrScrubberThumbnailEndpoint": {
          "data": {
            "id": "3434534-2050",
            "type": "video/svrThumbnailEndpoint"
          }
        },
        "light": {
          "data": null
        },
        "cameraSiren": {
          "data": null
        },
        "cameraLightSetting": {
          "data": null
        },
        "liveVideoSetting": {
          "data": {
            "id": "34534-2050",
            "type": "video/live-video-setting"
          }
        },
        "signalStrengthInfo": {
          "data": {
            "id": "34534-2050",
            "type": "video/signal-strength-info"
          }
        },
        "digitalPtzPosition": {
          "data": {
            "id": "345345-2050",
            "type": "video/digitalPtzPosition"
          }
        },
        "streamVideoToPanelInfo": {
          "data": {
            "id": "45634543-2050",
            "type": "video/stream-video-to-panel-info"
          }
        },
        "snapshot": {
          "data": {
            "id": "4564565-2050",
            "type": "video/snapshot"
          }
        },
        "privacyZonesSetting": {
          "data": null
        },
        "generalSetting": {
          "data": {
            "id": "456456-2050",
            "type": "video/settings/general-setting"
          }
        },
        "networkInfo": {
          "data": {
            "id": "4564565-2050",
            "type": "video/settings/network-info"
          }
        },
        "audioSetting": {
          "data": {
            "id": "465565456-2050",
            "type": "video/settings/audio-setting"
          }
        },
        "videoConfig": {
          "data": {
            "id": "6767676-2050",
            "type": "video/settings/video-config"
          }
        },
        "system": {
          "data": {
            "id": "8666767",
            "type": "systems/system"
          }
        },
        "stateInfo": {
          "data": null
        }
      }
    },
    {
      "id": "8888888-2048",
      "type": "video/devices/camera",
      "attributes": {
        "supportsSnapShot": true,
        "canTakeSnapshot": true,
        "supportsRecording": true,
        "canRequestRecording": true,
        "canUploadClips": true,
        "maxSvrClipDownloadDurationSec": 900,
        "maxSvrClipUploadDurationSec": 300,
        "username": "root",
        "hasSvrSchedule": false,
        "onvifParentId": null,
        "excludedFromVisualVerification": false,
        "excludedFromEscalatedEvents": false,
        "liveViewHdToggleEnabled": false,
        "supportsEndToEndWebRTCStreaming": false,
        "supports4MPStreaming": false,
        "supportsSiren": false,
        "canSirenBeActivatedByLogin": false,
        "isWarningReactionEnabled": false,
        "isSirenPlaying": false,
        "supportsLight": false,
        "osdOverlayEnabled": false,
        "isOnvifCamera": false,
        "canPanTilt": false,
        "maxPanTiltLevel": 0,
        "canZoom": false,
        "maxZoomLevel": 0,
        "minZoomLevelForPanTilt": 0,
        "panTiltPresets": [],
        "preferredPanTiltPreset": null,
        "isUnreachable": false,
        "lastSuccessfulSupervision": "2024-03-19T16:16:02.183Z",
        "lastOperatorViewedTime": null,
        "doorbellChimeType": -1,
        "supportedDoorbellWedgeOptions": null,
        "doorbellWedgeType": 0,
        "supportsWedgeYesNo": false,
        "supportsWedgeGIF": false,
        "supportsVmdSchedules": true,
        "deviceImagePath": "/web/webimages/camera_images/V521IR_64px.png?v=2",
        "deviceMake": null,
        "deviceModel": "ADC-V521IR",
        "macAddress": "0002D14755AB",
        "firmwareVersion": "IP8137-ALAM-0100d2",
        "thirdPartySerialNumber": null,
        "publicIp": "99.99.33.33",
        "privateIp": "192.168.8.49",
        "port": "40925",
        "httpsPort": "41925",
        "shouldUseEntireImageForSnapshot": false,
        "hasDdnsed": true,
        "usageProtocolMapping": {
          "6": 1,
          "9": 1,
          "10": 1,
          "18": 3,
          "20": 3
        },
        "isVirtualCamera": false,
        "isDigitalFovCamera": false,
        "isVarifocalCamera": false,
        "hasSdRecordingSchedule": false,
        "usingGatewayForBackendAccess": false,
        "isFirmwareUpToDate": true,
        "streamUsageToScrubberThumbnailsMapping": null,
        "lastDdnsUpdateTime": "2024-03-19T16:16:44.64Z",
        "supportsLiveView": true,
        "isLiveViewDisplayable": true,
        "forcedAspectRatio": null,
        "isTwoWayAudioEnabled": false,
        "isRecordedAudioEnabled": false,
        "hasFirmwareForTwoWayAudio": true,
        "canUpgradeFirmware": true,
        "hasUpstreamAudioUrl": true,
        "supportsVideoClipUpload": false,
        "canBeSaved": false,
        "canChangeDescription": false,
        "description": "Garage Camera",
        "deviceModelId": 0,
        "canConfirmStateChange": false,
        "canReceiveCommands": false,
        "remoteCommandsEnabled": false,
        "hasPermissionToChangeState": false,
        "deviceIcon": {
          "icon": 27
        },
        "batteryLevelNull": null,
        "lowBattery": false,
        "criticalBattery": false
      },
      "relationships": {
        "videoEvents": {
          "data": [],
          "meta": {
            "count": "0"
          }
        },
        "password": {
          "data": {
            "id": "666666-6666",
            "type": "video/cameraPassword"
          }
        },
        "videoSource": {
          "data": {
            "id": "4444444-4444",
            "type": "video/videoSources/liveVideoSource"
          }
        },
        "videoSourceHd": {
          "data": {
            "id": "4444444-4444",
            "type": "video/videoSources/liveVideoHighestResSource"
          }
        },
        "svrVideoSource": {
          "data": {
            "id": "3434333-3333",
            "type": "video/videoSources/svrVideoSource"
          }
        },
        "svrScrubberThumbnailEndpoint": {
          "data": {
            "id": "4444444-4444",
            "type": "video/svrThumbnailEndpoint"
          }
        },
        "light": {
          "data": null
        },
        "cameraSiren": {
          "data": null
        },
        "cameraLightSetting": {
          "data": null
        },
        "liveVideoSetting": {
          "data": {
            "id": "3333333-3333",
            "type": "video/live-video-setting"
          }
        },
        "signalStrengthInfo": {
          "data": {
            "id": "2222222-2222",
            "type": "video/signal-strength-info"
          }
        },
        "digitalPtzPosition": {
          "data": {
            "id": "2222222-2222",
            "type": "video/digitalPtzPosition"
          }
        },
        "streamVideoToPanelInfo": {
          "data": {
            "id": "1232222-1111",
            "type": "video/stream-video-to-panel-info"
          }
        },
        "snapshot": {
          "data": {
            "id": "4444444-2222",
            "type": "video/snapshot"
          }
        },
        "privacyZonesSetting": {
          "data": null
        },
        "generalSetting": {
          "data": {
            "id": "777777-7777",
            "type": "video/settings/general-setting"
          }
        },
        "networkInfo": {
          "data": {
            "id": "333333-3333",
            "type": "video/settings/network-info"
          }
        },
        "audioSetting": {
          "data": {
            "id": "666666-6666",
            "type": "video/settings/audio-setting"
          }
        },
        "videoConfig": {
          "data": {
            "id": "5555555-5555",
            "type": "video/settings/video-config"
          }
        },
        "system": {
          "data": {
            "id": "444444",
            "type": "systems/system"
          }
        },
        "stateInfo": {
          "data": null
        }
      }
    },
    {
      "id": "3333333-3333",
      "type": "video/devices/camera",
      "attributes": {
        "supportsSnapShot": true,
        "canTakeSnapshot": true,
        "supportsRecording": true,
        "canRequestRecording": true,
        "canUploadClips": true,
        "maxSvrClipDownloadDurationSec": 900,
        "maxSvrClipUploadDurationSec": 300,
        "username": "root",
        "hasSvrSchedule": false,
        "onvifParentId": null,
        "excludedFromVisualVerification": false,
        "excludedFromEscalatedEvents": false,
        "liveViewHdToggleEnabled": true,
        "supportsEndToEndWebRTCStreaming": false,
        "supports4MPStreaming": false,
        "supportsSiren": false,
        "canSirenBeActivatedByLogin": false,
        "isWarningReactionEnabled": false,
        "isSirenPlaying": false,
        "supportsLight": false,
        "osdOverlayEnabled": false,
        "isOnvifCamera": false,
        "canPanTilt": true,
        "maxPanTiltLevel": 0,
        "canZoom": false,
        "maxZoomLevel": 0,
        "minZoomLevelForPanTilt": 0,
        "panTiltPresets": [
          {
            "Id": "Home",
            "Name": "Home",
            "IconClass": "video-pt-center"
          },
          {
            "Id": "4444444",
            "Name": "Master Bedroom",
            "IconClass": ""
          },
          {
            "Id": "222222222",
            "Name": "Dinning Room",
            "IconClass": ""
          }
        ],
        "preferredPanTiltPreset": null,
        "isUnreachable": false,
        "lastSuccessfulSupervision": "2024-03-19T10:50:23.487Z",
        "lastOperatorViewedTime": null,
        "doorbellChimeType": -1,
        "supportedDoorbellWedgeOptions": null,
        "doorbellWedgeType": 0,
        "supportsWedgeYesNo": false,
        "supportsWedgeGIF": false,
        "supportsVmdSchedules": true,
        "deviceImagePath": "/web/webimages/camera_images/610PT_64px.png?v=2",
        "deviceMake": null,
        "deviceModel": "ADC-V610PT",
        "macAddress": "9999999999",
        "firmwareVersion": "TC5633-TCAL-0108a1",
        "thirdPartySerialNumber": null,
        "publicIp": "99.99.99.999",
        "privateIp": "192.168.0.12",
        "port": "40926",
        "httpsPort": "41926",
        "shouldUseEntireImageForSnapshot": false,
        "hasDdnsed": true,
        "usageProtocolMapping": {
          "6": 1,
          "9": 1,
          "10": 1,
          "18": 3,
          "20": 3
        },
        "isVirtualCamera": false,
        "isDigitalFovCamera": false,
        "isVarifocalCamera": false,
        "hasSdRecordingSchedule": false,
        "usingGatewayForBackendAccess": false,
        "isFirmwareUpToDate": true,
        "streamUsageToScrubberThumbnailsMapping": null,
        "lastDdnsUpdateTime": "2024-03-19T16:24:34.7333333Z",
        "supportsLiveView": true,
        "isLiveViewDisplayable": true,
        "forcedAspectRatio": null,
        "isTwoWayAudioEnabled": false,
        "isRecordedAudioEnabled": false,
        "hasFirmwareForTwoWayAudio": false,
        "canUpgradeFirmware": true,
        "hasUpstreamAudioUrl": false,
        "supportsVideoClipUpload": false,
        "canBeSaved": false,
        "canChangeDescription": false,
        "description": "Outside Camera",
        "deviceModelId": 0,
        "canConfirmStateChange": false,
        "canReceiveCommands": false,
        "remoteCommandsEnabled": false,
        "hasPermissionToChangeState": false,
        "deviceIcon": {
          "icon": 27
        },
        "batteryLevelNull": null,
        "lowBattery": false,
        "criticalBattery": false
      },
      "relationships": {
        "videoEvents": {
          "data": [],
          "meta": {
            "count": "0"
          }
        },
        "password": {
          "data": {
            "id": "11111-11111",
            "type": "video/cameraPassword"
          }
        },
        "videoSource": {
          "data": {
            "id": "11111111-1111",
            "type": "video/videoSources/liveVideoSource"
          }
        },
        "videoSourceHd": {
          "data": {
            "id": "1111111-1111",
            "type": "video/videoSources/liveVideoHighestResSource"
          }
        },
        "svrVideoSource": {
          "data": {
            "id": "111111111-1111",
            "type": "video/videoSources/svrVideoSource"
          }
        },
        "svrScrubberThumbnailEndpoint": {
          "data": {
            "id": "11111111-11111",
            "type": "video/svrThumbnailEndpoint"
          }
        },
        "light": {
          "data": null
        },
        "cameraSiren": {
          "data": null
        },
        "cameraLightSetting": {
          "data": null
        },
        "liveVideoSetting": {
          "data": {
            "id": "9111111-11111",
            "type": "video/live-video-setting"
          }
        },
        "signalStrengthInfo": {
          "data": {
            "id": "2111111-1111",
            "type": "video/signal-strength-info"
          }
        },
        "digitalPtzPosition": {
          "data": {
            "id": "111111111-22233",
            "type": "video/digitalPtzPosition"
          }
        },
        "streamVideoToPanelInfo": {
          "data": null
        },
        "snapshot": {
          "data": {
            "id": "11111111-2222",
            "type": "video/snapshot"
          }
        },
        "privacyZonesSetting": {
          "data": null
        },
        "generalSetting": {
          "data": {
            "id": "94111111-1111",
            "type": "video/settings/general-setting"
          }
        },
        "networkInfo": {
          "data": {
            "id": "911111112-2111",
            "type": "video/settings/network-info"
          }
        },
        "audioSetting": {
          "data": {
            "id": "911111111-2111",
            "type": "video/settings/audio-setting"
          }
        },
        "videoConfig": {
          "data": {
            "id": "111111111-1111",
            "type": "video/settings/video-config"
          }
        },
        "system": {
          "data": {
            "id": "4918381",
            "type": "systems/system"
          }
        },
        "stateInfo": {
          "data": null
        }
      }
    }
  ],
  "included": [],
  "meta": {
    "transformer_version": "1.1"
  }
}
kmcrawford commented 3 months ago

By making this change in the ajax project "rel_id": "video/camera" -> "rel_id": "video/devices/camera"

image

And making this change in the alarmdotcom project, I could see my devices listed in my local version of HA.

image