FTUI eigene Widgets - Beispiel
FTUI eigene Widgets - Schritt für Schritt Beispiel
Wir werden nun unser erstes eigenes FTUI Widget Schritt für Schritt erstellen. Es wird unterstellt das FTUI eigene Widgets bereits gelesen wurde.
Als Grundgerüst dient FTUI eigene Widgets und daraus bauen wir nun unser neues Widget.
Name | widget_abfall.js |
---|---|
Funktion | Die Anzeige von Müllabfuhrdaten aus einer .ics Datei |
Fhem-Modul | Calendar |
Als erstes benennen wir das widget um und fügen einen Copyright Vermerk hinzu.
aus:
var Modul_mywidget = function () {
widgetname: 'mywidget',
wird:
/* FTUI Plugin
* Copyright (c) 2018 by Bruchbude
* Under MIT License (http://www.opensource.org/licenses/mit.license.php)
*/
var Modul_abfall = function () {
widgetname: 'abfall',
Wir erstellen einen Calender Eintrag für unsere Abfalldaten. Dazu geben wir in der fhem Kommandozeile folgendes ein:
define Abfallkalender Calendar ical file /opt/fhem/www/tablet/abfallkalender.ics
Die Datei wird von Hand runtergeladen (die diversen Städte unterscheiden sich hier, weshalb wir erstmal alles von Hand machen) und in das entsprechende Verzeichnis kopiert.
Nun auf der linux Kommandozeile die Dateirechte setzen:
sudo chown fhem:dialout /opt/fhem/www/tablet/abfallkalender.ics
Später wird der download per knopfdruck erfolgen.
Nun erstellen wir einen Eintrag in unserer .html Datei
<li data-col="6" data-row="1" data-sizex="1" data-sizey="3">
<div class="cell" data-type="abfall" data-device="Abfallkalender" data-detail='["Grau","Blau","Gelb","Braun"]'></div>
</li>
Als nächstes sehen wir im Abfallkalender-Modul nach welches Reading wir benötigen.
Die Daten befinden sich in modeUpcoming welches wir in unserem Modul in der init() funktion wie folgt eintragen:
elem.initData('get', 'STATE');
me.addReading(elem, 'get');
wird zu:
elem.initData('modeUpcoming', 'modeUpcoming');
me.addReading(elem, 'modeUpcoming'); // update() wird aufgerufen wenn modeUpcoming sich ändert
Dazu kommt eine Änderung in der update() Funktion:
me.elements.filterDeviceReading('get', device, reading)
var value = elem.getReading('get').val;
wird zu:
me.elements.filterDeviceReading('modeUpcoming', device, reading)
var value = elem.getReading('modeUpcoming').val;
Dann bauen wir noch eine Ausgabe ein um zu sehen ob alles funktioniert. Damit sieht unser Modul so aus:
/* FTUI Plugin
* Copyright (c) 2018 by Bruchbude
* Under MIT License (http://www.opensource.org/licenses/mit.license.php)
*/
var Modul_abfall = function () {
function init() {
me.elements = $('div[data-type="' + me.widgetname + '"]', me.area);
me.elements.each(function (index) {
var elem = $(this);
elem.initData('modeUpcoming', 'modeUpcoming');
me.addReading(elem, 'modeUpcoming');
});
}
function update(device, reading) {
me.elements.filterDeviceReading('modeUpcoming', device, reading)
.each(function (index) {
var elem = $(this);
var value = elem.getReading('modeUpcoming').val;
if (value) {
alert(value);
//elem.html(value);
}
});
}
var me = $.extend(new Modul_widget(), {
widgetname: 'abfall',
init: init,
update: update,
});
return me;
};
Jetzt bauen wir das parsing für die calendar daten ein. Die Calendar Daten sehen so aus:
20181211GraueTonnegdabfallkalender
...getrennt durch ein Semikolon. Das Datum nehmen wir für die Berechnung der Tage und die Farbe zur Unterscheidung der Tonnen. Der Rest des Strings interessiert uns nicht.
function update(device, reading) {
me.elements.filterDeviceReading('modeUpcoming', device, reading).each(function (index){
var elem = $(this);
var value = elem.getReading('modeUpcoming').val;
if (!value) return; // error: no data found in calendar modul
var strArray = value.split(";");
strArray.sort(); // just to be sure all is sorted
var today = new Date();
today = parseInt(today.yyyymmdd().replace(/-/g,"")); // delete all "-" and convert to int
alert("grau: "+ getDaysToEmpty(strArray, "Grau", today) );
getDaysToEmpty(strArray, "Blau", today);
getDaysToEmpty(strArray, "Gelb", today);
getDaysToEmpty(strArray, "Braun", today);
elem.html();
});
}
Die Funktion getDaysToEmpty() sieht so aus:
//////////////////////////////////////////////////////////////////////////////
// Get the number of days until garbage collection
//////////////////////////////////////////////////////////////////////////////
function getDaysToEmpty(array, wasteColor, today){
var waste = array.filter(s => s.includes(wasteColor)); // get all dates for the selected waste container
for (var i =0; i< waste.length; ++i)
{
if (parseInt(waste[i]) >= today) // we need nothing from the past
return parseInt(waste[i]) - today;
}
return -1; // error
}
Jetzt da wir wissen wie lange es noch dauert bis die Müllabfuhr kommt können wir ein wenig html bauen
//////////////////////////////////////////////////////////////////////////////
// Draw an icon
//////////////////////////////////////////////////////////////////////////////
function addIcon(days, vertical, colorCircle, colorWaste)
{
var myHtml= "<div class='famultibutton fa-stack fa-2x' onclick='this.childNodes[1].classList.remove(\"blink\")'>"
myHtml+= "<i id='bg' class='fa fa-stack-2x fa-circle-thin' style='color: "+colorCircle+";'></i>"
myHtml+= "<i id='fg' class='fa fa-stack-1x fa-trash warn" + (days <2?' blink':'') + "' style='color: "+colorWaste+";'></i>"
myHtml+= "<i id='warn'>"+ days +"</i></div>" + (vertical?"<br>":"");
return myHtml;
}