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

I made progress #9

Open
noelhibbard opened this issue Jun 20, 2020 · 8 comments
Open

I made progress #9

noelhibbard opened this issue Jun 20, 2020 · 8 comments

Comments

@noelhibbard
Copy link

noelhibbard commented Jun 20, 2020

I was able to use Fiddler to sniff traffic coming from the Wyze app and was able to find all the API endpoints to login, get a device list with status, change the state of a device and logout. I haven't worked out the API to refresh the access token so I am logging in/out each time to get a brand new token so it's not super efficient. I was also unable to figure out the password hash. MD5(MD5(plaintextpassword)) isn't working on the API endpoints I am using. I had use Fiddler to find my password hash and phone id. Anyways, here is some sample code:

const request = require('request')
const md5 = require('md5')
const uuid = require('uuid').v1

var email = '[email protected]' // your wyze username
var password = 'password' // your plain text wyze password

var phone_id = uuid() // Generate random uuid to use for phone_id
var api_key = 'RckMFKbsds5p6QY3COEXc2ABwNTYY0q18ziEiSEm'
var passwordHash = md5(md5(md5(password)))

function login(phone_id, email, passwordHash, loginCb) {
    request({
        url: 'https://auth-prod.api.wyze.com/user/login',
        method: 'POST',
        headers: {
            "user-agent": "wyze_android_2.11.40",
            "x-api-key": api_key,
            "phone-id": phone_id,
            "content-type": "application/json; charset\u003dutf-8",
        },
        json: { email: email, password: passwordHash }
    }, (err, res, json) => {
        loginCb(json.access_token)
    })
}

function getDevices(access_token, phone_id, getDevicesCb) {
    request({
        url: 'https://api.wyzecam.com/app/v2/home_page/get_object_list',
        method: 'POST',
        headers: {
            "user-agent": "Dalvik/2.1.0 (Linux; U; Android 5.1.1; Fire Build/LMY49M)",
            "content-type": "application/json",
        },
        json: { "access_token": access_token, "app_name": "com.hualai", "app_ver": "com.hualai___2.11.40", "app_version": "2.11.40", "phone_id": phone_id, "phone_system_type": "2", "sc": "9f275790cab94a72bd206c8876429f3c", "sv": "9d74946e652647e9b6c9d59326aef104", "ts": Date.now() }
    }, (err, res, body) => {
        getDevicesCb(body.data.device_list)
    })
}

function logout(access_token, phone_id, logoutCb) {
    request({
        url: 'https://api.wyzecam.com/app/user/logout',
        method: 'POST',
        headers: {
            "user-agent": "Dalvik/2.1.0 (Linux; U; Android 5.1.1; Fire Build/LMY49M)",
            "content-type": "application/json",
        },
        json: { "sc": "a626948714654991afd3c0dbd7cdb901", "sv": "759245b61abd49128585e95f30e61add", "app_ver": "com.hualai___2.11.40", "ts": Date.now(), "access_token": access_token, "phone_id": phone_id, "app_name": "com.hualai", "app_version": "2.11.40" }
    }, (err, res, body) => {
        logoutCb()
    })
}

function runAction(access_token, phone_id, instance_id, action_key, runActionCb) {
    request({
        url: 'https://api.wyzecam.com/app/v2/auto/run_action',
        method: 'POST',
        headers: {
            "user-agent": "Dalvik/2.1.0 (Linux; U; Android 5.1.1; Fire Build/LMY49M)",
            "content-type": "application/json",
        },
        json: { "sc": "a626948714654991afd3c0dbd7cdb901", "sv": "011a6b42d80a4f32b4cc24bb721c9c96", "app_ver": "com.hualai___2.11.40", "ts": Date.now(), "access_token": access_token, "phone_id": phone_id, "app_name": "com.hualai", "app_version": "2.11.40", "provider_key": "WLPP1", "action_key": action_key, "instance_id": instance_id, "action_params": {}, "custom_string": "" }
    }, (err, res, body) => {
        runActionCb()
    })
}

// Login; list devices; find the device we want to control; toggle power state; logoff
var nickname = "Bedroom Lamp"
login(phone_id, email, passwordHash, access_token => {
    getDevices(access_token, phone_id, devices => {
        devices.forEach(device => {
            if (device.nickname == nickname) {
                console.log(`${nickname} is ${(device.device_params.switch_state == 0 ? 'off' : 'on')}!`)
                runAction(access_token, phone_id, device.mac, (device.device_params.switch_state == 0 ? 'power_on' : 'power_off'), () => {
                    console.log(`Turning ${nickname} ${(device.device_params.switch_state == 1 ? 'off' : 'on')}!`)
                    logout(access_token, phone_id, () => { })
                })
            }
        })
    })
})

This code is written in Nodejs and depends on request, md5 and uuid (npm i request md5 uuid).

@noelhibbard
Copy link
Author

I figured out the new password hash. Rather than md5(md5(password)) it is now md5(md5(md5(password))).

I updated the sample code above to use the new hash. Also I noticed the phone_id can be any randomly generated guid. So this sample code will work without having to sniff any of your own data.

@nblavoie
Copy link
Owner

Nice work!

@Neustradamus
Copy link

@nblavoie: It is possible to move this repository?
You have stopped the development, no?

Maybe @noelhibbard can now manage it, no?

@rockstar2020
Copy link

Great working example @noelhibbard,
By any chance do you know what would be the code to enable/disable motion detection on the Wyzecam?
I currently use IFTTT to control my Wyzecam with but I'd rather to independently connect via an API service like this one.

Many thanks

@noelhibbard
Copy link
Author

Great working example @noelhibbard,
By any chance do you know what would be the code to enable/disable motion detection on the Wyzecam?
I currently use IFTTT to control my Wyzecam with but I'd rather to independently connect via an API service like this one.

Many thanks

Sorry, I don't have any cameras. I had one but bricked it while trying to flash a 3rd party firmware. You should take a look at this project:
https://github.com/misenhower/homebridge-wyze-connected-home

It's a homebridge plugin that seems to cover most of the Wyze accessories. You could probably find hints at how you could accomplish what you need.

@noelportugal
Copy link

So I created https://github.com/noelportugal/wyze-node a while ago...I'm trying to revisit and remove the need to find the phoneId...I wonder why would it work for you using node package uuid and not for me? I'm not using api_key so I wonder if that is the reason?

@noelhibbard
Copy link
Author

noelhibbard commented Oct 26, 2020

So I created https://github.com/noelportugal/wyze-node a while ago...I'm trying to revisit and remove the need to find the phoneId...I wonder why would it work for you using node package uuid and not for me? I'm not using api_key so I wonder if that is the reason?

I'm not really sure. I basically just packet sniffed the whole process when running the iOS Wyze app and then reproduced it in Node. Or maybe Wyze wants a v1 UUID (because it contains a timestamp).

@noelportugal
Copy link

Yeah I tried UUID v1 and v4 with no luck...I gave up and hardcoded the phoneid for now...Wyze doesn't seem to care 🤷.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants