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

Tuya CO2 PM2.5 temp humidity sensor #14

Open
grigvlad opened this issue Nov 23, 2020 · 7 comments
Open

Tuya CO2 PM2.5 temp humidity sensor #14

grigvlad opened this issue Nov 23, 2020 · 7 comments

Comments

@grigvlad
Copy link

I have the CO2 PM2.5 temp humidity sensor.
Despite developing in Labview and not in Python, I hope you could help.
My device works well with app, and also I have managed to communicate with it using my code in Labview using Tuya APIs.
I get its device id and category, but it says the reading of measurements is not supported.
In wireshark, I got its UDP payload, 172 bytes length.
How can I decode it? what is the structure of the payload ?
1.txt
hope for your help

@jasonacox
Copy link
Owner

I don't have a Tuya sensor to help you troubleshoot. What device did you get?

The tinytuya or tuyapower scan functions should decrypt the UDP payload:

python -m tinytuya

Do you see the sensor in that list? If so, grab the Device ID and IP address. You can get the LOCAL KEY via the method described here: https://github.com/jasonacox/tinytuya#get-the-tuya-device-local-key

In case it helps, the data points (DPS) mapping for the sensor should be here: https://github.com/jasonacox/tinytuya#version-33---sensor-type

I suspect sensors may not respond to polling, but if it does, you could try something like:

import tinytuya

deviceID = "xxxxxxxx"
ipAddress = "xxxxxxxx"
localKey = "xxxxxxxx"

d = tinytuya.OutletDevice(deviceID, ipAddress, local_key)
d.set_version(3.3)
data = d.status() 

print('Response from Sensor: %r' % data)

If that doesn't work, we would need to decrypt the UDP payload. It would be something similar to how we decode the response payload (see https://github.com/jasonacox/tinytuya/blob/master/tinytuya/__init__.py)

        log.debug('status received data=%r', data)

        result = data[20:-8]  # hard coded offsets
        if self.dev_type != 'default':
            result = result[15:]

        log.debug('result=%r', result)

        if result.startswith(b'{'):
            # this is the regular expected code path
            if not isinstance(result, str):
                result = result.decode()
            result = json.loads(result)
        elif result.startswith(PROTOCOL_VERSION_BYTES_31):
            # got an encrypted payload
            # expect resulting json to look similar to:: {"devId":"ID","dps":{"1":true,"2":0},"t":EPOCH_SECS,"s":3_DIGIT_NUM}
            result = result[len(PROTOCOL_VERSION_BYTES_31):]  # remove version header
            result = result[16:]  # Remove 16-bytes appears to be MD5 hexdigest of payload
            cipher = AESCipher(self.local_key)
            result = cipher.decrypt(result)
            log.debug('decrypted result=%r', result)
            if not isinstance(result, str):
                result = result.decode()
            result = json.loads(result)
        elif self.version == 3.3:
            cipher = AESCipher(self.local_key)
            result = cipher.decrypt(result, False)
            log.debug('decrypted result=%r', result)
            if not isinstance(result, str):
                result = result.decode()
            result = json.loads(result)
        else:
            log.error('Unexpected status() payload=%r', result)

        return result

@grigvlad
Copy link
Author

grigvlad commented Nov 23, 2020 via email

@grigvlad
Copy link
Author

grigvlad commented Nov 23, 2020 via email

@jasonacox
Copy link
Owner

Hi @grigvlad - Keep in mind that Tuya devices are designed to communicate with the TuyaCloud. Once you add the device to the SmartLife App, it creates a LocalKey that is used to encrypt the data payloads. Without that key you can't read the payloads directly from the App. However, you may be able to use the TuyaCloud to get that information. It requires that you use your credential to get a token to request the data directly. I suggest you check out the developer information on Tuya's website: https://developer.tuya.com/en/docs/iot .

@grigvlad
Copy link
Author

grigvlad commented Nov 24, 2020 via email

@jasonacox
Copy link
Owner

Thanks Vladi, I would very much like to hear how your research goes.

Looking at the payload you are getting back, I do see the Tuya prefix and suffix:

        "prefix": "000055aa00000000000000",
        # Next byte is command "hexByte" + length of remaining payload + command + suffix
        # (unclear if multiple bytes used for length, zero padding implies could be more
        # than one byte)
        "suffix": "000000000000aa55"

I don't know the labview equivalent, but a python approach could be:

        # data contains the payload
        # KEY is the Tuya local key you have

        result = data[20:-8]  # trim off the first 20 bytes (header) and last 8 (crc?) 
        cipher = AESCipher(KEY)
        result = cipher.decrypt(result, False)
        print('decrypted result=%r', result)

@grigvlad
Copy link
Author

grigvlad commented Nov 24, 2020 via email

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

2 participants