L'inglese è la lingua sorgente delle stringhe; l'italiano sta nel catalogo translations/harbour-aira-it.ts (99 stringhe), che lupdate aggiorna e lrelease compila in build. Di serie la lingua del sistema, con ripiego sull'inglese. - nuova classe Translator: risolve la lingua prima di createView e allinea QLocale::setDefault, così anche i numeri seguono la lingua (23,0 °C in italiano, 23.0 °C in inglese) — le temperature passano da formatValue, non più dal toFixed() di JavaScript che metteva sempre il punto - Qt 5.6 non ha QQmlEngine::retranslate(): al cambio di lingua la radice QML viene ricaricata (setSource ricrea il componente anche a url invariata) - le etichette di stato in airajson.cpp usano QCoreApplication::translate per esteso: lupdate non riconosce una funzione wrapper e le avrebbe perse - selettore della lingua in Impostazioni (Sistema / English / Italiano) - test: 41/41, carica il .qm vero come fa main.cpp e verifica entrambe le lingue, il ripiego e i formati numerici - anteprime bilingui (docs/anteprima/ inglese, it/ italiano), README e PIANO aggiornati, spec RPM con i cataloghi in %files
135 lines
4.8 KiB
C++
135 lines
4.8 KiB
C++
#include "airajson.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QJsonValue>
|
|
#include <QLocale>
|
|
#include <QUrl>
|
|
|
|
namespace AiraJson {
|
|
|
|
QString normalizeBaseUrl(const QString &raw)
|
|
{
|
|
QString s = raw.trimmed();
|
|
if (s.isEmpty())
|
|
return QString();
|
|
|
|
if (!s.startsWith(QLatin1String("http://")) && !s.startsWith(QLatin1String("https://")))
|
|
s.prepend(QLatin1String("http://"));
|
|
|
|
while (s.endsWith(QLatin1Char('/')))
|
|
s.chop(1);
|
|
|
|
return s;
|
|
}
|
|
|
|
QVariantMap parseSummary(const QByteArray &body, bool *ok)
|
|
{
|
|
if (ok)
|
|
*ok = false;
|
|
|
|
QJsonParseError err;
|
|
const QJsonDocument doc = QJsonDocument::fromJson(body, &err);
|
|
if (err.error != QJsonParseError::NoError || !doc.isObject())
|
|
return QVariantMap();
|
|
|
|
const QJsonObject root = doc.object();
|
|
if (root.value(QStringLiteral("ok")).toBool() == false)
|
|
return QVariantMap();
|
|
|
|
const QJsonObject summary = root.value(QStringLiteral("summary")).toObject();
|
|
if (summary.isEmpty())
|
|
return QVariantMap();
|
|
|
|
if (ok)
|
|
*ok = true;
|
|
return summary.toVariantMap();
|
|
}
|
|
|
|
QString modeLabel(const QString &operatingStatus)
|
|
{
|
|
const QString s = operatingStatus;
|
|
if (s == QLatin1String("OPERATING_STATUS_AUTO"))
|
|
return QCoreApplication::translate("AiraJson", "Automatic");
|
|
if (s == QLatin1String("OPERATING_STATUS_HEATING"))
|
|
return QCoreApplication::translate("AiraJson", "Heating");
|
|
if (s == QLatin1String("OPERATING_STATUS_COOLING"))
|
|
return QCoreApplication::translate("AiraJson", "Cooling");
|
|
if (s == QLatin1String("OPERATING_STATUS_HOT_WATER"))
|
|
return QCoreApplication::translate("AiraJson", "Hot water");
|
|
if (s == QLatin1String("OPERATING_STATUS_STANDBY"))
|
|
return QCoreApplication::translate("AiraJson", "Standby");
|
|
if (s == QLatin1String("OPERATING_STATUS_OFF"))
|
|
return QCoreApplication::translate("AiraJson", "Off");
|
|
// Stato della pompa per zona (state.zoneN_mode).
|
|
if (s == QLatin1String("PUMP_MODE_STATE_HEATING"))
|
|
return QCoreApplication::translate("AiraJson", "Heating");
|
|
if (s == QLatin1String("PUMP_MODE_STATE_COOLING"))
|
|
return QCoreApplication::translate("AiraJson", "Cooling");
|
|
if (s == QLatin1String("PUMP_MODE_STATE_HOT_WATER"))
|
|
return QCoreApplication::translate("AiraJson", "Hot water");
|
|
if (s == QLatin1String("PUMP_MODE_STATE_IDLE"))
|
|
return QCoreApplication::translate("AiraJson", "Idle");
|
|
if (s == QLatin1String("PUMP_MODE_STATE_STANDBY"))
|
|
return QCoreApplication::translate("AiraJson", "Standby");
|
|
if (s == QLatin1String("PUMP_MODE_STATE_OFF"))
|
|
return QCoreApplication::translate("AiraJson", "Off");
|
|
// Stato operativo della pompa (state.pump_active_state).
|
|
if (s == QLatin1String("PUMP_ACTIVE_STATE_IDLE"))
|
|
return QCoreApplication::translate("AiraJson", "Stopped");
|
|
if (s == QLatin1String("PUMP_ACTIVE_STATE_RUNNING"))
|
|
return QCoreApplication::translate("AiraJson", "Running");
|
|
if (s.isEmpty())
|
|
return QStringLiteral("—");
|
|
// Sconosciuto: togliamo il prefisso e mostriamo il resto, minuscolo.
|
|
QString rest = s;
|
|
rest.remove(QLatin1String("OPERATING_STATUS_"));
|
|
rest.remove(QLatin1String("PUMP_MODE_STATE_"));
|
|
rest.remove(QLatin1String("PUMP_ACTIVE_STATE_"));
|
|
rest.remove(QLatin1String("POWER_PREFERENCE_"));
|
|
return rest.toLower();
|
|
}
|
|
|
|
QString formatValue(const QVariant &value)
|
|
{
|
|
if (!value.isValid() || value.isNull())
|
|
return QStringLiteral("—");
|
|
|
|
bool isNumber = false;
|
|
const double d = value.toDouble(&isNumber);
|
|
if (isNumber)
|
|
// QLocale() = locale predefinito, che translator.cpp allinea alla lingua
|
|
// dell'app: separatore decimale col punto in inglese, con la virgola in
|
|
// italiano (QString::number darebbe sempre il punto).
|
|
return QLocale().toString(d, 'f', 1);
|
|
|
|
const QString s = value.toString();
|
|
return s.isEmpty() ? QStringLiteral("—") : s;
|
|
}
|
|
|
|
QByteArray commandPayload(const QString &id, const QVariant &value)
|
|
{
|
|
QJsonObject o;
|
|
o.insert(QStringLiteral("id"), id);
|
|
if (value.isValid() && !value.isNull())
|
|
o.insert(QStringLiteral("value"), QJsonValue::fromVariant(value));
|
|
return QJsonDocument(o).toJson(QJsonDocument::Compact);
|
|
}
|
|
|
|
QString errorMessage(const QByteArray &body, int httpStatus)
|
|
{
|
|
QJsonParseError err;
|
|
const QJsonDocument doc = QJsonDocument::fromJson(body, &err);
|
|
if (err.error == QJsonParseError::NoError && doc.isObject()) {
|
|
const QString msg = doc.object().value(QStringLiteral("error")).toString();
|
|
if (!msg.isEmpty())
|
|
return msg;
|
|
}
|
|
if (httpStatus == 0)
|
|
return QCoreApplication::translate("AiraJson", "server unreachable");
|
|
return QCoreApplication::translate("AiraJson", "HTTP error %1").arg(httpStatus);
|
|
}
|
|
|
|
} // namespace AiraJson
|