/* TUYA MODULE Copyright (C) 2019 by Maxim Prokhorov */ #pragma once #include #include "tuya_dataframe.h" #include "tuya_types.h" #include "tuya_transport.h" namespace tuya { // 2 known Data Protocols: // // id type len value // 0x?? 0x01 0x00 0x01 0x00 - bool (0 for false, 1 for true) // 0x?? 0x02 0x00 0x04 0x00 0x00 0x00 0x00 - int // // Note: 'id' varies between devices. instead, matching DP in sequence with local controllers // Note: 'int' type is mostly used for dimmer and while it is 4 byte value, // only the first byte is used (i.e. value is between 0 and 255) template uint8_t dataProtocol(const T& frame) { if (!frame.length()) { return 0; } return frame[0]; } template Type dataType(const T& frame) { if (!frame.length()) { return Type::UNKNOWN; } const Type type = static_cast(frame[1]); switch (type) { case Type::BOOL: if (frame.length() != 5) break; if (frame[3] != 0x01) break; return type; case Type::INT: if (frame.length() != 8) break; if (frame[3] != 0x04) break; return type; default: return Type::UNKNOWN; } return Type::UNKNOWN; } // Since we know of the type only at runtime, specialize the protocol container template class DataProtocol { public: explicit DataProtocol(const container& data); DataProtocol(uint8_t id, Value value) : _id(id), _value(value) {} uint8_t id() const { return _id; } Value value() const { return _value; } container serialize(); private: uint8_t _id; Value _value; }; #if 0 template DataProtocol::DataProtocol(const Frame& frame) { static_assert(sizeof(T) != sizeof(T), "No constructor yet for this type!"); } #endif template <> DataProtocol::DataProtocol(const container& data) { _id = data[0]; _value = data[4]; } template <> DataProtocol::DataProtocol(const container& data) { _id = data[0]; _value = static_cast(data[4] << 24) | static_cast(data[5] << 16) | static_cast(data[6] << 8) | static_cast(data[7]); } template <> container DataProtocol::serialize() { return std::vector { _id, static_cast(Type::BOOL), 0x00, 0x01, static_cast(_value) }; } template <> container DataProtocol::serialize() { return std::vector { _id, static_cast(Type::INT), 0x00, 0x04, static_cast((_value >> 24) & 0xff), static_cast((_value >> 16) & 0xff), static_cast((_value >> 8) & 0xff), static_cast(_value & 0xff) }; } }