ha-wyzeapi icon indicating copy to clipboard operation
ha-wyzeapi copied to clipboard

[Feature Request] Support for new Wyze switch

Open zachn911 opened this issue 2 years ago • 28 comments

Is there plans for supporting the new wyze switches?

zachn911 avatar Nov 23 '21 08:11 zachn911

Are you able to MITM any of the data for these? I don't personally own, and doubt Josh has them either since they aren't supported yet, any of them to be able to collect the data.

JoeSchubert avatar Nov 23 '21 11:11 JoeSchubert

I have ideas on how to do it but haven’t done it before for Wyze products. Any recommendations on process that you have used before? Do you know if the traffic is encrypted? I would assume so.

zachn911 avatar Nov 23 '21 14:11 zachn911

It is. You need to MITM the connection and disable SSL pinning in the app using frida on Android or whatever would be equivalent for iOS. I've posted about it in a couple of these requests issues, but really need to just make a discussion topic about it.

JoeSchubert avatar Nov 23 '21 20:11 JoeSchubert

I'm also super interested in this. I'm personally not going to be terribly helpful in gathering the MITM data, but maybe we can post on Reddit or other communities to get some help? If it helps, the Alexa App lists these switches as "Wyze Plug" in the description field.

nebhead avatar Dec 15 '21 00:12 nebhead

@nebhead - I just looked at my Alexa and the Wyze Switch in mine shows up as a Switch and not a plug. Wonder what the difference is.

In any event, @yoinx , were you able to get what you need to add this feature. I could always send you a switch if needed.

spamoni4 avatar Dec 27 '21 01:12 spamoni4

No, nobody has provided anything and I kinda fell off the project for the last couple of months. For some reason I don't even get notifications for tags.

I'm not sure how comfortable I am having anything shipped to me though either. I have enough identity theft issues as is without providing people addresses online :s

JoeSchubert avatar Feb 03 '22 19:02 JoeSchubert

Sorry, I’ll try to work on getting what you need soon. Completely forgot about this all my time has been spent with the log4j vulnerabilities last 2 months.

zachn911 avatar Feb 03 '22 19:02 zachn911

No worries. I posted in one of these issues the general idea of how to get the data.

JoeSchubert avatar Feb 04 '22 02:02 JoeSchubert

This link is actually in the readme that gives a guide on doing it.

https://mulliken.net/blog/intercepting-ssl-pinned-connections-on-android

JoeSchubert avatar Feb 10 '22 03:02 JoeSchubert

Not super code savvy over here but I have a few of these switches and I'd love to get them integrated with my home assistant. Let me know if there's anything I can provide.

kmoniker avatar Feb 20 '22 21:02 kmoniker

Just got an android device to MITM. Hopefully will get time to get the data needed this week.

zachn911 avatar Feb 20 '22 22:02 zachn911

You don't need an actual device. You can do it through BlueStacks (which is rootable) and owasp zap as well (there's a video of this being done in the vacuum issue).

I'm having a hard time even getting my development environment setup in the little bit of free time I have currently... So no idea when I'll get a chance to work on implementing anything though.

JoeSchubert avatar Feb 22 '22 11:02 JoeSchubert

Are people still into this? I just picked up a few switches from home depot cheap, they work well enough but HA would make them mighty.

danielzrob avatar Mar 12 '22 08:03 danielzrob

Are people still into this? I just picked up a few switches from home depot cheap, they work well enough but HA would make them mighty.

TBH, I'm thinking of replacing all of mine with Zigbee switches. It's much more expensive, but I'm starting to realize that local control is more important. Also, having the switch off my wifi network would be good.

If this gets implemented, it would be great though. Might breathe new life into these switches for HA users.

nebhead avatar Mar 12 '22 16:03 nebhead

Are people still into this? I just picked up a few switches from home depot cheap, they work well enough but HA would make them mighty.

Personally, I'd really like the switch to be added... Having the Wyze switch on the same circuit as the Wyze bulbs makes for a much better experience than the Zwave switch we were using - most smart switches will still fully turn off the power to the bulbs on the same circuit, making it so the Wyze bulbs don't get any power and drop off the nextwork... Much prefer the Wyze solution, which allows you to do either. It would be nice if I could control the switch as well as the bulbs through HA.

AJax2012 avatar Mar 12 '22 22:03 AJax2012

Are people still into this? I just picked up a few switches from home depot cheap, they work well enough but HA would make them mighty.

Personally I'm very interested in this still.

Also: Using Alexa I was able to get home assistant to control the switch but it's more like a four step process if you're interested I can provide further details.

TEfjLONjDON avatar Mar 15 '22 08:03 TEfjLONjDON

For anyone interested in a method to control these "Wyze" switches using "Alexa". Below I have included A Method that is working for me.

FIRST: A.) Create an input_boolean for the switch. (name it apropriatly as this is how you will control the switch.)

	1. Navigate to /config/helpers  #" eg.... (https://your_sub_domain.duckdns.org:8123/config/helpers)"#
	2. Click "+ADD HELPER"
	3. Select type: "Toggle"
	4. Give it a Name: "hallway_light_switch"
	5. Set the Icon: "mdi:bulb"

my example input_boolean:

Name: hallway_light_switch
Icon: mdi:wall-sconce
Entity ID: input_boolean.hallway_light_switch
Area: Hallway

NEXT: B.) Create two template 'binary_sensor'(s). One with the 'payload on' set to "on". The other with the 'payload on' set to "off".

	1. Edit your configuration.yaml file to include two new input_booleans.
	Be sure to set the "device_class" to a DOMAIN that Alexa will play nice with. I used "device_class: 'door'"
	The "value_template" is where the magic happens! We want to monitor the state of the input_boolean we created earlier. 
	The easyest template method I've found looks like this:
		"{{ is_state('domain.entity_name','state' )}}" 
	In this case the domain is "input_boolean".
		"{{ is_state('input_boolean.hallway_light_switch', 'on') }}"

my example binary_sensor(s):

configuration.yaml
binary_sensor:
- platform: template
  sensors:
    hallway_light_switch:
      device_class: 'door'
      value_template: >-
        {{ is_state('input_boolean.hallway_light_switch', 'on') }}
      unique_id: "some_unique_id"
    hallway_light_switch_off:
      device_class: 'door'
      value_template: >-
        {{ is_state('input_boolean.hallway_light_switch', 'off') }}
      unique_id: "some_other_unique_id"

NOTE

	2. Now Don't Forget to sync your entities to alexa. 
		Go to "config/cloud/account" #" eg.... (https://your_sub_domain.duckdns.org:8123/config/cloud/account)"#
		Scroll down to the "Alexa" Section, Make sure all toggles are set to "on". eg... (Alexa >< "on") & (Enable State Reporting >< "on")
       	Click "SYNC ENTITIES TO AMAZON". (BOTTOM LEFT of Alexa section)
	!NOTE: IF YOU HAVE CONFIGERED ONLY CERTAIN DOMAINS AND ENTITIES TO SYNC WITH ALEXA.
	YOU MAY NEED TO ALOW ALEXA TO SEE THE NEW INPUT_BOOLEAN AND OR BINARY_SENSOR(S) WE CREATED EARLIER. 
	You can do this by clicking the "MANAGE ENTITIES" button. (BOTTOM RIGHT of alexa section)

NOW: C.) Create Two "Alexa Routine"(s)

	1. Make Sure you have already linked you "WYZE" account to your "ALEXA" Account! If you haven't done so, do it now before you continue.
	2. After Linking your wyze account with alexa, Open the "Alexa" app (again) on you mobile device. 
	3. Click "More". (BOTTOM RIGHT, on android app)
	4. Click "Routines".
	5. Click "+". (TOP RIGHT, on android app)
	6. Click "+" Beside "Enter routine name".
	7. Click "+" Beside "When this happens". Select "Smart Home"
	8. CHOOSE DEVICE (scrool and choose the HOMEASSISTANT "input_boolean" name you created. ie.."hallway_light_switch") 
		If you used "device_class: 'door'" Make SURE to set it to "Open" 
	9. Add an Action to turn "ON" the device (Scrool to the device you want to control & select it. ie... 
		"the actual WYZE Switch")

Now Repeat for the second "input_boolean" 'off'

	1. Open the "Alexa" app (again) on you mobile device. 
	2. Click "More". (BOTTOM RIGHT, on android app)
	3. Click "Routines".
	4. Click "+". (TOP RIGHT, on android app)
	5. Click "+" Beside "Enter routine name".
	6. Click "+" Beside "When this happens". Select "Smart Home"
	7. CHOOSE DEVICE (scrool and choose the HOMEASSISTANT "input_boolean" name you created. ie.."hallway_light_switch_off") 
		If you used "device_class: 'door'" Make SURE to set it to "Open" 
	8. Add an Action to turn "OFF" the device (Scrool to the device you want to control & select it. 
		ie... "the actual WYZE Switch")

!BONUS: D.) If you want to have the icon change to reflect the state then set an icon_template in those two binary_sensor(s) you created earlier like this:

EXAMPLE 1.

	icon_template: >-
	  {% if is_state('input_boolean.hallway_light_switch', 'on') %}
	    mdi:lightbulb-on
	  {% else %}
	    mdi:lightbulb-off
	  {% endif %}

Alt EXAMPLE 2.

icon_template: {% if is_state('input_boolean.hallway_light_switch', 'on') %} mdi:lightbulb-on {% else %} mdi:lightbulb-off {% endif %}

FULL EXAMPLE:

configuration.yaml
binary_sensor:
- platform: template
  sensors:
    hallway_light_switch:
      device_class: 'door'
      value_template: >-
        {{ is_state('input_boolean.hallway_light_switch', 'on') }}
      icon_template: >-
	 {% if is_state('input_boolean.hallway_light_switch', 'on') %}
	   mdi:lightbulb-on
	 {% else %}
	   mdi:lightbulb-off
	 {% endif %}
      unique_id: "some_unique_id"
    hallway_light_switch_off:
      device_class: 'door'
      value_template: >-
        {{ is_state('input_boolean.hallway_light_switch', 'off') }}
      icon_template: >-
	 {% if is_state('input_boolean.hallway_light_switch', 'on') %}
	   mdi:lightbulb-on
	 {% else %}
	   mdi:lightbulb-off
	 {% endif %}
      unique_id: "some_other_unique_id"

TEfjLONjDON avatar Mar 15 '22 10:03 TEfjLONjDON

I would love to have the Wyze Switch supported by Home Assistant as well.

edicius6 avatar Apr 10 '22 21:04 edicius6

I ended up replacing my switch after a couple months it stop connecting to Wi-Fi.

Sent from my iPhone

On Apr 10, 2022, at 4:45 PM, David Cline @.***> wrote:

 I would love to have the Wyze Switch supported by Home Assistant as well.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.

zachn911 avatar Apr 10 '22 23:04 zachn911

I ended up replacing my switch after a couple months it stop connecting to Wi-Fi.

I also replaced my switches with ZigBee switches instead. However, mine seemed to stay connected to my WiFi just fine. It was mostly that I wanted to have local control.

If anyone has any need for these switches, I'd be willing to sell them for half the cost I paid plus shipping.

Thanks!

nebhead avatar Apr 11 '22 16:04 nebhead

Subscribing to this issue - interested in this as well. I can take a look at https://mulliken.net/blog/intercepting-ssl-pinned-connections-on-android

djhanggi avatar Apr 16 '22 04:04 djhanggi

I haven't set up a MITM yet to monitor what actually is getting sent, yet, but I ran the wyzeapy library locally and it at least appears for now that this device doesn't have support at the current v2 get_property_list / get_object_list endpoints.

Some data: My switch has product_model = LD_SS1 and its type is currently COMMON. The only property it has available from the endpoint is AVAILABLE.

I'll need to get access to a rooted Android phone (I have a backup one I can root) to set up the MITM and inspect the traffic.

djhanggi avatar Apr 16 '22 17:04 djhanggi

I was able to inspect traffic and get the necessary information. It looks similar to the new APIs that the Lock and Thermostat use, and in particular, the thermostat.

I am trying to hack something together by just copying the thermostat code but it's unclear how the signing secret / app id should be deduced.

API endpoints:

  • GET https://wyze-sirius-service.wyzecam.com//plugin/sirius/get_iot_prop with query params:
    • nonce
    • did
    • keys: iot_state,switch-power,switch-iot,single_press_type
      • single_press_type is 1 if using classic control (controls the power at the box) or '2' if using smart control (controlling Wyze bulbs, presumably by IOT commands)
      • similarly, I believe switch-power indicates classic control is on/off and switch-iot is whether smart control is on/off
  • POST https://wyze-sirius-service.wyzecam.com//plugin/sirius/set_iot_prop_by_topic
    • nonce
    • did
    • props: 'switch-power' set to true/false to toggle

djhanggi avatar Apr 19 '22 03:04 djhanggi

Exciting ! Is there anything I can do to help ? I have several of these switches going too.

Note my skill level is low but happy to learn.

danielzrob avatar Apr 19 '22 16:04 danielzrob

A heads up that I probably won't be able to work on this for a few days / week so if you're free, anything you find would help.

I would say the thermostat (olive) and lock (ford) code have a lot of the same scaffolding this would have to do, including the nonce calculation & did passing. A quick hack would be to copy all that and just change the endpoint URL & change the props in the POST command to be switch-power. I'm not sure what we would need to use for the signing secret & app id, though.

Update from my saved requests: App ID: wssp_bc5c93d925b51c8f App info: wyze_android_2.28.0.102

Still unsure what the signing secret for the switch is

djhanggi avatar Apr 19 '22 18:04 djhanggi

I picked this up again last night and I'm still a bit stumped. @JoshuaMulliken if you have any insight into how to figure out the signing secret, it would be appreciated. I inspected the Android source and found a few candidates but none of them produce valid signatures. I believe that the correct signing key is calculated somehow from the Olive library referred to here and there's a calculation that's needed on one of the strings...some combination of XXTEA and base64 encoding/decoding? There's the app id wssp_bc5c93d925b51c8f and a 32-byte string paired with it.

djhanggi avatar May 19 '22 15:05 djhanggi

I wanted to do a single summary of everything we know since I tried reading through the C code linked above & couldn't make any sense of it. I don't think I'm going to get anywhere so I would need someone else to chime in (hopefully familiar with reading decompiled C code). Barring that / until that occurs at some point in the future I'm going to backlog this personally.

The wyzeapy support for this will mostly be identical to the thermostat_service code. The endpoints are:

  • GET wyze-sirius-service.wyzecam.com//plugin/sirius/get_iot_prop
  • POST wyze-sirius-service.wyzecam.com//plugin/sirius/set_iot_prop_by_topic

Note the double // in //plugin.

Otherwise, the code to handle the requests can be modeled after the thermostat. The GET url params are nonce, did, and keys that are:

  • iot_state
    • The same as the Thermostat code which represents availability
  • switch-power: bool
    • This is if the power is on/off at the electrical box; as if it was a dumb light switch.
  • switch-iot: bool
    • This is an option you can set in the Wyze app that indicates whether the lights are switched off in the cloud. You can configure the switch to send commands to turn off Wyze smart bulbs but still leave the power flowing in the switch box.
  • single_press_type: number
    • 1 if using classic control (switch-power represents the state of the switch)
    • 2 if using IOT control (switch-iot represents the state of the switch)

The POST params are nonce, did, and props corresponding to one of the above.

The header information is:

  • App ID: wssp_bc5c93d925b51c8f
  • App info: wyze_android_2.28.0.102
  • A request id may also need to be passed in, which is just the base64 encoding of the timestamp. I am not sure if this is required but it was present in the calls I MITM’d. I don’t think it’s currently passed in in the thermostat code.

The device/product model is LD_SS1 & the did is LD_SS1 appended with the MAC. The device type is currently COMMON.

The last part of the puzzle is figuring out the signing secret. Wyze uses the same internal library as the thermostat code (they call it olive), so there’s support in the integration already. After taking a look at the Android source code, there were a few candidate signing keys, but none correctly created a signature. (Their internal name for this is Mercury, I believe, if you take a look at the source code.) So I have reason to believe the secret is embedded or calculated from embedded information in the Olive library code, which was decompiled here.

I am happy to push a branch here if you don’t mind a stale one so that someone can quickly take the copied code I have & play around with the signing secret, but it’s also straightforward to replicate. You’ll just want to modify the olive signing secret in the crypto.py file to whatever candidate you’re trying, and then create a service for the switch. In base-service, follow the thermostat get/set methods & exchange out the keys and url.

djhanggi avatar May 20 '22 21:05 djhanggi

I ended up replacing my switch after a couple months it stop connecting to Wi-Fi.

I also replaced my switches with ZigBee switches instead. However, mine seemed to stay connected to my WiFi just fine. It was mostly that I wanted to have local control.

If anyone has any need for these switches, I'd be willing to sell them for half the cost I paid plus shipping.

Thanks!

I am slowly moving away from Wyze. I haven't replaced the 20 or so Wyze switches, yet because I can't find Zigbee switches that work with smart bulbs and aren't back ordered. I have added Sonoff SNZB-01 Zigbee buttons everywhere, 40 or so and they are 100% more reliable.

chrisvball avatar May 25 '22 05:05 chrisvball

Hi @djhanggi I want to try out your work, however the link https://mulliken.net/blog/intercepting-ssl-pinned-connections-on-android is expired, can you share some idea how to mitm it with ssl pin?

also, I'm not quite understand how the requests should work:

  1. is nonce, did and keys all in the params? how come keys can have multiple values?
  2. what is nonce and how is it calculated?
  3. where should i put App ID and App Info and request id?
  4. is the signing secret sent as client certificate?
  5. where is the user credentials or access token?

Thanks!

widewing avatar Aug 16 '22 05:08 widewing

Hi @djhanggi I want to try out your work, however the link https://mulliken.net/blog/intercepting-ssl-pinned-connections-on-android is expired, can you share some idea how to mitm it with ssl pin?

also, I'm not quite understand how the requests should work:

1. is `nonce`, `did` and `keys` all in the params? how come `keys` can have multiple values?

2. what is `nonce` and how is it calculated?

3. where should i put `App ID` and `App Info` and `request id`?

4. is the signing secret sent as client certificate?

5. where is the user credentials or access token?

Thanks!

Can try https://web.archive.org/web/20220520193451/https://mulliken.net/blog/intercepting-ssl-pinned-connections-on-android.

I would also recommend looking at the existing code here (and the wyzeapy library, also by @JoshuaMulliken) to see how those parameters fit into the requests - you should be able to run the library in Python locally to mimic requests & the MITM would only be needed to maybe try some signing secrets.

  1. Yes. Keys can have multiple values corresponding to each of the properties you want to GET or POST in the request (switch power, iot state, etc)

  2. I think the nonce is calculated just by multiplying the timestamp. The code in the wyzeapy library has the calculation

  3. Those are headers in the request I believe - the code in wyzeapy library sets it up correclty

  4. I think the signing secret is sent as a header as well, based on some secret hashed/calculated with the other request params

  5. Do you mean - where are credentials / access token in the actual GET/POST request? I think credentials are baked into the signing secret calculation / some other headers.

It's been a while so my memory isn't fresh but I remember while writing my setup that the wyzeapy library (in particular, the methods with olive in the name) does the right thing if you pass in the right props, and the only unknown at the moment is the signing secret, which I believe also uses the same calculation as in wyzeapy (just with a different seed secret)

djhanggi avatar Aug 16 '22 17:08 djhanggi