Support notification alerts for air condintioning

pull/982/head
Michael Zanetti 2023-02-25 17:03:01 +01:00
parent e86d06f862
commit 69d5792972
11 changed files with 240 additions and 129 deletions

View File

@ -136,9 +136,9 @@ int AirConditioningManager::setZoneWeekSchedule(const QUuid &zoneId, Temperature
return m_engine->jsonRpcClient()->sendCommand("AirConditioning.SetZoneWeekSchedule", params, this, "setZoneWeekScheduleResponse");
}
int AirConditioningManager::setZoneThings(const QUuid &zoneId, const QList<QUuid> &thermostats, const QList<QUuid> &windowSensors, const QList<QUuid> &indoorSensors, const QList<QUuid> &outdoorSensors)
int AirConditioningManager::setZoneThings(const QUuid &zoneId, const QList<QUuid> &thermostats, const QList<QUuid> &windowSensors, const QList<QUuid> &indoorSensors, const QList<QUuid> &outdoorSensors, const QList<QUuid> &notifications)
{
QVariantList thermostatIds, windowSensorIds, indoorSensorIds, outdoorSensorIds;
QVariantList thermostatIds, windowSensorIds, indoorSensorIds, outdoorSensorIds, notificationIds;
foreach (const QUuid &thingId, thermostats) {
thermostatIds.append(thingId);
}
@ -151,12 +151,16 @@ int AirConditioningManager::setZoneThings(const QUuid &zoneId, const QList<QUuid
foreach (const QUuid &thingId, outdoorSensors) {
outdoorSensorIds.append(thingId);
}
foreach (const QUuid &thingId, notifications) {
notificationIds.append(thingId);
}
QVariantMap params = {
{"zoneId", zoneId},
{"thermostats", thermostatIds},
{"windowSensors", windowSensorIds},
{"indoorSensors", indoorSensorIds},
{"outdoorSensors", outdoorSensorIds},
{"notifications", notificationIds},
};
return m_engine->jsonRpcClient()->sendCommand("AirConditioning.SetZoneThings", params, this, "setZoneThingsResponse");
}
@ -167,7 +171,7 @@ int AirConditioningManager::addZoneThermostat(const QUuid &zoneId, const QUuid &
if (!zoneInfo) {
return -1;
}
return setZoneThings(zoneId, zoneInfo->thermostats() << thermostat, zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors());
return setZoneThings(zoneId, zoneInfo->thermostats() << thermostat, zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors(), zoneInfo->notifications());
}
int AirConditioningManager::removeZoneThermostat(const QUuid &zoneId, const QUuid &thermostat)
@ -178,7 +182,7 @@ int AirConditioningManager::removeZoneThermostat(const QUuid &zoneId, const QUui
}
QList<QUuid> thermostats = zoneInfo->thermostats();
thermostats.removeAll(thermostat);
return setZoneThings(zoneId, thermostats, zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors());
return setZoneThings(zoneId, thermostats, zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors(), zoneInfo->notifications());
}
int AirConditioningManager::addZoneWindowSensor(const QUuid &zoneId, const QUuid &windowSensor)
@ -187,7 +191,7 @@ int AirConditioningManager::addZoneWindowSensor(const QUuid &zoneId, const QUuid
if (!zoneInfo) {
return -1;
}
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors() << windowSensor, zoneInfo->indoorSensors(), zoneInfo->outdoorSensors());
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors() << windowSensor, zoneInfo->indoorSensors(), zoneInfo->outdoorSensors(), zoneInfo->notifications());
}
int AirConditioningManager::removeWindowSensor(const QUuid &zoneId, const QUuid &windowSensor)
@ -198,7 +202,7 @@ int AirConditioningManager::removeWindowSensor(const QUuid &zoneId, const QUuid
}
QList<QUuid> windowSensors = zoneInfo->windowSensors();
windowSensors.removeAll(windowSensor);
return setZoneThings(zoneId, zoneInfo->thermostats(), windowSensors, zoneInfo->indoorSensors(), zoneInfo->outdoorSensors());
return setZoneThings(zoneId, zoneInfo->thermostats(), windowSensors, zoneInfo->indoorSensors(), zoneInfo->outdoorSensors(), zoneInfo->notifications());
}
int AirConditioningManager::addZoneIndoorSensor(const QUuid &zoneId, const QUuid &indoorSensor)
@ -207,7 +211,7 @@ int AirConditioningManager::addZoneIndoorSensor(const QUuid &zoneId, const QUuid
if (!zoneInfo) {
return -1;
}
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors() << indoorSensor, zoneInfo->outdoorSensors());
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors() << indoorSensor, zoneInfo->outdoorSensors(), zoneInfo->notifications());
}
int AirConditioningManager::removeZoneIndoorSensor(const QUuid &zoneId, const QUuid &indoorSensor)
@ -218,7 +222,7 @@ int AirConditioningManager::removeZoneIndoorSensor(const QUuid &zoneId, const QU
}
QList<QUuid> indoorSensors = zoneInfo->indoorSensors();
indoorSensors.removeAll(indoorSensor);
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), indoorSensors, zoneInfo->outdoorSensors());
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), indoorSensors, zoneInfo->outdoorSensors(), zoneInfo->notifications());
}
@ -228,7 +232,7 @@ int AirConditioningManager::addZoneOutdoorSensor(const QUuid &zoneId, const QUui
if (!zoneInfo) {
return -1;
}
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors() << outdoorSensor);
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors() << outdoorSensor, zoneInfo->notifications());
}
int AirConditioningManager::removeZoneOutdoorSensor(const QUuid &zoneId, const QUuid &outdoorSensor)
@ -239,7 +243,27 @@ int AirConditioningManager::removeZoneOutdoorSensor(const QUuid &zoneId, const Q
}
QList<QUuid> outdoorSensors = zoneInfo->outdoorSensors();
outdoorSensors.removeAll(outdoorSensor);
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors(), outdoorSensors);
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors(), outdoorSensors, zoneInfo->notifications());
}
int AirConditioningManager::addZoneNotification(const QUuid &zoneId, const QUuid &notification)
{
ZoneInfo *zoneInfo = m_zoneInfos->getZoneInfo(zoneId);
if (!zoneInfo) {
return -1;
}
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors(), zoneInfo->notifications() << notification);
}
int AirConditioningManager::removeZoneNotification(const QUuid &zoneId, const QUuid &notification)
{
ZoneInfo *zoneInfo = m_zoneInfos->getZoneInfo(zoneId);
if (!zoneInfo) {
return -1;
}
QList<QUuid> notifications = zoneInfo->notifications();
notifications.removeAll(notification);
return setZoneThings(zoneId, zoneInfo->thermostats(), zoneInfo->windowSensors(), zoneInfo->indoorSensors(), zoneInfo->outdoorSensors(), notifications);
}
void AirConditioningManager::notificationReceived(const QVariantMap &data)
@ -352,6 +376,10 @@ ZoneInfo *AirConditioningManager::unpack(const QVariantMap &zoneMap, ZoneInfo *z
}
qCDebug(dcAirConditioningExperience()) << "Zone status:" << zoneStatus;
zone->setZoneStatus(zoneStatus);
zone->setTemperature(zoneMap.value("temperature").toDouble());
zone->setHumidity(zoneMap.value("humidity").toDouble());
zone->setVoc(zoneMap.value("voc").toUInt());
zone->setPm25(zoneMap.value("pm25").toDouble());
zone->setCurrentSetpoint(zoneMap.value("currentSetpoint").toDouble());
zone->setStandbySetpoint(zoneMap.value("standbySetpoint").toDouble());
QMetaEnum modeEnum = QMetaEnum::fromType<ZoneInfo::SetpointOverrideMode>();
@ -368,7 +396,7 @@ ZoneInfo *AirConditioningManager::unpack(const QVariantMap &zoneMap, ZoneInfo *z
zone->weekSchedule()->get(day)->createSchedule(scheduleMap.value("startTime").toTime(), scheduleMap.value("endTime").toTime(), scheduleMap.value("temperature").toDouble());
}
}
QList<QUuid> thermostats, windowSensors, indoorSensors, outdoorSensors;
QList<QUuid> thermostats, windowSensors, indoorSensors, outdoorSensors, notifications;
foreach (const QVariant &variant, zoneMap.value("thermostats").toList()) {
thermostats.append(variant.toUuid());
}
@ -381,9 +409,13 @@ ZoneInfo *AirConditioningManager::unpack(const QVariantMap &zoneMap, ZoneInfo *z
foreach (const QVariant &variant, zoneMap.value("outdoorSensors").toList()) {
outdoorSensors.append(variant.toUuid());
}
foreach (const QVariant &variant, zoneMap.value("notifications").toList()) {
notifications.append(variant.toUuid());
}
zone->setThermostats(thermostats);
zone->setWindowSensors(windowSensors);
zone->setIndoorSensors(indoorSensors);
zone->setOutdoorSensors(outdoorSensors);
zone->setNotifications(notifications);
return zone;
}

View File

@ -37,7 +37,7 @@ public:
Q_INVOKABLE int setZoneStandbySetpoint(const QUuid &zoneId, double standbySetpoint);
Q_INVOKABLE int setZoneSetpointOverride(const QUuid &zoneId, double setpointOverride, ZoneInfo::SetpointOverrideMode mode, uint minutes);
Q_INVOKABLE int setZoneWeekSchedule(const QUuid &zoneId, TemperatureWeekSchedule *weekSchedule);
Q_INVOKABLE int setZoneThings(const QUuid &zoneId, const QList<QUuid> &thermostats, const QList<QUuid> &windowSensors, const QList<QUuid> &indoorSensors, const QList<QUuid> &outdoorSensors);
Q_INVOKABLE int setZoneThings(const QUuid &zoneId, const QList<QUuid> &thermostats, const QList<QUuid> &windowSensors, const QList<QUuid> &indoorSensors, const QList<QUuid> &outdoorSensors, const QList<QUuid> &notificationIds);
Q_INVOKABLE int addZoneThermostat(const QUuid &zoneId, const QUuid &thermostat);
Q_INVOKABLE int removeZoneThermostat(const QUuid &zoneId, const QUuid &thermostat);
@ -47,6 +47,8 @@ public:
Q_INVOKABLE int removeZoneIndoorSensor(const QUuid &zoneId, const QUuid &indoorSensor);
Q_INVOKABLE int addZoneOutdoorSensor(const QUuid &zoneId, const QUuid &outdoorSensor);
Q_INVOKABLE int removeZoneOutdoorSensor(const QUuid &zoneId, const QUuid &outdoorSensor);
Q_INVOKABLE int addZoneNotification(const QUuid &zoneId, const QUuid &notification);
Q_INVOKABLE int removeZoneNotification(const QUuid &zoneId, const QUuid &notification);
signals:
void engineChanged();

View File

@ -146,6 +146,70 @@ void ZoneInfo::setOutdoorSensors(const QList<QUuid> &outdoorSensors)
}
}
QList<QUuid> ZoneInfo::notifications() const
{
return m_notifications;
}
void ZoneInfo::setNotifications(const QList<QUuid> &notifications)
{
if (m_notifications != notifications) {
m_notifications = notifications;
}
}
double ZoneInfo::temperature() const
{
return m_temperature;
}
void ZoneInfo::setTemperature(double temperature)
{
if (m_temperature != temperature) {
m_temperature = temperature;
emit temperatureChanged();
}
}
double ZoneInfo::humidity() const
{
return m_humidity;
}
void ZoneInfo::setHumidity(double humidity)
{
if (m_humidity != humidity) {
m_humidity = humidity;
emit humidityChanged();
}
}
uint ZoneInfo::voc() const
{
return m_voc;
}
void ZoneInfo::setVoc(uint voc)
{
if (m_voc != voc) {
m_voc = voc;
emit vocChanged();
}
}
double ZoneInfo::pm25() const
{
return m_pm25;
}
void ZoneInfo::setPm25(double pm25)
{
if (m_pm25 != pm25) {
m_pm25 = pm25;
emit pm25Changed();
}
}
QVariant ZoneInfos::data(const QModelIndex &index, int role) const
{
switch (role) {

View File

@ -23,6 +23,11 @@ class ZoneInfo : public QObject
Q_PROPERTY(QList<QUuid> windowSensors READ windowSensors NOTIFY windowSensorsChanged)
Q_PROPERTY(QList<QUuid> indoorSensors READ indoorSensors NOTIFY indoorSensorsChanged)
Q_PROPERTY(QList<QUuid> outdoorSensors READ outdoorSensors NOTIFY outdoorSensorsChanged)
Q_PROPERTY(QList<QUuid> notifications READ notifications NOTIFY notificationsChanged)
Q_PROPERTY(double temperature READ temperature NOTIFY temperatureChanged)
Q_PROPERTY(double humidity READ humidity NOTIFY humidityChanged)
Q_PROPERTY(uint voc READ voc NOTIFY vocChanged)
Q_PROPERTY(double pm25 READ pm25 NOTIFY pm25Changed)
public:
enum ZoneStatusFlag {
ZoneStatusFlagNone = 0x00,
@ -80,6 +85,21 @@ public:
QList<QUuid> outdoorSensors() const;
void setOutdoorSensors(const QList<QUuid> &outdoorSensors);
QList<QUuid> notifications() const;
void setNotifications(const QList<QUuid> &notifications);
double temperature() const;
void setTemperature(double temperature);
double humidity() const;
void setHumidity(double humidity);
uint voc() const;
void setVoc(uint voc);
double pm25() const;
void setPm25(double pm25);
signals:
void nameChanged();
void zoneStatusChanged();
@ -90,6 +110,12 @@ signals:
void windowSensorsChanged();
void indoorSensorsChanged();
void outdoorSensorsChanged();
void notificationsChanged();
void temperatureChanged();
void humidityChanged();
void vocChanged();
void pm25Changed();
private:
QUuid m_id;
@ -105,6 +131,11 @@ private:
QList<QUuid> m_windowSensors;
QList<QUuid> m_indoorSensors;
QList<QUuid> m_outdoorSensors;
QList<QUuid> m_notifications;
double m_temperature = 0;
double m_humidity = 0;
uint m_voc = 0;
double m_pm25 = 0;
};
class ZoneInfos: public QAbstractListModel

View File

@ -56,6 +56,7 @@ void ThingsProxy::setEngine(Engine *engine)
m_engine = engine;
emit engineChanged();
if (!m_engine) {
setSourceModel(nullptr);
return;
}
@ -660,7 +661,7 @@ bool ThingsProxy::filterAcceptsRow(int source_row, const QModelIndex &source_par
}
}
ThingClass *thingClass = m_engine->thingManager()->thingClasses()->getThingClass(thing->thingClassId());
ThingClass *thingClass = thing->thingClass();
if (!m_shownInterfaces.isEmpty()) {
bool foundMatch = false;
foreach (const QString &filterInterface, m_shownInterfaces) {

View File

@ -27,6 +27,14 @@ public class NymeaAppNotificationService extends FirebaseMessagingService {
private static final String TAG = "nymea-app: NymeaAppNotificationService";
private int hashId(String id) {
int hash = 7;
for (int i = 0; i < id.length(); i++) {
hash = hash * 31 + id.charAt(i);
}
return hash;
}
public static boolean checkPlayServices() {
Log.d(TAG, "Checking for Google Play services");
try {
@ -41,11 +49,36 @@ public class NymeaAppNotificationService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Intent intent = new Intent(this, NymeaAppActivity.class);
// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
Log.d(TAG, "adding extra data to intent: " + remoteMessage.getData().get("nymeaData"));
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Make sure channels exist
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel alertChannel = new NotificationChannel("alert", "Alerts about your nymea system", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(alertChannel);
NotificationChannel infoChannel = new NotificationChannel("info", "Information about your nymea system", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(infoChannel);
}
Intent intent = new Intent(this, NymeaAppActivity.class);
Log.d(TAG, "Notification data: " + remoteMessage.getData());
String notificationIdString = remoteMessage.getData().get("notificationId");
Log.d(TAG, "NotificationID " + notificationIdString);
int notificationId = new Random().nextInt(60000);;
if (notificationIdString != null) {
notificationId = hashId(notificationIdString);
}
boolean sound = remoteMessage.getData().get("sound") == null || remoteMessage.getData().get("sound").equals("true");
boolean remove = remoteMessage.getData().get("remove") != null && remoteMessage.getData().get("remove").equals("true");
Log.d(TAG, "NotificationID " + notificationIdString + " int " + notificationId + " remove: " + (remove ? "yes" : "no") + " sound: " + (sound ? "yes" : "no"));
if (remove) {
notificationManager.cancel(notificationId);
return;
}
intent.setAction(Intent.ACTION_SEND);
intent.putExtra("notificationData", remoteMessage.getData().get("nymeaData"));
@ -60,15 +93,19 @@ public class NymeaAppNotificationService extends FirebaseMessagingService {
Log.d(TAG, "notification icon resource: " + resId + " Package:" + getPackageName());
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "notify_001")
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, sound ? "alert" : "info")
.setSmallIcon(resId)
.setColor(0xFF57BAAE)
.setContentTitle(remoteMessage.getData().get("title"))
.setContentText(remoteMessage.getData().get("body"))
.setAutoCancel(true)
.setSound(android.provider.Settings.System.DEFAULT_RINGTONE_URI)
.setContentIntent(pendingIntent);
if (sound) {
notificationBuilder.setSound(android.provider.Settings.System.DEFAULT_RINGTONE_URI);
}
// Action tests
// Intent actionIntent = new Intent(this, NymeaAppActivity.class);
// actionIntent.setAction(Intent.ACTION_SEND);
@ -80,15 +117,6 @@ public class NymeaAppNotificationService extends FirebaseMessagingService {
// notificationBuilder.addAction(resId, "70%", actionPendingIntent);
// Action tests end
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("notify_001", "Notifications from your nymea system", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
int notificationId = new Random().nextInt(60000);
Log.d(TAG, "Posting Notification: " + remoteMessage.getMessageId());
notificationManager.notify(notificationId, notificationBuilder.build());

View File

@ -64,7 +64,7 @@ Item {
icon: "sensors/temperature",
color: Style.iconColor,
activeColor: Style.accentColor,
text: Types.toUiValue(zoneWrapper.zoneTemperature.toFixed(1), Types.UnitDegreeCelsius) + Types.toUiUnit(Types.UnitDegreeCelsius),
text: Types.toUiValue(zone.temperature.toFixed(1), Types.UnitDegreeCelsius) + Types.toUiUnit(Types.UnitDegreeCelsius),
visible: zoneWrapper.indoorTempSensors.count > 0 && zoneWrapper.thermostats.count == 0,
alertVisible: false
},
@ -73,18 +73,18 @@ Item {
icon: "sensors/humidity",
color: app.interfaceToColor("humiditysensor"),
activeColor: app.interfaceToColor("humiditysensor"),
text: qsTr("%1% humidity").arg(zoneWrapper.zoneHumidity.toFixed(0)),
activeText:qsTr("%1% humidity").arg(zoneWrapper.zoneHumidity.toFixed(0)),
text: qsTr("%1% humidity").arg(zone.humidity.toFixed(0)),
activeText:qsTr("%1% humidity").arg(zone.humidity.toFixed(0)),
visible: zoneWrapper.indoorHumiditySensors.count > 0,
alertVisible: (root.zone.zoneStatus & ZoneInfo.ZoneStatusFlagHighHumidity) > 0
},
{
value: ZoneInfo.ZoneStatusFlagBadAir,
icon: "weathericons/weather-clouds",
color: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zoneWrapper.zoneVOC).color,
activeColor: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zoneWrapper.zoneVOC).color,
text: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zoneWrapper.zoneVOC).text,
activeText: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zoneWrapper.zoneVOC).text,// qsTr("Air quality alert!"),
color: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zone.voc).color,
activeColor: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zone.voc).color,
text: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zone.voc).text,
activeText: AirQualityIndex.currentIndex(AirQualityIndex.iaqVoc, zone.voc).text,// qsTr("Air quality alert!"),
visible: zoneWrapper.indoorVocSensors.count > 0 || zoneWrapper.indoorPm25Sensors.count > 0,
alertVisible: (root.zone.zoneStatus & ZoneInfo.ZoneStatusFlagBadAir) > 0
}

View File

@ -187,6 +187,45 @@ SettingsPageBase {
}
}
SettingsPageSectionHeader {
text: qsTr("Notifications")
}
Repeater {
model: zoneWrapper.notifications
delegate: ThingDelegate {
Layout.fillWidth: true
thing: zoneWrapper.notifications.get(index)
progressive: false
canDelete: true
onDeleteClicked: {
acManager.removeZoneNotification(zone.id, thing.id)
}
}
}
Button {
Layout.fillWidth: true
Layout.margins: Style.margins
text: qsTr("Add notification target")
onClicked: {
var page = pageStack.push(selectThingComponent, {
acManager: acManager,
zone: zone,
interfaces: ["notifications"],
hiddenThingIds: zone.outdoorSensors,
title: qsTr("Select notification target"),
placeHolderTitle: qsTr("No notification things installed"),
placeHolderText: qsTr("Before a notification target can be assigned to this zone, it needs to be connected to nymea."),
placeHolderButtonText: qsTr("Setup notification targets"),
placeHolderFilterInterface: "notifications"
})
page.selected.connect(function(thingId) {
acManager.addZoneNotification(zone.id, thingId)
})
}
}
Component {
id: selectThingComponent
SettingsPageBase {

View File

@ -44,10 +44,6 @@ Item {
property ZoneInfo zone: null
readonly property double zoneTemperature: d.zoneTemperature
readonly property double zoneHumidity: d.zoneHumidity
readonly property double zoneVOC: d.zoneVOC
readonly property ThingsProxy thermostats: ThingsProxy {
engine: zone.thermostats.length > 0 ? _engine : null
shownThingIds: zone.thermostats
@ -118,88 +114,8 @@ Item {
shownInterfaces: ["pm25sensor"]
}
QtObject {
id: d
property double zoneTemperature
function updateZoneTemperature() {
var value = undefined;
if (thermostats.count > 0) {
for (var i = 0; i < thermostats.count; i++) {
var tempState = thermostats.get(i).stateByName("temperature")
if (!tempState) {
continue;
}
if (value == undefined || tempState.value > value) {
value = tempState.value
}
}
}
if (value == undefined) {
for (var i = 0; i < indoorTempSensors.count; i++) {
var t = indoorTempSensors.get(i).stateByName("temperature").value
if (value == undefined || t > value) {
value = t
}
}
}
if (value != undefined) {
zoneTemperature = value;
}
}
property double zoneHumidity
function updateZoneHumidity() {
var value = undefined;
for (var i = 0; i < indoorHumiditySensors.count; i++) {
var t = indoorHumiditySensors.get(i).stateByName("humidity").value
if (value == undefined || t > value) {
value = t;
}
}
if (value != undefined) {
zoneHumidity = value;
}
}
property double zoneVOC
function updateZoneVOC() {
var value = undefined;
for (var i = 0; i < indoorVocSensors.count; i++) {
var t = indoorVocSensors.get(i).stateByName("voc").value
if (value == undefined || t > value) {
value = t;
}
}
if (value != undefined) {
zoneVOC = value;
}
}
}
Repeater {
id: thingsRepeater
model: ThingsProxy {
engine: zone.thermostats.length > 0 || zone.indoorSensors.length > 0 ? _engine : null
shownThingIds: zone.thermostats.concat(zone.indoorSensors)
}
delegate: Item {
readonly property Thing thing: index < thermostats.count ? thermostats.get(index) : indoorTempSensors.get(index - thermostats.count)
readonly property State temperatureState: thing ? thing.stateByName("temperature") : null
property double temp: temperatureState ? temperatureState.value : 0
onTempChanged: d.updateZoneTemperature()
readonly property State humidityState: thing ? thing.stateByName("humidity") : null
property double humidity: humidityState ? humidityState.value : 0
onHumidityChanged: d.updateZoneHumidity()
readonly property State vocState: thing ? thing.stateByName("voc") : null
property double voc: vocState ? vocState.value : 0
onVocChanged: d.updateZoneVOC()
}
onCountChanged: {
d.updateZoneTemperature()
d.updateZoneHumidity()
d.updateZoneVOC()
}
readonly property ThingsProxy notifications: ThingsProxy {
engine: root.zone.notifications.length > 0 ? _engine : null
shownThingIds: root.zone.notifications
}
}

View File

@ -43,7 +43,7 @@ Item {
precision: 0.5
value: root.zone.currentSetpoint
color: pendingValue < activeValue ? Style.blue : Style.red
activeValue: zoneWrapper.zoneTemperature
activeValue: zone.temperature
onMoved: {
acManager.setZoneSetpointOverride(root.zone.id, value, ZoneInfo.SetpointOverrideModeEventual, 0)
@ -72,17 +72,15 @@ Item {
text: Types.toUiValue(zone.currentSetpoint, Types.UnitDegreeCelsius).toFixed(1)
font.pixelSize: Math.min(Style.hugeFont.pixelSize, thermostat.contentItem.height / 8)
horizontalAlignment: Text.AlignHCenter
color: zoneWrapper.zoneTemperature == undefined
? Stype.foregroundColor
: zone.currentSetpoint > zoneWrapper.zoneTemperature
color: zone.currentSetpoint > zone.temperature
? Style.red
: zone.currentSetpoint < zoneWrapper.zoneTemperature
: zone.currentSetpoint < zone.temperature
? Style.blue
: Style.foregroundColor
}
Label {
Layout.fillWidth: true
text: Types.toUiValue(zoneWrapper.zoneTemperature, Types.UnitDegreeCelsius).toFixed(1)
text: Types.toUiValue(zone.temperature, Types.UnitDegreeCelsius).toFixed(1)
font.pixelSize: Math.min(Style.largeFont.pixelSize, thermostat.contentItem.height / 12)
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter

View File

@ -105,7 +105,7 @@ Flickable {
color: app.interfaceToColor("temperaturesensor")
}
Label {
text: Types.toUiValue(zoneWrapper.zoneTemperature, Types.UnitDegreeCelsius).toFixed(1) + Types.toUiUnit(Types.UnitDegreeCelsius)
text: Types.toUiValue(zoneDelegate.zone.temperature, Types.UnitDegreeCelsius).toFixed(1) + Types.toUiUnit(Types.UnitDegreeCelsius)
}
}