Grundriss mit Canvas

Begonnen von Patrick85, 16 Juni 2017, 22:20:10

Vorheriges Thema - Nächstes Thema

Patrick85

Hallo zusammen,
ich bin gerade dabei ein eigenes Widget zu erstellen, das den Grundriss meiner Wohnung grafisch darstellt und zusätzlich einige Sensorwerte in den entsprechenden Raum schreibt. Zudem wird bei aktiver Heizung der Raum rot eingefärbt. Eine 1. Version  funktioniert bereits, nur die Übergabe der einzelnen Werte an das Widget ist sehr umständlich. Dazu verwende ich ein Dummy das pro Wert ein UserReading hat (benötige ca. 25 Werte). Diese muss ich bei der Tablet UI Definition alle einzeln übergeben (data-get, data-get2, data-get3 usw.). Ich bin mir relativ sicher, dass es hier eine bessere Lösung gibt. Vielleicht kann mir jemand von den Widgetspezialisten einen Tipp geben?

Dummy mit UserReadings
define canvas_values dummy
attr   canvas_values room AVR


Notifys aktualisieren UserReadings
define n_grundriss_temperature notify AVR_EG_PD.*:temperature.* { fhem "setreading canvas_values $NAME.temperature $EVTPART1" }
define n_grundriss_humidity    notify AVR_EG_PD.*:humidity.*    { fhem "setreading canvas_values $NAME.humidity $EVTPART1" }
define n_grundriss_heating     notify AVR_EG_PC.*               { fhem "setreading canvas_values $NAME.heating $EVTPART0" }


Beispiel UserReadings von Dummy canvas_values





AVR_EG_PD3.temperature 23.4
AVR_EG_PD3.humidity53.4
AVR_EG_PC3.heatingoff

Widget in TabletUI einbinden (umständlich, da pro Wert ein eigene Parameter verwendet wird)
<div data-type="grundriss" data-device="canvas_values" data-get="AVR_EG_PD3.temperature" data-get2="AVR_EG_PD3.humidity" data-get3="AVR_EG_PC3.heating">

Auszug aus widget_grundriss.js - gesamte Datei im Anhang  (umständlich, da pro Wert ein eigener Abschnitt benötigt wird)
Pro Wert zur Zeit ein eigener Abschnitt mit filterDeviceReading

me.elements.filterDeviceReading('get', dev, par)
.each(function (index) {
var elem = $(this);
var value = elem.getReading('get').val;

if (value) {
value1 = value;
draw(elem);
}
});

me.elements.filterDeviceReading('get2', dev, par)
.each(function (index) {
var elem = $(this);
var value = elem.getReading('get2').val;

if (value) {
value2 = value;
draw(elem);
}
});

me.elements.filterDeviceReading('get3', dev, par)
.each(function (index) {
var elem = $(this);
var value = elem.getReading('get3').val;

if (value) {
value3 = value;
draw(elem);
}
});


lg
Patrick

setstate

Grundsätzlich passt das alles und ich sehen kein Optimierungspotential.

Außer dass das Widget-Konzept hier nicht ganz passt.

Ein Widget ist mehr ein einzelnes, atomares, wiederverwendbares Control, was mehrfach auf der Oberfläche vorkommen kann (me.elements.... .each(function (index) ...).

Für mich klingt dein Ansinnen eher nach einem kompletten Floorplan, der nur für eine Wohnung zu geschnitten ist. Oder gibt es noch hunderte andere Parameter, die die Räume und die Lage der Werte definieren?

Man würde doch vielmehr seinen individuellen Grundriss als Basis seiner Page anzeigen und dann viele kleine Widgets platzieren, die die Werte und was auch immer anzeigen. Zum Beispiel Label für Temperaturen, Symbols für Lampen und ganze Räume einfärben per Classchanger.

Dann muss man das Zeichnen natürlich per SVG anstatt Canvas machen, damit die Elemente per CSS ansprechbar bleiben.

Patrick85



Hallo setstate,
ZitatGrundsätzlich passt das alles und ich sehen kein Optimierungspotential.
danke für die Info. Dass da Widget Konzept hier nicht ganz richtig ist, habe ich mir schon gedacht. Ich habe aufgrund meiner beschränken Kenntnisse keine anderen Weg gefunden.

ZitatOder gibt es noch hunderte andere Parameter, die die Räume und die Lage der Werte definieren?
Nein, die Koordinaten der Räume werden direkt im Widget eingetragen und per Canvas dargestellt. Ich verwende absichtlich keinen Grundriss als Hintergrundbild, da ich das ganze dynamisch gestaltet will. Zum Beispiel sollen Fenster abhängig vom Zustand offen oder geschlossen sein.

lg
Patrick

Standarduser

Zitat von: Patrick85 am 16 Juni 2017, 22:20:10
ich bin gerade dabei ein eigenes Widget zu erstellen, das den Grundriss meiner Wohnung grafisch darstellt und zusätzlich einige Sensorwerte in den entsprechenden Raum schreibt.

Könntest Du mal einen Screenshot posten, damit wir eine Vorstellung davon gewinnen können, wohin die Reise geht?
Unter Umständen ist das ja für den einen oder anderen interessant. Mich jedenfalls interessiert das, da ich an einer ähnlichen Lösung arbeite, jedoch mit Hintergrundbild und Standardwidgets.

Patrick85

ZitatKönntest Du mal einen Screenshot posten
gerne, das ist der aktuelle Stand. Es fehlen noch einige Details wie die Stiege.

phil82

Hi,

ich hab das mit einem Hintergrundbild und Standard-Widgets gelöst.
Ich hab einfach den Grundriss als Hintergrundbild genommen und diverse Widgets per HTML platziert. (Rolladen, Licht, Heizung, etc).
Devices mit mehreren Funktionen hab ich als Popup realisert. z.B. die Heizungssteuerung.
Dann noch ein erweiterbares Menü auf der linken Seite und wichtige Gruppen-Funktionen am rechten Rand.

Im Grund recht simpel. Wobei die ganzen Widgets, Icons, Button, Platzierungen, Formatierung etc. schon etwas arbeit machen.
Das ganze lässt sich auch recht einfach erweitern, da jedes Devices einzeln gesehen werden kann und per HTML auf dem Grundriss plaziert wird.

Ich hab allerdings keine eingefärbten Räume. Das Hintergrundbild ist fest.

Gruß
Philipp

MrJackBlack

Hallo Phil82,

würdest du uns deinen Code zum Einbinden des Hintergrundbildes und dem Platzieren der Widgets teilen? Ich versuche eigentlich genau das gleiche zu erreichen was ihr hier schon gemacht habt :)

Danke,

Andi
FHEM 5.8 mit Homebridge auf Intel NUC
HUE, LIGHTIFY, JeeLink, CC1101, haufen Lampen und Sensoren. Interface via TabletUI auf einem Android Tablet. Seit Neuestem auch ein Landroid S über FHEM  angesteuert

phil82

Hallo Andi,

das Hintergrundbild hab ich einfach per HTML eingefügt:
<div style="background-image: url('myfiles/floorplanWohnung.png'); background-repeat: no-repeat; height: 713px;" ></div>
Das Bild ist ein einfacher Grundriss meiner Wohnung mit Wänden, angedeuteten Türen und Fenstern.

Die einzelnen Widgets werden per CSS positioniert:
<!-- Arbeitszimmer - Rolllade mit Fensterkontakt-->

<div data-type='symbol' data-device='hwAzFensterRechts' class='ty_fensterkontakt' style='position:absolute; top: 78px; left: 68px;'
data-states='["closed", "open"]' data-icons='["", ""]'
data-background-icons='["fa-square", "fa-square"]' data-colors='["#e6e6e6", "#e6e6e6"]'
data-background-colors='["#444", "#bd4036"]'></div>

<div data-device='hwAzRollade' data-type='switch'  class='ty_rolladen' style='position:absolute; top: 78px; left: 68px;'
data-get-on='hoch' data-get-off='runter'
data-states='["hoch", "runter", ".*"]' data-icons='["oa-fts_window_2w", "oa-fts_shutter_100", "oa-fts_shutter"]'
data-background-icon='' data-on-color='rgb(255, 255, 255)' data-off-color='rgb(255, 255, 255)'></div>

In dem Beispiel sind es zwei Widgets:
1. Einfaches Symbol für den Fensterkontakt: grau = Fenster zu; rot = Fenster auf
2. Switch für die Rollade: je nach Position wird ein anders Icon verwendet
Beide Widgets sind an der gleichen Position und nur übereinander gelegt, sodass das wie ein Widget aussieht.

Grundlegende Formatierungen erledigt ich per CSS und HTML. Jeder "Aktor" oder "Device" hat bei mir eine CSS-Klasse. z.B. "ty_fensterkontakt" und wird dort entsprechend formatiert:
.ty_fensterkontakt {
    font-size: 1.9em;
    width: 1.9em;
    height: 1.9em;
    line-height: 1.9em;
}

Die Positionsierung erfolgt per Style-Angabe style='position:absolute; top: 78px; left: 68px;'
Also im Grund "relativ" einfach.


Die Hauptfunktionen (Modus, Zentralsteuerung der Rolladen, etc.) auf der rechten Seite sind einfache HTML-Tabellen mit Button-Widgets, die per Style-Angabe positioniert wurden.
Das Menü auf dem 3. Screenshot ist per Link-Widget realisiert. - Siehe Beispiel vom FHEM.
Außerdem habe ich mehrere Popups im Einsatz, um Zusatzfunktionen bereitzustellen - siehe 2. Screenshot.

Das TabletUI wird bei mir vom Apache ausgeliefert. Dort verwende ich PHP, um eine Wiederverwendbarkeit zu ermöglichen. Ich hab mir ein paar kleine PHP-Funktionen programmiert, die den HTML-Code für gewisse Aktoren bereitstellen. z.B. für die Rolladen mit Fensterkontakt oder für die Heizungssteuerung (ist ja immer das Gleiche, nur unterschiedlichen Fhem-Device und unterschiedliche Positionen). Dies ist für Realisierung aber unerheblich.

Gruß
Philipp

MrJackBlack

@ phil82:

Nett! Jetzt muss nur noch schlechtes Wetter kommen und das Wochenende ist gesichert :D


Danke!
FHEM 5.8 mit Homebridge auf Intel NUC
HUE, LIGHTIFY, JeeLink, CC1101, haufen Lampen und Sensoren. Interface via TabletUI auf einem Android Tablet. Seit Neuestem auch ein Landroid S über FHEM  angesteuert