Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

129 lines
3.3 KiB

/*
TUYA MODULE
Copyright (C) 2019 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
*/
#pragma once
#include <cstdint>
#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 <typename T>
uint8_t dataProtocol(const T& frame) {
if (!frame.length()) {
return 0;
}
return frame[0];
}
template <typename T>
Type dataType(const T& frame) {
if (!frame.length()) {
return Type::UNKNOWN;
}
const Type type = static_cast<Type>(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 <typename Value>
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 <typename T, typename Frame>
DataProtocol<T>::DataProtocol(const Frame& frame) {
static_assert(sizeof(T) != sizeof(T), "No constructor yet for this type!");
}
#endif
template <>
DataProtocol<bool>::DataProtocol(const container& data) {
_id = data[0];
_value = data[4];
}
template <>
DataProtocol<uint32_t>::DataProtocol(const container& data) {
_id = data[0];
_value = static_cast<uint32_t>(data[4] << 24)
| static_cast<uint32_t>(data[5] << 16)
| static_cast<uint32_t>(data[6] << 8)
| static_cast<uint32_t>(data[7]);
}
template <>
container DataProtocol<bool>::serialize() {
return std::vector<uint8_t> {
_id, static_cast<uint8_t>(Type::BOOL), 0x00, 0x01,
static_cast<uint8_t>(_value)
};
}
template <>
container DataProtocol<uint32_t>::serialize() {
return std::vector<uint8_t> {
_id, static_cast<uint8_t>(Type::INT), 0x00, 0x04,
static_cast<uint8_t>((_value >> 24) & 0xff),
static_cast<uint8_t>((_value >> 16) & 0xff),
static_cast<uint8_t>((_value >> 8) & 0xff),
static_cast<uint8_t>(_value & 0xff)
};
}
}