Sensor save and load from storage, and deletion. Closes #96
This commit is contained in:
parent
5ce0b81e39
commit
645ef2098e
6 changed files with 237 additions and 129 deletions
|
@ -5,10 +5,6 @@ Column {
|
|||
id: sensorList
|
||||
spacing: 1
|
||||
|
||||
SensorView {
|
||||
id: sensorView
|
||||
}
|
||||
|
||||
BorderImage {
|
||||
id: header
|
||||
source: "header_bg.png"
|
||||
|
@ -22,6 +18,13 @@ Column {
|
|||
anchors.leftMargin: 15
|
||||
}
|
||||
HeaderTitle {
|
||||
text: ""
|
||||
anchors.right: sensorid.left
|
||||
visible: main.state == "EDIT"
|
||||
width: 50
|
||||
}
|
||||
HeaderTitle {
|
||||
id: sensorid
|
||||
text: "ID"
|
||||
anchors.right: modelTitle.left
|
||||
visible: main.state == "EDIT"
|
||||
|
@ -58,7 +61,7 @@ Column {
|
|||
}
|
||||
Repeater {
|
||||
model: sensorModel
|
||||
delegate: sensorView
|
||||
delegate: SensorView{ state: main.state == "EDIT" ? 'EDIT' : ''}
|
||||
}
|
||||
Row{
|
||||
spacing: 20
|
||||
|
@ -71,27 +74,9 @@ Column {
|
|||
main.state = "EDIT"
|
||||
}
|
||||
else{
|
||||
main.state ="VIEW"
|
||||
main.state = "VIEW"
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Rectangle {
|
||||
//TODO should this button exist at all, or always save?
|
||||
width: 50
|
||||
height: 20
|
||||
visible: main.state == "EDIT"
|
||||
Text{
|
||||
anchors.centerIn: parent
|
||||
text: "Cancel"
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
main.state ="VIEW"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,98 +1,138 @@
|
|||
import Qt 4.7
|
||||
import QtDesktop 0.1
|
||||
|
||||
Component {
|
||||
id: sensorView
|
||||
Item{
|
||||
id: sensorViewItem
|
||||
visible: main.state == "EDIT" || modelData.showInList
|
||||
height: childrenRect.height
|
||||
Item{
|
||||
id: sensorViewItem
|
||||
visible: state == "EDIT" || modelData.showInList
|
||||
height: childrenRect.height
|
||||
width: parent ? parent.width : 0
|
||||
|
||||
states:[
|
||||
State {
|
||||
name: "EDIT"
|
||||
}
|
||||
]
|
||||
|
||||
BorderImage {
|
||||
source: "row_bg.png"
|
||||
border.left: 5; border.top: 5
|
||||
border.right: 5; border.bottom: 5
|
||||
height: sensorInfo.height
|
||||
width: parent.width
|
||||
|
||||
property string state: main.state
|
||||
onStateChanged: {
|
||||
if (state != "EDIT") {
|
||||
modelData.setName(nameEdit.text)
|
||||
Text {
|
||||
visible: sensorViewItem.state != "EDIT"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
height: 40
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: modelData.name == '' ? '<unnamed>' : modelData.name;
|
||||
color: "#004275"
|
||||
}
|
||||
TextField {
|
||||
id: nameEdit
|
||||
visible: sensorViewItem.state == "EDIT"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: (40-nameEdit.height)/2
|
||||
text: modelData.name;
|
||||
placeholderText: 'Enter a name'
|
||||
onTextChanged: modelData.name = text
|
||||
}
|
||||
|
||||
Text{
|
||||
anchors.right: sensorid.left
|
||||
visible: sensorViewItem.state == "EDIT"
|
||||
height: 40
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: "Delete"
|
||||
font.underline: true
|
||||
color: "#004275"
|
||||
width: 50
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
confirmDeletion.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Text{
|
||||
id: sensorid
|
||||
anchors.right: model.left
|
||||
visible: sensorViewItem.state == "EDIT"
|
||||
height: 40
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: modelData.id
|
||||
color: "#004275"
|
||||
width: 50
|
||||
}
|
||||
Text{
|
||||
id: model
|
||||
anchors.right: visibleinlistcheckbox.left
|
||||
visible: sensorViewItem.state == "EDIT"
|
||||
height: 40
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: modelData.model
|
||||
color: "#004275"
|
||||
width: 100
|
||||
}
|
||||
Item {
|
||||
id: visibleinlistcheckbox
|
||||
height: 40
|
||||
width: 100
|
||||
anchors.right: sensorInfo.left
|
||||
CheckBox {
|
||||
id: checkBox
|
||||
anchors.centerIn: parent
|
||||
width: checkBox.height
|
||||
visible: sensorViewItem.state == "EDIT"
|
||||
checked: modelData.showInList
|
||||
onClicked: modelData.setShowInList(!modelData.showInList)
|
||||
}
|
||||
}
|
||||
|
||||
BorderImage {
|
||||
source: "row_bg.png"
|
||||
border.left: 5; border.top: 5
|
||||
border.right: 5; border.bottom: 5
|
||||
height: sensorInfo.height
|
||||
width: parent.width
|
||||
|
||||
Text {
|
||||
visible: main.state == "VIEW"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
height: 40
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: modelData.name == '' ? '<unnamed>' : modelData.name;
|
||||
color: "#004275"
|
||||
Column {
|
||||
id: sensorInfo
|
||||
anchors.right: parent.right
|
||||
width: 250
|
||||
SensorValue {
|
||||
visible: modelData.hasTemperature
|
||||
text: visible ? modelData.sensorValue(1).value + '°C' : ''
|
||||
icon: "icon_temp.png"
|
||||
lastUpdated: visible ? modelData.sensorValue(1).lastUpdated : new Date()
|
||||
}
|
||||
TextField {
|
||||
id: nameEdit
|
||||
visible: main.state == "EDIT"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 15
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: (40-nameEdit.height)/2
|
||||
text: modelData.name;
|
||||
placeholderText: 'Enter a name'
|
||||
}
|
||||
Text{
|
||||
anchors.right: model.left
|
||||
visible: main.state == "EDIT"
|
||||
height: 40
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: modelData.id
|
||||
color: "#004275"
|
||||
width: 50
|
||||
}
|
||||
Text{
|
||||
id: model
|
||||
anchors.right: visibleinlistcheckbox.left
|
||||
visible: main.state == "EDIT"
|
||||
height: 40
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: modelData.model
|
||||
color: "#004275"
|
||||
width: 100
|
||||
}
|
||||
Item {
|
||||
id: visibleinlistcheckbox
|
||||
height: 40
|
||||
width: 100
|
||||
anchors.right: sensorInfo.left
|
||||
CheckBox {
|
||||
id: checkBox
|
||||
anchors.centerIn: parent
|
||||
width: checkBox.height
|
||||
visible: main.state == "EDIT"
|
||||
checked: modelData.showInList
|
||||
onClicked: modelData.setShowInList(!modelData.showInList)
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: sensorInfo
|
||||
anchors.right: parent.right
|
||||
width: 250
|
||||
SensorValue {
|
||||
visible: modelData.hasTemperature
|
||||
text: visible ? modelData.sensorValue(1).value + '°C' : ''
|
||||
icon: "icon_temp.png"
|
||||
lastUpdated: visible ? modelData.sensorValue(1).lastUpdated : new Date()
|
||||
}
|
||||
SensorValue {
|
||||
visible: modelData.hasHumidity
|
||||
text: visible ? modelData.sensorValue(2).value + '%' : ''
|
||||
icon: "icon_humidity.png"
|
||||
lastUpdated: visible ? modelData.sensorValue(2).lastUpdated : new Date()
|
||||
}
|
||||
SensorValue {
|
||||
visible: modelData.hasHumidity
|
||||
text: visible ? modelData.sensorValue(2).value + '%' : ''
|
||||
icon: "icon_humidity.png"
|
||||
lastUpdated: visible ? modelData.sensorValue(2).lastUpdated : new Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dialog{
|
||||
id: confirmDeletion
|
||||
modal: true
|
||||
title: "Confirm deletion"
|
||||
Text{
|
||||
id: descriptionHeadline
|
||||
text:"Delete this sensor?"
|
||||
font.bold: true
|
||||
}
|
||||
Text{
|
||||
id: descriptionText
|
||||
anchors.top: descriptionHeadline.bottom
|
||||
anchors.topMargin: 10
|
||||
width: parent.width - 20
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
text: "Please note that a sensor that is still transmitting will reappear here again, but it will be hidden in the list by default."
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
deleteSensor.callWith(modelData.protocol, modelData.model, modelData.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,13 @@ __postInit__ = function() {
|
|||
}
|
||||
|
||||
com.telldus.sensors = function() {
|
||||
var sensorList = new com.telldus.qml.array();
|
||||
|
||||
var sensorList;
|
||||
function init() {
|
||||
var sensorData = 0;
|
||||
sensorList = loadSensorModel();
|
||||
sensorList.rowsRemoved.connect(function(){saveSensorModel();});
|
||||
sensorList.rowsInserted.connect(function(){saveSensorModel();});
|
||||
|
||||
while(sensorData = com.telldus.core.sensor()) {
|
||||
var p = sensorData["protocol"];
|
||||
var m = sensorData["model"];
|
||||
|
@ -19,7 +22,7 @@ com.telldus.sensors = function() {
|
|||
var tryFetchValue = function(p, m, id, types, type) {
|
||||
if (types & type) {
|
||||
sensorValue = com.telldus.core.sensorValue(p, m, id, type);
|
||||
sensorEvent(p, m, id, type, sensorValue["value"], sensorValue["timestamp"]);
|
||||
sensorEvent(p, m, id, type, sensorValue["value"], sensorValue["timestamp"], true);
|
||||
}
|
||||
}
|
||||
tryFetchValue(p, m, id, types, com.telldus.core.TELLSTICK_TEMPERATURE);
|
||||
|
@ -28,14 +31,94 @@ com.telldus.sensors = function() {
|
|||
}
|
||||
|
||||
com.telldus.core.sensorEvent.connect(sensorEvent);
|
||||
view = new com.telldus.qml.view({});
|
||||
view = new com.telldus.qml.view({
|
||||
deleteSensor: deleteSensor
|
||||
});
|
||||
|
||||
view.setProperty('sensorModel', sensorList);
|
||||
saveSensorModel();
|
||||
view.load("main.qml");
|
||||
application.addWidget("sensors.gui", "icon.png", view);
|
||||
}
|
||||
|
||||
function sensorEvent(protocol, model, id, dataType, value, timestamp) {
|
||||
function createSensor(protocol, model, id, name, showInList){
|
||||
var sensor = new com.telldus.sensors.sensor();
|
||||
sensor.protocol = protocol;
|
||||
sensor.model = model;
|
||||
sensor.id = id;
|
||||
sensor.name = name;
|
||||
sensor.nameChanged.connect(function() { saveSensorModel(); });
|
||||
sensor.showInList = showInList;
|
||||
sensor.showInListChanged.connect(function() { saveSensorModel(); });
|
||||
return sensor;
|
||||
}
|
||||
|
||||
function deleteSensor(protocol, model, id){
|
||||
var i = 0;
|
||||
var found = false;
|
||||
for (; i < sensorList.length; ++i) {
|
||||
if (sensorList.get(i).protocol != protocol) {
|
||||
continue;
|
||||
}
|
||||
if (sensorList.get(i).model != model) {
|
||||
continue;
|
||||
}
|
||||
if (sensorList.get(i).id != id) {
|
||||
continue;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if(found){
|
||||
sensorList.removeLater(i);
|
||||
}
|
||||
}
|
||||
|
||||
function loadSensorModel(){
|
||||
var settings = new com.telldus.settings();
|
||||
var sensors = new com.telldus.qml.array();
|
||||
|
||||
var sensorProperties = settings.value("sensors", "");
|
||||
if(sensorProperties){
|
||||
for (var i = 0; i < sensorProperties.length; i++) {
|
||||
var sensor = createSensor(sensorProperties[i].protocol, sensorProperties[i].model, sensorProperties[i].id, sensorProperties[i].name, sensorProperties[i].showInList=="true");
|
||||
for (var j = 0; j < sensorProperties[i].values.length; j++) {
|
||||
sensor.setValue(sensorProperties[i].values[j].type, sensorProperties[i].values[j].value, sensorProperties[i].values[j].lastUpdated)
|
||||
}
|
||||
sensors.push(sensor);
|
||||
}
|
||||
}
|
||||
return sensors;
|
||||
}
|
||||
|
||||
function saveSensorModel(){
|
||||
var settings = new com.telldus.settings();
|
||||
var sensorProperties = new Array();
|
||||
|
||||
for (var i = 0; i < sensorList.length; ++i) {
|
||||
var sensor = sensorList.get(i);
|
||||
|
||||
var allValues = new Array();
|
||||
if(sensor.hasHumidity){
|
||||
var sensorValue = sensor.sensorValue(com.telldus.core.TELLSTICK_HUMIDITY);
|
||||
var value = {type: com.telldus.core.TELLSTICK_HUMIDITY, lastUpdated: sensorValue.lastUpdated, value: sensorValue.value};
|
||||
allValues.push(value);
|
||||
}
|
||||
if(sensor.hasTemperature){
|
||||
var sensorValue = sensor.sensorValue(com.telldus.core.TELLSTICK_TEMPERATURE);
|
||||
var value = {type: com.telldus.core.TELLSTICK_TEMPERATURE, lastUpdated: sensorValue.lastUpdated, value: sensorValue.value};
|
||||
allValues.push(value);
|
||||
}
|
||||
|
||||
var sensorProp = {protocol:sensor.protocol, model:sensor.model, id:sensor.id, values:allValues, name:sensor.name, showInList:sensor.showInList};
|
||||
sensorProperties.push(sensorProp);
|
||||
}
|
||||
|
||||
settings.setValue("sensors", sensorProperties);
|
||||
}
|
||||
|
||||
function sensorEvent(protocol, model, id, dataType, value, timestamp, avoidSave) {
|
||||
|
||||
var sensor = 0;
|
||||
for (var i = 0; i < sensorList.length; ++i) {
|
||||
if (sensorList.get(i).protocol != protocol) {
|
||||
|
@ -52,19 +135,15 @@ com.telldus.sensors = function() {
|
|||
}
|
||||
|
||||
if (!sensor) {
|
||||
sensor = new com.telldus.sensors.sensor();
|
||||
sensor.protocol = protocol;
|
||||
sensor.model = model;
|
||||
sensor.id = id;
|
||||
sensor.showInList = false;
|
||||
sensor = createSensor(protocol, model, id, "", false);
|
||||
sensorList.push(sensor);
|
||||
print("Create new");
|
||||
} else {
|
||||
print("Update");
|
||||
}
|
||||
|
||||
print("Sensor event", protocol, model, id, dataType, value, timestamp);
|
||||
sensor.setValue(dataType, value, timestamp);
|
||||
|
||||
if(!avoidSave){
|
||||
saveSensorModel();
|
||||
}
|
||||
}
|
||||
|
||||
return { //Public functions
|
||||
|
|
|
@ -17,6 +17,7 @@ Sensor::Sensor(QObject *parent) :
|
|||
{
|
||||
d = new PrivateData;
|
||||
d->id = 0;
|
||||
d->showInList = false;
|
||||
}
|
||||
|
||||
Sensor::~Sensor() {
|
||||
|
@ -50,6 +51,9 @@ QString Sensor::name() const {
|
|||
}
|
||||
|
||||
void Sensor::setName(const QString &name) {
|
||||
if (name == d->name) {
|
||||
return;
|
||||
}
|
||||
d->name = name;
|
||||
emit nameChanged();
|
||||
}
|
||||
|
@ -67,7 +71,7 @@ bool Sensor::hasTemperature() const {
|
|||
return d->values.contains(TELLSTICK_TEMPERATURE);
|
||||
}
|
||||
|
||||
SensorValue * Sensor::sensorValue(int type) {
|
||||
QObject * Sensor::sensorValue(int type) {
|
||||
return (d->values.contains(type) ? d->values[type] : 0);
|
||||
}
|
||||
|
||||
|
@ -90,7 +94,6 @@ void Sensor::setValue(int type, const QString &value, const QDateTime ×tamp
|
|||
}
|
||||
|
||||
bool Sensor::showInList() const{
|
||||
//TODO showInList and name must be persistent...
|
||||
return d->showInList;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ class Sensor : public QObject
|
|||
Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged)
|
||||
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString protocol READ protocol WRITE setProtocol NOTIFY protocolChanged)
|
||||
Q_PROPERTY(bool showInList READ showInList NOTIFY showInListChanged)
|
||||
Q_PROPERTY(bool showInList READ showInList WRITE setShowInList NOTIFY showInListChanged)
|
||||
|
||||
public:
|
||||
explicit Sensor(QObject *parent = 0);
|
||||
|
@ -32,7 +32,6 @@ public:
|
|||
void setModel(const QString &model);
|
||||
|
||||
QString name() const;
|
||||
//void setName(const QString &name);
|
||||
|
||||
QString protocol() const;
|
||||
void setProtocol(const QString &protocol);
|
||||
|
@ -40,7 +39,7 @@ public:
|
|||
bool hasTemperature() const;
|
||||
bool showInList() const;
|
||||
|
||||
Q_INVOKABLE SensorValue *sensorValue(int type);
|
||||
Q_INVOKABLE QObject *sensorValue(int type);
|
||||
Q_INVOKABLE void setValue(int type, const QString &value, const QDateTime ×tamp);
|
||||
Q_INVOKABLE void setName(const QString &name);
|
||||
Q_INVOKABLE void setShowInList(bool show);
|
||||
|
|
|
@ -26,10 +26,12 @@ void Settings::setValue( const QString & key, const QVariant & value ) {
|
|||
d->s.beginGroup(key);
|
||||
d->s.setValue("size", list.size());
|
||||
d->s.setValue("type", "array");
|
||||
//d->s.beginWriteArray("list"); //TODO write or read? What prefix?
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
d->s.setArrayIndex(i);
|
||||
//d->s.setArrayIndex(i);
|
||||
this->setValue(QString::number(i), list.at(i));
|
||||
}
|
||||
//d->s.endArray();
|
||||
d->s.endGroup();
|
||||
|
||||
} else if (value.type() == QVariant::Map) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue