/**************************************************************************** ** ** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the QtIvi module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL-QTAS$ ** Commercial License Usage ** Licensees holding valid commercial Qt Automotive Suite licenses may use ** this file in accordance with the commercial license agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and The Qt Company. For ** licensing terms and conditions see https://www.qt.io/terms-conditions. ** For further information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free ** Documentation License version 1.3 as published by the Free Software ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \page attribute-system.html \title The Qt IVI Attribute System \keyword AttributeSystem \previouspage Dynamic Backend System \nextpage Models \contentspage Concepts \note This page is deprecated and is only left here for reference In the IVI world a system often needs to support a lot of different car configurations. These configurations could vary in display sizes and resolutions are used or the actual hardware changes to a e.g. less powerful cpu and less memory to software configurations where certain features are disabled, as well as simply disabling features via software. Most of the configurations are actually hardware related, while the ECU and UI software still stay the same. Something along these lines would be an example on what configurations an IVI system may need to support: \section1 Example Configurations \section2 Low \list \li Display Resolution: 1280x768 \li CPU: Single-Core 1 GB memory \li Other Hardware: \li 2 Zone Climate Control \li Air conditioning system \li Bluetooth Media Streaming \endlist \section2 Medium \list \li Display Resolution: 1920x1080 \li CPU: Dual-Core 1 GB memory \li Other Hardware: \li 3 Zone Climate Control \li Electric Window Opener \li Automatic Air conditioning system \li Bluetooth Media Streaming \li Wifi (client) \endlist \section2 High \list \li Display Resolution: 1920x1080 \li CPU: Quad-Core 2 GB memory \li Other Hardware: \li Massage Seats \li 5 Zone Climate Control \li Electric Window Opener \li Window Heater \li Window Sun Blinds \li 2 RSE systems \li Automatic Air conditioning system \li Automatic Air Quality System \li Bluetooth Media Streaming \li Wifi (host and client) \li Companion App \endlist QtIVI tries to provide an API which can cope with the all these configurations, thus requiring a lot of flexibility. This is the reason the Attribute System was created: the Attribute System is mainly used for Vehicle Function APIs as there is no common ground in this area and whether a specific feature is supported or not varies a lot. The heart of the attribute system is the QIviProperty. This class defines a special property of a given type, which can be controlled using a QIviPropertyAttribute. The QIviPropertyAttribute defines whether the property is available in the current configuration as well as its value boundaries. Such an attribute can support the following scenarios: \list \li The property is not available. \li The property is available and the values can be between a minimum and a maximum value. \li The property is available and only specific values from a given list are supported. \endlist The QIviPropertyAttribute is mainly used by the backend implementation to inform the QIvi Feature about the availability of a certain property, its underlying functionality and its expected value range. Usually the range doesn't change between different car configurations but different OEM backend implementations may even result in range changes. In QIviClimateControl attributes are used for every property. The backend can do the following to state its capabilities: \code // The zone synchronization is not supported zoneSynchronizationAttribute = QIviPropertyAttribute(false); // The air recirculation is off airRecirculation = false; // The air recirculation is supported by the system. No minimum and maximum values are needed for an bool airRecirculationAttribute = QIviPropertyAttribute(true); // The seat cooler is set to the intensity 10 seatCooler = 10; // The seat cooler is supported by the system and the minimum and maximum values are set to 0 and 10 seatCoolerAttribute = QIviPropertyAttribute(0, 10); // The current air flow direction is to the Floor airflowDirection = QIviClimateControl::Floor; // The system supports multiple air flows and all valid configurations are passed QVector airflow { (QIviClimateControl::Floor | QIviClimateControl::Dashboard), QIviClimateControl::Floor, QIviClimateControl::Dashboard }; airflowDirectionAttribute = QIviPropertyAttribute(airflow)); \endcode Because the actual value for each property is changed more often than its attribute, these two values are separated from each other. To make this still convenient to use within Qt's meta-type system the QIviProperty class was created: QIviProperty is a convenience class which lets you access the value and the attribute in an easy and type-safe way. The following snippet shows how a QIviProperty is used within a class. \code class SimpleControl : public QObject { Q_OBJECT Q_PROPERTY(QIviProperty *temperature READ temperatureProperty CONSTANT) SimpleControl(QObject *parent = nullptr); ~SimpleControl(); int temperature() const; QIviPropertyAttribute temperatureAttribute() const; QIviProperty *temperatureProperty() const; public slots: void setTemperature(int temperature); signals: void temperatureChanged(int temperature); void temperatureAttributeChanged(const QIviPropertyAttribute &attribute); } \endcode SimpleControl has a property to get and set the temperature. The setter and getter for the property work like any other setter/getter in C++ and also have a corresponding changed signal. In addition a QIviPropertyAttribute for the property is also provided with a getter and a changed signal. Usually the attribute is defined by the backend and thus no setter is available. To use the features of the QIviProperty, it is registered as a constant Qt property using the Q_PROPERTY and in addition a getter function is provided. This split makes it possible to use the class from C++ without any hurdles: \code SimpleControl *control = new SimpleControl(); // Create a SpinBox and enable it only if the system supports reading/writing the temperature QSpinBox *spinBox = new QSpinBox(); spinBox->setEnabled(control->temperatureAttribute()->isAvailable()); // Also setup the minimum and maximum of the SpinBox according to the values defined by the backend spinBox->setMinimum(control->temperatureAttribute()->minimumValue()); spinBox->setMaximum(control->temperatureAttribute()->maximumValue()); connect(spinBox, &QSpinBox::valueChanged, control, &SimpleControl::setTemperature); \endcode See the climate_widget example for a complete example. From QML this is done using the QIviProperty directly: \qml import QtQuick 2.0 import QtQuick.Controls 1.4 Item { width: 200 height: 200 SimpleControl { id: simpleControl } SpinBox { value: simpleControl.temperature.value minimumValue: simpleControl.temperature.minimumValue maximumValue: simpleControl.temperature.maximumValue enabled: simpleControl.temperature.available onValueChanged: { simpleControl.temperature.value = value } } } \endqml The SpinBox is connected to the value property of temperature using a binding. The binding will be updated once the value changes. This is handled by the QIviProperty property by telling it which signal to relay. For the temperature property, the SimpleControl::temperatureChanged signal is forwarded to temperature.valueChanged. See the climate_qml example for a complete example. In the implementation of the SimpleControl class, the QIviProperty needs to be setup correctly. The QIviProperty doesn't store any values and is simply forwarding the function calls and signal emissions to the corresponding functionality of the SimpleControl class. \code TemperatureProperty = QIviPropertyFactory::create(q, &SimpleControl::temperatureAttribute, &SimpleControl::temperatureAttributeChanged, &SimpleControl::temperature, &SimpleControl::temperatureChanged, &SimpleControl::setTemperature); \endcode Read-only properties are supported as well, by simply not providing the last argument (pointer to the setter function). */