UNPKG

iobroker.javascript

Version:
1,113 lines (917 loc) 77.7 kB
## Content - [Note](#note) - [Global functions](#global-functions) - [Best practice](#best-practice) - [Functions](#following-functions-can-be-used-in-scripts) - [require - load some module](#require---load-some-module) - [console - Gives out the message into log](#console---gives-out-the-message-into-log) - [exec - execute some OS command, like "cp file1 file2"](#exec---execute-some-os-command-like-cp-file1-file2) - [on - Subscribe on changes or updates of some state](#on---subscribe-on-changes-or-updates-of-some-state) - [once](#once) - [subscribe - same as on](#subscribe---same-as-on) - [unsubscribe](#unsubscribe) - [getSubscriptions](#getsubscriptions) - [getFileSubscriptions](#getfilesubscriptions) - [schedule](#schedule) - [Time schedule](#time-schedule) - [Astro-function](#astro-function) - [scheduleById](#schedulebyid) - [getSchedules](#getschedules) - [clearSchedule](#clearschedule) - [getAttr](#getattr) - [getAstroDate](#getastrodate) - [isAstroDay](#isastroday) - [compareTime](#comparetime) - [setState](#setstate) - [setStateAsync](#setstateasync) - [setStateDelayed](#setstatedelayed) - [clearStateDelayed](#clearstatedelayed) - [getStateDelayed](#getstatedelayed) - [getState](#getstate) - [getStateAsync](#getstateasync) - [existsState](#existsState) - [getObject](#getobject) - [setObject](#setobject) - [existsObject](#existsObject) - [extendObject](#extendobject) - [deleteObject](#deleteobject) - [getIdByName](#getidbyname) - [getEnums](#getenums) - [createState](#createstate) - [createStateAsync](#createstateasync) - [deleteState](#deletestate) - [deleteStateAsync](#deletestateasync) - [sendTo](#sendto) - [sendToAsync](#sendtoasync) - [sendToHost](#sendtohost) - [sendToHostAsync](#sendtohostasync) - [setInterval](#setinterval) - [clearInterval](#clearinterval) - [setTimeout](#settimeout) - [clearTimeout](#cleartimeout) - [setImmediate](#setImmediate) - [formatDate](#formatdate) - [formatTimeDiff](#formattimediff) - [getDateObject](#getDateObject) - [formatValue](#formatvalue) - [adapterSubscribe](#adaptersubscribe) - [adapterUnsubscribe](#adapterunsubscribe) - [$ - Selector](#---selector) - [readFile](#readfile) - [writeFile](#writefile) - [delFile](#delFile) - [renameFile](#renameFile) - [onFile](#onFile) - [offFile](#offFile) - [onStop](#onstop) - [getHistory](#gethistory) - [runScript](#runscript) - [runScriptAsync](#runScriptAsync) - [startScript](#startscript) - [startScriptAsync](#startscriptasync) - [stopScript](#stopscript) - [stopScriptAsync](#stopScriptAsync) - [isScriptActive](#isscriptactive) - [name](#scriptName) - [instance](#instance) - [messageTo](#messageto) - [messageToAsync](#messagetoasync) - [onMessage](#onmessage) - [onMessageUnregister](#onmessageunregister) - [onLog](#onlog) - [onLogUnregister](#onlogunregister) - [wait](#wait) - [sleep](#sleep) - [httpGet](#httpget) - [httpPost](#httppost) - [createTempFile](#createtempfile) - [registerNotification](#registerNotification) - [Scripts activity](#scripts-activity) - [Changelog](#changelog) ## Global functions You can define the global scripts in the `global` folder. All global scripts are available on all instances. If a global script is disabled, it will not be used. Global script will be just prepended to the normal script and compiled, so you cannot share data between scripts via global scripts. Use states for it. To use global functions in TypeScript, you have to `declare` them first, so the compiler knows about the global functions. Example: ```typescript // global script: // ============== function globalFn(arg: string): void { // actual implementation } // normal script: // ============== declare function globalFn(arg: string): void; // use as normal: globalFn('test'); ``` #### Best practice: Create two instances of javascript adapter: one "test" and one "production". After the script is tested in the "test" instance, it can be moved to "production". By that you can restart the "test" instance as you want. ## The following functions can be used in scripts: ### require - load some module ```js const mod = require('module_name'); ``` The following modules are preloaded: `node:dgram`, `node:crypto`, `node:dns`, `node:events`, `node:fs`, `node:http`, `node:https`, `node:http2`, `node:net`, `node:os`, `node:path`, `node:util`, `node:stream`, `node:zlib`, `suncalc2`, `axios`, `wake_on_lan`, `request` (deprecated) To use other modules, enter the name (and version) of the module in the instance configuration. ioBroker will install the module. You can require and use it in your scripts afterwards. ### console - Gives out the message into log Usage is the same as in `javascript` ### exec - execute some OS command, like `cp file1 file2` ```js exec(cmd, [options], callback); ``` Execute system command and get the outputs. ```js // Get the list of files and directories in /var/log exec('ls /var/log', (error, stdout, stderr) => { log('stdout: ' + stdout); }); ``` Node.js uses /bin/sh to execute commands. If you want to use another shell, you can use the option object as described in the [Node.js documentation](https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback) for child_process.exec. It is the best practice to always use fill path names to commands to make sure the right command is executed. **Notice:** you must enable *Enable command "setObject"* option to call it. ### on - Subscribe on changes or updates of some state ```js on(pattern, callbackOrId, value); ``` The callback function will return the object as parameter with the following content: ```js { id: 'javascript.0.myplayer', state: { val: 'new state', ts: 1416149118, ack: true, lc: 1416149118, from: 'system.adapter.sonos.0' }, oldState: { val: 'old state', ts: 1416148233, ack: true, lc: 1416145154, from: 'system.adapter.sonos.0' } } ``` **Note:** `state` was previously called `newState`. That is still working. Example: ```js let timer; // Create state "javascript.0.counter" createState('counter', 0); // On change on('adapter.0.device.channel.sensor', (data) => { // But not ofter than 30 seconds if (!timer) { timer = setTimeout(() => { timer = null; }, 30000); // Set acknowledged value setState('counter', 1 + getState('counter'), true); // Or to set unacknowledged command setState('adapter.0.device.channel.actor', true); } }); ``` You can use the following parameters to specify the trigger: | parameter | type/value | description | |-------------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| | logic | string | "and" or "or" logic to combine the conditions \(default: "and"\) | | | | | | id | string | id is equal to given one | | | RegExp | id matched to regular expression | | | Array | id matched to a list of allowed IDs | | | | | | name | string | name is equal to given one | | | RegExp | name matched to regular expression | | | Array | name matched to a list of allowed names | | | | | | change | string | "eq", "ne", "gt", "ge", "lt", "le", "any" | | | "eq" | (equal) New value must be equal to old one (state.val == oldState.val) | | | "ne" | (not equal) New value must be not equal to the old one (state.val != oldState.val) **If pattern is id-string this value is used by default** | | | "gt" | (greater) New value must be greater than old value (state.val > oldState.val) | | | "ge" | (greater or equal) New value must be greater or equal to old one (state.val >= oldState.val) | | | "lt" | (smaller) New value must be smaller than old one (state.val < oldState.val) | | | "le" | (smaller or equal) New value must be smaller or equal to old value (state.val <= oldState.val) | | | "any" | Trigger will be raised if just the new value comes | | | | | | val | mixed | New value must be equal to given one | | valNe | mixed | New value must be not equal to given one | | valGt | mixed | New value must be greater than given one | | valGe | mixed | New value must be greater or equal to given one | | valLt | mixed | New value must be smaller than given one | | valLe | mixed | New value must be smaller or equal to given one | | | | | | ack | boolean | Acknowledged state of new value is equal to given one | | q | number | Quality code state of new value is equal to given one. You can use '*' for matching to any code. **If not provided q = 0 is set as pattern!** | | | | | | oldVal | mixed | Previous value must be equal to given one | | oldValNe | mixed | Previous value must be not equal to given one | | oldValGt | mixed | Previous value must be greater than given one | | oldValGe | mixed | Previous value must be greater or equal to given one | | oldValLt | mixed | Previous value must be smaller than given one | | oldValLe | mixed | Previous value must be smaller or equal to given one | | | | | | oldAck | bool | Acknowledged state of previous value is equal to given one | | oldQ | number | Quality code state of previous value is equal to given one. You can use '*' for matching to any code | | | | | | ts | string | New value time stamp must be equal to given one (state.ts == ts) | | tsGt | string | New value time stamp must be not equal to the given one (state.ts != ts) | | tsGe | string | New value time stamp must be greater than given value (state.ts > ts) | | tsLt | string | New value time stamp must be greater or equal to given one (state.ts >= ts) | | tsLe | string | New value time stamp must be smaller than given one (state.ts < ts) | | | | | | oldTs | string | Previous time stamp must be equal to given one (oldState.ts == ts) | | oldTsGt | string | Previous time stamp must be not equal to the given one (oldState.ts != ts) | | oldTsGe | string | Previous time stamp must be greater than given value (oldState.ts > ts) | | oldTsLt | string | Previous time stamp must be greater or equal to given one (oldState.ts >= ts) | | oldTsLe | string | Previous time stamp must be smaller than given one (oldState.ts < ts) | | | | | | lc | string | Last change time stamp must be equal to given one (state.lc == lc) | | lcGt | string | Last change time stamp must be not equal to the given one (state.lc != lc) | | lcGe | string | Last change time stamp must be greater than given value (state.lc > lc) | | lcLt | string | Last change time stamp must be greater or equal to given one (state.lc >= lc) | | lcLe | string | Last change time stamp must be smaller than given one (state.lc < lc) | | | | | | oldLc | string | Previous last change time stamp must be equal to given one (oldState.lc == lc) | | oldLcGt | string | Previous last change time stamp must be not equal to the given one (oldState.lc != lc) | | oldLcGe | string | Previous last change time stamp must be greater than given value (oldState.lc > lc) | | oldLcLt | string | Previous last change time stamp must be greater or equal to given one (oldState.lc >= lc) | | oldLcLe | string | Previous last change time stamp must be smaller than given one (oldState.lc < lc) | | | | | | channelId | string | Channel ID must be equal to given one | | | RegExp | Channel ID matched to regular expression | | | Array | Channel ID matched to a list of allowed channel IDs | | | | | | channelName | string | Channel name must be equal to given one | | | RegExp | Channel name matched to regular expression | | | Array | Channel name matched to a list of allowed channel names | | | | | | deviceId | string | Device ID must be equal to given one | | | RegExp | Device ID matched to regular expression | | | Array | Device ID matched to a list of allowed device IDs | | | | | | deviceName | string | Device name must be equal to given one | | | RegExp | Device name matched to regular expression | | | Array | Device name matched to a list of allowed device names | | | | | | enumId | string | State belongs to given enum | | | RegExp | One enum ID of the state satisfies the given regular expression | | | Array | One enum ID of the state is in the given list of enum IDs | | | | | | enumName | string | State belongs to given enum | | | RegExp | One enum name of the state satisfies the given regular expression | | | Array | One enum name of the state is in the given list of enum names | | | | | | from | string | New value is from defined adapter | | | RegExp | New value is from an adapter that matches the regular expression | | | Array | New value is from an adapter that appears in the given list of allowed adapters | | | | | | fromNe | string | New value is not from defined adapter | | | RegExp | New value is not from an adapter that matches the regular expression | | | Array | New value is not from an adapter that appears in the given list of forbidden adapters | | | | | | oldFrom | string | Old value is from defined adapter | | | RegExp | Old value is from an adapter that matches the regular expression | | | Array | Old value is from an adapter that appears in the given list of allowed adapters | | | | | | oldFromNe | string | Old value is not from defined adapter | | | RegExp | Old value is not from an adapter that matches the regular expression | | | Array | Old value is not from an adapter that appears in the given list of forbidden adapters | Examples: Trigger on all states with ID `'*.STATE'` if they are acknowledged and have new value `true`. ```js { "id": /\.STATE$/, "val": true, "ack": true, "logic": "and" } ``` **Note:** you can use RegExp directly: ```js on(/^system\.adapter\..*\.\d+\.memRss$/, function (obj) { }); // same as on({id: /^system\.adapter\..*\.\d+\.memRss$/, change: "ne"}, function (obj) { }); ``` To simply connect two states with each other, write: ```js on('stateId1', 'stateId2'); ``` All changes of *stateId1* will be written to *stateId2*. If the `value` parameter is set in combination with state id as the second parameter, on any change the state will filled with the `value`. ```js on('stateId1', 'stateId2', 'triggered'); setState('stateId1', 'new value'); // stateId2 will be set to 'triggered'. ``` Function `on` returns handler back. This handler can be used by unsubscribing. *Notice:* By default only states with quality 0x00 will be passed to callback function. If you want to get all events, add `{q: '*'}` to pattern structure. *Notice:* Please note, that by default "change" is equal to "any", except when only id as string is set (like `on('id', () => {});`). In last case change will be set to "ne". *Notice:* If you want to also get state deletions/expires as trigger, you need to use change with `ne` or `any` AND q with `*` as filter! *Notice:* from 4.3.2 it is possible to write a type of trigger as second parameter: `on('my.id.0', 'any', obj => log(obj.state.val));` ### once Registers a one-time subscription which automatically unsubscribes after the first invocation. Same as [on](#on---subscribe-on-changes-or-updates-of-some-state), but just executed once. ```js once(pattern, callback); ``` ### subscribe - same as **[on](#on---subscribe-on-changes-or-updates-of-some-state)** ### unsubscribe ```js unsubscribe(id); // or unsubscribe(handler); ``` Remove all subscriptions for given object ID or for given handler. ```js // By handler let mySubscription = on({ id: 'javascript.0.myState', change: 'any' }, (data) => { // unsubscribe after first trigger if (unsubscribe(mySubscription)) { log('Subscription deleted'); } }); // by Object ID on({ id: 'javascript.0.myState1', change: 'ne' }, (data) => { log('Some event'); }); on({ id: 'javascript.0.myState1', change: 'any' }, (data) => { // unsubscribe if (unsubscribe('javascript.0.myState1')) { log('All subscriptions deleted'); } }); ``` ### getSubscriptions Get the list of subscriptions. Example of a result: ```js { 'megad.0.dataPointName': [ { name : 'script.js.NameOfScript', pattern : { id : 'megad.0.dataPointName', change : 'ne' } } ] } ``` ### getFileSubscriptions Get the list of file subscriptions. Example of a result: ```js { 'vis.0$%$main/*': [ { name : 'script.js.NameOfScript', id : 'vis.0', fileNamePattern: 'main/*' } ] } ``` ### schedule ```js schedule(pattern, callback); ``` Time scheduler with astro-function. #### Time schedule Pattern can be a string with [Cron-Syntax](http://en.wikipedia.org/wiki/Cron), which consists of 5 (without seconds) or 6 (with seconds) digits: ``` * * * * * * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0) │ │ │ │ └────────── month (1 - 12) │ │ │ └─────────────── day of month (1 - 31) │ │ └──────────────────── hour (0 - 23) │ └───────────────────────── min (0 - 59) └───────────────────────────── [optional] sec (0 - 59) ``` ```js // Example with 5 digits: schedule('*/2 * * * *', () => { log('Will be triggered every 2 minutes!'); }); // Example with 6 digits: schedule('*/3 * * * * *', () => { log('Will be triggered every 3 seconds!'); }); ``` The pattern can also be an object, it is used especially if seconds are required: the object could have the following properties: - `second` - `minute` - `hour` - `date` - `month` - `year` - `dayOfWeek` ```js schedule({ second: [20, 25] }, () => { log('Will be triggered at xx:xx:20 and xx:xx:25 of every minute!'); }); schedule({ hour: 12, minute: 30 }, () => { log('Will be triggered at 12:30!'); }); ``` Pattern can be a Javascript Date object (some specific time point) - in this case only it will be triggered only one time. If start or end times for a schedule are needed, this could also be implemented with usage of an object. In this scenario, the object has the properties: - `start` - `end` - `rule` start and end defines a Date object a DateString or a number of milliseconds since 01 January 1970 00:00:00 UTC. Rule is a schedule string with [Cron-Syntax](http://en.wikipedia.org/wiki/Cron) or an object: ```js let startTime = new Date(Date.now() + 5000); let endTime = new Date(startTime.getTime() + 5000); schedule({ start: startTime, end: endTime, rule: '*/1 * * * * *' }, () => { log('It will run after 5 seconds and stop after 10 seconds'); }); ``` The rule itself could be also an object: ```js let today = new Date(); let startTime = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1); let endTime = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7); let ruleData = { hour: 12, minute: 30 }; schedule({ start: startTime, end: endTime, rule: ruleData }, () => { log('Will be triggered at 12:30, starting tomorow, ending in 7 days'); }); ``` #### Astro-function Astro-function can be used via "astro" attribute: ```js schedule({ astro: 'sunrise' }, () => { log("Sunrise!"); }); schedule({ astro: 'sunset', shift: 10 }, () => { log("10 minutes after sunset!"); }); ``` The attribute "shift" is the offset in minutes. It can be negative, too, to define time before astro event. The following values can be used as attribute in astro-function: - `"sunrise"`: sunrise (top edge of the sun appears on the horizon) - `"sunriseEnd"`: sunrise ends (bottom edge of the sun touches the horizon) - `"goldenHourEnd"`: morning golden hour (soft light, the best time for photography) ends - `"solarNoon"`: solar noon (sun is in the highest position) - `"goldenHour"`: evening golden hour starts - `"sunsetStart"`: sunset starts (bottom edge of the sun touches the horizon) - `"sunset"`: sunset (sun disappears below the horizon, evening civil twilight starts) - `"dusk"`: dusk (evening nautical twilight starts) - `"nauticalDusk"`: nautical dusk (evening astronomical twilight starts) - `"night"`: night starts (dark enough for astronomical observations) - `"nightEnd"`: night ends (morning astronomical twilight starts) - `"nauticalDawn"`: nautical dawn (morning nautical twilight starts) - `"dawn"`: dawn (morning nautical twilight ends, morning civil twilight starts) - `"nadir"`: nadir (the darkest moment of the night, sun is in the lowest position) **Note:** to use "astro"-function the "latitude" and "longitude" must be defined in javascript adapter settings. **Note:** in some places sometimes it could be so that no night/nightEnd exists. Please read [here](https://github.com/mourner/suncalc/issues/70) about it. **Note:** you can use "on" function for schedule with small modification: ```js on({ time: '*/2 * * * *' }, () => { log((new Date()).toString() + " - Will be triggered every 2 minutes!"); }); on({ time: { hour: 12, minute: 30 }}, () => { log((new Date()).toString() + " - Will be triggered at 12:30!"); }); on({ astro: 'sunset', shift: 10 }, () => { log((new Date()).toString() + " - 10 minutes after sunset!"); }); ``` ## scheduleById ```js scheduleById(id, callback); scheduleById(id, ack, callback); ``` Allows creating a schedule based on a state value. If the state value changes, the old schedule will be deleted and a new schedule is created automatically. Supported formats: - `[h]h:[m]m:ss` (e.g. `12:42:15`, `15:3:12`, `3:10:25`) - `[h]h:[m]m` (e.g. `13:37`, `9:40`) ```js scheduleById('0_userdata.0.configurableTimeFormat', () => { log('Executed!'); }); ``` Example: Create state and register schedule on changes: ```js createState( '0_userdata.0.myTime', '00:00:00', // default value { type: 'string', read: true, write: true }, () => { scheduleById('0_userdata.0.myTime', () => { log('Executed!'); }); } ); ``` ### getSchedules ```js const list = getSchedules(true); ``` Returns the list of all CRON jobs and schedules (except astro). Argument must be `true` if you want to get the list for **every running script**. Otherwise, only schedules in the current script will be returned. ```js const list = getSchedules(true); list.forEach(schedule => log(JSON.stringify(schedule))); // clear all schedules in all scripts! list.forEach(schedule => clearSchedule(schedule)); ``` Example output: ``` 2020-11-01 20:15:19.929 - {"type":"cron","pattern":"0 * * * *","scriptName":"script.js.Heizung","id":"cron_1604258108384_74924"} 2020-11-01 20:15:19.931 - {"type":"schedule","schedule":"{"period":{}}","scriptName":"script.js.Heizung","id":"schedule_19576"} ``` ### clearSchedule If **no** "astro" function is used, you can cancel the schedule later. To allow this, the schedule object must be saved: ```js let sch = schedule('*/2 * * * *', () => { /* ... */ }); // later: clearSchedule(sch); ``` ### getAttr ```js getAttr({ attr1: { attr2: 5 } }, 'attr1.attr2'); ``` Returns an attribute of the object. Path to attribute can be nested, like in the example. If the first attribute is string, the function will try to parse the string as JSON string. ### getAstroDate ```js getAstroDate(pattern, date, offsetMinutes); ``` Returns a javascript Date object for the specified astro-name (e.g. `"sunrise"` or `"sunriseEnd"`). For valid values, see the list of allowed values in the [Astro](#astro--function) section in the *schedule* function. The returned Date object is calculated for the passed *date*. If no date is provided, the current day is used. ```js let sunriseEnd = getAstroDate('sunriseEnd'); log(`Sunrise ends today at ${sunriseEnd.toLocaleTimeString()}`); let today = new Date(); let tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1); let tomorrowNight = getAstroDate('night', tomorrow); ``` **Note: Depending on your geographical location, there can be cases where e.g. 'night'/'nightEnd' do not exist on certain time points (e.g. locations north in May/June each year!** You can use webpages like [suncalc.net](http://suncalc.net) to check if the time points are correct. ### isAstroDay ```js isAstroDay(); ``` Returns `true` if the current time is between the astro sunrise and sunset. ### compareTime ```js compareTime(startTime, endTime, operation, timeToCompare); ``` Compare given time with limits. If `timeToCompare` is not given, so the actual time will be used. The following operations are possible: - `">"` - if given time is greater than `startTime` - `">="` - if given time is greater or equal to `startTime` - `"<"` - if given time is less than `startTime` - `"<="` - if given time is less or equal to `startTime` - `"=="` - if given time is equal to `startTime` - `"<>"` - if given time is not equal to `startTime` - `"between"` - if given time is between `startTime` and `endTime` - `"not between"` - if given time is not between `startTime` and `endTime` Time can be Date object or Date with time or just time. You can use astro-names for the time definition. All 3 parameters can be set as astro time. Following values are possible: `sunrise`, `sunset`, `sunriseEnd`, `sunsetStart`, `dawn`, `dusk`, `nauticalDawn`, `nauticalDusk`, `nightEnd`, `night`, `goldenHourEnd`, `goldenHour`. See [Astro](#astro--function) for detail. ```js log(compareTime('sunsetStart', 'sunsetEnd', 'between') ? 'Now is sunrise' : 'Now is no sunrise'); ``` It is possible to define the time with offset too: ```js log(compareTime({ astro: 'sunsetStart', offset: 30 }, { astro: 'sunrise', offset: -30 }, '>') ? 'Now is at least 30 minutes after sunset' : 'No idea'); ``` Structure of an astro object. ```js { astro: 'sunsetStart',// mandatory, can be written as string and not as object if offset and date are default offset: 30, // optional date: new Date() // optional } ``` ### setState ```js setState(id, state, ack, callback); ``` *Note*: The following commands are identical ```js setState('myState', 1, false); setState('myState', { val: 1, ack: false }); setState('myState', 1); ``` Please refer to https://github.com/ioBroker/ioBroker/wiki/Adapter-Development-Documentation#commands-and-statuses for usage of `ack`. Short: - `ack` = `false` : Script wants to send a command to be executed by the target device/adapter - `ack` = `true` : Command was successfully executed, and state is updated as a positive result ### setStateAsync ```js await setStateAsync(id, state, ack); ``` Same as setState, but with `promise`. ### setStateDelayed ```js setStateDelayed(id, state, isAck, delay, clearRunning, callback); ``` Same as setState but with delay in milliseconds. You can clear all running delays for this ID (by default). E.g. ```js // Switch ON the light in the kitchen in one second setStateDelayed('Kitchen.Light.Lamp', true, 1000); // Switch OFF the light in the kitchen in 5 seconds and let first timeout run. setStateDelayed('Kitchen.Light.Lamp', false, 5000, false, () => { log('Lamp is OFF'); }); ``` This function returns the handler of the timer, and this timer can be individually stopped by clearStateDelayed ### setStateChanged ```js await setStateChanged(id, state, ack); ``` Same as setState, but set value only if the value is really changed. ### setStateChangedAsync ```js await setStateChangedAsync(id, state, ack); ``` Same as setStateChanged, but with `promise`. ### clearStateDelayed ```js clearStateDelayed(id); ``` Clears all delayed tasks for specified state ID or some specific delayed task. ```js setStateDelayed('Kitchen.Light.Lamp', false, 10000); // Switch OFF the light in the kitchen in ten second let timer = setStateDelayed('Kitchen.Light.Lamp', true, 5000, false); // Switch ON the light in the kitchen in five second clearStateDelayed('Kitchen.Light.Lamp', timer); // Nothing will be switched on clearStateDelayed('Kitchen.Light.Lamp'); // Clear all running delayed tasks for this ID ``` ### getStateDelayed ```js getStateDelayed(id); ``` This is a synchronous call, and you will get the list of all running timers (setStateDelayed) for this id. You can call this function without id and get timers for all IDs. In case you call this function for some specific object ID, you will get the following answer: ```js getStateDelayed('hm-rpc.0.LQE91119.1.STATE'); // returns an array like [ { timerId: 1, left: 1123, delay: 5000, val: true, ack: false }, { timerId: 2, left: 12555, delay: 15000, val: false, ack: false }, ] ``` If you ask for all IDs, the answer will look like: ```js getStateDelayed(); // returns an object like { 'hm-rpc.0.LQE91119.1.STATE': [ { timerId: 1, left: 1123, delay: 5000, val: true, ack: false }, { timerId: 2, left: 12555, delay: 15000, val: false, ack: false }, ], 'hm-rpc.0.LQE91119.2.LEVEL': [ { timerId: 3, left: 5679, delay: 10000, val: 100, ack: false }, ], } ``` - `left` is the time left in milliseconds - `delay` is the initial delay value in milliseconds You can ask by timerId directly. In this case, the answer will be: ```js getStateDelayed(3); // returns an object like { id: 'hm-rpc.0.LQE91119.2.LEVEL', left: 5679, delay: 10000, val: 100, ack: false } ``` ### getState ```js getState(id); ``` Returns state with the given id in the following form: ```js { val: value, ack: true/false, ts: timestamp, lc: lastchanged, from: origin } ``` If state does not exist, a warning will be printed in the logs and the object `{ val: null, notExist: true }` will be returned. To suppress the warning, check if the state exists before calling getState (see [existsState](#existsState)). ### getStateAsync ```js const stateObject = await getStateAsync(id); ``` Same as getState, but with `promise`. ### existsState ```js existsState(id, (err, isExists) => {}); ``` If option "Do not subscribe all states on start" is deactivated, you can use simpler call: ```js existsState(id) ``` the function returns in this case true or false. Check if a state exists. ### getObject ```js getObject(id, enumName); ``` Get description of object id as stored in a system. You can specify the enumeration name. If this is defined, two additional attributes will be added to result: enumIds and enumNames. These arrays have all enumerations, where ID is a member of. E.g.: ```js getObject('adapter.N.objectName', 'rooms'); ``` gives back in enumIds all rooms, where the requested object is a member. You can define "true" as enumName to get back *all* enumerations. ### setObject ```js setObject(id, obj, callback); ``` Write an object into DB. This command can be disabled in adapter's settings. Use this function carefully, while the global settings can be damaged. You should use it to **modify** an existing object you read beforehand, e.g.: ```js const obj = getObject('adapter.N.objectName'); obj.native.settings = 1; setObject('adapter.N.objectName', obj, (err) => { if (err) log('Cannot write object: ' + err); }); ``` ### existsObject ```js existsObject(id, function (err, isExists) {}); ``` If the option "Do not subscribe all states on start" is deactivated, you can use simpler call: ```js existsObject(id) ``` the function returns in this case true or false. Check if an object exists. ### extendObject ```js extendObject(id, obj, callback); ``` It is almost the same as `setObject`, but first it reads the object and tries to merge all settings together. Use it like this: ```js // Stop instance extendObject('system.adapter.sayit.0', {common: {enabled: false}}); ``` ### deleteObject ```js deleteObject(id, isRecursive, callback); ``` Delete an object from DB by ID. If the object has type `state`, the state value will be deleted too. Additional parameter `isRecursive` could be provided, so all children of given ID will be deleted. Very dangerous! Use it like this: ```js // Delete state deleteObject('javascript.0.createdState'); ``` *Notice: `isRecursive` option is available only with js-controller >= 2.2.x* ### getIdByName ```js getIdByName(name, alwaysArray); ``` Returns id of the object with given name. If there is more than one object with this name, the result will be an array. If `alwaysArray` flag is set, the result will always be an array if some ID found. ### getEnums ```js getEnums(enumName); ``` Get the list of existing enumerations with members, like: ```js getEnums('rooms'); // returns all rooms - e.g.: [ { id: 'enum.rooms.LivingRoom', members: [ 'hm-rpc.0.JEQ0024123.1', 'hm-rpc.0.BidCoS-RF.4' ], name: 'Living room' }, { id: 'enum.rooms.Bath', members: [ 'hm-rpc.0.JEQ0024124.1', 'hm-rpc.0.BidCoS-RF.5' ], name: 'Bath' } ] getEnums('functions'); // returns all functions - e.g.: [ { id: 'enum.functions.light', members: [ '0_userdata.0.AnotherOne', '0_userdata.0.MyLigh' ], name: { en: 'Light', ru: 'Свет', de: 'Licht', fr: 'Lumière', it: 'Leggero', nl: 'Licht', pl: 'Lekki', pt: 'Luz', es: 'Luz', 'zh-cn': '光' } } ] ``` ### createState ```js createState(name, initialValue, forceCreation, common, native, callback); ``` Create state and object in javascript space if it does not exist, e.g. `javascript.0.mystate`. !! Prefer to create own data points with the full ID `0_userdata.0.mystate` !!! #### Parameters: - `name`: name of the state without namespace, e.g. `mystate` - `initialValue`: variable can be initialized after created. Value "undefined" means do not initialize value. - `forceCreation`: create/overwrite state independent of if state yet exists or not. - `common`: common description of object see description [here](https://github.com/ioBroker/ioBroker/blob/master/doc/SCHEMA.md#state) - `native`: native description of an object. Any specific information. - `callback`: called after state is created and initialized. If you set in `common` the flag `alias` to `true`, then alias will be created with the same name (but in `alias.0` namespace) as the state. Alias is created only if it does not exist yet. The following settings for aliases are valid too: ```js common => { alias: { id: 'alias.0.myOtherState', // will be created automatically if not already exists write: 'val * 1000', // convert function for write to created state read: 'val / 1000' // convert function to read from created state } } ``` or ```js common => { alias: { id: 'alias.0.myOtherState', // will be created automatically if not already exists } } ``` It is possible short type of createState: - `createState('myDatapoint')` - simply create datapoint if it does not exist - `createState('myDatapoint', 1)` - create datapoint if it does not exist and initialize it with value 1 - `createState('myDatapoint', { type: 'string', role: 'json', read: true, write: false }, () => { log('created'); });` - with common definitions like type, read, write and role - `createState('myDatapoint', { name: 'My own datapoint', unit: '°C' }, () => { log('created'); });` - `createState('myDatapoint', 1, { name: 'My own datapoint', unit: '°C' })` - create datapoint if it does not exist with specific name and units ### createStateAsync ```js await createStateAsync(name, initialValue, forceCreation, common, native); ``` Same as `createState`, but the promise will be returned. ### deleteState ```js deleteState(name, callback); ``` Delete state and object in javascript space, e.g. `javascript.0.mystate`. States from other adapters cannot be deleted. ```js deleteState('myDatapoint') ``` simply delete datapoint if exists. ### deleteStateAsync ```js await deleteStateAsync(name); ``` Same as `deleteState`, but the promise will be returned. ### createAlias ```js createAlias(name, alias, forceCreation, common, native, callback); ``` Create alias in `alias.0` space if it does not exist, e.g. `javascript.0.myalias` and reference to a state or read/write states. The common definition is taken from the read alias id object, but a provided common takes precedence. #### Parameters: - `name`: id of the new alias state with (possible without alias namespace), e.g. `test.mystate` (namespace `alias.0.` will be added = `alias.0.test.mystate`) - `alias`: can be either an existing state id as string or an object with full alias definition including read/write ids and read/write functions. Note: Alias definitions can not be set as part of the common parameter! - `forceCreation`: create/overwrite alias independent of if state yet exists or not. - `common`: common description of alias object see description [here](https://github.com/ioBroker/ioBroker/blob/master/doc/SCHEMA.md#state). Values provided here will take precedence over the common definition of the read alias id object. Not: Alias definitions can not be set as part of this common parameter, see alias parameter! - `native`: native description of an object. Any specific information. - `callback`: called after state is created and initialized. It is possible a short type of createAlias: - `createAlias('myAlias', 'myDatapoint')` - simply create alias.0.myAlias that refernces to javascript.X.myDatapoint if it does not exist - `createAlias('myAlias', { id: { read: 'myReadDatapoint', write: 'myWriteDatapoint' }})` - creates alias and reference to different read/write states For other details, see createState, it is similar. ### createAliasAsync ```js await createAliasAsync(name, alias, forceCreation, common, native); ``` Same as `createAlias`, but the promise will be returned. ### sendTo ```js sendTo(adapter, command, message, callback); sendTo(adapter, command, message, options, callback); ``` Send a message to a specific or all adapter instances. When using the adapter name, the message