sw:openhab:examples:light:ecma

Это старая версия документа!


JSScripting

Вариант «application/javascript;version=ECMAScript-2021»

Универсальный скрипт для ламп и диммеров

Данный скрипт позволяет унифицировать управление светом через выключатели без внесения изменений в скрипт каждый раз при необходимости изменения назначения выключателей и целевых ламп.

Каждому выключателю назначается свой источник света через Custom Metadata, Namespace: linkedItem.

Требования:

  • Надстройка Javascript Automation (ECMA2011)
  • Установлен последний openhab-js
  • Кнопки, настроенные как переключатели или контакты (см. ниже переменную «switchState») с настраиваемыми метаданными (читайте дальше)

README

Необходимо поместить все выключатели в одну группу. Далее создать правило, где триггером будет выступать изменение статуса одного из членов группы со статуса ВЫКЛ (OPEN/OFF), на ВКЛ (CLOSED/ON).

triggers:
  - id: "1"
    configuration:
      groupName: gAllSwitches
      state: CLOSED
      previousState: OPEN
    type: core.GroupStateChangeTrigger

Также необходимо добавить для выключателей пользовательские метаданные (Custom Metadata) с именем (Namespace) «linkedItem» с именем элемента света/диммера, которым он будет управлять.

Принцип работы

Скрипт поддерживает выключатели и диммеры. Определение происходит автоматически, по типу элемента освещения (SwitchItem или DimmerItem).

Одно короткое нажатие:

  • включение/выключение обычных светильников (Switch).
  • включение/выключение диммеров (Dimmer) с восстановлением прежнего уровня затемнения.

Длительное нажатие:

  • включение/выключение обычных светильников (Switch).
  • диммеры увеличиваются до 100% / уменьшатся до значений minDim. Если остановится и снова нажать кнопку - происходит изменение направление диммирования.

Дополнительно Вы можете прописать любые другие действия для двойных/тройных и т. д. нажатий, настроив функцию «shortPressAction».

В переменных в начале скрипта можно прописать иные временные задержки для регистрации коротких нажатий, скорости диммирования и так далее.

Сам скрипт необходимо добавить в поле Action и выбрать «ECMAScript 262 Edition 11 (application/javascript;version=ECMAScript-2021)»

/*
The MIT License (MIT)
Copyright © 2023 LazyGatto, 
based on Felix Krämer script
https://community.openhab.org/t/multi-press-and-hold-to-dim-js-script-for-thing-buttons/144589
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.

Requirements:
Javascript Automation addon (ECMA2011)
Latest openhab-js installed
A button items configured as switches or contacts (see below 'switchState' variable) with custom metadata (read further)

README:
You have to place all your switches/contacts into one group, which one will be a trigger.
Also you have to add custom metadata for all your switches/contacts 'linkedItem', with item name of light/dimmer it will control.

Script supports switches and dimmers.
For one short press it will turn ON/OFF switches and dimmers.
For long press:
- switches will turn ON/OFF
- dimmers will increase to 100 / decrease to minDim values, stop, press and hold again button will revert dimming direction.

You can provide any custom actions for double/triple/etc presses by customizing 'shortPressAction' function and 'delayMulti'
variable to detect multiple buttom presses.
*/

// ==== Configuration ====

// Delays:
var delayMulti = 350;   // registering multiple pushes
var delayDimStep = 100; // pause between in-/decrease steps
var dimStep = 2; // step to increase/decrease dimming level for one iteration
var minDim = 4; // minimum level for dimming

var switchState = {
  ON: 'CLOSED', // CLOSED for Contact Type
  OFF: 'OPEN' // OPEN for Contact Type
}

// ==== END Configuration ====

var switchTriggered = items.getItem(triggeringItem.name);

// Change the behaviour for different button presses:
// stor.pressCount - button pressed times
function shortPressAction(stor) {

  switch (stor.pressCount) {

    // 1 press to toggle light on/off
    case 1:

      switch (stor.linkedItem.type) {

        case 'SwitchItem':
          stor.linkedItem.sendCommand(stor.linkedItem.state.toString() == "OFF" ? "ON" : "OFF");
          break;

        case 'DimmerItem':
          stor.linkedItem.sendCommand(stor.linkedItem.state == 0 ? stor.dimPreviousState : "OFF");
          break;
      }

      break;

    // 2 presses to switch between color temperatures
    /*
    case 2:
      var temp;
      if (linkedItem.state == 0)
        temp = 33;
      else if (linkedItem.state == 100)
        temp = 0;
      else
        temp = 100;
      linkedItem.sendCommand(temp);
      break;
    */

    // Add your Additional push count here like:
    /*
    case 3:
      // do something
      break;
    */

    default:
      console.log('Default case');
  }
}

function resetStorage(stor) {
  stor.btnTimer = null;
  stor.pressCount = 0;
  stor.dimTimer = null;
  cache.shared.put(stor.cacheId, stor);
}

function dimItem(stor) {

  var dimToSet = null;

  //early exit
  if (stor.switchTriggered.state.toString() == switchState.OFF) {
    resetStorage(stor);
    return;
  }

  if (stor.dimUp == true) {
    dimToSet = Number(stor.linkedItem.state) + dimStep;
    if (dimToSet > 100) {
      dimToSet = 100
      resetStorage(stor);
    }

  } else {
    dimToSet = Number(stor.linkedItem.state) - dimStep;
    if (dimToSet < minDim) {
      dimToSet = minDim
      resetStorage(stor);
    }

  }
  stor.linkedItem.sendCommand(dimToSet);
  stor.dimPreviousState = dimToSet;

  if (stor.dimTimer) {
    stor.dimTimer.reschedule(time.toZDT(delayDimStep));
  }
}

function getPressCountTimer(stor) {

  if (stor.switchTriggered.state.toString() == switchState.OFF) { // Short press cases

    shortPressAction(stor);
    resetStorage(stor);

  } else { // Hold cases

    resetStorage(stor);

    switch (stor.linkedItem.type) {

      case 'SwitchItem':
        stor.linkedItem.sendCommand(stor.linkedItem.state.toString() == "OFF" ? "ON" : "OFF");
        break;

      case 'DimmerItem':
        // Set dim direction
        if (stor.linkedItem.state > 90) {
          console.info('++++ ' + stor.linkedItem.name + ' state >90, Dimming Down');
          stor.dimUp = false;
        } else if (stor.linkedItem.state < 10) {
          console.info('++++ ' + stor.linkedItem.name + ' state <10, Dimming Up');
          stor.dimUp = true;
        } else {
          console.info('++++ ' + stor.linkedItem.name + ' state >10&<90, just revert Dimming');
          stor.dimUp = !stor.dimUp
        }

        if (stor.dimTimer === null) {
          stor.dimTimer = actions.ScriptExecution.createTimer(stor.dimTimerId, time.toZDT(), () => { dimItem(stor) });
        }
        cache.shared.put(stor.cacheId, stor);
        break;
    }

  }
}

if (switchTriggered.state.toString() == switchState.ON) {
  var funcGenerator = function (switchTriggered) {
    var cacheId = switchTriggered.name + '_Id';
    var linkedItem = items.getItem(switchTriggered.getMetadata("linkedItem")['value']);
    var stor = cache.shared.get(cacheId, () => ({
      'cacheId': cacheId,
      'switchTriggered': switchTriggered,
      'linkedItem': linkedItem,
      'btnTimer': null,
      'pressCount': 0,
      'dimTimer': null,
      'dimTimerId': linkedItem.name + '_dimTimerId',
      'dimUp': false,
      'dimPreviousState': 100,
    }));
    stor.pressCount++;
    if (stor.btnTimer !== null) {
      clearTimeout(stor.btnTimer);
    }
    stor.btnTimer = setTimeout(() => getPressCountTimer(stor), delayMulti);
  }
  funcGenerator(switchTriggered);
}

Если необходимо отдельно вывести информацию обо всех выключателях и какие для них прописаны источники света в мета данных, можно создать отдельный виджет, который списком покажет необходимую информацию

uid: widget_96f79b9179
tags: []
props:
  parameters: []
  parameterGroups: []
timestamp: May 23, 2023, 10:53:24 AM
component: f7-card
config: {}
slots:
  default:
    - component: oh-list
      config:
        mediaList: true
      slots:
        default:
          - component: oh-repeater
            config:
              fragment: true
              for: item
              sourceType: itemsInGroup
              groupItem: gAllSwitches
              fetchMetadata: linkedItem
            slots:
              default:
                - component: oh-list-item
                  config:
                    accordionList: true
                    icon: ='oh:' + loop.item.category
                    title: =loop.item.label
                    subtitle: >
                      ="item Name: " + loop.item.name
                    footer: >
                      ="linked Item: " + loop.item.metadata.linkedItem.value
                    after: =loop.item.state

  • sw/openhab/examples/light/ecma.1684833223.txt.gz
  • Последнее изменение: 2023/05/23 12:13
  • lazygatto