[Amazon Alexa] Nachfragen durch Alexa an den User

Begonnen von balli1187, 15 Februar 2022, 10:00:21

Vorheriges Thema - Nächstes Thema

balli1187

Mahlzeit,

ich nutze das Alex wie auch das Echodevice Modul zu Interaktion mit FHEM.
Gleich auch nochmal ein großes Dankeschön an die Entwickler!!!

Ich suche nach einer Möglichkeit, dass Alexa mir eine Frage stellt und die Antwort abwartet und weiter verabeitet.
Nativ fragt sich ja nach, wenn sie bspw. ein Kommando nicht richtig verstanden hat. Lässt sich das noch irgendwie anders triggern?
Bisher mache ich nur einfach Eingaben (Alexa, schalte dies/das) oder einfache Ausgaben (per echodevice und speak).

der User @rabehd hatte hier etwas von "Rückfragen versenden" geschrieben aber das konnte ich bisher noch nicht nachvollziehen.

Da ich eher nicht so der Morgenmensch bin, würde ich die Interaktion an einigen Stellen gern auf ein Minimum (Ja/nein) reduzieren ;)
FHEM auf QNAP im docker, nanoCUL per ser2net an VU+, 2x Echo Dot, 3x HM-ES-PMSw1-Pl, 3x HM-LC-Bl1PBU-FM, 6x Sonoff Basic, div. "Shelly Eigenbauten" von Papa Romeo, ESPRGBWW-Controller, ...
Projekte: Smart Mirror in Spiegelschrank auf RPi Zero

MadMax-FHEM

Eventuell hilft hier der Custom Skill.

Bzw. prinzipiell sollte es damit oder einem "angelehnten Mechanismus" gehen.

Allerdings ist die Anleitung bzgl. Custom Skill im Wiki sehr "outdated", bzw. die Prinzipien sind wohl noch dieselben aber auf Amazon-Seite hat sich (wohl) einiges geändert bzw. mindestens die Screenshots etc. sind definitiv anders...

Und seit es Routinen gibt und ich (für mich) entschieden habe was ich per Sprache (wie) steuern will und was automatisch gehen soll (weil das ist mein Ziel: möglichst viel/alles automatisch ohne überhaupt was tun zu müssen: auch keine "Spracheingabe")...
...habe ich meine Custom Skills "schlafen gelegt" (verm. so, dass ich sie nicht mal mehr wirklich aufwecken kann ;-) )...

Ansonsten kann man ja auf Amazon Seite (Skills ;) also "Knowledge Skills" vorausgesetzt) sowas auf jeden Fall programmieren, manche Skills machen das ja schon, also mit Rückfragen...
...ob man das im/mit Custom Skill einfach "nutzen" kann (also "sowas" schon "eingebaut" ist: keine Ahnung) oder noch was implementiert werden muss: keine Ahnung...

Auf jeden Fall interessant... :)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

balli1187

Hallo Joachim,

Der Custom Skill oder ähnliches, was mit "zu viel" Programmieraufwand einhergeht, ist für mich da eher keine Option. Aufwand/Nutzen stimmt dann einfach nicht, da ich wahrscheinlich keine essentiellen Funktionen darüber abbilden werde.
Generell geht es mir da so wie dir - das meiste soll automatisch ablaufen, ohne das ich etwas dazu tun muss. Smart Home bedeutet ja nicht, ne schicke App zu haben oder eine wohlklingende elektronische Assistentin.

Hin und wieder wäre es aber ganz reizvoll, nach einer Meldung gleich reagieren zu können.
Ohne jetzt eine ausgiebige Sicherheitsdiskussion anzufangen aber sowas wie "Es hat geläutet. Soll ich die Tür öffnen?......" "Ja".  Wie gesagt - nur um das Prinzip nochmal darzustellen.

im echodevice thread wurden auch die blueprints reingeworfen aber auch damit hab ich noch keine Erfahrungen.
FHEM auf QNAP im docker, nanoCUL per ser2net an VU+, 2x Echo Dot, 3x HM-ES-PMSw1-Pl, 3x HM-LC-Bl1PBU-FM, 6x Sonoff Basic, div. "Shelly Eigenbauten" von Papa Romeo, ESPRGBWW-Controller, ...
Projekte: Smart Mirror in Spiegelschrank auf RPi Zero

MadMax-FHEM

Bzgl. Nachfragen o.ä. also dass das "nett" wäre da bin ich voll "bei dir" ;)

Aber ich denke es wird nur mit dem Aufwand des Custom Skills (entweder out-of-the-box oder auch da noch nur mit Erweiterung) gehen...
...oder selbst einen Skill erstellen und mit fhem verbinden...

Außer: Amazon ändert was und macht es "einfach" zugänglich und zwar schon/auch für den SmartHome-Skill (auf den ja alexa-fhem Connector aufsetzt)...

D.h. das wäre eher auch etwas, was "man" Amazon "fragen" sollte...

Es gibt doch in der App die Möglichkeit "Feature-Wünsche" zu hinterlassen (gab es zumindest mal)...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

rabehd

Wie wäre es mit einem konkreten Beispiel?
Da könnte man mögliche Lösungen diskutieren.

Auch funktionierende Lösungen kann man hinterfragen.

MadMax-FHEM

Zitat von: rabehd am 15 Februar 2022, 13:49:39
Wie wäre es mit einem konkreten Beispiel?
Da könnte man mögliche Lösungen diskutieren.

Luftfeuchte im Bad steigt.
(Ich dusche und habe vergessen den Lüfter einzuschalten)

Alexa: soll ich den Lüfter einschalten?
Ich: ja
Alexa schaltet den Lüfter ein...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

rabehd

Zitat von: MadMax-FHEM am 15 Februar 2022, 13:51:53
Luftfeuchte im Bad steigt.
(Ich dusche und habe vergessen den Lüfter einzuschalten)

Alexa: soll ich den Lüfter einschalten?
Ich: ja
Alexa schaltet den Lüfter ein...

Gruß, Joachim

Meine Idee:
Event Luftfeuchte größer als löst Ansage aus und setzt eine Variable/Dummy für eine bestimmte Zeit.
Event voice wird ausgewertet, wenn Text passt und Variabel noch gesetzt ist, dann Aktion

Geht sicher auch anders.
Auch funktionierende Lösungen kann man hinterfragen.

MadMax-FHEM

#7
Zitat von: rabehd am 15 Februar 2022, 14:00:22
Meine Idee:
Event Luftfeuchte größer als löst Ansage aus und setzt eine Variable/Dummy für eine bestimmte Zeit.
Event voice wird ausgewertet, wenn Text passt und Variabel noch gesetzt ist, dann Aktion

Geht sicher auch anders.

Ja das habe ich in dem anderen Thread schon verstanden... ;)

ABER: man müsste ja mindestens sagen: "Alexa ja" und dann fraglich was Alexa mit der "Ansage" ja macht ;)

Ist nicht das was ich hierunter verstehe...

Mich hat ja schon "genervt", dass man beim Custom Skill immer erst mal den Custom Skill "aktivieren" muss:

Alexa sag Wohnung mach dies mach das usw.
(Wohnung war eines meiner Custom Skill "Namen" oder wie immer das genau genannt wurde / ich hatte verschiedene, damit eben zumindest ein wenig Sprachfluss ohne überflüssige Dinge möglich war)

Aber das ist ein generelles "Design Problem" von Amazon.

Google braucht "sowas" nicht, selbst wenn die Geräte/Möglichkeiten/Features/... von verschiedenen "Stellen" (Geräten, Firmen, ... -> bei Amazon wären das Skills) stammen...

Also das erste was bei einem solchen "Fluss" stört ist/wäre, dass man eben das "Wakeword" braucht.
Ohne das macht Alexa ja nichts.

Anders eben bei Skills, die das implementiert haben.
Die fragen nach und warten einfach auf eine (kurze) Antwort...

Ebenso wie das angesprochene "Szenario", wenn Alexa mal was nicht genau verstanden hat, dann frägt sie nach und wartet auf Antwort (ohne Wakeword-Aktivierung)...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

balli1187

Zitat von: rabehd am 15 Februar 2022, 14:00:22
Meine Idee:
Event Luftfeuchte größer als löst Ansage aus und setzt eine Variable/Dummy für eine bestimmte Zeit.
Event voice wird ausgewertet, wenn Text passt und Variabel noch gesetzt ist, dann Aktion

Geht sicher auch anders.

Genau wie es Joachim beschreiben hat, ist hier wenig Sprachfluss vorhanden bzw. wenig Interaktion im Sinne von beidseitigen Reaktionen auf die "Unterhaltung".

Bei deiner Lösung bleibt für mich auch die Frage, wie die Antwort "Ja" an Alexa kommt. Das geht halt nur über die Wakewords. Das stört mich im Nomalfall nicht aber die Idee hinter diesem Thread war schon für "Kleinigkeiten" (Oder relevanten Funktionen, auf die ich eine Rückmeldung geben will) darauf verzichten zu können.

Ansonsten kann man das Beispiel auch so handhaben:
Alexa: "Die Luftfeuchtigkeit ist sehr hoch. [Denk dran den Lüfter einzuschalten.]"
Ich: "Alexa, Lüfter an."

Wenn aber eine besseres "Miteinander" im Sinnen von echten Antworten auf Fragen möglich wären, würde es mir besser gefallen. Ich hatte ein paar Hoffnungen, dass dies vielleicht über versteckte Funktionen in Routinen möglich wäre oder dergleichen.

Der Custom Skill ist aus den von Joachim genannten Gründen keine Option für mich. Ein doppeltes Wakeword gefällt mir einfach sprachlich nicht und hat geringen WAF.
FHEM auf QNAP im docker, nanoCUL per ser2net an VU+, 2x Echo Dot, 3x HM-ES-PMSw1-Pl, 3x HM-LC-Bl1PBU-FM, 6x Sonoff Basic, div. "Shelly Eigenbauten" von Papa Romeo, ESPRGBWW-Controller, ...
Projekte: Smart Mirror in Spiegelschrank auf RPi Zero

locodriver

Ich probiere hier

https://forum.fhem.de/index.php/topic,126179.msg1207993.html#msg1207993

in ähnlicher Weise herum, allerdings bin ich noch nicht voran gekommen. Es hat aber nicht die oberste Prio bei mir - in den nächsten Tagen habe ich nicht genügend Zeit, mich damit zu beschäftigen...
fhem 6.0 auf Rpi3 Bookworm
HM-LAN-CFG (FW 0.965), HM-MOD-UART, 2x HM-TC-IT-WM-W-EU, 4x HM-Sec-RHS und 3x HM-CC-RT-DN, 6x HM-LC-Bl1-FM mit je 1x Somfy-Motor,
2x HM-LC-SW2-FM für Licht und Lüfter, 2x HM-PB-6-WM55, Alexa, Jeelinkcross, CUL, CUNO2, IR-Blaster

MadMax-FHEM

Zitat von: locodriver am 15 Februar 2022, 17:11:31
Ich probiere hier

https://forum.fhem.de/index.php/topic,126179.msg1207993.html#msg1207993

in ähnlicher Weise herum, allerdings bin ich noch nicht voran gekommen. Es hat aber nicht die oberste Prio bei mir - in den nächsten Tagen habe ich nicht genügend Zeit, mich damit zu beschäftigen...

Ist aber ja ein (etwas) anders gelagertes Thema...

Hier geht es ja um Reaktion "ohne vorherige Ansprache"...

(für dein "dortiges Problem" was ja eher "DOIF-Problem/-Frage" ist oder eben auf Module "umgeleitet" wird/werden könnte, die eben genau für "Sprach-/Satz-Auswertung" geschrieben wurden: TEERKO, Babble, Talk2Fhem, ... Hatte ich ja bereits "geantwortet" ;)  )

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

MadMax-FHEM

#11
Bin heute zufällig hierrüber gestolpert: https://www.youtube.com/watch?v=UQkeaxrX7D8

Werde ich mir mal ansehen...

EDIT: @Andre (justme1968), falls du hier (zufällig) mitliest/drüber stolperst... Wäre das https://www.smarthomelab.ca/actionable-notifications-from-alexa-to-home-assistant/ mit einem fhem-Custom Skill auch möglich? Sollte doch eigentlich gehen? Es gibt ja "sowas" wie das https://github.com/custom-components/alexa_media_player auch in fhem -> Echodevice-Modul (läuft bei mir). Dann noch einen Custom Skill (habe ich auch noch irgendwo, sofern die noch laufen ;)  Wenn nicht, sollte doch das von hier https://github.com/keatontaylor/alexa-actions/blob/master/skill-manifests/locale_de_de.json auch einfach passen, es geht ja nur um das "Model" für die "actionable-notifications", oder? Dann nat. das python was auf AWS läuft. Da müsste das hier https://github.com/keatontaylor/alexa-actions/blob/master/lambda/lambda_function.py nat. angepasst werden, damit statt Homeassistant fhem "gerufen" wird. Den Code sollte es doch schon geben/gibt es doch schon!? Was mir (noch) nicht klar ist, wie wird die "Abfrage" getriggert (gut ja Text abspielen ist einfach aber wie wird dann "eingeschaltet", dass Alexa auf eine Antwort ala "Ja"/"Nein" wartet und v.a. wie erkenne ich [in fhem] wie zu welcher Aktion [da gibt es ja wohl eine ID] dann die Antwort gehört?). Was mich bei Custom Skills (bislang) immer gestört hat, war, dass dieser erst immer noch "aktiviert" werden musste, also: Alexa sag der Wohnung mach dies oder das (oder was auch immer der "Startsatz"/"-Wort" war). Aber wenn das hier mit einem Custom Skill ginge: :) :) :) :)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

balli1187

Klasse, Joachim. Genau sowas hatte ich im Sinn.

Im Video ist aber leider zur Umsetzung nicht allzu viel zu sehen. Werd bei Gelegenheit mal den Blog anschauen.
Bisher hab ich keinen Custom Skill aus oben genannten Gründen.
Daher sorry falls die Frage schon x mal kam: Kann ich custom skill und smart Home skill parallel betreiben. Ich würde den Custom skill, dann vorerst nur für diese Geschichte verwenden wollen.
FHEM auf QNAP im docker, nanoCUL per ser2net an VU+, 2x Echo Dot, 3x HM-ES-PMSw1-Pl, 3x HM-LC-Bl1PBU-FM, 6x Sonoff Basic, div. "Shelly Eigenbauten" von Papa Romeo, ESPRGBWW-Controller, ...
Projekte: Smart Mirror in Spiegelschrank auf RPi Zero

MadMax-FHEM

Zitat von: balli1187 am 11 März 2022, 11:10:18
Daher sorry falls die Frage schon x mal kam: Kann ich custom skill und smart Home skill parallel betreiben. Ich würde den Custom skill, dann vorerst nur für diese Geschichte verwenden wollen.

Ja, geht (ging zumindest) parallel.

Sogar mit dem Connector zusammen.

Du musst halt in die config.json von alexa-fhem die "Credentials" deines Custom Skills eintragen, den selber auf WAS angelegten Custom Skill verknüpfen/aktivieren und nat. Port 3000 öffnen und weiterleiten zu alexa-fhem...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

plopes9000

With the code below in 37_echodevice I can now call a skill just with the skill id - no other setup required.

set ECHO_XYZ run_skill amzn1.ask.skill.9525f216-0058-4d37-bd0c-af5cabaa6a57

} elsif ($type eq "run_skill") {

                #Allgemeine Veariablen
                $SendUrl   .= "/api/behaviors/preview";
                $SendMetode = "POST";

                my $sequenceJson;

                # Sonderzeichen entfernen
                $SendData =~s/"/'/g;

                $SendData = '{"behaviorId":"PREVIEW","sequenceJson":"{\"@type\":\"com.amazon.alexa.behaviors.model.Sequence\",\"startNode\":{\"@type\":\"com.amazon.alexa.behaviors.model.SerialNode\",\"nodesToExecute\":[{\"@type\":\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\",\"type\":\"Alexa.Operation.SkillConnections.Launch\",\"operationPayload\":{\"targetDevice\":{\"deviceSerialNumber\":\"'.$hash->{helper}{".SERIAL"}. '\",\"deviceType\":\"'.$hash->{helper}{DEVICETYPE}.'\"},\"locale\":\"en-UK\",\"customerId\":\"' . $hash->{IODev}->{helper}{".CUSTOMER"} .'\",\"connectionRequest\":{\"uri\":\"connection://AMAZON.Launch/'.$SendData.'\",\"input\":{}}}}]}}","status":"ENABLED"}';
               
                $SendDataL  = $SendData;
}



Perhaps even better is to combine the announcement with calling the skill like below.
The code below does already work, just that atm the values are hardcoded.


elsif ($type eq "announcement") {

                #Allgemeine Veariablen
                $SendUrl   .= "/api/behaviors/preview";
                $SendMetode = "POST";

                my $sequenceJson;

                # Sonderzeichen entfernen
                $SendData =~s/"/'/g;

                my $announcement="<speak>my announcement goes here</speak>";
                my $skill_id="amzn1.ask.skill.9525f216-0058-4d37-bd0c-af5cabaa6a57";
                my $event_id="my_callback_id";
                my $skill_args='\"eventId\":\"'.$event_id.'\",\"answers\":[\"Yes\",\"No\"]';
                $SendData = '{"behaviorId":"PREVIEW","sequenceJson":"{\"@type\":\"com.amazon.alexa.behaviors.model.Sequence\",\"startNode\":{\"@type\":\"com.amazon.alexa.behaviors.model.SerialNode\",\"nodesToExecute\":[{\"@type\":\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\",\"type\":\"Alexa.DeviceControls.Volume\",\"operationPayload\":{\"deviceSerialNumber\":\"' . $hash->{helper}{".SERIAL"} . '\",\"customerId\":\"' . $hash->{IODev}->{helper}{".CUSTOMER"} .'\",\"locale\":\"de-DE\",\"value\":\"'.$SpeakVolume.'\",\"deviceType\":\"' . $hash->{helper}{DEVICETYPE} . '\"}},{\"@type\":\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\",\"type\":\"AlexaAnnouncement\",\"operationPayload\":{\"expireAfter\":\"PT5S\",\"content\":[{\"locale\":\"\",\"display\":{\"title\":\"FHEM\",\"body\":\"'.$announcement.'\"},\"speak\":{\"type\":\"ssml\",\"value\":\"' . $announcement . '\"}}],\"customerId\":\"' . $hash->{IODev}->{helper}{".CUSTOMER"} .'\",\"target\":{\"customerId\":\"' . $hash->{IODev}->{helper}{".CUSTOMER"} .'\",\"devices\":[{\"deviceSerialNumber\":\"' . $hash->{helper}{".SERIAL"} . '\",\"deviceTypeId\":\"' . $hash->{helper}{DEVICETYPE} . '\"}]}}},{\"@type\":\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\",\"type\":\"Alexa.DeviceControls.Volume\",\"operationPayload\":{\"deviceSerialNumber\":\"' . $hash->{helper}{".SERIAL"} . '\",\"customerId\":\"' . $hash->{IODev}->{helper}{".CUSTOMER"} .'\",\"locale\":\"de-DE\",\"value\":\"'.ReadingsVal($name , "volume", 50).'\",\"deviceType\":\"' . $hash->{helper}{DEVICETYPE} . '\"}},{\"@type\":\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\",\"type\":\"Alexa.Operation.SkillConnections.Launch\",\"operationPayload\":{\"targetDevice\":{\"deviceSerialNumber\":\"'.$hash->{helper}{".SERIAL"}. '\",\"deviceType\":\"'.$hash->{helper}{DEVICETYPE}.'\"},\"locale\":\"en-UK\",\"customerId\":\"' . $hash->{IODev}->{helper}{".CUSTOMER"} .'\",\"connectionRequest\":{\"uri\":\"connection://AMAZON.Launch/'.$skill_id.'\",\"input\":{'.$skill_args.'}}}}]}}","status":"ENABLED"}';
                $SendDataL  = $SendData;
}


Is this making any sense?

Next would be to receive the input arguments in the lambda function, and send back to fhem the response ... this is the part I'm less sure how to tackle.

Also not keen on opening any port to the internet ... keep hoping there is a way to use the existing echodevice or alexa connector connection instead of opening a port.

Cheers,
Paulo

MadMax-FHEM

Hi Paulo,

sorry did not have time yet for looking/checking "if that makes any sense" ;)

But I think there are only two ways of receiving results:

- Custom Skill (or equivalent) -> open Port...

- a server in the internet and somehow bringing local fhem and Amazon together like alexa-fhem Connector together with the fhem Vereinsserver...

But I am not sure if that with the "server in the middle" also works for that kind...

I hope you keep on!
And maybe also Andre (justme1968) finds this thread and the idea behind interesting!
Because then the chance that this will work are getting much higher... :)

So easter ist coming, maybe/hpefully I find some time then :)

Bye, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

plopes9000

Hi Joachim,

I've got it working, sort of a hack in many ways and several details still being considered, but it is working.


define MQTT2_zigbee_study_motion_sensor_doif DOIF ([MQTT2_zigbee_study_motion_sensor:occupancy] eq "true" and [MQTT2_zigbee_study_motion_sensor:illuminance_lux]<50 )
    (set MQTT2_zigbee_study_desk_lamp on) 
  DOELSEIF ([MQTT2_zigbee_study_desk_lamp:state] eq "ON")
    ( set ECHO_G091GG10145703NX announcement {"message" : "I've not detected motion in the Study for a while, would you like me to keep the desk lights on?", "event_id" : "study_desk_lights_off", "response_intents" : <- "AMAZON.YesIntent", "AMAZON.NoIntent" -> } )


The '<-' '->' are used here instead of the json array characters '[' ']' since the DOIF code does a search and replace on those characters.

The response appears as a reading on the ECHO device
study_desk_lights_off AMAZON.YesIntent

define ECHO_G091GG10145703NX_notify notify ECHO_G091GG10145703NX:study_desk_lights_off:.*(AMAZON.NoIntent|NoAnswer) { fhem 'set MQTT2_zigbee_study_desk_lamp off'; }


The custom skill uses the intents of the home assistant actionable notifications solution for now.
Would probably drop the "Selection".
{
    "interactionModel": {
        "languageModel": {
            "invocationName": "fhem custom skill",
            "intents": [
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.YesIntent",
                    "samples": [
                        "yes"
                    ]
                },
                {
                    "name": "AMAZON.NoIntent",
                    "samples": [
                        "no"
                    ]
                },
                {
                    "name": "Select",
                    "slots": [
                        {
                            "name": "Selections",
                            "type": "Selections"
                        }
                    ],
                    "samples": [
                        "{Selections}"
                    ]
                },
                {
                    "name": "Number",
                    "slots": [
                        {
                            "name": "Numbers",
                            "type": "AMAZON.FOUR_DIGIT_NUMBER"
                        }
                    ],
                    "samples": [
                        "{Numbers}"
                    ]
                },
                {
                    "name": "Duration",
                    "slots": [
                        {
                            "name": "Durations",
                            "type": "AMAZON.DURATION"
                        }
                    ],
                    "samples": [
                        "{Durations}"
                    ]
                },
                {
                    "name": "Date",
                    "slots": [
                        {
                            "name": "Dates",
                            "type": "AMAZON.DATE"
                        },
                        {
                            "name": "Times",
                            "type": "AMAZON.TIME"
                        }
                    ],
                    "samples": [
                        "{Dates} at {Times}",
                        "at {Times}",
                        "{Dates}"
                    ]
                }
            ],
            "types": [
                {
                    "name": "Selections",
                    "values": [
                        {
                            "name": {
                                "value": "Amazon Prime",
                                "synonyms": [
                                    "Amazon",
                                    "Amazon Video"
                                ]
                            }
                        },
                        {
                            "name": {
                                "value": "Hulu"
                            }
                        },
                        {
                            "name": {
                                "value": "YouTube"
                            }
                        },
                        {
                            "name": {
                                "value": "Netflix"
                            }
                        }
                    ]
                }
            ]
        }
    }


The custom skill uses the @justme-1968 lambda code https://github.com/justme-1968/alexa-fhem/blob/master/lambda.js.

37_echodevice.pm
        } elsif ($type eq "announcement") {
                #Allgemeine Veariablen
                $SendUrl   .= "/api/behaviors/preview";
                $SendMetode = "POST";

                $SendData=~s/<-/[/g;
                $SendData=~s/->/]/g;
                my $json = eval { JSON->new->utf8(0)->decode($SendData) };

                if (ref($json) eq "HASH") {
                  if (defined($json->{message}) && defined($json->{event_id}) && defined($json->{response_intents}) && ref($json->{response_intents}) eq "ARRAY" ) {
                        my $announcement=$json->{message};
                        my $event_id=$json->{event_id};
                        my $response_intents=JSON->new->utf8(1)->encode($json->{response_intents});
                        $response_intents=~s/"/\\"/g;
                        my $skill_id="amzn1.ask.skill.xxxxx";
                        my $skill_args='\"echo_id\":\"'.$name.'\",\"event_id\":\"'.$event_id.'\",\"message\":\"'.$announcement.'\",\"response_intents\":'.$response_intents;

                        Log3 $name, 2, "[$name] [echodevice_SendCommand] announcement: $announcement";
                        Log3 $name, 2, "[$name] [echodevice_SendCommand] event_id: $event_id";
                        Log3 $name, 2, "[$name] [echodevice_SendCommand] response_intents: $response_intents";
                        Log3 $name, 2, "[$name] [echodevice_SendCommand] skill_args: $skill_args";

                        $SendData = '{"behaviorId":"PREVIEW","sequenceJson":"{\"@type\":\"com.amazon.alexa.behaviors.model.Sequence\",\"startNode\":{\"@type\":\"com.amazon.alexa.behaviors.model.SerialNode\",\"nodesToExecute\":[{\"@type\":\"com.amazon.alexa.behaviors.model.OpaquePayloadOperationNode\",\"type\":\"Alexa.Operation.SkillConnections.Launch\",\"operationPayload\":{\"targetDevice\":{\"deviceSerialNumber\":\"'.$hash->{helper}{".SERIAL"}. '\",\"deviceType\":\"'.$hash->{helper}{DEVICETYPE}.'\"},\"locale\":\"en-UK\",\"customerId\":\"' . $hash->{IODev}->{helper}{".CUSTOMER"} .'\",\"connectionRequest\":{\"uri\":\"connection://AMAZON.Launch/'.$skill_id.'\",\"input\":{'.$skill_args.'}}}}]}}","status":"ENABLED"}';
                        $SendDataL  = $SendData;
                  }
                }
        }



server.js

diff /usr/local/lib/node_modules/alexa-fhem-backup/lib/server.js /usr/local/lib/node_modules/alexa-fhem/lib/server.js
613a614,631
> Server.prototype.setreading = function(device, reading, value) {
>   log.info ("Reading " + reading + " set to " + value + " for device " + device);
>   if ( this.connections )
>     for( let fhem of this.connections ) {
>       if (!fhem.alexa_device) continue;
>       fhem.execute('setreading ' + device + ' ' + reading + ' ' + value);
>     }
> }
>
> Server.prototype.deletereading = function(device, reading) {
>   log.info ("Delete reading " + reading + " for device " + device);
>   if ( this.connections )
>     for( let fhem of this.connections ) {
>       if (!fhem.alexa_device) continue;
>       fhem.execute('deletereading ' + device + ' ' + reading);
>     }
> }
>
1541a1560
>     log.info('#################### sessionId: ' +  event.session.sessionId);
1545a1565
>
1581c1601
<                          text: 'Hallo.'
---
>                          text: 'Hello.'
1582a1603,1611
>                      card: {
>                        type: 'Simple',
>                          title: 'fhem',
>                          content: 'Ok'
>                      //    image: {
>                      //     smallImageUrl: 'https://url-to-small-card-image...',
>                      //     largeImageUrl: 'https://url-to-large-card-image...'
>                      //    }
>                      },
1584c1613
<                      }
---
>                      },
1589,1608d1617
<       response.response.outputSpeech.text = 'Hallo. Wie kann ich helfen?';
< if( 0 ) {
<       response.response.directives = [
<       {
<         "type": "AudioPlayer.Play",
<         "playBehavior": "REPLACE_ALL",
<         "audioItem": {
<           "stream": {
<             "token": "string",
<             "url": "string",
<             "offsetInMilliseconds": 0
<           }
<         }
<       }
<     ];
< }
<       if( fhem && fhem.alexaConfirmationLevel < 2 )
<         response.response.outputSpeech.text = 'Hallo.';
<
<       response.response.reprompt = { outputSpeech: {type: 'PlainText', text: 'Noch jemand da?' } };
1614a1624,1655
>       log.info('###### session: ' +  session);
>       if (event.request.body)
>         log.info('###### event.request.body: ' +  JSON.stringify(event.request.body) );
>       if   (event.request.body
>          && event.request.body.event_id
>        && event.request.body.message
>        && event.request.body.echo_id
>        && event.request.body.response_intents
>        && Array.isArray(event.request.body.response_intents) ) {
>         if( !sessions[session] ) {
>           sessions[session] = {};
>           sessions[session].in_session = true;
>         }
>         sessions[session].event_id = event.request.body.event_id;
>         sessions[session].echo_id = event.request.body.echo_id;
>         sessions[session].message = event.request.body.message;
>         sessions[session].response_intents = event.request.body.response_intents;
>         log.info('#### sessions[session].event_id: ' + sessions[session].event_id);
>         log.info('#### : sessions[session].echo_id ' + sessions[session].echo_id);
>         log.info('#### : sessions[session].response_intents ' + sessions[session].response_intents);
>
>         this.deletereading(sessions[session].echo_id, sessions[session].event_id );
>         response.response.outputSpeech.text = sessions[session].message;
>         if( fhem && fhem.alexaConfirmationLevel < 2 )
>           response.response.outputSpeech.text = 'Hello.';
>         response.response.reprompt = { outputSpeech: {type: 'PlainText', text: sessions[session].message } };
>       } else {
>         response.response.outputSpeech.text = 'Hello. How can I help you?';
>         if( fhem && fhem.alexaConfirmationLevel < 2 )
>           response.response.outputSpeech.text = 'Hello.';
>         response.response.reprompt = { outputSpeech: {type: 'PlainText', text: 'Someone there?' } };
>       }
1616c1657,1660
<       in_session = false;
---
>       if    (sessions[session] && sessions[session].event_id
>           && sessions[session].echo_id && sessions[session].response_intents
>           && ! sessions[session].response_intent)
>         this.setreading(sessions[session].echo_id, sessions[session].event_id ,"NoAnswer");
1622a1667,1668
>
>       log.info('#### sessionId: ' +  event.session.sessionId);
1709c1755,1783
<         }
---
>         } else if (intent_name == 'Number'
>               || intent_name == 'Duration'
>               || intent_name == 'Date'
>               || intent_name == 'Select'
>               || intent_name == 'AMAZON.YesIntent'
>               || intent_name == 'AMAZON.NoIntent') {
>         if    (sessions[session]
>             && sessions[session].event_id
>             && sessions[session].echo_id
>             && sessions[session].response_intents)
>         {
>             const r_intent = sessions[session].response_intents.find(r_intent => r_intent == intent_name);
>           if (r_intent) {
>               log.info('#### 1 sessions[session].event_id: ' + sessions[session].event_id);
>               sessions[session].response_intent = intent_name;
>               this.setreading(sessions[session].echo_id, sessions[session].event_id ,intent_name);
>             match = true;
>             in_session=false;
>               response.response.shouldEndSession = true;
>           } else {
>               log.info('#### 2 sessions[session].event_id: ' + sessions[session].event_id);
>               response.response.outputSpeech.text = 'Sorry, did not get that. ' + sessions[session].message;
>               response.response.reprompt = { outputSpeech: {type: 'PlainText', text: sessions[session].message } };
>               response.response.shouldEndSession = false;
>               callback( response );
>               return;
>           }
>         }
>       }
1879a1954,1957
>       if    (sessions[session] && sessions[session].event_id
>           && sessions[session].echo_id && sessions[session].response_intents
>           && ! sessions[session].response_intent)
>         this.setreading(sessions[session].echo_id, sessions[session].event_id,"AMAZON.StopIntent");
1881c1959
<         response.response.outputSpeech.text = 'Bis bald.';
---
>         response.response.outputSpeech.text = 'OK.';
1887a1966
>
1888a1968,1971
>       if    (sessions[session] && sessions[session].event_id
>           && sessions[session].echo_id && sessions[session].response_intents
>           && ! sessions[session].response_intent)
>         this.setreading(sessions[session].echo_id, sessions[session].event_id,"AMAZON.CancelIntent");
1896d1978
<
1899a1982,1986
>       if    (sessions[session] && sessions[session].event_id
>           && sessions[session].echo_id && sessions[session].response_intents
>           && ! sessions[session].response_intent)
>         this.setreading(sessions[session].echo_id, sessions[session].event_id,"AMAZON.HelpIntent");
>
2014c2101
<           response.response.outputSpeech.text = 'Das habe ich leider nicht verstanden.';
---
>           response.response.outputSpeech.text = 'Sorry, I did not get that.';
2255,2256c2342
<         response.response.outputSpeech.text = 'Das habe ich leider nicht verstanden';
<
---
>         response.response.outputSpeech.text = 'Sorry, I did not get that.';
2267a2354
>     response.response.card.content = response.response.outputSpeech.text;



/media/etc/fhem/alexa-fhem.cfg
{
    "alexa": {
        "port": 3000,
        "name": "fhem custom skill",
        "keyFile": "./certs/server-key.pem",
        "certFile": "./certs/server-cert.pem",
        "applicationId": "amzn1.ask.skill.xxxx",
        "oauthClientID": "amzn1.application-oa2-client.xxxx"
    },
   "connections" : [
      {
         "server" : "127.0.0.1",
         "name" : "FHEM",
         "port" : "8083",
         "webname" : "fhem",
         "filter" : "alexaName=..*",
         "uid" : 999,
         "ssl": true,
         "auth": {"user": "xxx", "pass": "xxx"}
      }
   ],
   "sshproxy" : {
      "description" : "FHEM Connector",
      "ssh" : "/usr/bin/ssh"
   }
}



key open topics:
   - have not found a way around opening port 3000 ....
   - for some reason, I'm not getting a SessionEndedRequest when there is no response from the user.
      In the scenario of, "... no motion, shall I turn off the lights", not receiving an answer is exactly the use case where one would want to turn off the light .... hence not getting a SessionEndedRequest is a problem.
      Really would not like to hack a solution based on a timer or similar, SessionEndedRequest must come.
   - clean up
        custom skill id is hardcoded in 37_echodevice
        server.js code clean up


Any suggestions regarding the current design and implementation?

Cheers,
Paulo
       

MadMax-FHEM

Hey Paulo,

that sounds really GREAT! :)

Maybe I'll (have to ;)  ) get some time before Easter...

But (sorry): no ideas regarding your open points... :-\

Timer also was my first idea or (in my case) an at in fhem.
So "asking" and defmod an at for x seconds and if no response the "default action" is performed...

For the port 3000 issue I think that will remain?
If there would be a solution also for Custom Skills I think Andre would have posted one...

Keep on going!! :)

Bye, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

plopes9000

Hi Joachim,

Regarding the SessionEndedRequest I just tested on an echo dot and it works fine, I do get a SessionEndedRequest. Hence the issue is restricted to echo show type devices.

I've also removed the hardcoded skill id on the 37_echodevice.pm file in favour of an attribute at either the echomaster or a specific echo device.

echomaster attributes
userattr annoucement_skill_id
annoucement_skill_id amzn1.ask.skill.xxxx


37_echodevice.pm

                my $skill_id = AttrVal($hash->{IODev}{NAME},"annoucement_skill_id","");
                $skill_id = AttrVal($name,"annoucement_skill_id","") if($skill_id eq "");
                if($skill_id eq "") {
                   Log3 ($name, 4, "[$name] [echodevice_SendMessage, announcement] missing annoucement_skill_id attribute");
                   return;
                }




updated key open topics:
   - have not found a way around opening port 3000 ....
   - not getting a SessionEndedRequest on echo show devices when there is no response from the user.
   - clean up
        server.js code clean up



Best Regards,
Paulo

justme1968

falls es noch von interesse ist:

wenn man dinge probieren möchte die mit dem smart home api nicht gehen bietet sich fast immer custom skill variante an.

es gibt eigentlich 'nur' zwei nachteile: man muss den skill namen aktiv mit ansagen und man muss sich etwas einarbeiten :). dafür kann man so ziemlich alles umsetzen was man möchte.


die wiki beschreibung zur einrichtung auf amazon seite ist leider veraltet, aber das prinzip ist immer noch das gleiche. auf fhem seite ist die nötige funktionalität wie gehabt im alexa modul und alexa-fhem enthalten. eine alexa-fhem installation kann problemlos den fhem connector, einen custom skill mit port weiterleitung und belieb viele fhem instanzen gleichzeitig bedienen. das alexa modul unterstützt beim erstellen der skill konfiguration.

die eigentliche logik wird komplett auf fhem seite abgedeckt, fhem kann auf variable parameter im kommando zu greifen, fhem gibt eine gesprochen antwort über den echo und kann optional auf die fortsetzung des dialoges warten. in der fhem rückgabe können auch alle möglichkeiten von ssml (https://developer.amazon.com/de/blogs/alexa/post/5c631c3c-0d35-483f-b226-83dd98def117/new-ssml-features-give-alexa-a-wider-range-of-natural-expression) wie z.b. flüstern oder unterschiedliche stimmen genutzt werden.

fhem hat hier auch zugriff auf den raum in dem ein echo steht und auf die stimme des sprechenden falls eingerichtet.

ein beispiel das anhand eines sprach kommandos rechenoperationen durchführt findet sich z.b. hier: https://forum.fhem.de/index.php/topic,67490.msg589378.html#msg589378 .

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

plopes9000

@justme1968, that is indeed an interesting functionality of alexa-fhem that I was not ware of.

However since one has to call up the skill, it does not really fit the use case here - we would want the echo device to prompt a question on demand (eg. based on an automated trigger) rather them by user request.

I did get it to work well, except for the points I last raised:
   a) have not found a way around opening port 3000 ....
   b) not getting a SessionEndedRequest on echo show devices when there is no response from the user.

b) is a general problem with alexa skills behaviour on echo shows for which there does not appear to be a solution at the moment - since a while actually.

In the end after getting it to work, the benefit versus having to leave port 3000 open i.e. "a)", with the unsurmountable issue of "b)" - I have 10+ echo dot/flex and 4 echo shows - does not make it feel worthwhile for me.

Hence I have disabled it for now.

Thank you for responding and hinting at other options and thank you very much for all the work put into alexa-fhem, connector, etc. :)
Paulo


balli1187

@justme1968: danke für deine Rückmeldung.

Leider ist das "Aktive Ansagen des Skill-Namen" genau der Punkt, der mich am meisten vom Custom-Skill abhält. Ich persönlich empfinde das einfach nicht als "natürlich" (aber das ist natürlich mein Problem).

Vielleicht probiere ich es trotzdem mal aus, um mich mal ein wenig damit auseinander zu setzen. Bei den ganzen vorherigen Posts von Paulo, komme ich nicht so recht mit...
Vielleicht könnte man aber so ein paar Sachen des Custom Skills mit Hilfe des echodevice-Moduls triggern. Dieses bietet ja die Möglichkeit per textcommand einen (ansonsten gesprochenen) Befehl an amazon zu übergeben.
Wenn ich jetzt keinen Knoten im Hirn habe, könnte ich damit ja vielleicht die ersten Punkt umgehen?!
Bleibt nur die Frage ob sich die Abläufe dann so gestalten lassen, dass im Anschluss an ein (fiktives, ggf. kryptisches) Kommando die richtigen Abläufe (in dem Fall die Nachfragen auf einem bestimmtem Echo) abbilden lassen....
FHEM auf QNAP im docker, nanoCUL per ser2net an VU+, 2x Echo Dot, 3x HM-ES-PMSw1-Pl, 3x HM-LC-Bl1PBU-FM, 6x Sonoff Basic, div. "Shelly Eigenbauten" von Papa Romeo, ESPRGBWW-Controller, ...
Projekte: Smart Mirror in Spiegelschrank auf RPi Zero

locodriver

Ich habe etwas gefunden, was thematisch hier rein passt:

Ab 17:21 wird eine Querlüftung beschrieben und in der Videobeschreibung auf den ursprünglichen Beitrag verwiesen.

K.A., ob das hilfreich ist, hier in dieser Richtung weiter zu kommen...

https://www.youtube.com/watch?v=KEe1FJ6szKw

https://github.com/fabiankrauss/iobroker.scripte

Vielleicht können die "Experten" damit was für fhem basteln...?!
fhem 6.0 auf Rpi3 Bookworm
HM-LAN-CFG (FW 0.965), HM-MOD-UART, 2x HM-TC-IT-WM-W-EU, 4x HM-Sec-RHS und 3x HM-CC-RT-DN, 6x HM-LC-Bl1-FM mit je 1x Somfy-Motor,
2x HM-LC-SW2-FM für Licht und Lüfter, 2x HM-PB-6-WM55, Alexa, Jeelinkcross, CUL, CUNO2, IR-Blaster