mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
* Refactor config API * Corrections * Test Qt 6.8 * Revert "Test Qt 6.8" This reverts commit eceebec49ecf1a3eda281a0630a9a7577b44ef0a. * Corrections 2 * Update Changelog * Add configFilter element for getconfig call * Do not create errors for DB updates when in read-only mode * Have configuration migration and validation before Hyperion starts * Correct Tests * Corrections * Add migration items * Correct windows build * Ensure that first instance as default one exists * Remove dependency between AuthManager and SSDPHandler * Correct typos * Address CodeQL findings * Replace CamkeSettings by Presets and provide debug scenarios
768 lines
22 KiB
C++
768 lines
22 KiB
C++
#include <db/DBMigrationManager.h>
|
|
|
|
#include "db/SettingsTable.h"
|
|
#include <utils/Logger.h>
|
|
#include <utils/QStringUtils.h>
|
|
|
|
#include <HyperionConfig.h>
|
|
|
|
#include <QJsonObject>
|
|
|
|
DBMigrationManager::DBMigrationManager(QObject *parent)
|
|
: DBManager{parent}
|
|
{
|
|
}
|
|
|
|
bool DBMigrationManager::isMigrationRequired()
|
|
{
|
|
bool isNewRelease = false;
|
|
|
|
SettingsTable settingsTableGlobal;
|
|
|
|
if (settingsTableGlobal.resolveConfigVersion())
|
|
{
|
|
semver::version BUILD_VERSION(HYPERION_VERSION);
|
|
|
|
if (!BUILD_VERSION.isValid())
|
|
{
|
|
Error(_log, "Current Hyperion version [%s] is invalid. Exiting...", BUILD_VERSION.getVersion().c_str());
|
|
exit(1);
|
|
}
|
|
|
|
const semver::version& currentVersion = settingsTableGlobal.getConfigVersion();
|
|
if (currentVersion > BUILD_VERSION)
|
|
{
|
|
Error(_log, "Database version [%s] is greater than current Hyperion version [%s]. Exiting...", currentVersion.getVersion().c_str(), BUILD_VERSION.getVersion().c_str());
|
|
exit(1);
|
|
}
|
|
|
|
if (currentVersion < BUILD_VERSION)
|
|
{
|
|
isNewRelease = true;
|
|
}
|
|
}
|
|
return isNewRelease;
|
|
}
|
|
|
|
bool DBMigrationManager::migrateSettings(QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
semver::version BUILD_VERSION(HYPERION_VERSION);
|
|
|
|
SettingsTable settingsTableGlobal;
|
|
QJsonObject generalConfig = config.value("global").toObject().value("settings").toObject().value("general").toObject();
|
|
|
|
if (settingsTableGlobal.resolveConfigVersion(generalConfig))
|
|
{
|
|
semver::version currentVersion = settingsTableGlobal.getConfigVersion();
|
|
|
|
if (currentVersion < BUILD_VERSION)
|
|
{
|
|
Info(_log, "Migration from current version [%s] to new version [%s] started", currentVersion.getVersion().c_str(), BUILD_VERSION.getVersion().c_str());
|
|
|
|
// Extract, modify, and reinsert the global settings
|
|
QJsonObject globalSettings = config.value("global").toObject().value("settings").toObject();
|
|
upgradeGlobalSettings(currentVersion, globalSettings);
|
|
|
|
QJsonObject globalConfig = config.value("global").toObject();
|
|
globalConfig.insert("settings", globalSettings);
|
|
config.insert("global", globalConfig);
|
|
|
|
// Update each instance directly within the config
|
|
QJsonArray instancesConfig = config.value("instances").toArray();
|
|
for (int i = 0; i < instancesConfig.size(); ++i)
|
|
{
|
|
QJsonObject instanceConfig = instancesConfig[i].toObject();
|
|
QJsonObject instanceSettings = instanceConfig.value("settings").toObject();
|
|
|
|
upgradeInstanceSettings(currentVersion, static_cast<quint8>(i), instanceSettings);
|
|
|
|
// Reinsert the modified instance settings back into the instanceConfig
|
|
instanceConfig.insert("settings", instanceSettings);
|
|
instancesConfig.replace(i, instanceConfig);
|
|
}
|
|
config.insert("instances", instancesConfig);
|
|
|
|
Info(_log, "Migration from current version [%s] to new version [%s] finished", currentVersion.getVersion().c_str(), BUILD_VERSION.getVersion().c_str());
|
|
migrated = true;
|
|
}
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeGlobalSettings(const semver::version& currentVersion, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
|
|
semver::version migratedVersion = currentVersion;
|
|
|
|
//Migration step for versions < alpha 9
|
|
upgradeGlobalSettings_alpha_9(migratedVersion, config);
|
|
//Migration step for versions < 2.0.12
|
|
upgradeGlobalSettings_2_0_12(migratedVersion, config);
|
|
//Migration step for versions < 2.0.16
|
|
upgradeGlobalSettings_2_0_16(migratedVersion, config);
|
|
//Migration step for versions < 2.0.17
|
|
upgradeGlobalSettings_2_1_0(migratedVersion, config);
|
|
|
|
// Set the daqtabase version to the current build version
|
|
QJsonObject generalConfig = config["general"].toObject();
|
|
// Update the configVersion if necessary
|
|
if (generalConfig["configVersion"].toString() != HYPERION_VERSION) {
|
|
generalConfig["configVersion"] = HYPERION_VERSION;
|
|
migrated = true;
|
|
}
|
|
// Re-insert the modified "general" object back into the config
|
|
config["general"] = generalConfig;
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeInstanceSettings(const semver::version& currentVersion, quint8 instance, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
semver::version migratedVersion = currentVersion;
|
|
|
|
//Migration step for versions < alpha 9
|
|
upgradeInstanceSettings_alpha_9(migratedVersion, instance, config);
|
|
//Migration step for versions < 2.0.12
|
|
upgradeInstanceSettings_2_0_12(migratedVersion, instance, config);
|
|
//Migration step for versions < 2.0.13
|
|
upgradeInstanceSettings_2_0_13(migratedVersion, instance, config);
|
|
//Migration step for versions < 2.0.16
|
|
upgradeInstanceSettings_2_0_16(migratedVersion, instance, config);
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeGlobalSettings_alpha_9(semver::version& currentVersion, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.0-alpha.9" };
|
|
|
|
if (currentVersion < targetVersion)
|
|
{
|
|
Info(_log, "Global settings: Migrate from version [%s] to version [%s] or later", currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
if (config.contains("grabberV4L2"))
|
|
{
|
|
QJsonObject newGrabberV4L2Config = config["grabberV4L2"].toObject();
|
|
|
|
if (newGrabberV4L2Config.contains("encoding_format"))
|
|
{
|
|
newGrabberV4L2Config.remove("encoding_format");
|
|
newGrabberV4L2Config["grabberV4L2"] = newGrabberV4L2Config;
|
|
migrated = true;
|
|
}
|
|
|
|
//Add new element enable
|
|
if (!newGrabberV4L2Config.contains("enable"))
|
|
{
|
|
newGrabberV4L2Config["enable"] = false;
|
|
migrated = true;
|
|
}
|
|
config["grabberV4L2"] = newGrabberV4L2Config;
|
|
Debug(_log, "GrabberV4L2 records migrated");
|
|
}
|
|
|
|
if (config.contains("grabberAudio"))
|
|
{
|
|
QJsonObject newGrabberAudioConfig = config["grabberAudio"].toObject();
|
|
|
|
//Add new element enable
|
|
if (!newGrabberAudioConfig.contains("enable"))
|
|
{
|
|
newGrabberAudioConfig["enable"] = false;
|
|
migrated = true;
|
|
}
|
|
config["grabberAudio"] = newGrabberAudioConfig;
|
|
Debug(_log, "GrabberAudio records migrated");
|
|
}
|
|
|
|
if (config.contains("framegrabber"))
|
|
{
|
|
QJsonObject newFramegrabberConfig = config["framegrabber"].toObject();
|
|
|
|
//Align element namings with grabberV4L2
|
|
//Rename element type -> device
|
|
if (newFramegrabberConfig.contains("type"))
|
|
{
|
|
newFramegrabberConfig["device"] = newFramegrabberConfig["type"].toString();
|
|
newFramegrabberConfig.remove("type");
|
|
migrated = true;
|
|
}
|
|
//Rename element frequency_Hz -> fps
|
|
if (newFramegrabberConfig.contains("frequency_Hz"))
|
|
{
|
|
newFramegrabberConfig["fps"] = newFramegrabberConfig["frequency_Hz"].toInt(25);
|
|
newFramegrabberConfig.remove("frequency_Hz");
|
|
migrated = true;
|
|
}
|
|
|
|
//Rename element display -> input
|
|
if (newFramegrabberConfig.contains("display"))
|
|
{
|
|
newFramegrabberConfig["input"] = newFramegrabberConfig["display"];
|
|
newFramegrabberConfig.remove("display");
|
|
migrated = true;
|
|
}
|
|
|
|
//Add new element enable
|
|
if (!newFramegrabberConfig.contains("enable"))
|
|
{
|
|
newFramegrabberConfig["enable"] = false;
|
|
migrated = true;
|
|
}
|
|
|
|
config["framegrabber"] = newFramegrabberConfig;
|
|
Debug(_log, "Framegrabber records migrated");
|
|
}
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeGlobalSettings_2_0_12(semver::version& currentVersion, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.12" };
|
|
|
|
if (currentVersion < targetVersion)
|
|
{
|
|
Info(_log, "Global settings: Migrate from version [%s] to version [%s] or later", currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
// Have Hostname/IP-address separate from port for Forwarder
|
|
if (config.contains("forwarder"))
|
|
{
|
|
QJsonObject newForwarderConfig = config["forwarder"].toObject();
|
|
|
|
QJsonArray json;
|
|
if (newForwarderConfig.contains("json"))
|
|
{
|
|
const QJsonArray oldJson = newForwarderConfig["json"].toArray();
|
|
QJsonObject newJsonConfig;
|
|
|
|
for (const QJsonValue& value : oldJson)
|
|
{
|
|
if (value.isString())
|
|
{
|
|
QString oldHost = value.toString();
|
|
// Resolve hostname and port
|
|
QStringList addressparts = QStringUtils::split(oldHost, ":", QStringUtils::SplitBehavior::SkipEmptyParts);
|
|
QString host = addressparts[0];
|
|
|
|
if (host != "127.0.0.1")
|
|
{
|
|
newJsonConfig["host"] = host;
|
|
|
|
if (addressparts.size() > 1)
|
|
{
|
|
newJsonConfig["port"] = addressparts[1].toInt();
|
|
}
|
|
else
|
|
{
|
|
newJsonConfig["port"] = 19444;
|
|
}
|
|
newJsonConfig["name"] = host;
|
|
|
|
json.append(newJsonConfig);
|
|
migrated = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!json.isEmpty())
|
|
{
|
|
newForwarderConfig["jsonapi"] = json;
|
|
}
|
|
newForwarderConfig.remove("json");
|
|
migrated = true;
|
|
}
|
|
|
|
QJsonArray flatbuffer;
|
|
if (newForwarderConfig.contains("flat"))
|
|
{
|
|
const QJsonArray oldFlatbuffer = newForwarderConfig["flat"].toArray();
|
|
QJsonObject newFlattbufferConfig;
|
|
|
|
for (const QJsonValue& value : oldFlatbuffer)
|
|
{
|
|
if (value.isString())
|
|
{
|
|
QString oldHost = value.toString();
|
|
// Resolve hostname and port
|
|
QStringList addressparts = QStringUtils::split(oldHost, ":", QStringUtils::SplitBehavior::SkipEmptyParts);
|
|
QString host = addressparts[0];
|
|
|
|
if (host != "127.0.0.1")
|
|
{
|
|
newFlattbufferConfig["host"] = host;
|
|
|
|
if (addressparts.size() > 1)
|
|
{
|
|
newFlattbufferConfig["port"] = addressparts[1].toInt();
|
|
}
|
|
else
|
|
{
|
|
newFlattbufferConfig["port"] = 19400;
|
|
}
|
|
newFlattbufferConfig["name"] = host;
|
|
|
|
flatbuffer.append(newFlattbufferConfig);
|
|
}
|
|
}
|
|
|
|
if (!flatbuffer.isEmpty())
|
|
{
|
|
newForwarderConfig["flatbuffer"] = flatbuffer;
|
|
}
|
|
newForwarderConfig.remove("flat");
|
|
migrated = true;
|
|
}
|
|
}
|
|
|
|
if (json.isEmpty() && flatbuffer.isEmpty())
|
|
{
|
|
newForwarderConfig["enable"] = false;
|
|
}
|
|
|
|
if (migrated)
|
|
{
|
|
config["forwarder"] = newForwarderConfig;
|
|
Debug(_log, "Forwarder records migrated");
|
|
currentVersion = targetVersion;
|
|
}
|
|
}
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeGlobalSettings_2_0_16(semver::version& currentVersion, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.16" };
|
|
|
|
if (currentVersion < targetVersion)
|
|
{
|
|
Info(_log, "Global settings: Migrate from version [%s] to version [%s] or later", currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
if (config.contains("cecEvents"))
|
|
{
|
|
bool isCECEnabled {false};
|
|
if (config.contains("grabberV4L2"))
|
|
{
|
|
QJsonObject newGrabberV4L2Config = config["grabberV4L2"].toObject();
|
|
if (newGrabberV4L2Config.contains("cecDetection"))
|
|
{
|
|
isCECEnabled = newGrabberV4L2Config.value("cecDetection").toBool(false);
|
|
newGrabberV4L2Config.remove("cecDetection");
|
|
config["grabberV4L2"] = newGrabberV4L2Config;
|
|
|
|
QJsonObject newGCecEventsConfig = config["cecEvents"].toObject();
|
|
newGCecEventsConfig["enable"] = isCECEnabled;
|
|
if (!newGCecEventsConfig.contains("actions"))
|
|
{
|
|
QJsonObject action1
|
|
{
|
|
{"action", "Suspend"},
|
|
{"event", "standby"}
|
|
};
|
|
QJsonObject action2
|
|
{
|
|
{"action", "Resume"},
|
|
{"event", "set stream path"}
|
|
};
|
|
|
|
QJsonArray actions { action1, action2 };
|
|
newGCecEventsConfig.insert("actions",actions);
|
|
}
|
|
config["cecEvents"] = newGCecEventsConfig;
|
|
|
|
migrated = true;
|
|
Debug(_log, "CEC configuration records migrated");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeGlobalSettings_2_1_0(semver::version& currentVersion, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.17-beta.2" };
|
|
|
|
if (currentVersion < targetVersion)
|
|
{
|
|
Info(_log, "Global settings: Migrate from version [%s] to version [%s] or later", currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
if (config.contains("general"))
|
|
{
|
|
QJsonObject newGeneralConfig = config["general"].toObject();
|
|
newGeneralConfig.remove("previousVersion");
|
|
config.insert("general", newGeneralConfig);
|
|
|
|
Debug(_log, "General settings migrated");
|
|
migrated = true;
|
|
}
|
|
|
|
if (config.contains("network"))
|
|
{
|
|
QJsonObject newNetworkConfig = config["network"].toObject();
|
|
newNetworkConfig.remove("apiAuth");
|
|
newNetworkConfig.remove("localAdminAuth");
|
|
config.insert("network", newNetworkConfig);
|
|
|
|
Debug(_log, "Network settings migrated");
|
|
migrated = true;
|
|
}
|
|
|
|
}
|
|
|
|
//Remove wrong instance 255 configuration records, created by the global instance #255
|
|
SettingsTable globalSettingsTable(255);
|
|
globalSettingsTable.deleteInstance();
|
|
migrated = true;
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeInstanceSettings_alpha_9(semver::version& currentVersion, quint8 instance, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.0-alpha.9" };
|
|
|
|
if (currentVersion < targetVersion)
|
|
{
|
|
Info(_log, "Settings instance [%u]: Migrate from version [%s] to version [%s] or later", instance, currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
// LED LAYOUT UPGRADE
|
|
// from { hscan: { minimum: 0.2, maximum: 0.3 }, vscan: { minimum: 0.2, maximum: 0.3 } }
|
|
// from { h: { min: 0.2, max: 0.3 }, v: { min: 0.2, max: 0.3 } }
|
|
// to { hmin: 0.2, hmax: 0.3, vmin: 0.2, vmax: 0.3}
|
|
if (config.contains("leds"))
|
|
{
|
|
const QJsonArray ledarr = config["leds"].toArray();
|
|
const QJsonObject firstLed = ledarr[0].toObject();
|
|
|
|
if (firstLed.contains("hscan") || firstLed.contains("h"))
|
|
{
|
|
const bool whscan = firstLed.contains("hscan");
|
|
QJsonArray newLedarr;
|
|
|
|
for (const auto& entry : ledarr)
|
|
{
|
|
const QJsonObject led = entry.toObject();
|
|
QJsonObject hscan;
|
|
QJsonObject vscan;
|
|
QJsonValue hmin;
|
|
QJsonValue hmax;
|
|
QJsonValue vmin;
|
|
QJsonValue vmax;
|
|
QJsonObject nL;
|
|
|
|
if (whscan)
|
|
{
|
|
hscan = led["hscan"].toObject();
|
|
vscan = led["vscan"].toObject();
|
|
hmin = hscan["minimum"];
|
|
hmax = hscan["maximum"];
|
|
vmin = vscan["minimum"];
|
|
vmax = vscan["maximum"];
|
|
}
|
|
else
|
|
{
|
|
hscan = led["h"].toObject();
|
|
vscan = led["v"].toObject();
|
|
hmin = hscan["min"];
|
|
hmax = hscan["max"];
|
|
vmin = vscan["min"];
|
|
vmax = vscan["max"];
|
|
}
|
|
// append to led object
|
|
nL["hmin"] = hmin;
|
|
nL["hmax"] = hmax;
|
|
nL["vmin"] = vmin;
|
|
nL["vmax"] = vmax;
|
|
newLedarr.append(nL);
|
|
}
|
|
// replace
|
|
config["leds"] = newLedarr;
|
|
migrated = true;
|
|
Info(_log, "Instance [%u]: LED Layout migrated", instance);
|
|
}
|
|
}
|
|
|
|
if (config.contains("ledConfig"))
|
|
{
|
|
QJsonObject oldLedConfig = config["ledConfig"].toObject();
|
|
if (!oldLedConfig.contains("classic"))
|
|
{
|
|
QJsonObject newLedConfig;
|
|
newLedConfig.insert("classic", oldLedConfig);
|
|
QJsonObject defaultMatrixConfig{ {"ledshoriz", 1}
|
|
,{"ledsvert", 1}
|
|
,{"cabling","snake"}
|
|
,{"start","top-left"}
|
|
};
|
|
newLedConfig.insert("matrix", defaultMatrixConfig);
|
|
|
|
config["ledConfig"] = newLedConfig;
|
|
migrated = true;
|
|
Info(_log, "Instance [%u]: LED-Config migrated", instance);
|
|
}
|
|
}
|
|
|
|
// LED Hardware count is leading for versions after alpha 9
|
|
// Setting Hardware LED count to number of LEDs configured via layout, if layout number is greater than number of hardware LEDs
|
|
if (config.contains("device"))
|
|
{
|
|
QJsonObject newDeviceConfig = config["device"].toObject();
|
|
|
|
if (newDeviceConfig.contains("hardwareLedCount"))
|
|
{
|
|
int hwLedcount = newDeviceConfig["hardwareLedCount"].toInt();
|
|
if (config.contains("leds"))
|
|
{
|
|
const QJsonArray ledarr = config["leds"].toArray();
|
|
int layoutLedCount = ledarr.size();
|
|
|
|
if (hwLedcount < layoutLedCount)
|
|
{
|
|
Warning(_log, "Instance [%u]: HwLedCount/Layout mismatch! Setting Hardware LED count to number of LEDs configured via layout", instance);
|
|
hwLedcount = layoutLedCount;
|
|
newDeviceConfig["hardwareLedCount"] = hwLedcount;
|
|
migrated = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (newDeviceConfig.contains("type"))
|
|
{
|
|
QString type = newDeviceConfig["type"].toString();
|
|
if (type == "atmoorb" || type == "fadecandy" || type == "philipshue")
|
|
{
|
|
if (newDeviceConfig.contains("output"))
|
|
{
|
|
newDeviceConfig["host"] = newDeviceConfig["output"].toString();
|
|
newDeviceConfig.remove("output");
|
|
migrated = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (migrated)
|
|
{
|
|
config["device"] = newDeviceConfig;
|
|
Debug(_log, "LED-Device records migrated");
|
|
}
|
|
}
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeInstanceSettings_2_0_12(semver::version& currentVersion, quint8 instance, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.12" };
|
|
|
|
if (currentVersion < targetVersion)
|
|
{
|
|
Info(_log, "Settings instance [%u]: Migrate from version [%s] to version [%s] or later", instance, currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
// Have Hostname/IP-address separate from port for LED-Devices
|
|
if (config.contains("device"))
|
|
{
|
|
QJsonObject newDeviceConfig = config["device"].toObject();
|
|
|
|
if (newDeviceConfig.contains("host"))
|
|
{
|
|
QString oldHost = newDeviceConfig["host"].toString();
|
|
|
|
// Resolve hostname and port
|
|
QStringList addressparts = QStringUtils::split(oldHost, ":", QStringUtils::SplitBehavior::SkipEmptyParts);
|
|
|
|
newDeviceConfig["host"] = addressparts[0];
|
|
|
|
if (addressparts.size() > 1)
|
|
{
|
|
if (!newDeviceConfig.contains("port"))
|
|
{
|
|
newDeviceConfig["port"] = addressparts[1].toInt();
|
|
}
|
|
migrated = true;
|
|
}
|
|
}
|
|
|
|
if (newDeviceConfig.contains("type"))
|
|
{
|
|
QString type = newDeviceConfig["type"].toString();
|
|
if (type == "apa102")
|
|
{
|
|
if (newDeviceConfig.contains("colorOrder"))
|
|
{
|
|
QString colorOrder = newDeviceConfig["colorOrder"].toString();
|
|
if (colorOrder == "bgr")
|
|
{
|
|
newDeviceConfig["colorOrder"] = "rgb";
|
|
migrated = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (migrated)
|
|
{
|
|
config["device"] = newDeviceConfig;
|
|
Debug(_log, "LED-Device records migrated");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeInstanceSettings_2_0_13(semver::version& currentVersion, quint8 instance, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.13" };
|
|
|
|
if (currentVersion < targetVersion)
|
|
{
|
|
Info(_log, "Settings instance [%u]: Migrate from version [%s] to version [%s] or later", instance, currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
// Have Hostname/IP-address separate from port for LED-Devices
|
|
if (config.contains("device"))
|
|
{
|
|
QJsonObject newDeviceConfig = config["device"].toObject();
|
|
|
|
if (newDeviceConfig.contains("type"))
|
|
{
|
|
QString type = newDeviceConfig["type"].toString();
|
|
|
|
const QStringList serialDevices{ "adalight", "dmx", "atmo", "sedu", "tpm2", "karate" };
|
|
if (serialDevices.contains(type))
|
|
{
|
|
if (!newDeviceConfig.contains("rateList"))
|
|
{
|
|
newDeviceConfig["rateList"] = "CUSTOM";
|
|
migrated = true;
|
|
}
|
|
}
|
|
|
|
if (type == "adalight")
|
|
{
|
|
if (newDeviceConfig.contains("lightberry_apa102_mode"))
|
|
{
|
|
bool lightberry_apa102_mode = newDeviceConfig["lightberry_apa102_mode"].toBool();
|
|
if (lightberry_apa102_mode)
|
|
{
|
|
newDeviceConfig["streamProtocol"] = "1";
|
|
}
|
|
else
|
|
{
|
|
newDeviceConfig["streamProtocol"] = "0";
|
|
}
|
|
newDeviceConfig.remove("lightberry_apa102_mode");
|
|
migrated = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (migrated)
|
|
{
|
|
config["device"] = newDeviceConfig;
|
|
Debug(_log, "LED-Device records migrated");
|
|
}
|
|
}
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|
|
bool DBMigrationManager::upgradeInstanceSettings_2_0_16(semver::version& currentVersion, quint8 instance, QJsonObject& config)
|
|
{
|
|
bool migrated = false;
|
|
const semver::version targetVersion{ "2.0.16" };
|
|
|
|
if (currentVersion >= targetVersion) return migrated;
|
|
|
|
Info(_log, "Settings instance [%u]: Migrate from version [%s] to version [%s] or later", instance, currentVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
|
|
currentVersion = targetVersion;
|
|
|
|
if (config.contains("device"))
|
|
{
|
|
QJsonObject newDeviceConfig = config["device"].toObject();
|
|
|
|
auto convertIntToString = [&](const QString& key) {
|
|
if (newDeviceConfig.contains(key) && newDeviceConfig[key].isDouble()) {
|
|
int value = newDeviceConfig[key].toInt();
|
|
newDeviceConfig[key] = QString::number(value);
|
|
migrated = true;
|
|
}
|
|
};
|
|
|
|
if (newDeviceConfig.contains("type"))
|
|
{
|
|
QString type = newDeviceConfig["type"].toString();
|
|
|
|
if (type == "philipshue")
|
|
{
|
|
convertIntToString("groupId");
|
|
|
|
if (newDeviceConfig.contains("lightIds"))
|
|
{
|
|
QJsonArray lightIds = newDeviceConfig["lightIds"].toArray();
|
|
for (int i = 0; i < lightIds.size(); ++i)
|
|
{
|
|
if (lightIds[i].isDouble())
|
|
{
|
|
lightIds[i] = QString::number(lightIds[i].toInt());
|
|
migrated = true;
|
|
}
|
|
}
|
|
newDeviceConfig["lightIds"] = lightIds;
|
|
}
|
|
}
|
|
else if (type == "nanoleaf")
|
|
{
|
|
const auto updatePanelOrder = [&](const QString& key, const QString& zeroStr, const QString& oneStr) {
|
|
if (newDeviceConfig.contains(key))
|
|
{
|
|
int order = newDeviceConfig[key].isDouble() ? newDeviceConfig[key].toInt() : newDeviceConfig[key].toString().toInt();
|
|
newDeviceConfig[key] = (order == 0) ? zeroStr : oneStr;
|
|
migrated = true;
|
|
}
|
|
};
|
|
|
|
newDeviceConfig.remove("panelStartPos");
|
|
migrated = true;
|
|
|
|
updatePanelOrder("panelOrderTopDown", "top2down", "bottom2up");
|
|
updatePanelOrder("panelOrderLeftRight", "left2right", "right2left");
|
|
}
|
|
}
|
|
|
|
if (migrated)
|
|
{
|
|
config["device"] = newDeviceConfig;
|
|
Debug(_log, "LED-Device records migrated");
|
|
}
|
|
}
|
|
|
|
return migrated;
|
|
}
|
|
|