Skip to content

Commit

Permalink
Add rows on dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
javalikescript committed Oct 22, 2022
1 parent 7b1f4be commit fcf1356
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 96 deletions.
3 changes: 3 additions & 0 deletions extensions/web-base/www/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ article.tiles, .tile-container {
padding: 1rem;
width: 100%;
}
.tile-row {
width: 100%;
}
.tile {
height: 18rem;
width: 18rem;
Expand Down
111 changes: 64 additions & 47 deletions extensions/web-dashboard/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,80 @@
"schema": {
"type": "object",
"properties": {
"tiles": {
"title": "Tiles",
"rows": {
"title": "Rows",
"type": "array",
"items": {
"title": "Tile",
"title": "Row",
"type": "object",
"properties": {
"title": {
"title": "Title",
"type": "string"
},
"type": {
"title": "The property type",
"type": "string",
"enumValues": [
{"const": "AlarmProperty", "title": "Alarm"},
{"const": "ApparentPowerProperty", "title": "Apparent Power"},
{"const": "BarometricPressureProperty", "title": "Barometric Pressure"},
{"const": "BooleanProperty", "title": "Boolean"},
{"const": "CurrentProperty", "title": "Current"},
{"const": "HumidityProperty", "title": "Humidity"},
{"const": "LeakProperty", "title": "Leak"},
{"const": "LevelProperty", "title": "Level"},
{"const": "LockedProperty", "title": "Locked"},
{"const": "MotionProperty", "title": "Motion"},
{"const": "OnOffProperty", "title": "On/Off"},
{"const": "OpenProperty", "title": "Open"},
{"const": "SmokeProperty", "title": "Smoke"},
{"const": "TemperatureProperty", "title": "Temperature"}
],
"enumValues-NotUsed": [
{"const": "BrightnessProperty", "title": "Brightness"},
{"const": "ColorModeProperty", "title": "Color Mode"},
{"const": "ColorProperty", "title": "Color"},
{"const": "ColorTemperatureProperty", "title": "Color Temperature"},
{"const": "ConcentrationProperty", "title": "Concentration"},
{"const": "DensityProperty", "title": "Density"},
{"const": "FrequencyProperty", "title": "Frequency"},
{"const": "HeatingCoolingProperty", "title": "Heating Cooling"},
{"const": "ImageProperty", "title": "Image"},
{"const": "InstantaneousPowerFactorProperty", "title": "Instantaneous Power Factor"},
{"const": "InstantaneousPowerProperty", "title": "Instantaneous Power"},
{"const": "PushedProperty", "title": "Pushed"},
{"const": "TargetTemperatureProperty", "title": "Target Temperature"},
{"const": "ThermostatModeProperty", "title": "Thermostat Mode"},
{"const": "VideoProperty", "title": "Video"},
{"const": "VoltageProperty", "title": "Voltage"}
],
"default": "auto"
"required": true
},
"thingIds": {
"title": "Things",
"tiles": {
"title": "Tiles",
"type": "array",
"items": {
"title": "Thing Id",
"type": "string",
"enumVar": "thingIds"
"title": "Tile",
"type": "object",
"properties": {
"title": {
"title": "Title",
"type": "string",
"required": true
},
"type": {
"title": "The property type",
"type": "string",
"default": "LevelProperty",
"required": true,
"enumValues": [
{"const": "AlarmProperty", "title": "Alarm"},
{"const": "ApparentPowerProperty", "title": "Apparent Power"},
{"const": "BarometricPressureProperty", "title": "Barometric Pressure"},
{"const": "BooleanProperty", "title": "Boolean"},
{"const": "CurrentProperty", "title": "Current"},
{"const": "HumidityProperty", "title": "Humidity"},
{"const": "LeakProperty", "title": "Leak"},
{"const": "LevelProperty", "title": "Level"},
{"const": "LockedProperty", "title": "Locked"},
{"const": "MotionProperty", "title": "Motion"},
{"const": "OnOffProperty", "title": "On/Off"},
{"const": "OpenProperty", "title": "Open"},
{"const": "SmokeProperty", "title": "Smoke"},
{"const": "TemperatureProperty", "title": "Temperature"}
],
"enumValues-NotUsed": [
{"const": "BrightnessProperty", "title": "Brightness"},
{"const": "ColorModeProperty", "title": "Color Mode"},
{"const": "ColorProperty", "title": "Color"},
{"const": "ColorTemperatureProperty", "title": "Color Temperature"},
{"const": "ConcentrationProperty", "title": "Concentration"},
{"const": "DensityProperty", "title": "Density"},
{"const": "FrequencyProperty", "title": "Frequency"},
{"const": "HeatingCoolingProperty", "title": "Heating Cooling"},
{"const": "ImageProperty", "title": "Image"},
{"const": "InstantaneousPowerFactorProperty", "title": "Instantaneous Power Factor"},
{"const": "InstantaneousPowerProperty", "title": "Instantaneous Power"},
{"const": "PushedProperty", "title": "Pushed"},
{"const": "TargetTemperatureProperty", "title": "Target Temperature"},
{"const": "ThermostatModeProperty", "title": "Thermostat Mode"},
{"const": "VideoProperty", "title": "Video"},
{"const": "VoltageProperty", "title": "Voltage"}
]
},
"thingIds": {
"title": "Things",
"type": "array",
"items": {
"title": "Thing Id",
"type": "string",
"enumVar": "thingIds"
}
}
}
}
}
}
Expand Down
89 changes: 52 additions & 37 deletions extensions/web-dashboard/web-dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,38 @@ define(['./web-dashboard.xml'], function(dashboardTemplate) {
}
}

function processTile(tileDef, things, properties) {
var type = tileDef.type;
var values = [];
var paths = [];
forEachPropertyType(things, type, function(thing, thingId, property, propertyName) {
if (thing.archiveData && !property.configuration) {
paths.push(thingId + '/' + propertyName);
}
var props = properties[thingId];
if (props && isValidValue(props[propertyName])) {
values.push(props[propertyName]);
}
}, tileDef.thingIds);
var value = undefined;
if (values.length > 0) {
var valueType = typeof values[0];
if (valueType === 'number') {
value = values.reduce(function(s, v) { return s + v; }, 0) / values.length
} else if (valueType === 'boolean') {
value = values.indexOf(true) >= 0;
}
}
//console.log('value: ' + value + ', type: ' + type, values);
return assignMap({}, tileDef, {
title: oneOf(tileDef.title, type, 'n/a'),
paths: paths,
count: values.length,
value: value,
unit: formatUnit(unitByType[type])
});
}

var extensionId = 'web-dashboard';
var extensionName = 'Dashboard';

Expand All @@ -122,7 +154,7 @@ define(['./web-dashboard.xml'], function(dashboardTemplate) {
config: {},
things: [],
properties: {},
tiles: [],
rows: [],
lastChange: null,
changeTimer: null
},
Expand Down Expand Up @@ -162,46 +194,29 @@ define(['./web-dashboard.xml'], function(dashboardTemplate) {
},
processThings: function(config, things, properties) {
//console.log('processThings()', config, things, properties);
var tiles = [];
var tilesDef = config.tiles;
if (tilesDef) {
for (var i = 0; i < tilesDef.length; i++) {
var tileDef = tilesDef[i];
var type = tileDef.type;
var values = [];
var paths = [];
forEachPropertyType(things, type, function(thing, thingId, property, propertyName) {
if (thing.archiveData && !property.configuration) {
paths.push(thingId + '/' + propertyName);
}
var props = properties[thingId];
if (props && isValidValue(props[propertyName])) {
values.push(props[propertyName]);
}
}, tileDef.thingIds);
var value = undefined;
if (values.length > 0) {
var valueType = typeof values[0];
if (valueType === 'number') {
value = values.reduce(function(s, v) { return s + v; }, 0) / values.length
} else if (valueType === 'boolean') {
value = values.indexOf(true) >= 0;
var rows = [];
var rowsDef = config.rows;
if (rowsDef) {
for (var i = 0; i < rowsDef.length; i++) {
var rowDef = rowsDef[i];
var tilesDef = rowDef.tiles;
if (tilesDef) {
var tiles = [];
for (var j = 0; j < tilesDef.length; j++) {
var tileDef = tilesDef[j];
var tile = processTile(tileDef, things, properties);
//console.log('tile', JSON.stringify(tile, undefined, 2), JSON.stringify(tileDef, undefined, 2));
tiles.push(tile);
}
rows.push({
title: oneOf(rowDef.title, 'n/a'),
tiles: tiles
});
}
//console.log('value: ' + value + ', type: ' + type, values);
var tile = assignMap({}, tileDef, {
title: oneOf(tileDef.title, type, 'n/a'),
paths: paths,
count: values.length,
value: value,
unit: formatUnit(unitByType[type])
});
//console.log('tile', JSON.stringify(tile, undefined, 2), JSON.stringify(tileDef, undefined, 2));
tiles.push(tile);
}
}
//console.log('tiles', JSON.stringify(tiles, undefined, 2));
this.tiles = tiles;
//console.log('rows', JSON.stringify(rows, undefined, 2));
this.rows = rows;
this.lastChange = new Date();
if (this.changeTimer) {
window.clearTimeout(this.changeTimer);
Expand Down
29 changes: 17 additions & 12 deletions extensions/web-dashboard/web-dashboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@
<button v-on:click="toggleFullScreen()" title="Refresh"><i class="fas fa-expand-alt"></i></button>
<button v-on:click="onShow()" title="Refresh"><i class="fas fa-sync"></i></button>
</template>
<article class="tiles">
<div class="tile" v-on:click="onTileClicked(tile)" v-for="tile in tiles">
<div class="bar">
<span>{{ tile.title }}</span>
<div>
<button v-if="tile.paths.length > 0" v-on:click="openHistoricalData(tile.paths)"><i class="fas fa-chart-line"></i></button>
</div>
<article>
<div class="tile-container" v-for="row in rows">
<div class="tile-row">
<h1>{{ row.title }}</h1>
</div>
<p class="tile-value" v-if="typeof tile.value === 'boolean'"><i :class="['fas', formatValue(tile)]"></i></p>
<p class="tile-value" v-else>{{ formatValue(tile) }}</p>
<div class="bar">
<div/>
<span>{{ tile.unit }}</span>
<div class="tile" v-on:click="onTileClicked(tile)" v-for="tile in row.tiles">
<div class="bar">
<span>{{ tile.title }}</span>
<div>
<button v-if="tile.paths.length > 0" v-on:click="openHistoricalData(tile.paths)"><i class="fas fa-chart-line"></i></button>
</div>
</div>
<p class="tile-value" v-if="typeof tile.value === 'boolean'"><i :class="['fas', formatValue(tile)]"></i></p>
<p class="tile-value" v-else>{{ formatValue(tile) }}</p>
<div class="bar">
<div/>
<span>{{ tile.unit }}</span>
</div>
</div>
</div>
</article>
Expand Down

0 comments on commit fcf1356

Please sign in to comment.