@jwerlsdf
weiter gehts mit der nächsten version.
vorgehensweise wie oben.
es sind ein paar mehr datenpunkte dazugekommen
bitte vorher die datenpunkte anlegen. typ und detailanweisung im zeilenkommentar beachten
const dp_doorstop = '0_userdata.0.omlet.doorstop'; // datenpunkt mit typ bool und rolle button anlegen und namen hier eintragen
const dp_doortimeopen = '0_userdata.0.omlet.doortimeopen'; // datenpunkt mit typ string, zeit im 24h format im format 06:00 oder 20:30
const dp_doortimeclose = '0_userdata.0.omlet.doortimeclose'; // datenpunkt mit typ string, zeit im 24h format im format 06:00 oder 20:30
const dp_devicedata = '0_userdata.0.omlet.devicedata'; //// datenpunkt mit typ string, hier wird nach jeder aktualisierung der aktuelle device status abgerufen und eingetragen
wenn im datenpunkt dp_doortimeopen und dp_doortimeclose etwas eingetragen wird, dann sollte die jeweilige zeit gesetzt werden.
im Anschluss wird die Konfiguration gleich abgerufen und im Datenpunkt dp_devicedata abgespeichert, sowie auch dp_doortimeopen und dp_doortimeclose wieder aktualisiert
der button doorstop führt die entsprechende aktion aus.
um mit dem angeschlossenen gerät nicht zu viel unruhe zu erzeugen, habe ich (hoffentlich) nur die lesenden aktionen ausgeführt. die schreibenden aktionen habe ich mal ausgelassen, was aber auch mangels test zu höheren fehlerrisiko neigt. aber mal schauen.
bitte möglichst genau darüber berichten
// -- configuration area
const token = 'apitoken';
const outdoorDeviceId = 'laTnMsWSJxBMGgJD';
const dp_light = '0_userdata.0.omlet.light'; // datenpunkt mit typ bool anlegen und namen hier eintragen
const dp_door = '0_userdata.0.omlet.door'; // datenpunkt mit typ bool anlegen und namen hier eintragen
const dp_doorstop = '0_userdata.0.omlet.doorstop'; // datenpunkt mit typ bool und rolle button anlegen und namen hier eintragen
const dp_doortimeopen = '0_userdata.0.omlet.doortimeopen';
const dp_doortimeclose = '0_userdata.0.omlet.doortimeclose';
const dp_devicedata = '0_userdata.0.omlet.devicedata';
// --
const axios = require("axios/dist/browser/axios.cjs");
const BASE_URL = 'https://x107.omlet.co.uk/api/v1'; //kann hier geprüft werden https://smart.omlet.de/developers/api
let omlet = undefined;
async function connect() {
console.log("start main2");
omlet = await omletAPIClient(token);
await getDevices(true);
//console.log(JSON.stringify(await getDevices(), null, 2));
}
async function getDevices(info = false) {
try {
const devices = await getRequest('/device');
if (devices && info) {
devices.forEach(device => {
console.log(`Device name: ${device.name}, deviceId: ${device.deviceId}`);
});
}
return devices;
} catch (error) {
console.log(error);
return [];
}
}
async function getDevice(deviceId) {
try {
const device = await getRequest(`/device/${deviceId}`);
return device;
} catch (error) {
console.log(error);
return {};
}
}
async function getConfiguration(deviceId) {
try {
const configuration = await getRequest(`/device/${deviceId}/configuration`);
return configuration;
} catch (error) {
console.log(error);
return {};
}
}
async function setConfiguration(deviceId, configuration) {
try {
const result = await patchRequest(`/device/${deviceId}/configuration`, configuration);
return result;
} catch (error) {
console.log(error);
return {};
}
}
async function getDeviceInfo(deviceId) {
const device = await getDevice(deviceId);
setState(dp_devicedata, JSON.stringify(device, null, 2), device);
setState(dp_doortimeopen, device.configuration.door.openTime);
setState(dp_doortimeclose, device.configuration.door.closeTime);
}
async function doAction(deviceId, actionName) {
const devices = await getDevices();
const device = devices.find(device => device.deviceId === deviceId);
if (device) {
const action = device.actions.find(action => action.actionName === actionName);
if (action) {
await postRequest(action.url);
await getDeviceInfo(outdoorDeviceId);
}
}
}
async function lightOn(deviceId) {
await doAction(deviceId, 'on');
}
async function lightOff(deviceId) {
await doAction(deviceId, 'off');
}
async function doorOpen(deviceId) {
await doAction(deviceId, 'open');
}
async function doorClose(deviceId) {
await doAction(deviceId, 'close');
}
async function doorStop(deviceId) {
await doAction(deviceId, 'stop');
}
async function setDoorTimeClose(deviceId, time) {
const configuration = getConfiguration(deviceId);
const newConfiguration = {
...configuration,
door: {
...configuration.door,
closeTime: time
}
};
await setConfiguration(deviceId, newConfiguration);
await getDeviceInfo(outdoorDeviceId);
}
async function setDoorTimeOpen(deviceId, time) {
const configuration = getConfiguration(deviceId);
const newConfiguration = {
...configuration,
door: {
...configuration.door,
openTime: time
}
};
await setConfiguration(deviceId, newConfiguration);
await getDeviceInfo(outdoorDeviceId);
}
function omletAPIClient(token) {
return axios.create({
baseURL: BASE_URL,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
}
function isValidTime24h(value) {
return /^(?:[01]\d|2[0-3]):[0-5]\d$/.test(value);
}
async function getRequest(url) {
try {
const data = await omlet.get(url);
console.debug(`get request: ${url},status: ${data.status}`);
return data.data;
} catch (e) {
console.log(e);
}
}
async function postRequest(url) {
try {
const data = await omlet.post(url);
console.debug(`post request: ${url},status: ${data.status}`);
return data.data;
} catch (e) {
console.log(e);
}
}
async function patchRequest(url, data) {
try {
const data = await omlet.patch(url, data);
console.debug(`patch request: ${url},status: ${data.status}`);
return data.data;
} catch (e) {
console.log(e);
}
}
function watchTimeState(id, label) {
on({ id: id, change: 'ne' }, async (obj) => {
const newVal = String(obj.state.val || '').trim();
const oldVal = obj.oldState && obj.oldState.val != null
? String(obj.oldState.val)
: '';
if (isValidTime24h(newVal)) {
log(`${label}: gültige Zeit gesetzt -> ${newVal}`, 'debug');
let configuration = await getConfiguration(outdoorDeviceId);
return;
}
log(`${label}: ungültige Zeit "${newVal}" - setze auf "${oldVal}" zurück`, 'warn');
// ungültige Eingabe zurücksetzen
setState(id, oldVal);
});
}
async function main() {
await connect();
await getDeviceInfo(outdoorDeviceId);
on({ id: dp_door, change: 'ne' }, async (evt) => {
//log(evt);
if (evt.state.val) {
await doorOpen(outdoorDeviceId);
} else {
await doorClose(outdoorDeviceId);
}
});
on({ id: dp_light, change: 'ne' }, async (evt) => {
//log(evt);
if (evt.state.val) {
await lightOn(outdoorDeviceId);
} else {
await lightOff(outdoorDeviceId);
}
});
on({ id: dp_doorstop, change: 'any' }, async (evt) => {
log(evt);
doorStop(outdoorDeviceId);
setState(dp_doorstop, false);
});
watchTimeState(dp_doortimeopen, 'Öffnungszeit');
watchTimeState(dp_doortimeclose, 'Schließzeit');
// await lightOn(outdoorDeviceId);
// await lightOff(outdoorDeviceId);
let configuration = await getConfiguration(outdoorDeviceId);
let a = 0;
}
main();
für astro hat der iobroker ja bereits ereignisse eingebaut,
wenn die dann aufgerufen werden musst du dann einfach nur die Funktionen doorOpen und doorClose mit der deviceId (die in der Variable outdoorDeviceId steht) aufrufen
Sind die Funktionen soweit verständlich? Brauchst du mehr Detaildokumentation für spätere Anpassungen?