index.js: schlanke Version mit Factories, PERIOD_PHRASES, GetPowerKammerUsageIntent, GetEnergyCostKammerIntent
This commit is contained in:
+69
-393
@@ -1,415 +1,91 @@
|
||||
const Alexa = require('ask-sdk-core');
|
||||
const https = require('https');
|
||||
|
||||
// ---- Konfiguration ----
|
||||
// Werte kommen aus der .env-Datei im selben Verzeichnis (siehe unten)
|
||||
require('dotenv').config();
|
||||
const HA_URL = process.env.HA_URL; // z.B. "https://haos.vogt.de.com"
|
||||
const HA_TOKEN = process.env.HA_TOKEN; // Long-Lived Access Token aus HA
|
||||
const { makeApplianceIntent, makeSimpleSensorIntent, makeSlotSensorIntent, PERIOD_PHRASES } = require('./factories');
|
||||
const {
|
||||
LaunchRequestHandler,
|
||||
HelpIntentHandler,
|
||||
CancelAndStopIntentHandler,
|
||||
FallbackIntentHandler,
|
||||
SessionEndedRequestHandler,
|
||||
ErrorHandler,
|
||||
} = require('./static-handlers');
|
||||
|
||||
// Raum-ID (aus dem RoomList Slot) -> climate Entity-ID in Home Assistant
|
||||
const roomToClimateEntity = {
|
||||
badezimmer: 'climate.badezimmer_heizungssteuerung',
|
||||
kinderzimmer: 'climate.kinderzimmer_heizungssteuerung',
|
||||
kueche: 'climate.kueche_heizungssteuerung',
|
||||
schlafzimmer: 'climate.schlafzimmer_heizungssteuerung',
|
||||
wohnzimmer: 'climate.wohnzimmer_heizungssteuerung',
|
||||
// diele, gaeste_wc, balkon_hinten, balkon_vorne, kammer: kein Sensor vorhanden
|
||||
};
|
||||
// Hinweis: Temperaturabfragen laufen jetzt ueber die native Nabu-Casa-
|
||||
// Smart-Home-Integration, nicht mehr ueber diesen Custom Skill.
|
||||
|
||||
// Aktueller Stromverbrauch (Leistung in Watt)
|
||||
const POWER_ENTITY = 'sensor.kammer_netzbezug_plus_keller_power_calc';
|
||||
// ---- Einfache Sensor-Werte (kein Slot) ----
|
||||
|
||||
// Stromkosten je Zeitraum (Periode-ID aus dem PeriodList Slot -> Entity-ID)
|
||||
const periodToEnergyCostEntity = {
|
||||
tag: 'sensor.netzbezug_kosten_tag',
|
||||
woche: 'sensor.netzbezug_kosten_woche',
|
||||
monat: 'sensor.netzbezug_kosten_monat',
|
||||
};
|
||||
const GetPowerUsageIntentHandler = makeSimpleSensorIntent({
|
||||
intentName: 'GetPowerUsageIntent',
|
||||
entityId: 'sensor.kammer_netzbezug_plus_keller_power_calc',
|
||||
transformValue: (v) => Math.round(parseFloat(v)),
|
||||
template: (value, unit) => `Der aktuelle Stromverbrauch betraegt ${value} ${unit || 'Watt'}.`,
|
||||
notFoundMessage: 'Ich konnte den aktuellen Stromverbrauch nicht auslesen.',
|
||||
});
|
||||
|
||||
// Waschmaschine
|
||||
const WASHING_MACHINE_STATUS_ENTITY = 'sensor.waschmaschine_betriebszustand';
|
||||
const WASHING_MACHINE_PROGRESS_ENTITY = 'sensor.waschmaschine_programm_fortschritt';
|
||||
const WASHING_MACHINE_END_TIME_ENTITY = 'sensor.waschmaschine_programm_endzeit';
|
||||
const GetPowerKammerUsageIntentHandler = makeSimpleSensorIntent({
|
||||
intentName: 'GetPowerKammerUsageIntent',
|
||||
entityId: 'sensor.kammer_serverschrank_leistung',
|
||||
transformValue: (v) => Math.round(parseFloat(v)),
|
||||
template: (value, unit) => `Der aktuelle Stromverbrauch in der Kammer betraegt ${value} ${unit || 'Watt'}.`,
|
||||
notFoundMessage: 'Ich konnte den aktuellen Stromverbrauch in der Kammer nicht auslesen.',
|
||||
});
|
||||
|
||||
// Trockner
|
||||
const DRYER_STATUS_ENTITY = 'sensor.trockner_betriebszustand';
|
||||
const DRYER_PROGRESS_ENTITY = 'sensor.trockner_programm_fortschritt';
|
||||
const DRYER_END_TIME_ENTITY = 'sensor.trockner_programm_endzeit';
|
||||
// ---- Stromkosten nach Zeitraum (Slot Period) ----
|
||||
|
||||
// Hilfsfunktion: HA REST API abfragen
|
||||
function getHaState(entityId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = new URL(`${HA_URL}/api/states/${entityId}`);
|
||||
const options = {
|
||||
hostname: url.hostname,
|
||||
path: url.pathname,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${HA_TOKEN}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
const req = https.request(options, (res) => {
|
||||
let data = '';
|
||||
res.on('data', (chunk) => (data += chunk));
|
||||
res.on('end', () => {
|
||||
if (res.statusCode !== 200) {
|
||||
reject(new Error(`HA API Fehler: ${res.statusCode} - ${data}`));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
resolve(JSON.parse(data));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
const LaunchRequestHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
|
||||
const GetEnergyCostIntentHandler = makeSlotSensorIntent({
|
||||
intentName: 'GetEnergyCostIntent',
|
||||
slotName: 'Period',
|
||||
idToEntityMap: {
|
||||
tag: 'sensor.netzbezug_kosten_tag',
|
||||
woche: 'sensor.netzbezug_kosten_woche',
|
||||
monat: 'sensor.netzbezug_kosten_monat',
|
||||
},
|
||||
handle(handlerInput) {
|
||||
const speakOutput = 'Willkommen beim Hausassistent. Du kannst mich zum Beispiel fragen, wie warm es in einem Raum ist.';
|
||||
return handlerInput.responseBuilder
|
||||
.speak(speakOutput)
|
||||
.reprompt(speakOutput)
|
||||
.getResponse();
|
||||
transformValue: (v) => parseFloat(v).toFixed(2).replace('.', ','),
|
||||
template: (value, unit, periodSpoken, periodId) =>
|
||||
`Die Stromkosten fuer ${PERIOD_PHRASES[periodId] || periodSpoken} betragen ${value} ${unit || 'Euro'}.`,
|
||||
unknownSlotMessage: 'Ich habe den Zeitraum leider nicht verstanden. Du kannst zum Beispiel nach Tag, Woche oder Monat fragen.',
|
||||
});
|
||||
|
||||
const GetEnergyCostKammerIntentHandler = makeSlotSensorIntent({
|
||||
intentName: 'GetEnergyCostKammerIntent',
|
||||
slotName: 'Period',
|
||||
idToEntityMap: {
|
||||
tag: 'sensor.kammer_serverschrank_kosten_tag',
|
||||
woche: 'sensor.kammer_serverschrank_kosten_woche',
|
||||
monat: 'sensor.kammer_serverschrank_kosten_monat',
|
||||
},
|
||||
};
|
||||
transformValue: (v) => parseFloat(v).toFixed(2).replace('.', ','),
|
||||
template: (value, unit, periodSpoken, periodId) =>
|
||||
`Die Stromkosten fuer die Kammer ${PERIOD_PHRASES[periodId] || periodSpoken} betragen ${value} ${unit || 'Euro'}.`,
|
||||
unknownSlotMessage: 'Ich habe den Zeitraum leider nicht verstanden. Du kannst zum Beispiel nach Tag, Woche oder Monat fragen.',
|
||||
});
|
||||
|
||||
const GetTemperatureIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'GetTemperatureIntent'
|
||||
);
|
||||
},
|
||||
async handle(handlerInput) {
|
||||
const slots = handlerInput.requestEnvelope.request.intent.slots;
|
||||
const roomSlot = slots.Room;
|
||||
// ---- Geraete mit Status/Fortschritt/Endzeit ----
|
||||
|
||||
// Die ID und den sauberen Namen aus dem Slot Type RoomList holen
|
||||
// (nicht den roh gesprochenen Text, der z.B. "wohnzimmer ist" statt "wohnzimmer" sein kann)
|
||||
const resolvedValue = roomSlot?.resolutions?.resolutionsPerAuthority?.[0]?.values?.[0]?.value;
|
||||
const roomId = resolvedValue?.id;
|
||||
const roomNameSpoken = resolvedValue?.name || roomSlot?.value || 'diesem Raum';
|
||||
const GetWashingMachineIntentHandler = makeApplianceIntent({
|
||||
intentName: 'GetWashingMachineIntent',
|
||||
deviceName: 'Die Waschmaschine',
|
||||
statusEntity: 'sensor.waschmaschine_betriebszustand',
|
||||
progressEntity: 'sensor.waschmaschine_programm_fortschritt',
|
||||
endTimeEntity: 'sensor.waschmaschine_programm_endzeit',
|
||||
});
|
||||
|
||||
if (!roomId) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak(`Ich kenne den Raum ${roomNameSpoken} leider nicht. Bitte versuch es mit einem anderen Raumnamen.`)
|
||||
.reprompt('Für welchen Raum möchtest du die Temperatur wissen?')
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const entityId = roomToClimateEntity[roomId];
|
||||
|
||||
if (!entityId) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak(`Für ${roomNameSpoken} habe ich leider keinen Temperatursensor.`)
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
try {
|
||||
const state = await getHaState(entityId);
|
||||
const currentTemp = state.attributes?.current_temperature;
|
||||
|
||||
if (currentTemp === undefined || currentTemp === null) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak(`Ich konnte die aktuelle Temperatur für ${roomNameSpoken} nicht auslesen.`)
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const speakOutput = `Die Temperatur im ${roomNameSpoken} beträgt ${currentTemp} Grad.`;
|
||||
return handlerInput.responseBuilder.speak(speakOutput).getResponse();
|
||||
} catch (err) {
|
||||
console.error('HA API Fehler:', err);
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Ich konnte gerade keine Verbindung zu Home Assistant herstellen. Bitte versuch es später noch einmal.')
|
||||
.getResponse();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const GetPowerUsageIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'GetPowerUsageIntent'
|
||||
);
|
||||
},
|
||||
async handle(handlerInput) {
|
||||
try {
|
||||
const state = await getHaState(POWER_ENTITY);
|
||||
const powerValue = state.state;
|
||||
|
||||
if (powerValue === undefined || powerValue === null || powerValue === 'unknown' || powerValue === 'unavailable') {
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Ich konnte den aktuellen Stromverbrauch nicht auslesen.')
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const unit = state.attributes?.unit_of_measurement || 'Watt';
|
||||
const roundedPower = Math.round(parseFloat(powerValue));
|
||||
const speakOutput = `Der aktuelle Stromverbrauch beträgt ${roundedPower} ${unit}.`;
|
||||
return handlerInput.responseBuilder.speak(speakOutput).getResponse();
|
||||
} catch (err) {
|
||||
console.error('HA API Fehler:', err);
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Ich konnte gerade keine Verbindung zu Home Assistant herstellen. Bitte versuch es später noch einmal.')
|
||||
.getResponse();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const GetEnergyCostIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'GetEnergyCostIntent'
|
||||
);
|
||||
},
|
||||
async handle(handlerInput) {
|
||||
const slots = handlerInput.requestEnvelope.request.intent.slots;
|
||||
const periodSlot = slots.Period;
|
||||
|
||||
const resolvedValue = periodSlot?.resolutions?.resolutionsPerAuthority?.[0]?.values?.[0]?.value;
|
||||
const periodId = resolvedValue?.id;
|
||||
const periodNameSpoken = resolvedValue?.name || periodSlot?.value || 'diesem Zeitraum';
|
||||
|
||||
if (!periodId) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Ich habe den Zeitraum leider nicht verstanden. Du kannst zum Beispiel nach Tag, Woche oder Monat fragen.')
|
||||
.reprompt('Für welchen Zeitraum möchtest du die Stromkosten wissen?')
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const entityId = periodToEnergyCostEntity[periodId];
|
||||
|
||||
if (!entityId) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak(`Für ${periodNameSpoken} habe ich leider keine Kostenauswertung.`)
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
try {
|
||||
const state = await getHaState(entityId);
|
||||
const costValue = state.state;
|
||||
|
||||
if (costValue === undefined || costValue === null || costValue === 'unknown' || costValue === 'unavailable') {
|
||||
return handlerInput.responseBuilder
|
||||
.speak(`Ich konnte die Stromkosten für ${periodNameSpoken} nicht auslesen.`)
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const unit = state.attributes?.unit_of_measurement || 'Euro';
|
||||
const roundedCost = parseFloat(costValue).toFixed(2).replace('.', ',');
|
||||
const speakOutput = `Die Stromkosten für diesen ${periodNameSpoken} betragen ${roundedCost} ${unit}.`;
|
||||
return handlerInput.responseBuilder.speak(speakOutput).getResponse();
|
||||
} catch (err) {
|
||||
console.error('HA API Fehler:', err);
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Ich konnte gerade keine Verbindung zu Home Assistant herstellen. Bitte versuch es später noch einmal.')
|
||||
.getResponse();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const GetWashingMachineIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'GetWashingMachineIntent'
|
||||
);
|
||||
},
|
||||
async handle(handlerInput) {
|
||||
try {
|
||||
const [statusState, progressState, endTimeState] = await Promise.all([
|
||||
getHaState(WASHING_MACHINE_STATUS_ENTITY).catch(() => null), // optional, falls Entity nicht existiert
|
||||
getHaState(WASHING_MACHINE_PROGRESS_ENTITY),
|
||||
getHaState(WASHING_MACHINE_END_TIME_ENTITY),
|
||||
]);
|
||||
|
||||
// Betriebszustand prüfen (z.B. "fertig", "inaktiv") - analog zum HA-Template
|
||||
const betrieb = statusState?.state?.toLowerCase().trim();
|
||||
const inactiveStates = ['fertig', 'inaktiv', 'finished', 'inactive'];
|
||||
if (betrieb && inactiveStates.includes(betrieb)) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Die Waschmaschine läuft aktuell nicht.')
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const progress = progressState.state;
|
||||
const endTimeRaw = endTimeState.state;
|
||||
const unknownValues = ['unknown', 'unavailable', 'none'];
|
||||
|
||||
if (unknownValues.includes(progress) || unknownValues.includes(endTimeRaw)) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Die Waschmaschine läuft aktuell nicht.')
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const endTime = new Date(endTimeRaw);
|
||||
const now = new Date();
|
||||
const diffMs = endTime.getTime() - now.getTime();
|
||||
|
||||
if (diffMs <= 0) {
|
||||
return handlerInput.responseBuilder.speak('Die Waschmaschine ist fertig.').getResponse();
|
||||
}
|
||||
|
||||
const roundedProgress = Math.round(parseFloat(progress));
|
||||
|
||||
// Endzeit als HH:MM in deutscher Zeitzone formatieren
|
||||
const timeFormatted = new Intl.DateTimeFormat('de-DE', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
timeZone: 'Europe/Berlin',
|
||||
}).format(endTime);
|
||||
|
||||
const speakOutput = `Die Waschmaschine ist ${roundedProgress} Prozent fertig und endet um ${timeFormatted} Uhr.`;
|
||||
return handlerInput.responseBuilder.speak(speakOutput).getResponse();
|
||||
} catch (err) {
|
||||
console.error('HA API Fehler:', err);
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Ich konnte gerade keine Verbindung zu Home Assistant herstellen. Bitte versuch es später noch einmal.')
|
||||
.getResponse();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const GetDryerIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'GetDryerIntent'
|
||||
);
|
||||
},
|
||||
async handle(handlerInput) {
|
||||
try {
|
||||
const [statusState, progressState, endTimeState] = await Promise.all([
|
||||
getHaState(DRYER_STATUS_ENTITY).catch(() => null),
|
||||
getHaState(DRYER_PROGRESS_ENTITY),
|
||||
getHaState(DRYER_END_TIME_ENTITY),
|
||||
]);
|
||||
|
||||
const betrieb = statusState?.state?.toLowerCase().trim();
|
||||
const inactiveStates = ['fertig', 'inaktiv', 'finished', 'inactive'];
|
||||
if (betrieb && inactiveStates.includes(betrieb)) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Der Trockner läuft aktuell nicht.')
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const progress = progressState.state;
|
||||
const endTimeRaw = endTimeState.state;
|
||||
const unknownValues = ['unknown', 'unavailable', 'none'];
|
||||
|
||||
if (unknownValues.includes(progress) || unknownValues.includes(endTimeRaw)) {
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Der Trockner läuft aktuell nicht.')
|
||||
.getResponse();
|
||||
}
|
||||
|
||||
const endTime = new Date(endTimeRaw);
|
||||
const now = new Date();
|
||||
const diffMs = endTime.getTime() - now.getTime();
|
||||
|
||||
if (diffMs <= 0) {
|
||||
return handlerInput.responseBuilder.speak('Der Trockner ist fertig.').getResponse();
|
||||
}
|
||||
|
||||
const roundedProgress = Math.round(parseFloat(progress));
|
||||
|
||||
const timeFormatted = new Intl.DateTimeFormat('de-DE', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
timeZone: 'Europe/Berlin',
|
||||
}).format(endTime);
|
||||
|
||||
const speakOutput = `Der Trockner ist ${roundedProgress} Prozent fertig und endet um ${timeFormatted} Uhr.`;
|
||||
return handlerInput.responseBuilder.speak(speakOutput).getResponse();
|
||||
} catch (err) {
|
||||
console.error('HA API Fehler:', err);
|
||||
return handlerInput.responseBuilder
|
||||
.speak('Ich konnte gerade keine Verbindung zu Home Assistant herstellen. Bitte versuch es später noch einmal.')
|
||||
.getResponse();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const HelpIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.HelpIntent'
|
||||
);
|
||||
},
|
||||
handle(handlerInput) {
|
||||
const speakOutput = 'Du kannst mich zum Beispiel fragen: wie warm ist es im Wohnzimmer.';
|
||||
return handlerInput.responseBuilder.speak(speakOutput).reprompt(speakOutput).getResponse();
|
||||
},
|
||||
};
|
||||
|
||||
const CancelAndStopIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
(Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.CancelIntent' ||
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.StopIntent')
|
||||
);
|
||||
},
|
||||
handle(handlerInput) {
|
||||
const speakOutput = 'Bis bald!';
|
||||
return handlerInput.responseBuilder.speak(speakOutput).getResponse();
|
||||
},
|
||||
};
|
||||
|
||||
const FallbackIntentHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return (
|
||||
Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' &&
|
||||
Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.FallbackIntent'
|
||||
);
|
||||
},
|
||||
handle(handlerInput) {
|
||||
const speakOutput = 'Das habe ich nicht verstanden. Du kannst mich zum Beispiel fragen, wie warm es im Wohnzimmer ist.';
|
||||
return handlerInput.responseBuilder.speak(speakOutput).reprompt(speakOutput).getResponse();
|
||||
},
|
||||
};
|
||||
|
||||
const SessionEndedRequestHandler = {
|
||||
canHandle(handlerInput) {
|
||||
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'SessionEndedRequest';
|
||||
},
|
||||
handle(handlerInput) {
|
||||
return handlerInput.responseBuilder.getResponse();
|
||||
},
|
||||
};
|
||||
|
||||
const ErrorHandler = {
|
||||
canHandle() {
|
||||
return true;
|
||||
},
|
||||
handle(handlerInput, error) {
|
||||
console.error(`~~~~ Error handled: ${error.stack}`);
|
||||
const speakOutput = 'Entschuldigung, da ist etwas schiefgelaufen. Bitte versuch es noch einmal.';
|
||||
return handlerInput.responseBuilder.speak(speakOutput).reprompt(speakOutput).getResponse();
|
||||
},
|
||||
};
|
||||
const GetDryerIntentHandler = makeApplianceIntent({
|
||||
intentName: 'GetDryerIntent',
|
||||
deviceName: 'Der Trockner',
|
||||
statusEntity: 'sensor.trockner_betriebszustand',
|
||||
progressEntity: 'sensor.trockner_programm_fortschritt',
|
||||
endTimeEntity: 'sensor.trockner_programm_endzeit',
|
||||
});
|
||||
|
||||
exports.handler = Alexa.SkillBuilders.custom()
|
||||
.addRequestHandlers(
|
||||
LaunchRequestHandler,
|
||||
GetTemperatureIntentHandler,
|
||||
GetPowerUsageIntentHandler,
|
||||
GetPowerKammerUsageIntentHandler,
|
||||
GetEnergyCostIntentHandler,
|
||||
GetEnergyCostKammerIntentHandler,
|
||||
GetWashingMachineIntentHandler,
|
||||
GetDryerIntentHandler,
|
||||
HelpIntentHandler,
|
||||
|
||||
Reference in New Issue
Block a user