Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: [GW_DBD] Front door not supported #1386

Open
Angel-Vazquez opened this issue Nov 13, 2024 · 18 comments · May be fixed by #1388
Open

BUG: [GW_DBD] Front door not supported #1386

Angel-Vazquez opened this issue Nov 13, 2024 · 18 comments · May be fixed by #1388
Labels
bug Something isn't working

Comments

@Angel-Vazquez
Copy link

Describe the bug

New Wyze product "Wyze Duo Cam Doorbell" is currently not supported.
https://www.wyze.com/products/wyze-duo-cam-doorbell

Using the :latest tag at the moment to verify.

Affected Bridge Version

latest

Bridge type

Docker Run/Compose

Affected Camera(s)

Wyze Duo Cam Doorbell

Affected Camera Firmware

1.0.23.93

docker-compose or config (if applicable)

No response

@Angel-Vazquez Angel-Vazquez added the bug Something isn't working label Nov 13, 2024
@Angel-Vazquez
Copy link
Author

Tentative fix is to add the model name inside here.
https://github.com/mrlt8/docker-wyze-bridge/blob/main/app/wyzecam/api_models.py

Angel-Vazquez added a commit to Angel-Vazquez/docker-wyze-bridge that referenced this issue Nov 14, 2024
@Angel-Vazquez Angel-Vazquez linked a pull request Nov 14, 2024 that will close this issue
@dmkjr
Copy link

dmkjr commented Nov 14, 2024

@Angel-Vazquez awesome news! Did that work? I see you said tentative and then a PR was created.

@Angel-Vazquez
Copy link
Author

Angel-Vazquez commented Nov 14, 2024 via email

@Angel-Vazquez
Copy link
Author

@dmkjr - Any ideas on testing this change? I pulled the version to my local repo and ran docker compose up, but it's not working.

@Angel-Vazquez
Copy link
Author

when executing Docker Build -t test-wyze . in the /docker directory I receive this error:

ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref fbd32e3d-1ac0-47ba-b85c-9fcdc69886b3::945aaegfpe1ti4ev5b2ovevyw: "/app": not found

@dmkjr
Copy link

dmkjr commented Nov 15, 2024

when executing Docker Build -t test-wyze . in the /docker directory I receive this error:


ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref fbd32e3d-1ac0-47ba-b85c-9fcdc69886b3::945aaegfpe1ti4ev5b2ovevyw: "/app": not found

Was the only change to add the name of the camera? Due to resolution issues, there probably is another file that needs to be edited outside of the name. Use another camera model and search the repository for where it's referenced.

@Angel-Vazquez
Copy link
Author

Was the only change to add the name of the camera? Due to resolution issues, there probably is another file that needs to be edited outside of the name. Use another camera model and search the repository for where it's referenced.

Correct, the only change was the single-line addition.

If you want to throw it on another tag that isn't main, I don't mind running that particular build on my server to verify before promotion to main.

@dmkjr
Copy link

dmkjr commented Nov 15, 2024

Was the only change to add the name of the camera? Due to resolution issues, there probably is another file that needs to be edited outside of the name. Use another camera model and search the repository for where it's referenced.

Correct, the only change was the single-line addition.

If you want to throw it on another tag that isn't main, I don't mind running that particular build on my server to verify before promotion to main.

I'm looking at it now.

@Angel-Vazquez
Copy link
Author

I'm looking at it now.

Thanks for that.
If you have steps for the future, I don't mind taking a look at other issues and attempting to be a contributor.

@dmkjr
Copy link

dmkjr commented Nov 15, 2024

I'm looking at it now.

Thanks for that. If you have steps for the future, I don't mind taking a look at other issues and attempting to be a contributor.

You are missing some reference.

import os
import re
import uuid
from typing import Any, Optional

from pydantic import BaseModel

MODEL_NAMES = {
    "WYZEC1": "V1",
    "WYZEC1-JZ": "V2",
    "WYZE_CAKP2JFUS": "V3",
    "HL_CAM4": "V4",
    "HL_CAM3P": "V3 Pro",
    "WYZECP1_JEF": "Pan",
    "HL_PAN2": "Pan V2",
    "HL_PAN3": "Pan V3",
    "HL_PANP": "Pan Pro",
    "HL_CFL2": "Floodlight V2",
    "WYZEDB3": "Doorbell",
    "HL_DB2": "Doorbell V2",
    "GW_BE1": "Doorbell Pro",
    "AN_RDB1": "Doorbell Pro 2",
    "GW_GC1": "OG",
    "GW_GC2": "OG 3X",
    "WVOD1": "Outdoor",
    "HL_WCO2": "Outdoor V2",
    "AN_RSCW": "Battery Cam Pro",
    "LD_CFP": "Floodlight Pro",
    "GW_DBD": "Doorbell Duo",
}

# These cameras don't seem to support WebRTC
NO_WEBRTC = {
    "WYZEC1",
    "HL_PANP",
    "WVOD1",
    "HL_WCO2",
    "AN_RSCW",
    "WYZEDB3",
    "HL_DB2",
    "GW_BE1",
    "AN_RDB1",
}


# known 2k cameras
PRO_CAMS = {"HL_CAM3P", "HL_PANP", "HL_CAM4", "HL_DB2", "HL_CFL2"}

PAN_CAMS = {"WYZECP1_JEF", "HL_PAN2", "HL_PAN3", "HL_PANP"}

BATTERY_CAMS = {"WVOD1", "HL_WCO2", "AN_RSCW"}

AUDIO_16k = {"WYZE_CAKP2JFUS", "HL_CAM3P", "MODEL_HL_PANP"}
# Doorbells
DOORBELL = {"WYZEDB3", "HL_DB2", "GW_DBD"}

FLOODLIGHT_CAMS = {"HL_CFL2"}

VERTICAL_CAMS = {"WYZEDB3", "GW_BE1", "AN_RDB1"}
# Minimum known firmware version that supports multiple streams
SUBSTREAM_FW = {"WYZEC1-JZ": "4.9.9", "WYZE_CAKP2JFUS": "4.36.10", "HL_CAM3P": "4.58.0"}

RTSP_FW = {"4.19.", "4.20.", "4.28.", "4.29.", "4.61."}


class WyzeCredential(BaseModel):
    """Authenticated credentials; see [wyzecam.api.login][].

    :var access_token: Access token used to authenticate other API calls
    :var refresh_token: Refresh token used to refresh the access_token if it expires
    :var user_id: Wyze user id of the authenticated user
    :var mfa_options: Additional options for 2fa support
    :var mfa_details: Additional details for 2fa support
    :var sms_session_id: Additional details for SMS support
    :var email_session_id: Additional details for email support
    :var phone_id: The phone id passed to [login()][wyzecam.api.login]
    """

    access_token: Optional[str] = None
    refresh_token: Optional[str] = None
    user_id: Optional[str] = None
    mfa_options: Optional[list] = None
    mfa_details: Optional[dict[str, Any]] = None
    sms_session_id: Optional[str] = None
    email_session_id: Optional[str] = None
    phone_id: Optional[str] = str(uuid.uuid4())


class WyzeAccount(BaseModel):
    """User profile information; see [wyzecam.api.get_user_info][].

    :var phone_id: The phone id passed to [login()][wyzecam.api.login]
    :var logo: URL to a profile photo of the user
    :var nickname: nickname of the user
    :var email: email of the user
    :var user_code: code of the user
    :var user_center_id: center id of the user
    :var open_user_id: open id of the user (used for authenticating with newer firmwares; important!)
    """

    phone_id: str
    logo: str
    nickname: str
    email: str
    user_code: str
    user_center_id: str
    open_user_id: str


class WyzeCamera(BaseModel):
    """Wyze camera device information; see [wyzecam.api.get_camera_list][].

    :var p2p_id: the p2p id of the camera, used for identifying the camera to tutk.
    :var enr: the enr of the camera, used for signing challenge requests from cameras during auth.
    :var mac: the mac address of the camera.
    :var product_model: the product model (or type) of camera
    :var camera_info: populated as a result of authenticating with a camera
                      using a [WyzeIOTCSession](../../iotc_session/).
    :var nickname: the user specified 'nickname' of the camera
    :var timezone_name: the timezone of the camera

    """

    p2p_id: Optional[str]
    p2p_type: Optional[int]
    ip: Optional[str]
    enr: Optional[str]
    mac: str
    product_model: str
    camera_info: Optional[dict[str, Any]] = None
    nickname: Optional[str]
    timezone_name: Optional[str]
    firmware_ver: Optional[str]
    dtls: Optional[int]
    parent_dtls: Optional[int]
    parent_enr: Optional[str]
    parent_mac: Optional[str]
    thumbnail: Optional[str]

    def set_camera_info(self, info: dict[str, Any]) -> None:
        # Called internally as part of WyzeIOTC.connect_and_auth()
        self.camera_info = info

    @property
    def name_uri(self) -> str:
        """Return a URI friendly name by removing special characters and spaces."""
        uri_sep = "-"
        if os.getenv("URI_SEPARATOR") in {"-", "_", "#"}:
            uri_sep = os.getenv("URI_SEPARATOR", uri_sep)
        uri = clean_name(self.nickname or self.mac, uri_sep).lower()
        if os.getenv("URI_MAC", "").lower() == "true" and (self.mac or self.parent_mac):
            uri += uri_sep + (self.mac or self.parent_mac or "")[-4:]
        return uri

    @property
    def model_name(self) -> str:
        return MODEL_NAMES.get(self.product_model, self.product_model)

    @property
    def webrtc_support(self) -> bool:
        """Check if camera model is known to support WebRTC."""
        return self.product_model not in NO_WEBRTC

    @property
    def is_2k(self) -> bool:
        return self.product_model in PRO_CAMS or self.model_name.endswith("Pro")

    @property
    def is_floodlight(self) -> bool:
        return self.product_model in FLOODLIGHT_CAMS

    @property
    def default_sample_rate(self) -> int:
        return 16000 if self.product_model in AUDIO_16k else 8000

    @property
    def is_gwell(self) -> bool:
        return self.product_model.startswith("GW_")

    @property
    def is_battery(self) -> bool:
        return self.product_model in BATTERY_CAMS

    @property
    def is_vertical(self) -> bool:
        return self.product_model in VERTICAL_CAMS

    @property
    def is_pan_cam(self) -> bool:
        return self.product_model in PAN_CAMS

    @property
    def can_substream(self) -> bool:
        if self.rtsp_fw:
            return False
        min_ver = SUBSTREAM_FW.get(self.product_model)
        return is_min_version(self.firmware_ver, min_ver)

    @property
    def rtsp_fw(self) -> bool:
        return bool(self.firmware_ver and self.firmware_ver[:5] in RTSP_FW)


def clean_name(name: str, uri_sep: str = "_") -> str:
    """Return a URI friendly name by removing special characters and spaces."""
    return (
        re.sub(r"[^\-\w+]", "", name.strip().replace(" ", uri_sep))
        .encode("ascii", "ignore")
        .decode()
    ).upper()


def is_min_version(version: Optional[str], min_version: Optional[str]) -> bool:
    if not version or not min_version:
        return False
    version_parts = list(map(int, version.split(".")))
    min_version_parts = list(map(int, min_version.split(".")))
    return (version_parts >= min_version_parts) or (
        version_parts == min_version_parts and version >= min_version
    )

@dmkjr
Copy link

dmkjr commented Nov 15, 2024

Secondly, on your build.... that error means it doesn't see /app in the build as rquired.

@Angel-Vazquez
Copy link
Author

I verified that and it it seems to have /app in the directory, so I'm unsure why it's throwing that error.

I appended "GW_DBD" to the DOORBELL set per your comment.

@dmkjr
Copy link

dmkjr commented Nov 16, 2024

I verified that and it it seems to have /app in the directory, so I'm unsure why it's throwing that error.

I appended "GW_DBD" to the DOORBELL set per your comment.

Just had a few minutes. I was able to compile the code.

CleanShot 2024-11-15 at 23 23 29@2x

@Angel-Vazquez
Copy link
Author

Must be my environment throwing errors when compiling, but I'm glad it compiled in your known environment.

@dmkjr
Copy link

dmkjr commented Nov 17, 2024

Must be my environment throwing errors when compiling, but I'm glad it compiled in your known environment.

No. You have to move the Dockerfile to the location of the files. Then it will find your /app directory. Make sure you are building to the correct processor you need.

@Angel-Vazquez
Copy link
Author

No. You have to move the Dockerfile to the location of the files. Then it will find your /app directory. Make sure you are building to the correct processor you need.

Thanks for the tip there, I was able to compile it once I move the Dockerfile up a directory.

With that being said, the Duo Cam Doorbell is not working still. I modified the following lines in the api_models.py file:

MODEL_NAMES = {
    "WYZEC1": "V1",
    "WYZEC1-JZ": "V2",
    "WYZE_CAKP2JFUS": "V3",
    "HL_CAM4": "V4",
    "HL_CAM3P": "V3 Pro",
    "WYZECP1_JEF": "Pan",
    "HL_PAN2": "Pan V2",
    "HL_PAN3": "Pan V3",
    "HL_PANP": "Pan Pro",
    "HL_CFL2": "Floodlight V2",
    "WYZEDB3": "Doorbell",
    "HL_DB2": "Doorbell V2",
    "GW_BE1": "Doorbell Pro",
    "AN_RDB1": "Doorbell Pro 2",
    "GW_GC1": "OG",
    "GW_GC2": "OG 3X",
    "WVOD1": "Outdoor",
    "HL_WCO2": "Outdoor V2",
    "AN_RSCW": "Battery Cam Pro",
    "LD_CFP": "Floodlight Pro",
    "GW_DBD": "Doorbell Duo",
}

# These cameras don't seem to support WebRTC
NO_WEBRTC = {
    "WYZEC1",
    "HL_PANP",
    "WVOD1",
    "HL_WCO2",
    "AN_RSCW",
    "WYZEDB3",
    "HL_DB2",
    "GW_BE1",
    "AN_RDB1",
}


# known 2k cameras
PRO_CAMS = {"HL_CAM3P", "HL_PANP", "HL_CAM4", "HL_DB2", "HL_CFL2", "GW_DBD"}

PAN_CAMS = {"WYZECP1_JEF", "HL_PAN2", "HL_PAN3", "HL_PANP"}

BATTERY_CAMS = {"WVOD1", "HL_WCO2", "AN_RSCW", "GW_DBD"}

AUDIO_16k = {"WYZE_CAKP2JFUS", "HL_CAM3P", "MODEL_HL_PANP"}
# Doorbells
DOORBELL = {"WYZEDB3", "HL_DB2", "GW_DBD"}

FLOODLIGHT_CAMS = {"HL_CFL2"}

VERTICAL_CAMS = {"WYZEDB3", "GW_BE1", "AN_RDB1", "GW_DBD"}

But I believe the error is within wyze_stream.py line 98 where we define the setup func, as the Duo Cam Doorbell will be true with self.camera.is_gwell as the model number starts with "GW".

I did comment it out, re-compiled the Dockerfile, but was unable to get the camera running using VLC.

If I did begin to comment out code or edit it to force it to run, I'll receive a tutk.py error "IOTC_ER_UNLICENSE".

@dmkjr
Copy link

dmkjr commented Nov 19, 2024

Wyze is building firmware (or testing firmware) that's blocking some extra API stuff. I'm not saying that's the case here, but could be. I haven't had any time to look into it yet.

@dmkjr
Copy link

dmkjr commented Dec 1, 2024

@Angel-Vazquez appears to be device specific configuration @ device_config.json.

May need to figure that out. Might require inspecting the camera firmware to understand OR inspect the Wyze API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants