iobroker.alias-manager
Version:
568 lines (552 loc) • 76.8 kB
JavaScript
/**
* 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