WiP: write GeneralSettings to YAML

This commit is contained in:
Raphael Coeffic
2021-12-31 10:53:09 +01:00
parent 0e437ca492
commit c5d686a6f0
9 changed files with 261 additions and 72 deletions
+1
View File
@@ -33,6 +33,7 @@ set(firmwares_SRCS
edgetx/yaml_ops.cpp
edgetx/yaml_generalsettings.cpp
edgetx/yaml_calibdata.cpp
edgetx/yaml_trainerdata.cpp
edgetx/yaml_switchconfig.cpp
edgetx/yaml_modeldata.cpp
edgetx/yaml_rawswitch.cpp
@@ -31,6 +31,14 @@ static YAML::Node loadYamlFromByteArray(const QByteArray& data)
return YAML::Load(data_istream);
}
static void writeYamlToByteArray(const YAML::Node& node, QByteArray& data)
{
// TODO: use real streaming to avoid memory copies
std::stringstream data_ostream;
data_ostream << node;
data = QByteArray::fromStdString(data_ostream.str());
}
bool loadModelsListFromYaml(std::vector<CategoryData> categories,
EtxModelfiles& modelFiles,
const QByteArray& data)
@@ -98,5 +106,8 @@ bool writeModelToYaml(const ModelData& model, QByteArray& data)
bool writeRadioSettingsToYaml(const GeneralSettings& settings, QByteArray& data)
{
return false;
YAML::Node node;
node = settings;
writeYamlToByteArray(node, data);
return true;
}
@@ -37,5 +37,5 @@ bool loadModelsListFromYaml(std::vector<CategoryData> categories,
bool loadModelFromYaml(ModelData& model, const QByteArray& data);
bool loadRadioSettingsFromYaml(GeneralSettings& settings, const QByteArray& data);
bool writeModelToByteArray(const ModelData& model, QByteArray& data);
bool writeRadioSettingsToByteArray(const GeneralSettings& settings, QByteArray& data);
bool writeModelToYaml(const ModelData& model, QByteArray& data);
bool writeRadioSettingsToYaml(const GeneralSettings& settings, QByteArray& data);
@@ -39,11 +39,109 @@ namespace YAML {
template<>
struct convert<GeneralSettings> {
// static YAML::Node encode(const GeneralSettings& rhs) {
// Node node;
// // TODO: convert struct into Node
// return node;
// }
static YAML::Node encode(const GeneralSettings& rhs) {
Node node;
node["version"] = rhs.version;
// Radio calib
// YamlCalibData calib;
// node["calib"] = calib;
// calib.copy(rhs.calibMid, rhs.calibSpanNeg, rhs.calibSpanPos);
node["currModel"] = rhs.currModelIndex;
node["currModelFilename"] = rhs.currModelFilename;
node["contrast"] = rhs.contrast;
node["vBatWarn"] = rhs.vBatWarn;
node["txVoltageCalibration"] = rhs.txVoltageCalibration;
node["vBatMin"] = rhs.vBatMin + 90;
node["vBatMax"] = rhs.vBatMax + 120;
node["backlightMode"] = backlightModeLut << rhs.backlightMode;
node["trainer"] = rhs.trainer;
node["view"] = rhs.view;
node["fai"] = rhs.fai;
node["disableMemoryWarning"] = rhs.disableMemoryWarning;
node["beepMode"] = rhs.beeperMode;
node["disableAlarmWarning"] = rhs.disableAlarmWarning;
node["disableRssiPoweroffAlarm"] = rhs.disableRssiPoweroffAlarm;
node["USBMode"] = rhs.usbMode;
node["jackMode"] = rhs.jackMode;
node["hapticMode"] = rhs.hapticMode;
node["stickMode"] = rhs.stickMode;
node["timezone"] = rhs.timezone;
node["adjustRTC"] = rhs.adjustRTC;
node["inactivityTimer"] = rhs.inactivityTimer;
node["telemetryBaudrate"] = rhs.telemetryBaudrate; // TODO: conversion???
node["splashMode"] = rhs.splashMode; // TODO: B&W only
node["templateSetup"] = rhs.templateSetup;
node["hapticLength"] = rhs.hapticLength + 2;
node["speakerPitch"] = rhs.speakerPitch * 15;
node["hapticStrength"] = rhs.hapticStrength + 2;
node["beepLength"] = rhs.beeperLength + 2;
node["gpsFormat"] = rhs.gpsFormat;
node["speakerVolume"] = rhs.speakerVolume + 12 ;
node["backlightBright"] = rhs.backlightBright;
node["switchesDelay"] = rhs.switchesDelay;
node["globalTimer"] = rhs.globalTimer;
node["bluetoothName"] = rhs.bluetoothName;
node["bluetoothBaudrate"] = rhs.bluetoothBaudrate;
node["bluetoothMode"] = bluetoothModeLut << rhs.bluetoothMode;
node["countryCode"] = rhs.countryCode;
node["jitterFilter"] = rhs.jitterFilter;
node["disableRtcWarning"] = rhs.rtcCheckDisable; // TODO: verify
node["keysBacklight"] = rhs.keysBacklight;
node["imperial"] = rhs.imperial;
node["ttsLanguage"] = rhs.ttsLanguage;
node["beepVolume"] = rhs.beepVolume + 2;
node["wavVolume"] = rhs.wavVolume + 2;
node["varioVolume"] = rhs.varioVolume + 2;
node["varioPitch"] = rhs.varioPitch * 10;
node["varioRange"] = rhs.varioRange * 15;
node["varioRepeat"] = rhs.varioRepeat;
node["backgroundVolume"] = rhs.backgroundVolume + 2;
node["auxSerialMode"] = uartModeLut << rhs.auxSerialMode;
node["aux2SerialMode"] = uartModeLut << rhs.aux2SerialMode;
node["antennaMode"] = antennaModeLut << rhs.antennaMode;
node["backlightColor"] = rhs.backlightColor;
// if (node["customFn"]) {
// const YAML::Node& cfn = node["customFn"];
// for (int i = 0; i < CPN_MAX_SPECIAL_FUNCTIONS; i++) {
// cfn[i] = rhs.customFn[i];
// }
// }
// YamlStickConfig stickConfig;
// node["sticksConfig"] = stickConfig;
// YamlSwitchConfig switchConfig;
// node["switchConfig"] = switchConfig;
// switchConfig.copy(rhs.switchName, rhs.switchConfig);
// YamlPotConfig potsConfig;
// node["potsConfig"] = potsConfig;
// potsConfig.copy(rhs.potName, rhs.potConfig);
// YamlSliderConfig slidersConfig;
// node["slidersConfig"] = slidersConfig;
// slidersConfig.copy(rhs.sliderName, rhs.sliderConfig);
// Color lcd theme settings are not used in EdgeTx
// RadioTheme::ThemeData themeData;
node["ownerRegistrationID"] = rhs.registrationId;
// Gyro (for now only xlites)
node["gyroMax"] = rhs.gyroMax;
node["gyroOffset"] = rhs.gyroOffset;
// OneBit sampling (X9D only?)
node["uartSampleMode"] = rhs.uartSampleMode;
return node;
}
static bool decode(const Node& node, GeneralSettings& rhs) {
@@ -138,6 +236,7 @@ namespace YAML {
YamlStickConfig stickConfig;
node["sticksConfig"] >> stickConfig;
stickConfig.copy(rhs.stickName);
YamlSwitchConfig switchConfig;
node["switchConfig"] >> switchConfig;
+18 -1
View File
@@ -19,7 +19,6 @@
*/
#include "yaml_ops.h"
#include <algorithm>
YAML::Node operator >> (const YAML::Node& node, const YamlLookupTable& lut)
{
@@ -54,3 +53,21 @@ void operator >> (const YAML::Node& node, bool& value)
value = node.as<int>();
}
}
namespace YAML {
Node operator << (const YamlLookupTable& lut, const int& value)
{
const auto& it =
find_if(lut.begin(), lut.end(), [=](const YamlLookupTableElmt& elmt) {
if (elmt.first == value) return true;
return false;
});
if (it != lut.end()) {
return Node(it->second);
}
return Node();
}
}
+31 -8
View File
@@ -21,6 +21,7 @@
#pragma once
#include <yaml-cpp/yaml.h>
#include <algorithm>
#include <QString>
typedef std::pair<int, std::string> YamlLookupTableElmt;
@@ -59,7 +60,6 @@ private:
T factor;
};
YAML::Node operator >> (const YAML::Node& node, const YamlLookupTable& lut);
void operator >> (const YAML::Node& node, const ioffset_int& value);
@@ -111,17 +111,40 @@ void operator>>(const YAML::Node& node, T (&value)[N])
//return true;
}
namespace YAML {
Node operator << (const YamlLookupTable& lut, const int& value);
template <typename T, const YamlLookupTable& lut>
struct convert_enum
{
static YAML::Node encode(const T& rhs)
{
return lut << rhs;
}
static bool decode(const YAML::Node& node, T& rhs)
{
if (node) {
YAML::Node conv = node >> lut;
if (conv.IsScalar()) {
rhs = (T)conv.as<int>();
}
}
return true;
}
};
}
#define ENUM_CONVERTER(enum_type, lut) \
template <> \
struct convert<enum_type> { \
static YAML::Node encode(const enum_type& rhs) \
{ \
return convert_enum<enum_type, lut>::encode(rhs); \
} \
static bool decode(const YAML::Node& node, enum_type& rhs) \
{ \
if (node) { \
YAML::Node conv = node >> lut; \
if (conv.IsScalar()) { \
rhs = (enum_type)conv.as<int>(); \
} \
} \
return true; \
return convert_enum<enum_type, lut>::decode(node, rhs); \
} \
}
@@ -0,0 +1,73 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "yaml_trainerdata.h"
#include "generalsettings.h"
const YamlLookupTable trainerMixMode = {
{TrainerMix::TRN_MIX_MODE_OFF, "OFF"},
{TrainerMix::TRN_MIX_MODE_ADD, "ADD"},
{TrainerMix::TRN_MIX_MODE_SUBST, "REPL"},
};
namespace YAML
{
Node convert<TrainerMix>::encode(const TrainerMix& rhs)
{
Node node;
// TODO: convert struct into Node
return node;
}
bool convert<TrainerMix>::decode(const Node& node, TrainerMix& rhs)
{
node["srcChn"] >> rhs.src;
// node["mode"] >> rhs.mode; // TODO: string mapping
node["studWeight"] >> rhs.weight;
return true;
}
Node convert<TrainerData>::encode(const TrainerData& rhs)
{
Node node;
// TODO: convert struct into Node
return node;
}
bool convert<TrainerData>::decode(const Node& node, TrainerData& rhs)
{
if (node["calib"]) {
const Node& calib = node["calib"];
for (int i = 0; i < 4; i++) {
calib[i] >> rhs.calib[i];
}
}
if (node["mix"]) {
const Node& mix = node["mix"];
for (int i = 0; i < 4; i++) {
mix[i] >> rhs.mix[i];
}
}
return true;
}
} // namespace YAML
@@ -21,51 +21,19 @@
#include "yaml_ops.h"
#include "generalsettings.h"
namespace YAML {
extern const YamlLookupTable trainerMixMode;
template<>
struct convert<TrainerMix> {
namespace YAML
{
template <>
struct convert<TrainerMix> {
static Node encode(const TrainerMix& rhs);
static bool decode(const Node& node, TrainerMix& rhs);
};
// static YAML::Node encode(const TrainerMix& rhs) {
// Node node;
// // TODO: convert struct into Node
// return node;
// }
static bool decode(const YAML::Node& node, TrainerMix& rhs)
{
node["srcChn"] >> rhs.src;
//node["mode"] >> rhs.mode; // TODO: string mapping
node["studWeight"] >> rhs.weight;
return true;
}
};
template<>
struct convert<TrainerData> {
// static YAML::Node encode(const TrainerData& rhs) {
// Node node;
// // TODO: convert struct into Node
// return node;
// }
static bool decode(const YAML::Node& node, TrainerData& rhs)
{
if (node["calib"]) {
const YAML::Node& calib = node["calib"];
for (int i = 0; i < 4; i++) {
calib[i] >> rhs.calib[i];
}
}
if (node["mix"]) {
const YAML::Node& mix = node["mix"];
for (int i = 0; i < 4; i++) {
mix[i] >> rhs.mix[i];
}
}
return true;
}
};
}
template <>
struct convert<TrainerData> {
static Node encode(const TrainerData& rhs);
static bool decode(const Node& node, TrainerData& rhs);
};
} // namespace YAML
+6 -9
View File
@@ -220,13 +220,6 @@ bool CategorizedStorageFormat::loadYaml(RadioData & radioData)
qDebug() << tr("Found %1").arg(filename);
}
// setError(tr("Error: Yaml format ignored - under development"));
// return false; // force failure until fully developed
/*
This code a copy of loadBin with yaml file extensions ONLY
*/
QByteArray radioSettingsBuffer;
if (!loadFile(radioSettingsBuffer, "RADIO/radio.yml")) {
setError(tr("Can't extract RADIO/radio.yml"));
@@ -291,6 +284,10 @@ bool CategorizedStorageFormat::loadYaml(RadioData & radioData)
bool CategorizedStorageFormat::writeYaml(const RadioData & radioData)
{
setError("Error: Yaml format ignored - under development");
return false; // force failure until fully developed
QByteArray radioSettingsBuffer;
if (!writeRadioSettingsToYaml(radioData.generalSettings, radioSettingsBuffer)) {
return false;
}
return writeFile(radioSettingsBuffer, "RADIO/radio.yml");
}