Man kennt das Problem, als ambitionierter Hobbyfotograf hat man tausende von Fotos auf seiner Festplatte rumliegen und sehen tut sie keiner.
Dabei wäre es doch ganz schön, wenn man die Fotos selbst und auch andere die mal zu Gesicht bekommen würden. Dafür gibt es z.B. picframe eine Software, die unter Linux läuft, bevorzugt auf einem Raspberry Pi oder Zero W und mit der man einen elektronischen DIY Bilderrahmen erstellen kann.
Damit ist es möglich eine Diashow abzuspielen, bei mir läuft das auf einem Raspi Pi Zero 2 W, der sollte es auch schon sein, ein W ist ein bisschen zu schwach auf der Brust. Per HDMI kann man dort einen beliebigen Monitor anschließen und mit allerhand Spielereien seine Fotos auf diesem wiedergeben. Versierte Bastler bauen dann aus dem Monitor einen Bilderrahmen.
Es soll hier aber nicht darum gehen, wie man picframe installiert, das steht auf der o.a. Webseite ausführlich beschrieben, sondern wie man picframe über MQTT und fhem steuern kann.
Was ich hier beschreibe bezieht sich auf die Developer Version v2-dev von picframe, die um einiges mächtiger ist als die erste Version von picframe, u.a. gibt es da ein Webinterface mit dem man picframe steuern kann. Das würde ja auch eigentlich ausreichen, ich wollte das aber gerne mit FTUI3, das auf einem Tablet läuft, steuern. Wie man das macht, davon handelt dieser Artikel.
Los geht’s mit einem fhem Device
Erstmal muss man ein fhem MQTT Device anlegen, Voraussetzung dafür ist ein MQTT2 Server, den man auch unter fhem einrichten kann. Wie das genau geht steht in der Doku zu fhem, ich zeige hier nur eine Liste der Attribute des Device, damit man sehen kann was alles eingestellt werden muss.
Attributes:
DbLogExclude .*
autocreate 1
readingList picframe:picframe/picframe/state:.* { json2nameValue($EVENT) }
picframe:picframe/picframe/media/state:.* { json2nameValue($EVENT) }
picframe:picframe/picframe/media/attributes:.* { json2nameValue($EVENT) }
picframe:picframe/picframe/availability:.* availability
picframe:picframe/picframe/display/state:.* {display=>lc($EVENT)}
picframe:picframe/picframe/brightness/state:.* {brightness=>lc($EVENT)}
picframe:picframe/picframe/shuffle/state:.* {shuffle=>lc($EVENT)}
picframe:picframe/picframe/clock/state:.* {clock=>lc($EVENT)}
picframe:picframe/picframe/text_overlay/state:.* {text_overlay=>lc($EVENT)}
picframe:picframe/picframe/time_delay/state:.* time_delay
picframe:picframe/picframe/fade_time/state:.* fade_time
picframe:picframe/picframe/mat_images/state:.* mat_images
picframe:picframe/picframe/subdirectory/state:.* subdirectory
picframe:picframe/picframe/date_from/state:.* date_from
picframe:picframe/picframe/date_to/state:.* date_to
picframe:picframe/picframe/location_filter/state:.* location_filter
picframe:picframe/picframe/tags_filter/state:.* tags_filter
picframe:picframe/picframe/text_overlay_format/state:.* text_overlay_format
picframe:picframe/picframe/shuffle_mode/state:.* shuffle_mode
picframe:picframe/picframe/text_on_video/state:.* state
room Geräte->Systeme->MQTT2
setList play:noArg {fhem("set mqtt2_server publish picframe/picframe/play/press PRESS")}
pause:noArg {fhem("set mqtt2_server publish picframe/picframe/pause/press PRESS")}
next:noArg {fhem("set mqtt2_server publish picframe/picframe/next/press PRESS")}
previous:noArg {fhem("set mqtt2_server publish picframe/picframe/previous/press PRESS")}
display:ON,OFF {fhem("set mqtt2_server publish picframe/picframe/display/set $EVTPART1")}
shuffle:ON,OFF {fhem("set mqtt2_server publish picframe/picframe/shuffle/set $EVTPART1")}
clock:ON,OFF {fhem("set mqtt2_server publish picframe/picframe/clock/set $EVTPART1")}
text_overlay:ON,OFF {fhem("set mqtt2_server publish picframe/picframe/text_overlay/set $EVTPART1")}
brightness:slider,0,0.05,1 {fhem("set mqtt2_server publish picframe/picframe/brightness/set $EVTPART1")}
time_delay:slider,1,1,400 {fhem("set mqtt2_server publish picframe/picframe/time_delay/set $EVTPART1")}
fade_time:slider,1,1,50 {fhem("set mqtt2_server publish picframe/picframe/fade_time/set $EVTPART1")}
mat_images:slider,0,0.01,1 {fhem("set mqtt2_server publish picframe/picframe/mat_images/set $EVTPART1")}
shuffle_mode:standard,fewer_repeats {fhem("set mqtt2_server publish picframe/picframe/shuffle_mode/set $EVTPART1")}
subdirectory:textField {fhem("set mqtt2_server publish picframe/picframe/subdirectory/set $EVTPART1")}
date_from:textField {fhem("set mqtt2_server publish picframe/picframe/date_from/set $EVTPART1")}
date_to:textField {fhem("set mqtt2_server publish picframe/picframe/date_to/set $EVTPART1")}
location_filter:textField {fhem("set mqtt2_server publish picframe/picframe/location_filter/set $EVTPART1")}
tags_filter:textField {fhem("set mqtt2_server publish picframe/picframe/tags_filter/set $EVTPART1")}
text_overlay_format:textField {fhem("set mqtt2_server publish picframe/picframe/text_overlay_format/set $EVTPART1")}
userReadings image_url {
my $path = ReadingsVal($name, "filepath", "");
$path =~ s/([^A-Za-z0-9\-_.~\/])/sprintf("%%%02X", ord($1))/ge;
return "http://picframe.ip:9000/media?path=$path";
}
pciframe.ip ist die IP Adresse des Raspi auf dem picframe läuft.
Hat man das Device angelegt, kann man mit den entsprechenden Readings picframe steuern.
FTUI3 anlegen
So sieht das bei mir auf meinem Tablet aus:

Wie man sieht wird das Bild selbst und die entprechenden Infos zum Bild ausgegeben und man hat diverse Möglichkeiten die Ausgabe zu beeinflussen.
Es lassen sich aber nicht alle Einstellungen, die über die Weboberfläche gehen, per MQTT einstellen.
So sieht der entprechende Code für FTUI3 aus:
<ftui-tab-view id="picframe">
<!-- Bild, EXIF Daten -->
<ftui-grid-tile row="1" col="2" height="4" width="9" shape="round" class="semitransparent" padding="10px">
<ftui-row>
<!-- Bild -->
<ftui-column padding="1px">
<ftui-image width="400px" nocache refresh [src]="picframe:image_url
</ftui-image>
</ftui-column>
<!-- EXIF Daten -->
<ftui-column width="11%" padding="2px">
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Datei</ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Kamera</ftui-label>
</ftui-row>
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Modell</ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Brennweite</ftui-label>
</ftui-row>
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Zeit</ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Blende</ftui-label>
</ftui-row>
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Iso</ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label size="1">Location</ftui-label>
</ftui-row>
</ftui-column>
<ftui-column width="35%" padding="2px">
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:filename" size="0"></ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:items_1_make" size="1"></ftui-label>
</ftui-row>
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:model" size="1"></ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:focal_length | toInt()" size="1">
</ftui-label><ftui-label size="1"> mm</ftui-label>
</ftui-row>
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:exposure_time" size="1"></ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:f_number" size="1"></ftui-label>
</ftui-row>
<ftui-row color="gray" align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:iso" size="1"></ftui-label>
</ftui-row>
<ftui-row align-items="left" padding="0 0 0 6px">
<ftui-label [text]="picframe:location" size="0"></ftui-label>
</ftui-row>
</ftui-column>
</ftui-row>
</ftui-grid-tile>
<!-- Schalter -->
<ftui-grid-tile row="5" col="2" height="4" width="3" shape="round" class="semitransparent">
<ftui-row>
<ftui-column align-items="left">
<!-- Schalter -->
<ftui-row>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-label size="1">Display</ftui-label>
</ftui-column>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-switch [(value)]="picframe:display"></ftui-switch>
</ftui-column>
</ftui-row>
<ftui-row>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-label size="1">Shuffle</ftui-label>
</ftui-column>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-switch [(value)]="picframe:shuffle" ></ftui-switch>
</ftui-column>
</ftui-row>
<ftui-row>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-label size="1">Text Overlay</ftui-label>
</ftui-column>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-switch [(value)]="picframe:text_overlay" ></ftui-switch>
</ftui-column>
</ftui-row>
<ftui-row>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-label size="1">Matting</ftui-label>
</ftui-column>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-switch [(value)]="picframe:mat_images" ></ftui-switch>
</ftui-column>
</ftui-row>
<ftui-row>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-label size="1">< Play ></ftui-label>
</ftui-column>
<ftui-column align-items="left" padding="0 0 0 5px">
<ftui-row align-items="left" padding="5 5 5 5px">
<ftui-button (value)="picframe:previous" states="on"><</ftui-button>
<ftui-button shape="normal"
[(value)]="picframe:pause">
<ftui-icon size="1" margin="2px" [name]="picframe:state | map('PAUSED:play, PLAYING:pause')"></ftui-icon>
</ftui-button>
<ftui-button (value)="picframe:next" states="on">></ftui-button>
</ftui-row>
</ftui-column>
</ftui-row>
</ftui-column>
</ftui-row>
</ftui-grid-tile>
<!-- Sliders -->
<ftui-grid-tile row="5" col="5" height="4" width="6" shape="round" class="semitransparent">
<ftui-row>
<!-- Time Delay -->
<ftui-column>
<ftui-label size="0" margin="4px">Dauer</ftui-label>
<ftui-slider margin="5px" [(value)]="picframe:time_delay"
min="0" max="300"
is-vertical has-ruler tooltips="always" tick="10">
</ftui-slider>
</ftui-column>
<!-- Fade Time -->
<ftui-column>
<ftui-label size="0" margin="4px">Blend</ftui-label>
<ftui-slider margin="5px" [(value)]="picframe:fade_time"
min="0" max="300"
is-vertical has-ruler tooltips="always" tick="10">
</ftui-slider>
</ftui-column>
<!-- Brightness -->
<ftui-column>
<ftui-label size="0" margin="4px">Helligkeit</ftui-label>
<ftui-slider margin="5px" [(value)]="picframe:brightness"
min="0" max="1" step="0.1"
is-vertical has-ruler tooltips="always" tick="0.1">
</ftui-slider>
</ftui-column>
<!-- Mat Image -->
<ftui-column>
<ftui-label size="0" margin="4px">Mat Images</ftui-label>
<ftui-slider margin="5px" [(value)]="picframe:mat_images"
min="0" max="1" step="0.01"
is-vertical has-ruler tooltips="always" tick="0.1">
</ftui-slider>
</ftui-column>
</ftui-row>
</ftui-grid-tile>
</ftui-tab-view>
Das war’s schon und der Manipulation von picframe über FTUI3 steht nichts mehr im Wege.