BaQs / pyEzviz

Python package for ezviz cameras
Apache License 2.0
103 stars 45 forks source link

Support switch on DeviceSwitchType.ALARM_LIGHT #30

Closed modestpharaoh closed 1 year ago

modestpharaoh commented 3 years ago

i have the LC1 floodlight camera and I'd be interesting to automate the turrn on/off of the light.

i could see the floodlight status connected to "DeviceSwitchType.ALARM_LIGHT".

i tried to use the same client method "self._client.switch_status" to turn it on/off, but obviously not working..

i am not sure, which method should be used..

BaQs commented 3 years ago

This gist provides the proper calls to be made to switch the light of a LC1C Camera.

modestpharaoh commented 3 years ago

Awesome! I did a test with LC1, and it works too ...

Just wonder, How do you able to sniff https packets from iphone ?

API_ENDPOINT_FLOODLIGHT_CONTROL="/1/1/303/switchStatus"

    def floodlight_control(self, serial, enable=1, max_retries=0):
        """Enable Floodlight."""
        if max_retries > MAX_RETRIES:
            raise PyEzvizError("Can't gather proper data. Max retries exceeded.")

        try:
            req = self._session.put(
                "https://"
                + self._API_DOMAIN
                + API_BASE_TLD
                + API_ENDPOINT_DEVICES
                + serial
                + API_ENDPOINT_FLOODLIGHT_CONTROL,
                data={
                    "enable": enable,
                    "type": "303",
                    "channelNo": "1",
                    "deviceSerial": serial,
                },
                timeout=self._timeout,
            )

        except OSError as e:
            raise PyEzvizError("Could not access Ezviz' API: " + str(e))

        if req.status_code == 401:
            # session is wrong, need to re-log-in
            self.login()
            logging.info("Got 401, relogging (max retries: %s)", str(max_retries))
            return self.alarm_sound(serial, soundType, enable, max_retries + 1)
        elif req.status_code != 200:
            logging.error("Got %s : %s)", str(req.status_code), str(req.text))

        return True
modestpharaoh commented 3 years ago

Seems the following method is right global method to turn on/off any DeviceSwitchType switch /1/1/303/switchStatus

Tested in other switches too, and seems to be working.

I wonder do you have any idea about switches 300, 302, 304 ? they are available on LC1 too !?

300: False
301: False  LIGHT_FLICKER   - flash floodlight, when detect motion
302: False
303: True   ALARM_LIGHT   floodlight on off
304: False  
305: True}  ALARM_LIGHT_RELEVANCE    >> floodlight linkage
BaQs commented 3 years ago

Awesome! I did a test with LC1, and it works too ...

Just wonder, How do you able to sniff https packets from iphone ?


API_ENDPOINT_FLOODLIGHT_CONTROL="/1/1/303/switchStatus"

    def floodlight_control(self, serial, enable=1, max_retries=0):

        """Enable Floodlight."""

        if max_retries > MAX_RETRIES:

            raise PyEzvizError("Can't gather proper data. Max retries exceeded.")

        try:

            req = self._session.put(

                "https://"

                + self._API_DOMAIN

                + API_BASE_TLD

                + API_ENDPOINT_DEVICES

                + serial

                + API_ENDPOINT_FLOODLIGHT_CONTROL,

                data={

                    "enable": enable,

                    "type": "303",

                    "channelNo": "1",

                    "deviceSerial": serial,

                },

                timeout=self._timeout,

            )

        except OSError as e:

            raise PyEzvizError("Could not access Ezviz' API: " + str(e))

        if req.status_code == 401:

            # session is wrong, need to re-log-in

            self.login()

            logging.info("Got 401, relogging (max retries: %s)", str(max_retries))

            return self.alarm_sound(serial, soundType, enable, max_retries + 1)

        elif req.status_code != 200:

            logging.error("Got %s : %s)", str(req.status_code), str(req.text))

        return True

I use "charles" proxy on my laptop. On iphone configure proxy to my iphone IP. Authorize ssl cert from charles. Then use your app and play around with Charles to find out what you need 👍

RenierM26 commented 3 years ago

Hi @BaQs and @modestpharaoh,

I have updated the pyezviz code to make use of the correct switch endpoint. Nice work!

Note: The main app arg parser still needs to be updated to make use of all the additional switch types.

modestpharaoh commented 3 years ago

Thanks @RenierM26 , and nice works for ha-ezviz component

modestpharaoh commented 3 years ago

302: False

Seems the following method is right global method to turn on/off any DeviceSwitchType switch /1/1/303/switchStatus

Tested in other switches too, and seems to be working.

I wonder do you have any idea about switches 300, 302, 304 ? they are available on LC1 too !?

300: False
301: False    LIGHT_FLICKER   - flash floodlight, when detect motion
302: False
303: True ALARM_LIGHT   floodlight on off
304: False    
305: True}  ALARM_LIGHT_RELEVANCE    >> floodlight linkage

With LC1 floodlight, I tried to test 300, 302, 304 switches:

RenierM26 commented 3 years ago

This is the latest switch list from the Android apk. Unfortunately the Lcom/ezviz/devicemgr/model/filter/DeviceSwitchType enum class seems to be obfuscated so I can't get the switch numbers directly from the file. I see there are a few we still need to figure out.

"ALARM_TONE",
    "STREAM_ADAPTIVE",
    "LIGHT",
    "INTELLIGENT_ANALYSIS",
    "LOG_UPLOAD",
    "DEFENCE_PLAN",
    "PRIVACY",
    "SOUND_LOCALIZATION",
    "CRUISE",
    "INFRARED_LIGHT",
    "WIFI",
    "WIFI_MARKETING",
    "WIFI_LIGHT",
    "PLUG",
    "SLEEP",
    "SOUND",
    "BABY_CARE",
    "LOGO",
    "MOBILE_TRACKING",
    "CHANNELOFFLINE",
    "ALL_DAY_VIDEO",
    "AUTO_SLEEP",
    "ROAMING_STATUS",
    "DEVICE_4G",
    "ALARM_REMIND_MODE",
    "OUTDOOR_RINGING_SOUND",
    "INTELLIGENT_PQ_SWITCH",
    "DOORBELL_TALK",
    "HUMAN_INTELLIGENT_DETECTION",
    "LIGHT_FLICKER",
    "ALARM_LIGHT",
    "ALARM_LIGHT_RELEVANCE",
    "DEVICE_HUMAN_RELATE_LIGHT",
    "TAMPER_ALARM",
    "DETECTION_TYPE",
    "OUTLET_RECOVER",
    "CHIME_INDICATOR_LIGHT",
    "TRACKING",
    "CRUISE_TRACKING",
    "PARTIAL_IMAGE_OPTIMIZE",
    "FEATURE_TRACKING",
    "Companion",
    "
RenierM26 commented 3 years ago

With the ones we know removed. Just keeping the "in between" ones to help with the order.

    "OUTDOOR_RINGING_SOUND",    #39
    "INTELLIGENT_PQ_SWITCH",
    "DOORBELL_TALK",
    "HUMAN_INTELLIGENT_DETECTION",
    "LIGHT_FLICKER",            #301
    "ALARM_LIGHT",              #303
    "ALARM_LIGHT_RELEVANCE",    #305
    "DEVICE_HUMAN_RELATE_LIGHT",
    "TAMPER_ALARM",
    "DETECTION_TYPE",
    "OUTLET_RECOVER",          #600
    "CHIME_INDICATOR_LIGHT",
    "TRACKING",                #650
    "CRUISE_TRACKING",
    "PARTIAL_IMAGE_OPTIMIZE",
    "FEATURE_TRACKING",
    "Companion",
    "
RenierM26 commented 1 year ago

Some of the switches are used to return a "supported feature" and can't be turned on/off. Some are just used by the EZVIZ proprietary camera view api.

I have implemented a means to track supported features in the latest API release as well as the Home assistant official integration (and the EZVIZ BETA one via HACS)