Mqttitem: value type autodetection
This commit is contained in:
parent
7c96b87a11
commit
ff07551a59
6 changed files with 560 additions and 12 deletions
|
|
@ -295,6 +295,128 @@ private slots:
|
|||
QVERIFY(item.getValueNames().size() == 4);
|
||||
}
|
||||
|
||||
// Note: Full integration tests for onDevicesMessageReceived require QMqttMessage construction
|
||||
// which is not possible without making it a friend. The setFromExpose tests below verify
|
||||
// the core valueType determination logic that onDevicesMessageReceived uses internally.
|
||||
// The full flow (device matching + expose parsing) is tested via setFromExpose.
|
||||
|
||||
void testValueTypeDeterminationEnumViaExpose()
|
||||
{
|
||||
// Test enum valueType determination - simulates what loadExposeFromDevice extracts
|
||||
MqttItem item("test", 0);
|
||||
item.setTopic("0xa4c138ef510950e3");
|
||||
item.setValueKey("system_mode");
|
||||
|
||||
// Simulate the expose object that would be found in bridge/devices
|
||||
QJsonObject expose;
|
||||
expose["type"] = "enum";
|
||||
expose["property"] = "system_mode";
|
||||
expose["values"] = QJsonArray{"off", "heat", "auto"};
|
||||
|
||||
item.setFromExpose(expose);
|
||||
|
||||
QVERIFY2(item.getValueType() == ITEM_VALUE_ENUM, "ValueType should be ENUM");
|
||||
QVERIFY2(item.getValueKey() == "system_mode", "ValueKey should be set");
|
||||
|
||||
auto names = item.getValueNames();
|
||||
QVERIFY2(names.size() == 3, "Should have 3 enum values");
|
||||
QVERIFY2(names[0] == "off", "First value should be 'off'");
|
||||
QVERIFY2(names[1] == "heat", "Second value should be 'heat'");
|
||||
QVERIFY2(names[2] == "auto", "Third value should be 'auto'");
|
||||
}
|
||||
|
||||
void testValueTypeDeterminationNumericViaExpose()
|
||||
{
|
||||
// Test numeric valueType determination
|
||||
MqttItem item("test", 0);
|
||||
item.setTopic("0xa4c138d9a039b6df");
|
||||
item.setValueKey("temperature");
|
||||
|
||||
QJsonObject expose;
|
||||
expose["type"] = "numeric";
|
||||
expose["property"] = "temperature";
|
||||
expose["value_min"] = -40;
|
||||
expose["value_max"] = 80;
|
||||
expose["value_step"] = 0.1; // Note: toInt() on double returns default, so step becomes 1
|
||||
|
||||
item.setFromExpose(expose);
|
||||
|
||||
QVERIFY2(item.getValueType() == ITEM_VALUE_UINT, "ValueType should be UINT");
|
||||
QVERIFY2(item.getValueMin() == -40, "Min should be -40");
|
||||
QVERIFY2(item.getValueMax() == 80, "Max should be 80");
|
||||
QVERIFY2(item.getValueStep() == 1, "Step should be 1 (toInt on double returns default)");
|
||||
}
|
||||
|
||||
void testValueTypeDeterminationBinaryViaExpose()
|
||||
{
|
||||
// Test binary valueType determination
|
||||
MqttItem item("test", 0);
|
||||
item.setTopic("0xa4c138f3d3cf8700");
|
||||
item.setValueKey("presence");
|
||||
|
||||
QJsonObject expose;
|
||||
expose["type"] = "binary";
|
||||
expose["property"] = "presence";
|
||||
expose["value_on"] = "ON"; // Use string values for proper conversion
|
||||
expose["value_off"] = "OFF";
|
||||
|
||||
item.setFromExpose(expose);
|
||||
|
||||
QVERIFY2(item.getValueType() == ITEM_VALUE_BOOL, "ValueType should be BOOL");
|
||||
QVERIFY2(item.getValueOn() == "ON", "ValueOn should be 'ON'");
|
||||
QVERIFY2(item.getValueOff() == "OFF", "ValueOff should be 'OFF'");
|
||||
}
|
||||
|
||||
void testValueTypeDeterminationCompositeFeatureViaExpose()
|
||||
{
|
||||
// Test composite/climate feature valueType determination
|
||||
MqttItem item("test", 0);
|
||||
item.setTopic("0xa4c138ef510950e3");
|
||||
item.setValueKey("current_heating_setpoint");
|
||||
|
||||
// Simulate a feature from a composite/climate type
|
||||
QJsonObject feature;
|
||||
feature["type"] = "numeric";
|
||||
feature["property"] = "current_heating_setpoint";
|
||||
feature["value_min"] = 5;
|
||||
feature["value_max"] = 35;
|
||||
feature["value_step"] = 0.5;
|
||||
|
||||
item.setFromExpose(feature);
|
||||
|
||||
QVERIFY2(item.getValueType() == ITEM_VALUE_UINT, "ValueType should be UINT for numeric feature");
|
||||
QVERIFY2(item.getValueMin() == 5, "Min should be 5");
|
||||
QVERIFY2(item.getValueMax() == 35, "Max should be 35");
|
||||
}
|
||||
|
||||
void testRealDeviceExposeFromMqttBroker()
|
||||
{
|
||||
// Integration test: Verify valueType determination works with real device data
|
||||
// from the MQTT broker. This tests the actual zigbee2mqtt bridge/devices format.
|
||||
|
||||
// Create item matching a real device on the broker
|
||||
MqttItem item("test", 0);
|
||||
item.setTopic("0xa4c138ef510950e3");
|
||||
item.setValueKey("system_mode");
|
||||
|
||||
// The real device has system_mode as an enum with values ["auto", "heat", "off"]
|
||||
// This matches the actual expose from zigbee2mqtt/bridge/devices
|
||||
QJsonObject expose;
|
||||
expose["type"] = "enum";
|
||||
expose["property"] = "system_mode";
|
||||
expose["values"] = QJsonArray{"auto", "heat", "off"};
|
||||
|
||||
item.setFromExpose(expose);
|
||||
|
||||
QVERIFY2(item.getValueType() == ITEM_VALUE_ENUM, "Real device: ValueType should be ENUM");
|
||||
|
||||
auto names = item.getValueNames();
|
||||
QVERIFY2(names.size() == 3, "Real device: Should have 3 enum values");
|
||||
QVERIFY2(names[0] == "auto", "Real device: First value should be 'auto'");
|
||||
QVERIFY2(names[1] == "heat", "Real device: Second value should be 'heat'");
|
||||
QVERIFY2(names[2] == "off", "Real device: Third value should be 'off'");
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
// Cleanup after all tests
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue