NEUE Betreff: Text-to-Speech App

Begonnen von mediastudio, 02 November 2025, 17:59:16

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Zitat von: Beta-User am 12 November 2025, 21:24:36AMAD benötigt afaik die App Automagic.
Ja, ist aber immer noch zu bekommen und läuft bei mir problemlos.

LG

pah

Beta-User

Zitat von: Prof. Dr. Peter Henning am 13 November 2025, 10:18:54
Zitat von: Beta-User am 12 November 2025, 21:24:36AMAD benötigt afaik die App Automagic.
Ja, ist aber immer noch zu bekommen und läuft bei mir problemlos.
"Noch". Dachte mir schon, dass man das irgendwie noch ans Laufen bekommt, aber gab es da nicht schon unter Andoid 10 (oder 11?) irgendein Thema mit dem Overlay?

Egal. Wir diskutieren grade, ob es noch lebt oder schon tot ist. Automagic wird jedenfalls afaik nicht wieder lebendig, von daher stellt sich doch schon länger die Frage, wie wir es ersetzen können.

Allerdings ist die dahinter liegende Frage valide, ob man nicht (auch) diese App als drop-in-replacement für Automagic hinsichtlich der Schnittstelle zu FHEM (AMADCommBridge) dienen könnte.
Wobei ich beim Blick in die commandref grade gesehen habe, dass es da noch Tasker gäbe; mal sehen...

@mediastudio
Wie sind denn deine Pläne hinsichtlich der Lizensierung des Codes? Auch GPL?
Falls du selbst nicht in diese Richtung entwickeln magst, findet sich vielleicht jemand, der in diese Richtung mitwirken würde, und es wäre auch nicht die erste App, die über den Verein finanziert den Weg in den Appstore gefunden hätte...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

mediastudio

Hallo zusammen,

hier ist ein Beispiel, wie ihr den FHEMVoiceClient testen könnt.
Es ist wichtig, dass die beigefügten Skripte in der FHEM.cfg übernommen werden,
damit alles reibungslos funktioniert.

Bitte beachtet: Solltet ihr weitere Sprachmodule eingebunden haben, kann ich leider
keine Garantie für die Funktionalität des FHEMVoiceClient übernehmen. Ich empfehle,
lediglich das zu übernehmen, was ich bereits getestet habe. In diesem Fall sollte es auch bei euch funktionieren.


##########################################
## Wichtig!! in der fhem.cfg hinzufügen ##
##########################################

#################################
# TTS Text2Speech
#################################
define MyTTS Text2Speech hw=0.0
attr MyTTS TTS_UseMP3Wrap 1
attr MyTTS room Text2Speech


#######################################################################
##  im Webinterface unter Android zwei Readings:                     ##
##                                                                   ##
##  lastTTS → wird vom Handy gelesen und gesprochen                  ##
##  debugTTS → dient nur der Kontrolle, was wirklich gesendet wurde  ##
#######################################################################

define voiceRecognitionLastResult dummy
attr voiceRecognitionLastResult room Android
attr voiceRecognitionLastResult setList textField


define androidTablet dummy
attr androidTablet room Android
attr androidTablet setList ttsSay:textField
attr androidTablet webCmd ttsSay


define androidTablet_tts notify androidTablet:ttsSay.* { \
  my @parts = ();; \
  for (my $i = 1;; $i < 10;; $i++) { ;;\
    my $var = "\$EVTPART$i";; \
    no strict 'refs';; \
    push @parts, eval $var if defined(eval $var) && eval($var) ne '';; \
  };; \
  my $text = join(' ', @parts);; \
  if ($text) { ;;\
  fhem("setreading androidTablet lastTTS $text");; \
  fhem("setreading androidTablet debugTTS $text");; \
      Log3('androidTablet', 3, "androidTablet_tts -> $text");; \
  } else { ;;\
      Log3('androidTablet', 3, "androidTablet_tts -> kein Text erkannt");; \
  } \
}




Das sollte in die fhem.cfg

Hier ist ein Beispiel wie man das testen kann.


###################################################################################################
####  So sind die Befehle mit Sprache EIN und Ausgabe aufgebaut, das ist FHEM Standart gewesen  ###
###################################################################################################
## Der Testschalter wird im Room Testschalter angelegt.
## Im room Android kann man sehen was als Sprache von der App FHEMVoiceClient an Fhem gesendet wurde.
##
## Sprache empfangen: "voiceRecognitionLastResult" testschalter Licht aus
## Fhem sendet zurüch an FHEMVoiceClient: AttsSay Der Test wurde ausgeschaltet
##
## Wichtig die Räume oder Aktoren so schreiben wie sie von "voiceRecognitionLastResult" erkannt werden.
##
## Hier ein Testschalter, Sprachausgabe bei Betätigung oder über App Spracheingabe
##
## .*(Testschalter|testschalter).* hier wird der Raum benannt,
## wenn "Testschalter Licht ein" oder "Testschalter Licht an"
## erkannt wird, schaltet der "Testschalter" und
## set androidTablet ttsSay Der Test wurde eingeschaltet , hier wird die Sprache ausgegeben.


######################
### Test Schalter ####
######################
define Testschalter dummy
attr Testschalter alias Test Schalter
attr Testschalter devStateIcon on:power.on off:power.off
attr Testschalter group Testschalter
attr Testschalter icon lampe_1_blau_40.png
attr Testschalter room Testschalter
attr Testschalter setList off on

define Testschalter_1 notify Testschalter:on  set androidTablet ttsSay Test Eingeschaltet
define Testschalter_2 notify Testschalter:off  set androidTablet ttsSay Test Ausgeschaltet

### Sprachbefehl für Test Schalter
define speechRecognizer_Testschalter_ein notify .*voiceRecognitionLastResult.*(Testschalter|testschalter).*Licht.*(ein|an).* set Testschalter on;; set androidTablet ttsSay Der Test wurde eingeschaltet
define speechRecognizer_Testschalter_aus notify .*voiceRecognitionLastResult.*(Testschalter|testschalter).*Licht.*aus.* set Testschalter off;; set androidTablet ttsSay  Der Test wurde ausgeschaltet




mediastudio

Betreff: Information zu "Hotword" Variable

Hallo,

ich möchte dich kurz über die Variable "Hotword" informieren.
Ich habe diese Funktion zwar vorgesehen, jedoch noch nicht freigegeben,
da es damit noch einige Probleme gibt. Daher ist dieses Feld derzeit
ohne Funktion und muss nicht weiter beachtet werden.

Viele Grüße,

Beta-User

Zitat von: mediastudio am 13 November 2025, 12:18:22Ich empfehle,
lediglich das zu übernehmen, was ich bereits getestet habe. In diesem Fall sollte es auch bei euch funktionieren.
Das "MyTTS"-Device wird in den von dir gezeigten cfg-Auszügen gar nicht genutzt ;) .

Wie dem auch sei: nach meinem Verständnis müßte nach einer Spracheingabe der dummy "voiceRecognitionLastResult" irgendwelche Infos in Readings (und sei es nur state) enthalten, in denen steht, was gesprochen wurde. Oder es müßte zumindest nach einer Spracheingabe irgendein Event mit dem Textteil "voiceRecognitionLastResult" im Event-Monitor zu sehen sein.

Beides ist bei mir nicht der Fall.

Ergo:
Kannst du bitte checken, ob du bei einer Spracheingabe was dazu passendes im Event-Monitor sehen kannst und/oder wie der dummy danach aussieht?
Nett wäre, wenn du hier ein per "copy for forum" erstelltes list davon (es gibt in der Detailansicht jedes Devices unten einen entsprechenden "Knopf") (und einem der Testschalter_*-notify nach "Benutzung" sowie dem "androidTablet"-Device) hier einstellen könntest. An den cfg-Auszügen sieht man keine Reading-Werte oder Zeitstempel...   
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

Beta-User

OK, bin einen halben Schritt weiter: Das Problem scheint tatsächlich csrf zu sein. Setzt man csrfToken auf "none", erfolgt sowohl die Sprachausgabe dessen, was im Reading "lastTTS" des Devices "androidTablet" steht (das war bei meinem Testen grade vom TYPE webViewControl...), und es wird nach einer Spracheingabe  auch voiceRecognitionLastResult gefüllt:
define voiceRecognitionLastResult dummy
attr voiceRecognitionLastResult room Steuerung->Interfaces
attr voiceRecognitionLastResult setList textField
#   FUUID      6913ae84-f33f-d171-380a-6594cec92cb66379
#   NAME       voiceRecognitionLastResult
#   NR         706
#   STATE      das ist ein Test
#   TYPE       dummy
#   READINGS:
#     2025-11-14 06:50:08   state           das ist ein Test
#
setstate voiceRecognitionLastResult das ist ein Test
setstate voiceRecognitionLastResult 2025-11-14 06:50:08 state das ist ein Test


Soweit, so gut.

@mediastudio:
Alle Sicherheitsmechanismen auszuschalten ist imo keine Option, der pauschale Verweis, dass man sich (ggf. via wireguard) im eigenen Netz befindet, ist m.E. nicht zielführend. Wie gehen wir mit dem csrf-Thema um?


Zum Vergleich, wie das bei AMAD läuft - da werden bei empfangener Spracheingabe zwei Readings an der Bridge geschrieben, sollte eigentlich selbsterklärend sein:
define AMADBridge AMADCommBridge
[...]
setstate AMADBridge 2022-08-04 23:49:13 receiveVoiceCommand schalte das licht am esstisch aus
setstate AMADBridge 2022-08-04 23:49:13 receiveVoiceDevice TabletWohnzimmer
setstate AMADBridge 2025-11-14 06:51:10 state opened

"TabletWohnzimmer" war/ist ein AMADDevice (das aber schon länger nicht mehr funktional ist, wie man am Zeitstempel erkennen kann...)

OT: Der schnelle (und bisher erfolglose) Versuch, das AMADDevice via Tasker wiederzubeleben, ist hier zu finden: https://forum.fhem.de/index.php?topic=143045.0
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

mediastudio

Betreff: Update zur FHEMVoiceClient App

Hallo FHEM USER,

ich möchte euch darüber informieren, dass mir bewusst ist, dass für den universellen Gebrauch der
FHEMVoiceClient App eine Eingabe für HTTPS erforderlich ist. Ich plane, dieses Thema in den nächsten
Tagen anzugehen und bin zuversichtlich, dass dies umsetzbar sein sollte.

In den Diskussionen höre ich oft, wie gut andere vorhandene Apps verschiedene Funktionen erfüllen.
Daher möchte ich noch einmal klarstellen, was meine Vision für die FHEMVoiceClient App ist.
Ursprünglich wollte ich die Funktionalitäten realisieren, die vor Jahren mit der in FHEM integrierten
WebView App möglich waren, ohne dass zusätzliche Apps eingebunden werden müssen.
So bleibt es jedem Nutzer selbst überlassen, welche Lösungen er einsetzen möchte.

Sobald die FHEMVoiceClient App mit HTTPS funktioniert, werde ich sie zum Test bereitstellen.

Vielen Dank für euer Verständnis und eure Geduld!

Mit besten Grüßen,
Wilfried Fröse

Beta-User

Danke für die Info.

Vermutlich werden mehr User über das csrf-Problem stolpern wie über HTTPS, aber letzteres ist schon mal ein guter Anfang  :) .
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

mediastudio

Hallo zusammen,

ich möchte gerne meine Erfahrungen und Entwicklungen im Bereich FHEM mit euch teilen,
insbesondere im Hinblick auf die Sprachsteuerung. Vor 14 Jahren habe ich mit FHEM begonnen
und war begeistert von der Möglichkeit, Spracheingaben über WebView zu integrieren.
Die Herausforderung, auch Alexa zu integrieren, stellte sich zwar als kompliziert
heraus – die Lizenzrechtsproblematik kam schnell auf – aber die investierte Zeit in das
Projekt war für mich sehr wertvoll.

Die ursprüngliche Implementierung, bei der ein eigenes Modul zur Emulation von Alexa in
FHEM verwendet wurde, hat mich sehr gefreut. Ähnlich war es mit der Spracheingabe über
WebView: Ich hatte tausende von Codezeilen in meiner fhem.cfg, aber die ständigen Aktualisierungen
der Android-Versionen machten vieles komplizierter und weniger unterhaltsam.

Im Laufe der Zeit wuchs meine fhem.cfg, als hätte ich einen Bestseller mit Fortsetzung.
Ein weiterer interessanter Aspekt war die Einführung von `setuuid`. Unleserlich verwirrend,
ich habe alle Zeilen mit ,setuuid'  gelöscht, ok ich hatte kein Problem mit und heute auch
nicht nachdem ich die Zeilen alle gelöscht habe, es ist einfach zu gewerkstelligen und
die fhem.cfg ist schlanker.

Nach all den Jahren bin ich stolz darauf, eine stabile Smart-Home-Installation mit FHEM aufgebaut
zu haben, die auch heute noch tadellos funktioniert. Es ist immer wieder ein tolles Gefühl, wenn
ich mein Handy nehme und den Spruch ,,Sesam öffne dich" sage und sich dann tatsächlich das Garagentor öffnet.
Die überraschten Gesichter Fremder sind unbezahlbar!

Nun zu meiner aktuellen Botschaft: Ich habe meine fhem.cfg aufgeräumt, insbesondere in Bezug auf Sprachbefehle
mit `voiceRecognitionLastResult`. Dabei ist eine neue Datei entstanden: 99_myVoiceControl.pm.
Dieses Modul ermöglicht es, fast alle Sprachbefehle, die von der FHEMVoiceClient-App gesendet werden,
auszuführen und sogar rückwirkend zu beantworten.

Die 99_myVoiceControl.pm unterstützt Lichtsteuerungen und Dimmer, auch die Anpassung von Helligkeit in
mehreren Räumen, inklusive Logging. Das bedeutet, dass ich nicht nur einzelne Befehle geben kann, sondern
mehrere gleichzeitig. Zum Beispiel kann ich einfach sagen: ,,Wandlampen Küche Flur Licht an", und alle
entsprechenden Befehle werden reibungslos ausgeführt – das gilt natürlich auch fürs Ausschalten.

Ich denke, dass dieses Modul für viele andere Anwender von Interesse sein könnte. Schaut euch die Struktur
der 99_myVoiceControl.pm an; es ist problemlos möglich, eigene spezielle Sprachbefehle einzufügen,
wie zum Beispiel # Mapping von Räumen zu Geräten. Darüber hinaus plane ich, eine Tabelle zu erstellen,
in der man die Sprachbefehle notieren kann, die dann an die 99_myVoiceControl.pm übergeben werden.

Wer Lust hat, kann dieses Modul gerne testen. Ich bin absolut begeistert davon,
denn so gut und schnell wie mit meiner FHEMVoiceClient-App hat Sprachsteuerung noch nie funktioniert.

Ich wünsche euch viel Spaß beim Ausprobieren!

99_myVoiceControl.pm

###############################################################################
# 99_myVoiceControl.pm – Erweiterte Sprachsteuerung für FHEM
# unterstützt Licht & Dimmer (auch heller/dunkler) + mehrere Räume + Logging
###############################################################################
package main;
use strict;
use warnings;
use utf8;
use Encode qw(decode);

sub myVoiceControl_Initialize { }

###############################################################################
# Hilfsfunktionen
###############################################################################

# Aktuellen Prozentwert robust ermitteln
sub myVoiceControl_get_current_pct {
  my ($dev) = @_;
  return 0 unless $dev && defined $defs{$dev};

  my $pct = ReadingsVal($dev, "pct", "");
  return int($pct) if $pct =~ /^\d{1,3}$/;

  $pct = ReadingsVal($dev, "lastPct", "");
  return int($pct) if $pct =~ /^\d{1,3}$/;

  foreach my $r ("dim", "level", "percent", "percentage") {
    $pct = ReadingsVal($dev, $r, "");
    return int($pct) if $pct =~ /^\d{1,3}$/;
  }

  my $state = ReadingsVal($dev, "state", "");
  if ($state =~ /(\d{1,3})/) {
    return int($1);
  } elsif ($state =~ /\bon\b/i) {
    return 100;
  } elsif ($state =~ /\boff\b/i) {
    return 0;
  }

  return 0;
}

# Dimmer setzen + eigenes Reading schreiben
sub myVoiceControl_set_dimmer {
  my ($dev, $value) = @_;
  return unless $dev && defined $defs{$dev};

  $value = 0 if $value < 0;
  $value = 100 if $value > 100;
  $value = int($value);

  fhem("set $dev dim $value");
  readingsSingleUpdate($defs{$dev}, "lastPct", $value, 1);
  Log 1, "myVoiceControl_set_dimmer: $dev -> $value%";
}

###############################################################################
# Hauptfunktion
###############################################################################
sub myVoiceControl {
  my ($cmd) = @_;
  return unless $cmd;

  $cmd = decode("utf8", $cmd) unless utf8::is_utf8($cmd);
  $cmd = lc($cmd);
  $cmd =~ s/ä/ae/g; $cmd =~ s/ö/oe/g; $cmd =~ s/ü/ue/g; $cmd =~ s/ß/ss/g;

  Log 1, "Sprachbefehl empfangen: $cmd";

  # Mapping Räume → Geräte
  my %devices = (
    'kueche'          => ['Deckenstrahler_Actor', 'light'],
    'flur'            => ['Flur_Esszimmer_Actor', 'light'],
    'tischlampe'      => ['Tischleuchte_Licht_Actor', 'light'],
    'tischleuchte'    => ['Tischleuchte_Licht_Actor', 'light'],
    'schlafzimmer'    => ['Schlafzimmer_Actor', 'light'],
    'schrankbeleuchtung' => ['Schrankbeleuchtung_Actor', 'light'],
    'wandlampe'       => ['Wandlampen_Actor', 'light'],
    'wandlampen'      => ['Wandlampen_Actor', 'light'],
    'gaeste wc'       => ['Gaeste_WC_Actor', 'light'],
    'badezimmer'      => ['Badezimmer_Actor', 'light'],
    'hauswirtschaftsraum' => ['HWR_Licht_Actor', 'light'],
    'gaestezimmer'    => ['Gaestezimmer_Actor', 'light'],
    'eingang'         => ['Flur_Eingang_Actor', 'light'],
    'schlummerlicht'  => ['SchlummerlichtDimmer', 'dimmer'],
    'multimedia wand' => ['Multimedia_Actor', 'light'],
    'buero'           => ['Buero_Dimmer', 'dimmer'],
    'wohnzimmer'      => ['Wohnzimmer_Dimmer', 'dimmer'],
    'fernsehwand'     => ['Multimedia_Dimmer', 'dimmer'],
    'garage'          => ['Garage_Sonoff_Licht', 'light'],
  );

  my @rooms_found;
  foreach my $room (keys %devices) {
    push @rooms_found, $room if $cmd =~ /\b$room\b/;
  }

  # keine Räume gefunden?
  if (!@rooms_found) {
    fhem("set androidTablet ttsSay Ich habe keinen Raum erkannt");
    Log 1, "Kein Raum erkannt: $cmd";
    return;
  }

  # Aktion ermitteln
  my $action = "";
  my $percent;

  if ($cmd =~ /\b(aus|off|ausschalten)\b/) {
    $action = "off";
  } elsif ($cmd =~ /\b(ein|an|einschalten|on)\b/) {
    $action = "on";
  } elsif ($cmd =~ /\b(heller|hoeher|höher|mehr|rauf)\b/) {
    $action = "brighter";
  } elsif ($cmd =~ /\b(dunkler|niedriger|weniger|runter)\b/) {
    $action = "darker";
  } elsif ($cmd =~ /(\d{1,3})/) {
    $percent = $1; $action = "dim";
  }

  my @done;
  foreach my $room (@rooms_found) {
    my ($dev, $type) = @{$devices{$room}};
    next unless $dev;

    if ($type eq 'light') {
      if ($action eq 'on') {
        fhem("set $dev on");
        push @done, ucfirst($room) . " Licht an";
      } elsif ($action eq 'off') {
        fhem("set $dev off");
        push @done, ucfirst($room) . " Licht aus";
      }
    }

    if ($type eq 'dimmer') {
      my $current = myVoiceControl_get_current_pct($dev);
      my $newval = $current;

      if ($action eq 'on') {
        $newval = 100;
      } elsif ($action eq 'off') {
        $newval = 0;
      } elsif ($action eq 'brighter') {
        $newval = $current + 10;
      } elsif ($action eq 'darker') {
        $newval = $current - 10;
      } elsif ($action eq 'dim' && defined $percent) {
        $newval = $percent;
      }

      $newval = 0   if $newval < 0;
      $newval = 100 if $newval > 100;

      myVoiceControl_set_dimmer($dev, $newval);
      push @done, ucfirst($room) . " ($newval%)";
    }
  }

  # Rückmeldung / Logging
  if (@done) {
    my $msg = join(", ", @done);
    fhem("set androidTablet ttsSay $msg");
    Log 1, "Ausgeführt: $msg";
    fhem("setreading Voice_LastCommand state $cmd");
    fhem("setreading Voice_LastCommand result $msg");
  } else {
    fhem("set androidTablet ttsSay Ich habe keine gültige Aktion erkannt");
    Log 1, "Keine gültige Aktion: $cmd";
  }
}

1;
###############################################################################
# Ende
###############################################################################



mediastudio

OK hier nich die Zeilen für die fhem.cfg

#########################################
###  Licht Modul 99_myVoiceControl.pm ###
#########################################
define VoiceRecognitionNotify notify voiceRecognitionLastResult:.* { myVoiceControl(ReadingsVal("voiceRecognitionLastResult","state","")) }
attr VoiceRecognitionNotify room Spracherkennung
attr VoiceRecognitionNotify alias Sprachsteuerung




mediastudio

Zitat von: mediastudio am 14 November 2025, 17:17:53OK hier noch die Zeilen für die fhem.cfg

#########################################
###  Licht Modul 99_myVoiceControl.pm ###
#########################################
define VoiceRecognitionNotify notify voiceRecognitionLastResult:.* { myVoiceControl(ReadingsVal("voiceRecognitionLastResult","state","")) }
attr VoiceRecognitionNotify room Spracherkennung
attr VoiceRecognitionNotify alias Sprachsteuerung