Add support for imperial unit conversion
This commit is contained in:
parent
66438d8caf
commit
0ea07bd508
@ -74,6 +74,7 @@
|
||||
#include "scripting/completionmodel.h"
|
||||
#include "types/script.h"
|
||||
#include "types/scripts.h"
|
||||
#include "types/types.h"
|
||||
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
@ -93,6 +94,13 @@ static QObject* awsClientProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
return AWSClient::instance();
|
||||
}
|
||||
|
||||
static QObject* typesProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(scriptEngine)
|
||||
return Types::instance();
|
||||
}
|
||||
|
||||
void registerQmlTypes() {
|
||||
|
||||
const char uri[] = "Nymea";
|
||||
@ -104,7 +112,7 @@ void registerQmlTypes() {
|
||||
qmlRegisterUncreatableType<NymeaConnection>(uri, 1, 0, "NymeaConnection", "Can't create this in QML. Get it from the Engine.");
|
||||
|
||||
// libnymea-common
|
||||
qmlRegisterUncreatableType<Types>(uri, 1, 0, "Types", "Can't create this in QML. Get it from the Engine.");
|
||||
qmlRegisterSingletonType<Types>(uri, 1, 0, "Types", typesProvider);
|
||||
|
||||
qmlRegisterUncreatableType<ParamType>(uri, 1, 0, "ParamType", "Can't create this in QML. Get it from the ParamTypes.");
|
||||
qmlRegisterUncreatableType<ParamTypes>(uri, 1, 0, "ParamTypes", "Can't create this in QML. Get it from the DeviceClass.");
|
||||
|
||||
@ -86,7 +86,7 @@ SOURCES += \
|
||||
configuration/mqttpolicy.cpp \
|
||||
configuration/mqttpolicies.cpp \
|
||||
models/devicemodel.cpp \
|
||||
system/systemcontroller.cpp
|
||||
system/systemcontroller.cpp \
|
||||
|
||||
HEADERS += \
|
||||
configuration/networkmanager.h \
|
||||
@ -153,8 +153,7 @@ HEADERS += \
|
||||
configuration/mqttpolicy.h \
|
||||
configuration/mqttpolicies.h \
|
||||
models/devicemodel.h \
|
||||
system/systemcontroller.h
|
||||
|
||||
system/systemcontroller.h \
|
||||
|
||||
ubports: {
|
||||
DEFINES += UBPORTS
|
||||
|
||||
@ -226,10 +226,16 @@ void LogsModelNg::logsReply(const QVariantMap &data)
|
||||
for (int i = 0; i < newBlock.count(); i++) {
|
||||
LogEntry *entry = newBlock.at(i);
|
||||
m_list.insert(offset + i, entry);
|
||||
Device *dev = m_engine->deviceManager()->devices()->getDevice(entry->deviceId());
|
||||
if (!dev) {
|
||||
qWarning() << "Device not found in system. Cannot add item to graph series.";
|
||||
continue;
|
||||
}
|
||||
|
||||
StateType *entryStateType = dev->deviceClass()->stateTypes()->getStateType(entry->typeId());
|
||||
|
||||
if (m_graphSeries) {
|
||||
Device *dev = m_engine->deviceManager()->devices()->getDevice(entry->deviceId());
|
||||
if (dev && dev->deviceClass()->stateTypes()->getStateType(entry->typeId())->type() == "Bool") {
|
||||
if (entryStateType->type() == "Bool") {
|
||||
|
||||
// We don't want bools painting triangles, add a toggle point to keep lines straight
|
||||
if (i > 0) {
|
||||
@ -265,18 +271,19 @@ void LogsModelNg::logsReply(const QVariantMap &data)
|
||||
|
||||
// Add a pint in the future to extend the graph (so it can scroll with time and the graph wouldn't end at the last known value)
|
||||
if (m_graphSeries->count() == 0) {
|
||||
m_graphSeries->append(QPointF(QDateTime::currentDateTime().addDays(1).toMSecsSinceEpoch(), entry->value().toReal()));
|
||||
m_graphSeries->append(QPointF(QDateTime::currentDateTime().addDays(1).toMSecsSinceEpoch(), Types::instance()->toUiValue(entry->value(), entryStateType->unit()).toReal()));
|
||||
}
|
||||
|
||||
// Add the actual value
|
||||
m_graphSeries->append(QPointF(entry->timestamp().toMSecsSinceEpoch(), entry->value().toReal()));
|
||||
QVariant value = Types::instance()->toUiValue(entry->value(), entryStateType->unit());
|
||||
m_graphSeries->append(QPointF(entry->timestamp().toMSecsSinceEpoch(), value.toReal()));
|
||||
|
||||
// Adjust min/max
|
||||
if (!newMin.isValid() || newMin > entry->value()) {
|
||||
newMin = entry->value().toReal();
|
||||
if (!newMin.isValid() || newMin > value) {
|
||||
newMin = value.toReal();
|
||||
}
|
||||
if (!newMax.isValid() || newMax < entry->value()) {
|
||||
newMax = entry->value().toReal();
|
||||
if (!newMax.isValid() || newMax < value) {
|
||||
newMax = value.toReal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,6 +76,7 @@ SOURCES += \
|
||||
types/repository.cpp \
|
||||
types/script.cpp \
|
||||
types/scripts.cpp \
|
||||
types/types.cpp \
|
||||
types/vendor.cpp \
|
||||
types/vendors.cpp \
|
||||
types/deviceclass.cpp \
|
||||
|
||||
@ -42,6 +42,7 @@ class ParamType : public QObject
|
||||
Q_PROPERTY(QVariant minValue READ minValue CONSTANT)
|
||||
Q_PROPERTY(QVariant maxValue READ maxValue CONSTANT)
|
||||
Q_PROPERTY(Types::InputType inputType READ inputType CONSTANT)
|
||||
Q_PROPERTY(Types::Unit unit READ unit CONSTANT)
|
||||
Q_PROPERTY(QString unitString READ unitString CONSTANT)
|
||||
Q_PROPERTY(QVariantList allowedValues READ allowedValues CONSTANT)
|
||||
Q_PROPERTY(bool readOnly READ readOnly CONSTANT)
|
||||
|
||||
222
libnymea-common/types/types.cpp
Normal file
222
libnymea-common/types/types.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
#include "types.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
Types *Types::s_instance = nullptr;
|
||||
|
||||
Types::Types(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Types *Types::instance()
|
||||
{
|
||||
if (!s_instance) {
|
||||
s_instance = new Types();
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
Types::UnitSystem Types::unitSystem() const
|
||||
{
|
||||
return m_unitSystem;
|
||||
}
|
||||
|
||||
void Types::setUnitSystem(Types::UnitSystem unitSystem)
|
||||
{
|
||||
if (m_unitSystem != unitSystem) {
|
||||
m_unitSystem = unitSystem;
|
||||
emit unitSystemChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString Types::toUiUnit(Types::Unit unit) const
|
||||
{
|
||||
Types::Unit uiUnit = unit;
|
||||
if (m_unitSystem == UnitSystemImperial) {
|
||||
switch (unit) {
|
||||
case Types::UnitDegreeCelsius:
|
||||
uiUnit = Types::UnitDegreeFahrenheit;
|
||||
break;
|
||||
case Types::UnitGram:
|
||||
uiUnit = Types::UnitOunce;
|
||||
break;
|
||||
case Types::UnitKiloGram:
|
||||
uiUnit = Types::UnitPound;
|
||||
break;
|
||||
case Types::UnitMilliMeter:
|
||||
case Types::UnitCentiMeter:
|
||||
uiUnit = Types::UnitInch;
|
||||
break;
|
||||
case Types::UnitMeter:
|
||||
uiUnit = Types::UnitFoot;
|
||||
break;
|
||||
case Types::UnitKiloMeter:
|
||||
uiUnit = Types::UnitMile;
|
||||
break;
|
||||
case Types::UnitMeterPerSecond:
|
||||
uiUnit = Types::UnitFootPerSecond;
|
||||
break;
|
||||
case Types::UnitKiloMeterPerHour:
|
||||
uiUnit = Types::UnitMilePerHour;
|
||||
break;
|
||||
default:
|
||||
uiUnit = unit;
|
||||
}
|
||||
}
|
||||
switch (uiUnit) {
|
||||
case Types::UnitNone:
|
||||
return "";
|
||||
case Types::UnitSeconds:
|
||||
return "s";
|
||||
case Types::UnitMinutes:
|
||||
return "m";
|
||||
case Types::UnitHours:
|
||||
return "h";
|
||||
case Types::UnitUnixTime:
|
||||
return "datetime";
|
||||
case Types::UnitMeterPerSecond:
|
||||
return "m/s";
|
||||
case Types::UnitKiloMeterPerHour:
|
||||
return "km/h";
|
||||
case Types::UnitDegree:
|
||||
return "°";
|
||||
case Types::UnitRadiant:
|
||||
return "rad";
|
||||
case Types::UnitDegreeCelsius:
|
||||
return "°C";
|
||||
case Types::UnitDegreeKelvin:
|
||||
return "°K";
|
||||
case Types::UnitMired:
|
||||
return "mir";
|
||||
case Types::UnitMilliBar:
|
||||
return "mbar";
|
||||
case Types::UnitBar:
|
||||
return "bar";
|
||||
case Types::UnitPascal:
|
||||
return "Pa";
|
||||
case Types::UnitHectoPascal:
|
||||
return "hPa";
|
||||
case Types::UnitAtmosphere:
|
||||
return "atm";
|
||||
case Types::UnitLumen:
|
||||
return "lm";
|
||||
case Types::UnitLux:
|
||||
return "lx";
|
||||
case Types::UnitCandela:
|
||||
return "cd";
|
||||
case Types::UnitMilliMeter:
|
||||
return "mm";
|
||||
case Types::UnitCentiMeter:
|
||||
return "cm";
|
||||
case Types::UnitMeter:
|
||||
return "m";
|
||||
case Types::UnitKiloMeter:
|
||||
return "km";
|
||||
case Types::UnitGram:
|
||||
return "g";
|
||||
case Types::UnitKiloGram:
|
||||
return "kg";
|
||||
case Types::UnitDezibel:
|
||||
return "db";
|
||||
case Types::UnitBpm:
|
||||
return "bpm";
|
||||
case Types::UnitKiloByte:
|
||||
return "kB";
|
||||
case Types::UnitMegaByte:
|
||||
return "MB";
|
||||
case Types::UnitGigaByte:
|
||||
return "GB";
|
||||
case Types::UnitTeraByte:
|
||||
return "TB";
|
||||
case Types::UnitMilliWatt:
|
||||
return "mW";
|
||||
case Types::UnitWatt:
|
||||
return "W";
|
||||
case Types::UnitKiloWatt:
|
||||
return "kW";
|
||||
case Types::UnitKiloWattHour:
|
||||
return "kWh";
|
||||
case Types::UnitEuroPerMegaWattHour:
|
||||
return "€/MWh";
|
||||
case Types::UnitEuroCentPerKiloWattHour:
|
||||
return "ct/kWh";
|
||||
case Types::UnitPercentage:
|
||||
return "%";
|
||||
case Types::UnitPartsPerMillion:
|
||||
return "ppm";
|
||||
case Types::UnitEuro:
|
||||
return "€";
|
||||
case Types::UnitDollar:
|
||||
return "$";
|
||||
case Types::UnitHertz:
|
||||
return "Hz";
|
||||
case Types::UnitAmpere:
|
||||
return "A";
|
||||
case Types::UnitMilliAmpere:
|
||||
return "mA";
|
||||
case Types::UnitVolt:
|
||||
return "V";
|
||||
case Types::UnitMilliVolt:
|
||||
return "mV";
|
||||
case Types::UnitVoltAmpere:
|
||||
return "VA";
|
||||
case Types::UnitVoltAmpereReactive:
|
||||
return "VAR";
|
||||
case Types::UnitAmpereHour:
|
||||
return "Ah";
|
||||
case Types::UnitMicroSiemensPerCentimeter:
|
||||
return "µS/cm";
|
||||
case Types::UnitDuration:
|
||||
return "s";
|
||||
|
||||
// Units not in nymea:core
|
||||
case Types::UnitDegreeFahrenheit:
|
||||
return "°F";
|
||||
case Types::UnitOunce:
|
||||
return "oz";
|
||||
case Types::UnitPound:
|
||||
return "lb";
|
||||
case Types::UnitInch:
|
||||
return "in";
|
||||
case Types::UnitFoot:
|
||||
return "ft";
|
||||
case Types::UnitMile:
|
||||
return "mi";
|
||||
case Types::UnitFootPerSecond:
|
||||
return "fps";
|
||||
case Types::UnitMilePerHour:
|
||||
return "mph";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
QVariant Types::toUiValue(const QVariant &value, Types::Unit unit) const
|
||||
{
|
||||
if (m_unitSystem == UnitSystemImperial) {
|
||||
switch (unit) {
|
||||
case Types::UnitDegreeCelsius: // To Fahrenheit
|
||||
return (value.toDouble() * 9/5) + 32;
|
||||
case Types::UnitGram: // To Ounce
|
||||
return value.toDouble() / 28.35;
|
||||
case Types::UnitKiloGram: // To Pound
|
||||
return value.toDouble() * 2.205;
|
||||
case Types::UnitMilliMeter: // To Inch
|
||||
return value.toDouble() / 25.4;
|
||||
case Types::UnitCentiMeter: // To Inch
|
||||
return value.toDouble() / 2.54;
|
||||
case Types::UnitMeter: // To Feet
|
||||
return value.toDouble() * 3.281;
|
||||
case Types::UnitKiloMeter: // To Mile
|
||||
return value.toDouble() / 1.609;
|
||||
case Types::UnitMeterPerSecond: // To foot per second
|
||||
return value.toDouble() * 3.281;
|
||||
case Types::UnitKiloMeterPerHour:
|
||||
return value.toDouble() / 1.609;
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -24,12 +24,12 @@
|
||||
#define TYPES_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
class Types
|
||||
class Types: public QObject
|
||||
{
|
||||
Q_GADGET
|
||||
Q_ENUMS(InputType)
|
||||
Q_ENUMS(Unit)
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(UnitSystem unitSystem READ unitSystem WRITE setUnitSystem NOTIFY unitSystemChanged)
|
||||
|
||||
public:
|
||||
enum InputType {
|
||||
@ -44,6 +44,7 @@ public:
|
||||
InputTypeUrl,
|
||||
InputTypeMacAddress
|
||||
};
|
||||
Q_ENUM(InputType)
|
||||
|
||||
enum Unit {
|
||||
UnitNone,
|
||||
@ -97,10 +98,42 @@ public:
|
||||
UnitVoltAmpereReactive,
|
||||
UnitAmpereHour,
|
||||
UnitMicroSiemensPerCentimeter,
|
||||
UnitDuration
|
||||
};
|
||||
UnitDuration,
|
||||
|
||||
// Those do not exist in nymea:core at this point, Adding them for easier conversion to imperial
|
||||
UnitDegreeFahrenheit,
|
||||
UnitOunce,
|
||||
UnitPound,
|
||||
UnitInch,
|
||||
UnitFoot,
|
||||
UnitMile,
|
||||
UnitFootPerSecond,
|
||||
UnitMilePerHour,
|
||||
};
|
||||
Q_ENUM(Unit)
|
||||
|
||||
enum UnitSystem {
|
||||
UnitSystemMetric,
|
||||
UnitSystemImperial
|
||||
};
|
||||
Q_ENUM(UnitSystem)
|
||||
|
||||
static Types* instance();
|
||||
|
||||
UnitSystem unitSystem() const;
|
||||
void setUnitSystem(UnitSystem unitSystem);
|
||||
|
||||
Q_INVOKABLE QString toUiUnit(Types::Unit unit) const;
|
||||
Q_INVOKABLE QVariant toUiValue(const QVariant &value, Types::Unit unit) const;
|
||||
|
||||
signals:
|
||||
void unitSystemChanged();
|
||||
|
||||
private:
|
||||
Types(QObject *parent = nullptr);
|
||||
static Types *s_instance;
|
||||
|
||||
UnitSystem m_unitSystem = UnitSystemMetric;
|
||||
|
||||
};
|
||||
#endif // TYPES_H
|
||||
|
||||
@ -2904,6 +2904,18 @@ Bitte versuche es erneut.</translation>
|
||||
<source>Automatic</source>
|
||||
<translation>Automatisch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unit system</source>
|
||||
<translation>Einheitensystem</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Metric</source>
|
||||
<translation>Metrisch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Imperial</source>
|
||||
<translation>Imperialistisch</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MagicPage</name>
|
||||
@ -3886,6 +3898,15 @@ Möchtest Du fortfahren?</translation>
|
||||
<source>Accounts</source>
|
||||
<translation>Konten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Smartlocks</source>
|
||||
<translation>Smartlocks</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>smartlock</source>
|
||||
<extracomment>Select ...</extracomment>
|
||||
<translation>Smartlock</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NymeaConnection</name>
|
||||
|
||||
@ -2242,6 +2242,18 @@ Please try again.</source>
|
||||
<source>Automatic</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unit system</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Metric</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Imperial</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MagicPage</name>
|
||||
@ -3044,6 +3056,15 @@ Please try again.</source>
|
||||
<source>Accounts</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Smartlocks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>smartlock</source>
|
||||
<extracomment>Select ...</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NymeaConnection</name>
|
||||
|
||||
@ -2242,6 +2242,18 @@ Please try again.</source>
|
||||
<source>Automatic</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unit system</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Metric</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Imperial</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MagicPage</name>
|
||||
@ -3044,6 +3056,15 @@ Please try again.</source>
|
||||
<source>Accounts</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Smartlocks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>smartlock</source>
|
||||
<extracomment>Select ...</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NymeaConnection</name>
|
||||
|
||||
@ -2294,6 +2294,18 @@ Please try again.</source>
|
||||
<source>Automatic</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unit system</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Metric</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Imperial</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MagicPage</name>
|
||||
@ -3107,6 +3119,15 @@ Please try again.</source>
|
||||
<source>Accounts</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Smartlocks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>smartlock</source>
|
||||
<extracomment>Select ...</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NymeaConnection</name>
|
||||
|
||||
@ -45,6 +45,7 @@ ApplicationWindow {
|
||||
property string cloudEnvironment: "Community"
|
||||
property bool showConnectionTabs: false
|
||||
property int tabCount: 1
|
||||
property string units: "metric" // or "imperial"
|
||||
}
|
||||
|
||||
property string privacyPolicyUrl: "https://nymea.io/privacy-statement/en/nymea_privacy.html"
|
||||
@ -55,6 +56,12 @@ ApplicationWindow {
|
||||
PlatformHelper.bottomPanelColor = Material.background
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: Types
|
||||
property: "unitSystem"
|
||||
value: settings.units === "metric" ? Types.UnitSystemMetric : Types.UnitSystemImperial
|
||||
}
|
||||
|
||||
RootItem {
|
||||
id: rootItem
|
||||
anchors.fill: parent
|
||||
@ -65,7 +72,7 @@ ApplicationWindow {
|
||||
id: discovery
|
||||
objectName: "discovery"
|
||||
awsClient: AWSClient
|
||||
// discovering: pageStack.currentItem.objectName === "discoveryPage"
|
||||
// discovering: pageStack.currentItem.objectName === "discoveryPage"
|
||||
}
|
||||
property alias _discovery: discovery
|
||||
|
||||
|
||||
@ -83,6 +83,24 @@ Page {
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Unit system")
|
||||
}
|
||||
ComboBox {
|
||||
id: unitsComboBox
|
||||
currentIndex: settings.units === "metric" ? 0 : 1
|
||||
model: [ qsTr("Metric"), qsTr("Imperial") ]
|
||||
onActivated: {
|
||||
settings.units = index == 0 ? "metric" : "imperial";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Return to home on idle")
|
||||
|
||||
@ -90,7 +90,8 @@ ColumnLayout {
|
||||
Label {
|
||||
id: topLabel
|
||||
Layout.fillWidth: true
|
||||
text: rotateMouseArea.currentValue + (dial.stateType ? dial.stateType.unitString : "")
|
||||
property var unit: dial.stateType ? dial.stateType.unit : Types.UnitNone
|
||||
text: Types.toUiValue(rotateMouseArea.currentValue, unit) + Types.toUiUnit(unit)
|
||||
font.pixelSize: app.largeFont * 1.5
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: dial.showValueLabel && dial.stateType !== null
|
||||
|
||||
@ -164,10 +164,11 @@ Item {
|
||||
ctx.strokeStyle = Material.foreground
|
||||
ctx.fillStyle = Material.foreground
|
||||
ctx.lineWidth = 0;
|
||||
var label = root.stateType ? root.stateType.unitString : ""
|
||||
var unit = root.stateType ? root.stateType.unit : Types.UnitNone
|
||||
var label = Types.toUiUnit(unit)
|
||||
var textSize = ctx.measureText(label)
|
||||
ctx.text(label, -textSize.width - app.margins, height + app.margins + app.smallFont)
|
||||
// ctx.stroke();
|
||||
ctx.stroke();
|
||||
ctx.fill()
|
||||
ctx.closePath()
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
text: root.stateType.type.toLowerCase() === "bool"
|
||||
? root.stateType.displayName
|
||||
: 1.0 * Math.round(root.valueState.value * Math.pow(10, root.roundTo)) / Math.pow(10, root.roundTo) + " " + root.stateType.unitString
|
||||
: 1.0 * Math.round(Types.toUiValue(root.valueState.value, root.stateType.unit) * Math.pow(10, root.roundTo)) / Math.pow(10, root.roundTo) + " " + Types.toUiUnit(root.stateType.unit)
|
||||
font.pixelSize: app.largeFont
|
||||
}
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ CustomViewBase {
|
||||
color: app.interfaceToColor(root.interfaceName)
|
||||
}
|
||||
Label {
|
||||
text: deviceState.value + " " + stateType.unitString
|
||||
text: Types.toUiValue(deviceState.value, stateType.unit) + " " + Types.toUiUnit(stateType.unit)
|
||||
font.pixelSize: app.largeFont
|
||||
}
|
||||
|
||||
|
||||
@ -145,7 +145,7 @@ ItemDelegate {
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: root.param.value.toFixed(slider.decimals) + root.paramType.unitString
|
||||
text: Types.toUiValue(root.param.value, root.paramType.unit).toFixed(slider.decimals) + Types.toUiUnit(root.paramType.unit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,7 +170,7 @@ ItemDelegate {
|
||||
width: 150
|
||||
onValueModified: root.param.value = value
|
||||
textFromValue: function(value) {
|
||||
return value
|
||||
return Types.toUiValue(value, root.paramType.unit)
|
||||
}
|
||||
Component.onCompleted: {
|
||||
if (root.value === undefined) {
|
||||
@ -179,7 +179,7 @@ ItemDelegate {
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: root.paramType.unitString
|
||||
text: Types.toUiUnit(root.paramType.unit)
|
||||
visible: text.length > 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ ItemDelegate {
|
||||
}
|
||||
|
||||
Label {
|
||||
text: paramType.unitString
|
||||
text: Types.toUiUnit(paramType.unit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,9 +132,9 @@ ItemDelegate {
|
||||
text: {
|
||||
switch (root.paramType.type.toLowerCase()) {
|
||||
case "double":
|
||||
return Math.round(root.value * 10) / 10
|
||||
return Math.round(Types.toUiValue(root.value, root.paramType.unit) * 10) / 10
|
||||
}
|
||||
return root.value
|
||||
return Types.toUiValue(root.value, root.paramType.unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,10 +153,11 @@ ItemDelegate {
|
||||
id: sliderComponent
|
||||
RowLayout {
|
||||
spacing: app.margins
|
||||
Label { text: root.paramType.minValue }
|
||||
Label { text: Types.toUiValue(root.paramType.minValue, root.paramType.unit) }
|
||||
Slider {
|
||||
from: paramType.minValue
|
||||
to: paramType.maxValue
|
||||
value: root.value
|
||||
stepSize: {
|
||||
switch (root.paramType.type.toLowerCase()) {
|
||||
case "double":
|
||||
@ -169,7 +170,7 @@ ItemDelegate {
|
||||
root.value = value;
|
||||
}
|
||||
}
|
||||
Label { text: root.paramType.maxValue }
|
||||
Label { text: Types.toUiValue(root.paramType.maxValue, root.paramType.unit) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -209,13 +209,13 @@ MainPageTile {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sensorsRoot.currentStateType.unitString
|
||||
text: Types.toUiUnit(sensorsRoot.currentStateType.unit)
|
||||
font.pixelSize: app.smallFont
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: sensorsRoot.currentState.value// + " " + sensorsRoot.currentStateType.unitString
|
||||
text: Math.round(Types.toUiValue(sensorsRoot.currentState.value, sensorsRoot.currentStateType.unit) * 100) / 100
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import "../../components"
|
||||
|
||||
Label {
|
||||
property var value
|
||||
text: Math.round(value * 100) / 100
|
||||
property var unit: Types.UnitNone
|
||||
text: Math.round(Types.toUiValue(value, unit) * 100) / 100
|
||||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ RowLayout {
|
||||
signal changed(var value)
|
||||
|
||||
property var value
|
||||
property var unit: Types.UnitNone
|
||||
property alias from: slider.from
|
||||
property alias to: slider.to
|
||||
|
||||
@ -52,6 +53,6 @@ RowLayout {
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: slider.value.toFixed(root.decimals)
|
||||
text: Types.toUiValue(slider.value, root.unit).toFixed(root.decimals)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,12 @@ SpinBox {
|
||||
width: 150
|
||||
signal changed(var value)
|
||||
stepSize: Math.min(10, (to - from) / 10)
|
||||
property var unit: Types.UnitNone
|
||||
editable: true
|
||||
onValueModified: {
|
||||
changed(value)
|
||||
}
|
||||
textFromValue: function(value) {
|
||||
return Types.toUiValue(value, unit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ DeviceListPageBase {
|
||||
color: {
|
||||
switch (model.interfaceName) {
|
||||
case "closablesensor":
|
||||
return sensorValueDelegate.stateValue.value === true ? "green" : "red";
|
||||
return sensorValueDelegate.stateValue && sensorValueDelegate.stateValue.value === true ? "green" : "red";
|
||||
default:
|
||||
return app.interfaceToColor(model.interfaceName)
|
||||
}
|
||||
@ -112,7 +112,7 @@ DeviceListPageBase {
|
||||
name: {
|
||||
switch (model.interfaceName) {
|
||||
case "closablesensor":
|
||||
return sensorValueDelegate.stateValue.value === true ? Qt.resolvedUrl("../images/lock-closed.svg") : Qt.resolvedUrl("../images/lock-open.svg");
|
||||
return sensorValueDelegate.stateValue && sensorValueDelegate.stateValue.value === true ? Qt.resolvedUrl("../images/lock-closed.svg") : Qt.resolvedUrl("../images/lock-open.svg");
|
||||
default:
|
||||
return app.interfaceToIcon(model.interfaceName)
|
||||
}
|
||||
@ -121,15 +121,16 @@ DeviceListPageBase {
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
property var unit: sensorValueDelegate.stateType ? sensorValueDelegate.stateType.unit : Types.UnitNone
|
||||
text: {
|
||||
switch (model.interfaceName) {
|
||||
case "closablesensor":
|
||||
return sensorValueDelegate.stateValue.value === true ? qsTr("is closed") : qsTr("is open");
|
||||
return sensorValueDelegate.stateValue && sensorValueDelegate.stateValue.value === true ? qsTr("is closed") : qsTr("is open");
|
||||
default:
|
||||
return sensorValueDelegate.stateType && sensorValueDelegate.stateType.type.toLowerCase() === "bool"
|
||||
? sensorValueDelegate.stateType.displayName
|
||||
: sensorValueDelegate.stateValue
|
||||
? "%1 %2".arg(Math.round(sensorValueDelegate.stateValue.value * 100) / 100).arg(sensorValueDelegate.stateType.unitString)
|
||||
? "%1 %2".arg(Math.round(Types.toUiValue(sensorValueDelegate.stateValue.value, unit) * 100) / 100).arg(Types.toUiUnit(unit))
|
||||
: ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ DeviceListPageBase {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: sensorValueDelegate.stateValue
|
||||
? "%1 %2".arg(1.0 * Math.round(sensorValueDelegate.stateValue.value * 100000) / 100000).arg(sensorValueDelegate.stateType.unitString)
|
||||
? "%1 %2".arg(1.0 * Math.round(Types.toUiValue(sensorValueDelegate.stateValue.value, sensorValueDelegate.stateType.unit) * 100000) / 100000).arg(Types.toUiUnit(sensorValueDelegate.stateType.unit))
|
||||
: ""
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
@ -229,11 +229,11 @@ Page {
|
||||
|
||||
return labelComponent
|
||||
}
|
||||
Binding { target: valueLoader.item; property: "value"; value: model.value }
|
||||
Binding { target: valueLoader.item; property: "value"; value: Types.toUiValue(model.value, entryDelegate.stateType.unit) }
|
||||
Binding {
|
||||
target: entryDelegate.stateType && valueLoader.item.hasOwnProperty("unitString") ? valueLoader.item : null;
|
||||
property: "unitString"
|
||||
value: entryDelegate.stateType ? entryDelegate.stateType.unitString : ""
|
||||
value: entryDelegate.stateType ? Types.toUiUnit(entryDelegate.stateType.unit) : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +125,8 @@ DevicePageBase {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Label {
|
||||
visible: stateDelegate.stateType.unit !== Types.UnitUnixTime && stateDelegate.stateType.unitString.length > 0
|
||||
text: stateDelegate.stateType.unitString
|
||||
visible: stateDelegate.stateType.unit !== Types.UnitUnixTime && stateDelegate.stateType.unit !== Types.UnitUnixTime
|
||||
text: Types.toUiUnit(stateDelegate.stateType.unit)
|
||||
}
|
||||
|
||||
Component.onCompleted: updateLoader()
|
||||
@ -202,6 +202,7 @@ DevicePageBase {
|
||||
possibleValues: stateDelegate.stateType.allowedValues,
|
||||
from: minValue,
|
||||
to: maxValue,
|
||||
unit: stateDelegate.stateType.unit,
|
||||
writable: isWritable,
|
||||
stateType: stateDelegate.stateType
|
||||
})
|
||||
@ -237,6 +238,11 @@ DevicePageBase {
|
||||
value: stateDelegate.deviceState.value
|
||||
when: !stateDelegate.valueCacheDirty && stateDelegate.pendingActionId === -1
|
||||
}
|
||||
Binding {
|
||||
target: stateDelegateLoader.item.hasOwnProperty("unit") ? stateDelegateLoader.item : null
|
||||
property: "unit"
|
||||
value: stateDelegate.stateType.unit
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: stateDelegateLoader.item && stateDelegateLoader.item.hasOwnProperty("changed") ? stateDelegateLoader.item : null
|
||||
|
||||
@ -560,7 +560,7 @@ MainPageTile {
|
||||
|
||||
Label {
|
||||
text: sensorsRoot.shownStateType
|
||||
? Math.round(sensorsRoot.device.states.getState(shownStateType.id).value * 100) / 100 + " " + sensorsRoot.shownStateType.unitString
|
||||
? (Math.round(Types.toUiValue(sensorsRoot.device.states.getState(shownStateType.id).value, sensorsRoot.shownStateType.unit) * 100) / 100) + " " + Types.toUiUnit(sensorsRoot.shownStateType.unit)
|
||||
: ""
|
||||
// font.pixelSize: app.smallFont
|
||||
Layout.fillWidth: true
|
||||
|
||||
@ -147,7 +147,8 @@ Page {
|
||||
text : {
|
||||
switch (model.source) {
|
||||
case LogEntry.LoggingSourceStates:
|
||||
return "%1 -> %2".arg(delegate.deviceClass.stateTypes.getStateType(model.typeId).displayName).arg(model.value);
|
||||
var stateType = delegate.deviceClass.stateTypes.getStateType(model.typeId);
|
||||
return "%1 -> %2 %3".arg(stateType.displayName).arg(Types.toUiValue(model.value, stateType.unit)).arg(Types.toUiUnit(stateType.unit));
|
||||
case LogEntry.LoggingSourceSystem:
|
||||
return model.loggingEventType === LogEntry.LoggingEventTypeActiveChange ? qsTr("System started") : "N/A"
|
||||
case LogEntry.LoggingSourceActions:
|
||||
|
||||
Reference in New Issue
Block a user