UNPKG

iobroker.alias-manager

Version:
568 lines (552 loc) 76.8 kB
/** * Copyright 2018-2020 bluefox <dogafox@gmail.com> * * The MIT License (MIT) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. **/ // Version 0.1.6, 2019.08.14 // Keep this file ES5 conform! No const, let, not lambdas => , no ..., no default values for arguments, no let [arg] = abc() and other modern stuff. 'use strict'; var Types = { unknown: 'unknown', airCondition: 'airCondition', blind: 'blind', button: 'button', buttonSensor: 'buttonSensor', camera: 'camera', url: 'url', image: 'image', dimmer: 'dimmer', door: 'door', fireAlarm: 'fireAlarm', floodAlarm: 'floodAlarm', gate: 'gate', humidity: 'humidity', info: 'info', instance: 'instance', light: 'light', lock: 'lock', location: 'location', media: 'media', motion: 'motion', rgb: 'rgb', ct: 'ct', rgbSingle: 'rgbSingle', hue: 'hue', slider: 'slider', socket: 'socket', temperature: 'temperature', thermostat: 'thermostat', valve: 'valve', volume: 'volume', vacuumCleaner: 'vacuumCleaner', volumeGroup: 'volumeGroup', window: 'window', windowTilt: 'windowTilt', weatherCurrent: 'weatherCurrent', weatherForecast: 'weatherForecast', warning: 'warning' }; // Description of flags // role - RegEx to detect role // channelRole - RegEx to detect channel role of state // ignoreRole - RegEx to ignore some specific roles // indicator - is it will be shown like small icon or as a value // type - state type: 'number', 'string' or 'boolean' or array of possible values // name - own TAG of the state to process it in the logic // write - if set to true or false, it will be checked the write attribute, if no attribute, so "false" will be assumed // read - if set to true or false, it will be checked the write attribute, if no attribute, so "true" will be assumed // min - type of attribute: number', 'string' or 'boolean'. This attribute must exists in common // max - type of attribute: number', 'string' or 'boolean'. This attribute must exists in common // required - if required to detect the pattern as valid // noSubscribe - no automatic subscription for this state (e.g if write only) // searchInParent - if this pattern should be search in device too and not only in channel // enums - function to execute custom category detection // multiple - if more than one state may have this pattern in channel // noDeviceDetection - do not search indicators in parent device // notSingle - this state may belong to more than one tile simultaneously (e.g. volume tile and media with volume) // inverted - is state of indicator must be inverted // stateName - regex for state names (IDs). Not suggested // defaultRole - is for detection irrelevant, but will be used by iobroker.devices. function ChannelDetector() { if (!(this instanceof ChannelDetector)) { return new ChannelDetector(); } var patternWorking = {role: /^indicator\.working$/, indicator: true, name: 'WORKING', required: false, defaultRole: 'indicator.working'}; var patternUnreach = {role: /^indicator(\.maintenance)?\.unreach$/, indicator: true, type: 'boolean', name: 'UNREACH', required: false, defaultRole: 'indicator.maintenance.unreach'}; var patternLowbat = {role: /^indicator(\.maintenance)?\.lowbat$|^indicator(\.maintenance)?\.battery/, indicator: true, type: 'boolean', name: 'LOWBAT', required: false, defaultRole: 'indicator.maintenance.lowbat'}; var patternMaintain = {role: /^indicator\.maintenance$/, indicator: true, type: 'boolean', name: 'MAINTAIN', required: false, defaultRole: 'indicator.maintenance'}; var patternError = {role: /^indicator\.error$/, indicator: true, name: 'ERROR', required: false, defaultRole: 'indicator.error'}; var patternDirection = {role: /^indicator\.direction$/, indicator: true, name: 'DIRECTION', required: false, defaultRole: 'indicator.direction'}; var patternReachable = {role: /^indicator\.reachable$/, indicator: true, type: 'boolean', name: 'CONNECTED', required: false, defaultRole: 'indicator.reachable', inverted: true}; var patterns = { mediaPlayer: { // receive the state of player via media.state. Controlling of the player via buttons states: [ // one of {role: /^media.state(\..*)?$/, indicator: false, type: ['boolean', 'number'], name: 'STATE', required: true, defaultRole: 'media.state'}, // optional {role: /^button.play(\..*)?$|^action.play(\..*)?$/, indicator: false, write: true, type: 'boolean', name: 'PLAY', required: false, noSubscribe: true, defaultRole: 'button.play'}, {role: /^button.pause(\..*)?$|^action.pause(\..*)?$/, indicator: false, write: true, type: 'boolean', name: 'PAUSE', required: false, noSubscribe: true, defaultRole: 'button.pause'}, {role: /^button.stop(\..*)?$|^action.stop(\..*)?$/, indicator: false, write: true, type: 'boolean', name: 'STOP', required: false, noSubscribe: true, defaultRole: 'button.stop'}, {role: /^button.next(\..*)?$|^action.next(\..*)?$/, indicator: false, write: true, type: 'boolean', name: 'NEXT', required: false, noSubscribe: true, defaultRole: 'button.next'}, {role: /^button.prev(\..*)?$|^action.prev(\..*)?$/, indicator: false, write: true, type: 'boolean', name: 'PREV', required: false, noSubscribe: true, defaultRole: 'button.prev'}, {role: /^media.mode.shuffle(\..*)?$/, indicator: false, write: true, type: 'boolean', name: 'SHUFFLE', required: false, noSubscribe: true, defaultRole: 'media.mode.shuffle'}, {role: /^media.mode.repeat(\..*)?$/, indicator: false, write: true, type: 'number', name: 'REPEAT', required: false, noSubscribe: true, defaultRole: 'media.mode.repeat'}, {role: /^media.artist(\..*)?$/, indicator: false, write: false, type: 'string', name: 'ARTIST', required: false, defaultRole: 'media.artist'}, {role: /^media.album(\..*)?$/, indicator: false, write: false, type: 'string', name: 'ALBUM', required: false, defaultRole: 'media.album'}, {role: /^media.title(\..*)?$/, indicator: false, write: false, type: 'string', name: 'TITLE', required: false, defaultRole: 'media.title'}, // one of following [ {role: /^media.cover$|^media.cover.big$/, indicator: false, write: false, type: 'string', name: 'COVER', required: false, notSingle: true, defaultRole: 'media.cover'}, {role: /^media.cover(\..*)$/, indicator: false, write: false, type: 'string', name: 'COVER', required: false, notSingle: true}, ], {role: /^media.duration(\..*)?$/, indicator: false, write: false, type: 'number', name: 'DURATION', required: false, noSubscribe: true, defaultRole: 'media.duration', defaultUnit: 'sec'}, {role: /^media.elapsed(\..*)?$/, indicator: false, type: 'number', name: 'ELAPSED', required: false, noSubscribe: true, defaultRole: 'media.elapsed', defaultUnit: 'sec'}, {role: /^media.seek(\..*)?$/, indicator: false, write: true, type: 'number', name: 'SEEK', required: false, noSubscribe: true, defaultRole: 'media.seek'}, {role: /^media.track(\..*)?$/, indicator: false, type: 'string', name: 'TRACK', required: false, noSubscribe: true, defaultRole: 'media.track'}, {role: /^media.episode(\..*)?$/, indicator: false, type: 'string', name: 'EPISODE', required: false, noSubscribe: true, defaultRole: 'media.episode'}, {role: /^media.season(\..*)?$/, indicator: false, type: 'string', name: 'SEASON', required: false, noSubscribe: true, defaultRole: 'media.season'}, {role: /^level.volume?$/, indicator: false, type: 'number', min: 'number', max: 'number', write: true, name: 'VOLUME', required: false, notSingle: true, noSubscribe: true, defaultRole: 'level.volume'}, {role: /^value.volume?$/, indicator: false, type: 'number', min: 'number', max: 'number', write: false, name: 'VOLUME_ACTUAL', required: false, notSingle: true, noSubscribe: true, defaultRole: 'value.volume'}, {role: /^media.mute?$/, indicator: false, type: 'boolean', write: true, name: 'MUTE', required: false, notSingle: true, noSubscribe: true, defaultRole: 'media.mute'}, // Ignore following states of chromecast {stateName: /\.paused$|\.playerState$/, indicator: false, name: 'IGNORE', required: false, multiple: true, noSubscribe: true}, patternReachable, patternLowbat, patternMaintain, patternError ], type: Types.media }, weatherForecast : { states: [ {role: /^weather.icon$|^weather.icon.forecast.0$/, indicator: false, type: 'string', name: 'ICON', required: true, defaultRole: 'weather.icon.forecast.0'}, {role: /^value.temperature.min.forecast.0$/, indicator: false, type: 'number', name: 'TEMP_MIN', required: true, defaultRole: 'value.temperature.min.forecast.0'}, {role: /^value.temperature.max.forecast.0$/, indicator: false, type: 'number', name: 'TEMP_MAX', required: true, defaultRole: 'value.temperature.max.forecast.0'}, // optional {role: /^value.precipitation$|^value.precipitation.forecast.0$/, indicator: false, type: 'number', name: 'PRECIPITATION_CHANCE', unit: '%', required: false, defaultRole: 'value.precipitation.forecast.0'}, {role: /^value.precipitation$|^value.precipitation.forecast.0$/, indicator: false, type: 'number', name: 'PRECIPITATION', unit: 'mm', required: false, defaultRole: 'value.precipitation.forecast.0'}, {role: /^date$|^date.forecast.0$/, indicator: false, type: 'string', name: 'DATE', required: false, defaultRole: 'date.forecast.0'}, {role: /^dayofweek$|^dayofweek.forecast.0$/, indicator: false, type: 'string', name: 'DOW', required: false, defaultRole: 'dayofweek.forecast.0'}, {role: /^weather.state$|^weather.state.forecast.0$/, indicator: false, type: 'string', name: 'STATE', required: false, defaultRole: 'weather.state.forecast.0'}, {role: /^value.temperature$|^value.temperature.forecast.0$/, indicator: false, type: 'number', name: 'TEMP', required: false, defaultRole: 'value.temperature.forecast.0'}, {role: /^value.pressure$/, indicator: false, type: 'number', name: 'PRESSURE', required: false, defaultRole: 'weather.icon.forecast.0'}, {role: /^value.humidity$|value.humidity.forecast.0$/, indicator: false, type: 'number', name: 'HUMIDITY', required: false, defaultRole: 'value.humidity.forecast.0'}, {role: /^value.temperature.windchill$|^value.temperature.windchill.forecast.0$/, indicator: false, type: 'number', name: 'WIND_CHILL', required: false, defaultRole: 'value.temperature.windchill.forecast.0'}, {role: /^value.temperature.feelslike$|^value.temperature.feelslike.forecast.0$/, indicator: false, type: 'number', name: 'FEELS_LIKE', required: false, defaultRole: 'value.temperature.feelslike.forecast.0'}, {role: /^value.speed.wind$|^value.speed.wind.forecast.0$/, indicator: false, type: 'number', name: 'WIND_SPEED', required: false, defaultRole: 'value.speed.wind.forecast.0'}, {role: /^value.direction.wind$|^value.direction.wind.forecast.0$/, indicator: false, type: 'number', name: 'WIND_DIRECTION',required: false, defaultRole: 'value.direction.wind.forecast.0'}, {role: /^weather.direction.wind$|^weather.direction.wind.forecast.0$/, indicator: false, type: 'string', name: 'WIND_DIRECTION_STR',required: false, defaultRole: 'weather.direction.wind.forecast.0'}, {role: /^weather.icon.wind$|^weather.icon.wind.forecast.0$/, indicator: false, type: 'string', name: 'WIND_ICON', required: false, defaultRole: 'weather.icon.wind.forecast.0'}, {role: /^weather.chart.url$/, indicator: false, type: 'string', name: 'HISTORY_CHART', required: false, noSubscribe: true, defaultRole: 'weather.chart.url'}, {role: /^weather.chart.url.forecast$/, indicator: false, type: 'string', name: 'FORECAST_CHART', required: false, noSubscribe: true, defaultRole: 'weather.chart.url.forecast'}, {role: /^location$/, indicator: false, type: 'string', name: 'LOCATION', required: false, multiple: true, defaultRole: 'location'}, // other days {role: /^weather.icon.forecast.(\d)$/, indicator: false, type: 'string', name: 'ICON%d', required: false, searchInParent: true, multiple: true, noSubscribe: true, notSingle: true}, {role: /^value.temperature.min.forecast.(\d)$/, indicator: false, type: 'number', name: 'TEMP_MIN%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.temperature.max.forecast.(\d)$/, indicator: false, type: 'number', name: 'TEMP_MAX%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^date.forecast.(\d)$/, indicator: false, type: 'string', name: 'DATE%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^dayofweek.forecast.(\d)$/, indicator: false, type: 'string', name: 'DOW%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^weather.state.forecast.(\d)$/, indicator: false, type: 'string', name: 'STATE%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.temperature.forecast.(\d)$/, indicator: false, type: 'number', name: 'TEMP%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.humidity.forecast.(\d)$/, indicator: false, type: 'number', name: 'HUMIDITY%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.humidity.max.forecast.(\d)$/, indicator: false, type: 'number', name: 'HUMIDITY_MAX%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.precipitation.forecast.(\d)$/, indicator: false, type: 'number', unit: '%', name: 'PRECIPITATION_CHANCE%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.precipitation.forecast.(\d)$/, indicator: false, type: 'number', unit: 'mm', name: 'PRECIPITATION%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.speed.wind.forecast.(\d)$/, indicator: false, type: 'number', name: 'WIND_SPEED%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^value.direction.wind.forecast.(\d)$/, indicator: false, type: 'number', name: 'WIND_DIRECTION%d',required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^weather.direction.wind.forecast.(\d)$/, indicator: false, type: 'string', name: 'WIND_DIRECTION_STR%d',required: false, searchInParent: true, multiple: true, noSubscribe: true}, {role: /^weather.icon.wind.forecast.(\d)$/, indicator: false, type: 'string', name: 'WIND_ICON%d', required: false, searchInParent: true, multiple: true, noSubscribe: true}, ], type: Types.weatherForecast }, rgb: { states: [ {role: /^level\.color\.red$/, indicator: false, type: 'number', write: true, name: 'RED', required: true, defaultRole: 'level.color.red'}, {role: /^level\.color\.green$/, indicator: false, type: 'number', write: true, name: 'GREEN', required: true, defaultRole: 'level.color.green'}, {role: /^level\.color\.blue$/, indicator: false, type: 'number', write: true, name: 'BLUE', required: true, defaultRole: 'level.color.blue'}, {role: /^level\.color\.white$/, indicator: false, type: 'number', write: true, name: 'WHITE', required: false, defaultRole: 'level.color.white'}, {role: /^level\.dimmer$/, indicator: false, type: 'number', write: true, name: 'DIMMER', required: false, defaultRole: 'level.dimmer', defaultUnit: '%'}, {role: /^level\.brightness$/, indicator: false, type: 'number', write: true, name: 'BRIGHTNESS', required: false}, {role: /^level\.color\.saturation$/, indicator: false, type: 'number', write: true, name: 'SATURATION', required: false}, {role: /^level\.color\.temperature$/, indicator: false, type: 'number', write: true, name: 'TEMPERATURE', required: false, defaultRole: 'level.color.temperature', defaultUnit: '°K'}, {role: /^switch\.light$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^switch$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^state(\.light)?$/, indicator: false, type: 'boolean', write: false, name: 'ON_ACTUAL', required: false, defaultRole: 'state.light'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.rgb }, // remove it when all adapters fixed (2018.08.15) r=>red, g=>green, b=>blue rgbOld: { states: [ {role: /^level\.color\.r$/, indicator: false, type: 'number', write: true, name: 'RED', required: true}, {role: /^level\.color\.g$/, indicator: false, type: 'number', write: true, name: 'GREEN', required: true}, {role: /^level\.color\.b$/, indicator: false, type: 'number', write: true, name: 'BLUE', required: true}, {role: /^level\.dimmer$/, indicator: false, type: 'number', write: true, name: 'DIMMER', required: false}, {role: /^level\.brightness$/, indicator: false, type: 'number', write: true, name: 'BRIGHTNESS', required: false}, {role: /^level\.color\.saturation$/, indicator: false, type: 'number', write: true, name: 'SATURATION', required: false}, {role: /^level\.color\.temperature$/, indicator: false, type: 'number', write: true, name: 'TEMPERATURE', required: false, defaultUnit: '°K'}, {role: /^switch\.light$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^switch$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.rgb }, rgbSingle: { states: [ {role: /^level\.color\.rgb$/, indicator: false, type: 'string', write: true, name: 'RGB', required: true, defaultRole: 'level.color.rgb'}, {role: /^level\.dimmer$/, indicator: false, type: 'number', write: true, name: 'DIMMER', required: false, defaultRole: 'level.dimmer'}, {role: /^level\.brightness$/, indicator: false, type: 'number', write: true, name: 'BRIGHTNESS', required: false, defaultUnit: '%'}, {role: /^level\.color\.saturation$/, indicator: false, type: 'number', write: true, name: 'SATURATION', required: false}, {role: /^level\.color\.temperature$/, indicator: false, type: 'number', write: true, name: 'TEMPERATURE', required: false, defaultRole: 'level.color.temperature', defaultUnit: '°K'}, {role: /^switch\.light$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^switch$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^state(\.light)?$/, indicator: false, type: 'boolean', write: false, name: 'ON_ACTUAL', required: false, defaultRole: 'state.light'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.rgbSingle }, hue: { states: [ {role: /^level\.color\.hue$/, indicator: false, type: 'number', write: true, name: 'HUE', required: true, defaultRole: 'level.color.hue', defaultUnit: '°'}, {role: /^level\.dimmer$/, indicator: false, type: 'number', write: true, name: 'DIMMER', required: false, searchInParent: true, defaultRole: 'level.dimmer', defaultUnit: '°C'}, {role: /^level\.brightness$/, indicator: false, type: 'number', write: true, name: 'BRIGHTNESS', required: false}, {role: /^level\.color\.saturation$/, indicator: false, type: 'number', write: true, name: 'SATURATION', required: false}, {role: /^level\.color\.temperature$/, indicator: false, type: 'number', write: true, name: 'TEMPERATURE', required: false, defaultRole: 'level.color.temperature', defaultUnit: '°K'}, {role: /^switch\.light$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^switch$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^state(\.light)?$/, indicator: false, type: 'boolean', write: false, name: 'ON_ACTUAL', required: false, defaultRole: 'state.light'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.hue }, ct: { states: [ {role: /^level\.color\.temperature$/, indicator: false, type: 'number', write: true, name: 'TEMPERATURE', required: true, defaultRole: 'level.color.temperature', defaultUnit: '°K'}, {role: /^level\.dimmer$/, indicator: false, type: 'number', write: true, name: 'DIMMER', required: false, defaultRole: 'level.dimmer', defaultUnit: '%'}, {role: /^level\.brightness$/, indicator: false, type: 'number', write: true, name: 'BRIGHTNESS', required: false}, {role: /^level\.color\.saturation$/, indicator: false, type: 'number', write: true, name: 'SATURATION', required: false}, {role: /^switch\.light$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, {role: /^switch$/, indicator: false, type: 'boolean', write: true, name: 'ON', required: false, defaultRole: 'switch.light'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.ct }, warning: { states: [ {role: /^value\.warning$/, indicator: false, name: 'LEVEL', required: true, defaultRole: 'value.warning'}, // optional {role: /^weather\.title\.short$/, indicator: false, type: 'string', name: 'TITLE', required: false, defaultRole: 'weather.title.short'}, {role: /^weather\.title$/, indicator: false, type: 'string', name: 'INFO', required: false, defaultRole: 'weather.title'}, {role: /^date\.start$/, indicator: false, type: 'string', name: 'START', required: false, defaultRole: 'date.start'}, {role: /^date\.end$/, indicator: false, type: 'string', name: 'END', required: false, defaultRole: 'date.end'}, {role: /^date$/, indicator: false, type: 'string', name: 'START', required: false}, {role: /^weather\.chart\.url/, indicator: false, type: 'string', name: 'ICON', required: false, defaultRole: 'weather.chart.url'}, // For detailed screen {role: /^weather\.state$/, indicator: false, type: 'string', name: 'DESC', required: false, noSubscribe: true, defaultRole: 'weather.state'}, ], type: Types.warning }, // most full description could be found here: https://yandex.ru/dev/dialogs/alice/doc/smart-home/concepts/device-type-thermostat-ac-docpage/ airCondition: { states: [ {role: /temperature(\..*)?$/, indicator: false, write: true, type: 'number', name: 'SET', required: true, defaultRole: 'level.temperature', defaultUnit: '°C'}, // AUTO, COOL, HEAT, ECO, OFF, DRY, FAN_ONLY {role: /thermostat$/, indicator: false, write: true, type: 'number', searchInParent: true, name: 'MODE', required: true, defaultRole: 'level.mode.thermostat', defaultStates: {0: 'OFF', 1: 'AUTO', 2: 'COOL', 3: 'HEAT', 4: 'ECO', 5: 'FAN_ONLY', 6: 'DRY'}}, // optional {role: /speed\.fan$/, indicator: false, write: true, type: 'number', name: 'SPEED', required: false, defaultRole: 'level.mode.fan', defaultStates: {0: 'AUTO', 1: 'HIGH', 2: 'LOW', 3: 'MEDIUM', 4: 'QUIET', 5: 'TURBO'}}, {role: /^switch\.power$/, indicator: false, write: true, type: ['boolean', 'number'], searchInParent: true, name: 'POWER', required: false, defaultRole: 'switch.power'}, {role: /^switch$/, indicator: false, write: true, type: 'boolean', searchInParent: true, name: 'POWER', required: false}, {role: /temperature(\..*)?$/, indicator: false, write: false, type: 'number', searchInParent: true, name: 'ACTUAL', required: false, defaultRole: 'value.temperature', defaultUnit: '°C'}, {role: /humidity(\..*)?$/, indicator: false, write: false, type: 'number', searchInParent: true, name: 'HUMIDITY', required: false, defaultRole: 'value.humidity', defaultUnit: '%'}, {role: /^switch\.boost(\..*)?$/, indicator: false, write: true, type: ['boolean', 'number'], searchInParent: true, name: 'BOOST', required: false, defaultRole: 'switch.boost'}, {role: /swing$/, indicator: false, write: true, type: 'number', searchInParent: true, name: 'SWING', required: false, defaultRole: 'level.mode.swing', defaultStates: {0: 'AUTO', 1: 'HORIZONTAL', 2: 'STATIONARY', 3: 'VERTICAL'}}, patternUnreach, patternMaintain, patternError ], type: Types.airCondition }, thermostat: { states: [ {role: /temperature(\..*)?$/, indicator: false, write: true, type: 'number', name: 'SET', required: true, defaultRole: 'level.temperature', defaultUnit: '°C'}, // optional {role: /temperature(\..*)?$/, indicator: false, write: false, type: 'number', searchInParent: true, name: 'ACTUAL', required: false, defaultRole: 'value.temperature', defaultUnit: '°C'}, {role: /humidity(\..*)?$/, indicator: false, write: false, type: 'number', searchInParent: true, name: 'HUMIDITY', required: false, defaultRole: 'value.humidity', defaultUnit: '%'}, {role: /^switch\.boost(\..*)?$/, indicator: false, write: true, type: ['boolean', 'number'], searchInParent: true, name: 'BOOST', required: false, defaultRole: 'switch.boost'}, {role: /^switch\.power$/, indicator: false, write: true, type: ['boolean', 'number'], searchInParent: true, name: 'POWER', required: false, defaultRole: 'switch.power'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.thermostat }, vacuumCleaner: { states: [ {role: /^switch\.power$/, indicator: false, write: true, type: ['boolean', 'number'], searchInParent: true, name: 'POWER', required: true, defaultRole: 'switch.power'}, // AUTO, ECO, EXPRESS, NORMAL, QUIET {role: /mode\.cleanup$/, indicator: false, write: true, type: 'number', name: 'MODE', required: true, defaultRole: 'level.mode.cleanup', defaultStates: {0: 'AUTO', 1: 'NORMAL', 2: 'QUIET', 3: 'ECO', 4: 'EXPRESS'}}, // optional {role: /mode\.work$/, indicator: false, write: true, type: 'number', name: 'WORK_MODE', required: false, defaultRole: 'level.mode.work', defaultStates: {0: 'AUTO', 1: 'FAST', 2: 'MEDIUM', 3: 'SLOW', 4: 'TURBO'}}, {role: /^value\.water$/, indicator: false, write: true, type: 'number', unit: '%', name: 'WATER', required: false, defaultRole: 'value.water', defaultUnit: '%'}, {role: /^value\.waste$/, indicator: false, write: true, type: 'number', unit: '%', name: 'WASTE', required: false, defaultRole: 'value.waste', defaultUnit: '%'}, {role: /^value\.battery$/, indicator: false, write: true, type: 'number', unit: '%', name: 'BATTERY', required: false, defaultRole: 'value.battery', defaultUnit: '%'}, {role: /^value\.state$/, indicator: false, write: true, type: ['number', 'string'], name: 'STATE', required: false, defaultRole: 'value.state'}, {role: /^switch\.pause$/, indicator: false, write: true, type: 'boolean', searchInParent: true, name: 'PAUSE', required: false, defaultRole: 'switch.pause'}, {role: /^indicator(\.maintenance)?\.waste$|^indicator(\.alarm)?\.waste/, indicator: true, type: 'boolean', name: 'WASTE_ALARM', required: false, defaultRole: 'indicator.maintenance.waste'}, {role: /^indicator(\.maintenance)?\.water$|^indicator(\.alarm)?\.water/, indicator: true, type: 'boolean', name: 'WATER_ALARM', required: false, defaultRole: 'indicator.maintenance.water'}, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.vacuumCleaner }, blinds: { states: [ {role: /^level(\.blind)?$/, indicator: false, type: 'number', write: true, enums: roleOrEnumBlind, name: 'SET', required: true, defaultRole: 'level.blind', defaultUnit: '%'}, // optional {role: /^value(\.blind)?$/, indicator: false, type: 'number', enums: roleOrEnumBlind, name: 'ACTUAL', required: false, defaultRole: 'value.blind', defaultUnit: '%'}, {role: /^button\.stop$|^action\.stop$/, indicator: false, type: 'boolean', write: true, enums: roleOrEnumBlind, name: 'STOP', required: false, noSubscribe: true, defaultRole: 'button.stop'}, patternDirection, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.blind }, lock: { states: [ {role: /^switch\.lock$/, indicator: false, type: 'boolean', write: true, name: 'SET', required: true, defaultRole: 'switch.lock'}, // optional {role: /^state$/, indicator: false, type: 'boolean', write: false, name: 'ACTUAL', required: false, defaultRole: 'state'}, { indicator: false, type: 'boolean', write: true, read: false, name: 'OPEN', required: false, noSubscribe: true, defaultRole: 'button'}, patternDirection, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.lock }, motion: { states: [ {role: /^state\.motion$|^sensor\.motion$/, indicator: false, type: 'boolean', name: 'ACTUAL', required: true, defaultRole: 'sensor.motion'}, // optional {role: /brightness$/, indicator: false, type: 'number', name: 'SECOND', required: false, defaultRole: 'value.brightness'}, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.motion }, window: { states: [ {role: /^state(\.window)?$|^sensor(\.window)?/, indicator: false, type: 'boolean', enums: roleOrEnumWindow, name: 'ACTUAL', required: true, defaultRole: 'sensor.window'}, // optional patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.window }, windowTilt: { states: [ {role: /^state?$|^value(\.window)?$/, indicator: false, type: 'number', enums: roleOrEnumWindow, name: 'ACTUAL', required: true, defaultRole: 'value.window'}, // optional patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.windowTilt }, fireAlarm: { states: [ {role: /^state?$|^sensor(\.alarm)?\.fire/, indicator: false, type: 'boolean', name: 'ACTUAL', required: true, channelRole: /^sensor(\.alarm)?\.fire$/, defaultRole: 'sensor.alarm.fire'}, // optional patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.fireAlarm }, door: { states: [ {role: /^state?$|^state(\.door)?$|^sensor(\.door)?/, indicator: false, type: 'boolean', write: false, enums: roleOrEnumDoor, name: 'ACTUAL', required: true, defaultRole: 'sensor.door'}, // optional patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.door }, dimmer: { states: [ {role: /^level(\.dimmer)?$|^level\.brightness$/, indicator: false, type: 'number', write: true, enums: roleOrEnumLight, name: 'SET', required: true, defaultRole: 'level.dimmer', ignoreRole: /^level\.dimspeed$/, defaultUnit: '%'}, // optional {role: /^value(\.dimmer)?$/, indicator: false, type: 'number', write: false, enums: roleOrEnumLight, name: 'ACTUAL', required: false, defaultRole: 'value.dimmer', defaultUnit: '%'}, {role: /^switch(\.light)?$|^state$/, indicator: false, type: 'boolean', write: true, enums: roleOrEnumLight, name: 'ON_SET', required: false, defaultRole: 'switch.light'}, {role: /^switch(\.light)?$|^state$/, indicator: false, type: 'boolean', write: false, enums: roleOrEnumLight, name: 'ON_ACTUAL', required: false, defaultRole: 'switch.light'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.dimmer }, light: { states: [ {role: /^switch(\.light)?$|^state$/, indicator: false, type: 'boolean', write: true, enums: roleOrEnumLight, name: 'SET', required: true, defaultRole: 'switch.light'}, // optional {role: /^switch(\.light)?$|^state$/, indicator: false, type: 'boolean', write: false, enums: roleOrEnumLight, name: 'ACTUAL', required: false, defaultRole: 'switch.light'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.light }, volume: { states: [ {role: /^level\.volume$/, indicator: false, type: 'number', min: 'number', max: 'number', write: true, name: 'SET', required: true, defaultRole: 'level.volume'}, // optional {role: /^value\.volume$/, indicator: false, type: 'number', min: 'number', max: 'number', write: false, name: 'ACTUAL', required: false, defaultRole: 'value.volume'}, {role: /^media\.mute$/, indicator: false, type: 'boolean', write: true, name: 'MUTE', required: false, defaultRole: 'media.mute'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.volume }, location_one: { states: [ {role: /^value\.gps$/, indicator: false, type: 'string', write: false, name: 'GPS', required: true, defaultRole: 'value.gps'}, // optional {role: /^value\.gps\.elevation$/, indicator: false, type: 'number', write: false, name: 'ELEVATION', required: false, defaultRole: 'value.gps.elevation'}, {role: /^value\.radius$|value\.gps\.radius$/, indicator: false, type: 'number', write: false, name: 'RADIUS', required: false, defaultRole: 'value.gps.radius'}, {role: /^value\.accuracy$|^value\.gps\.accuracy$/, indicator: false, type: 'number', write: false, name: 'ACCURACY', required: false, defaultRole: 'value.gps.accuracy'}, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.location }, location: { states: [ {role: /^value\.gps\.longitude$/, indicator: false, type: 'number', write: false, name: 'LONGITUDE', required: true, defaultRole: 'value.gps.longitude', defaultUnit: '°'}, {role: /^value\.gps\.latitude$/, indicator: false, type: 'number', write: false, name: 'LATITUDE', required: true, defaultRole: 'value.gps.latitude', defaultUnit: '°'}, // optional {role: /^value\.gps\.elevation$/, indicator: false, type: 'number', write: false, name: 'ELEVATION', required: false, defaultRole: 'value.gps.elevation'}, {role: /^value\.radius$|value\.gps\.radius$/, indicator: false, type: 'number', write: false, name: 'RADIUS', required: false, defaultRole: 'value.gps.radius'}, {role: /^value\.accuracy$|^value\.gps\.accuracy$/, indicator: false, type: 'number', write: false, name: 'ACCURACY', required: false, defaultRole: 'value.gps.accuracy'}, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.location }, volumeGroup: { states: [ {role: /^level\.volume\.group?$/, indicator: false, type: 'number', min: 'number', max: 'number', write: true, name: 'SET', required: true, defaultRole: 'level.volume.group'}, {role: /^value\.volume\.group$/, indicator: false, type: 'number', min: 'number', max: 'number', write: false, name: 'ACTUAL', required: false, defaultRole: 'value.volume.group'}, {role: /^media\.mute\.group$/, indicator: false, type: 'boolean', write: true, name: 'MUTE', required: false, defaultRole: 'media.mute.group'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.volumeGroup }, levelSlider: { states: [ {role: /^level(\..*)?$/, indicator: false, type: 'number', min: 'number', max: 'number', write: true, name: 'SET', required: true, defaultRole: 'level', defaultUnit: '%'}, {role: /^value(\..*)?$/, indicator: false, type: 'number', min: 'number', max: 'number', write: false, name: 'ACTUAL', required: false, defaultRole: 'value'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.slider }, socket: { states: [ {role: /^switch$|^state$|^switch\.active$/, indicator: false, type: 'boolean', write: true, name: 'SET', required: true, defaultRole: 'switch'}, {role: /^state$|^state\.active$/, indicator: false, type: 'boolean', write: false, name: 'ACTUAL', required: false, defaultRole: 'switch'}, patternWorking, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.socket }, button: { states: [ {role: /^button(\.[.\w]+)?$|^action(\.[.\w]+)?$/, indicator: false, type: 'boolean', read: false, write: true, name: 'SET', required: true, noSubscribe: true, defaultRole: 'button'}, patternUnreach, patternLowbat, patternMaintain, patternError ], type: Types.button }, buttonSensor: { states: [ {role: /^button(\.[.\w]+)?$/, in