Различия
Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия | |||
sw:openhab:examples:irrigation [2023/05/23 10:57] – удалено - внешнее изменение (Дата неизвестна) 127.0.0.1 | sw:openhab:examples:irrigation [2023/05/23 10:57] (текущий) – ↷ Страница перемещена из sw:openhab:binding:examples:irrigation в sw:openhab:examples:irrigation lazygatto | ||
---|---|---|---|
Строка 1: | Строка 1: | ||
+ | ====== Полив ====== | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | В телеграме спрашивали код виджета полива, | ||
+ | |||
+ | ===== Виджеты ===== | ||
+ | |||
+ | < | ||
+ | tags: [] | ||
+ | props: | ||
+ | parameters: | ||
+ | - description: | ||
+ | label: Prop 1 | ||
+ | name: prop1 | ||
+ | required: false | ||
+ | type: TEXT | ||
+ | - context: item | ||
+ | description: | ||
+ | label: Item | ||
+ | name: item | ||
+ | required: false | ||
+ | type: TEXT | ||
+ | parameterGroups: | ||
+ | timestamp: Aug 23, 2021, 9:24:51 PM | ||
+ | component: f7-card | ||
+ | config: | ||
+ | style: | ||
+ | border-radius: | ||
+ | box-shadow: 5px 5px 10px 1px rgba(0, | ||
+ | height: auto | ||
+ | margin: 5px | ||
+ | line-height: | ||
+ | font-family: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-card-header | ||
+ | config: | ||
+ | class: | ||
+ | - justify-content-center | ||
+ | - align-items-center | ||
+ | - text-align-center | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Полив | ||
+ | style: | ||
+ | font-size: 250% | ||
+ | - component: f7-card-content | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | padding: 0px | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-segmented | ||
+ | config: | ||
+ | strong: true | ||
+ | color: green | ||
+ | class: | ||
+ | - segmented-strong | ||
+ | style: | ||
+ | --f7-segmented-strong-padding: | ||
+ | --f7-segmented-strong-between-buttons: | ||
+ | --f7-segmented-strong-button-font-weight: | ||
+ | --f7-segmented-strong-bg-color: | ||
+ | --f7-segmented-strong-button-hover-bg-color: | ||
+ | width: 100% | ||
+ | outline: true | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: Утром | ||
+ | action: variable | ||
+ | actionVariable: | ||
+ | actionVariableValue: | ||
+ | active: =(vars.select == 1) | ||
+ | outline: =(vars.select == 1) | ||
+ | style: | ||
+ | font-weight: | ||
+ | font-size: 150% | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: Вечером | ||
+ | action: variable | ||
+ | actionVariable: | ||
+ | actionVariableValue: | ||
+ | active: =(vars.select == 2) | ||
+ | outline: =(vars.select == 2) | ||
+ | style: | ||
+ | font-weight: | ||
+ | font-size: 150% | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: Днём | ||
+ | action: variable | ||
+ | actionVariable: | ||
+ | actionVariableValue: | ||
+ | active: =(vars.select == 3) | ||
+ | outline: =(vars.select == 3) | ||
+ | style: | ||
+ | font-weight: | ||
+ | font-size: 150% | ||
+ | - component: f7-tab | ||
+ | config: | ||
+ | visible: =(vars.select == 1 || vars.select == NULL) | ||
+ | style: | ||
+ | animation: f7-fade-in 300ms | ||
+ | padding: 0px | ||
+ | margin: 5px | ||
+ | margin-right: | ||
+ | class: | ||
+ | - display-flex | ||
+ | - justify-content-space-between | ||
+ | - flex-direction-column | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | font-size: 120% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Утренний полив | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | item: IrrigationStartAtSunrise | ||
+ | color: green | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | font-size: 120% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: {} | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: " | ||
+ | style: | ||
+ | margin-right: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.Voshod.displayState | ||
+ | - component: f7-row | ||
+ | config: {} | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Время после рассвета | ||
+ | style: | ||
+ | margin-right: | ||
+ | - component: oh-link | ||
+ | config: | ||
+ | color: green | ||
+ | text: =items.IrrigationHoursAfterSunrise.state | ||
+ | action: popup | ||
+ | popoverOpen: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-popover | ||
+ | config: | ||
+ | class: | ||
+ | - timerpopover | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-stepper-card | ||
+ | config: | ||
+ | color: green | ||
+ | item: IrrigationHoursAfterSunrise | ||
+ | title: Минут после рассвета | ||
+ | min: 0 | ||
+ | max: 180 | ||
+ | step: 10 | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | margin-bottom: | ||
+ | font-size: 120% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: {} | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: " | ||
+ | style: | ||
+ | margin-right: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.IrrigationStartTime.displayState | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | padding: 5px | ||
+ | margin: 0px | ||
+ | font-size: 120% | ||
+ | border: 1px solid green | ||
+ | border-radius: | ||
+ | display: inline | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-repeater | ||
+ | config: | ||
+ | accordionList: | ||
+ | fragment: false | ||
+ | for: item | ||
+ | sourceType: itemsInGroup | ||
+ | groupItem: GroupIrrigationValves | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin-top: 5px | ||
+ | display: flex | ||
+ | justify-content: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-link | ||
+ | config: | ||
+ | iconMaterial: | ||
+ | color: ' | ||
+ | iconSize: 25px | ||
+ | action: popover | ||
+ | popoverOpen: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-popover | ||
+ | config: | ||
+ | class: =' | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-block | ||
+ | config: | ||
+ | style: | ||
+ | animate: true | ||
+ | align-self: center | ||
+ | justify-self: | ||
+ | justify-content: | ||
+ | text-align: center | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Запуск вручную | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =items[loop.item.name].state | ||
+ | color: green | ||
+ | action: toggle | ||
+ | actionCommand: | ||
+ | actionCommandAlt: | ||
+ | actionItem: =loop.item.name | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =loop.item.label | ||
+ | action: analyzer | ||
+ | actionAnalyzerItems: | ||
+ | style: | ||
+ | --f7-button-hover-bg-color: | ||
+ | color: var(--f7-button-text-color) | ||
+ | font-size: 20px | ||
+ | margin-left: | ||
+ | - component: oh-stepper | ||
+ | config: | ||
+ | item: =(loop.item.name + ' | ||
+ | title: Время полива | ||
+ | min: 0 | ||
+ | max: 180 | ||
+ | step: 1 | ||
+ | round: true | ||
+ | color: green | ||
+ | autorepeat: true | ||
+ | autorepeat-dynamic: | ||
+ | style: | ||
+ | margin-left: | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | iconF7: gear_alt_fill | ||
+ | color: ' | ||
+ | action: variable | ||
+ | actionVariable: | ||
+ | actionVariableValue: | ||
+ | - component: f7-segmented | ||
+ | config: | ||
+ | strong: true | ||
+ | small: true | ||
+ | outline: true | ||
+ | color: green | ||
+ | class: | ||
+ | - segmented-round | ||
+ | style: | ||
+ | --f7-segmented-strong-padding: | ||
+ | --f7-segmented-strong-between-buttons: | ||
+ | --f7-segmented-strong-button-font-weight: | ||
+ | --f7-segmented-strong-bg-color: | ||
+ | --f7-segmented-strong-button-hover-bg-color: | ||
+ | --f7-segmented-strong-button-active-bg-color: | ||
+ | margin-top: 5px | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-repeater | ||
+ | config: | ||
+ | fragment: true | ||
+ | for: day | ||
+ | sourceType: array | ||
+ | in: | ||
+ | - name: 1 | ||
+ | label: Пн | ||
+ | - name: 2 | ||
+ | label: Вт | ||
+ | - name: 3 | ||
+ | label: Ср | ||
+ | - name: 4 | ||
+ | label: Чт | ||
+ | - name: 5 | ||
+ | label: Пт | ||
+ | - name: 6 | ||
+ | label: Сб | ||
+ | - name: 7 | ||
+ | label: Вс | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =loop.day.label | ||
+ | action: toggle | ||
+ | actionCommand: | ||
+ | actionCommandAlt: | ||
+ | actionItem: =(loop.item.name + ' | ||
+ | fill: " | ||
+ | style: | ||
+ | font-weight: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | visible: =vars[loop.item.name + ' | ||
+ | style: | ||
+ | margin: 10px | ||
+ | display: flex | ||
+ | justify-content: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Коррекция | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: по температуре | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | margin-right: | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | color: green | ||
+ | item: =(loop.item.name + ' | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: по осадкам | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | margin: 0px 10px | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | color: green | ||
+ | item: =(loop.item.name + ' | ||
+ | - component: f7-tab | ||
+ | config: | ||
+ | visible: =(vars.select == 2) | ||
+ | style: | ||
+ | animation: f7-fade-in 300ms | ||
+ | padding: 0px | ||
+ | margin: 5px | ||
+ | margin-right: | ||
+ | class: | ||
+ | - display-flex | ||
+ | - justify-content-space-between | ||
+ | - flex-direction-column | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | font-size: 120% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Вечерний полив | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | item: IrrigationStartAtSundown | ||
+ | color: green | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | font-size: 120% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: {} | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: " | ||
+ | style: | ||
+ | margin-right: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.Zakat.displayState | ||
+ | - component: f7-row | ||
+ | config: {} | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Время до заката | ||
+ | style: | ||
+ | margin-right: | ||
+ | - component: oh-link | ||
+ | config: | ||
+ | color: green | ||
+ | text: =items.IrrigationHoursBeforeSundown.state | ||
+ | action: popover | ||
+ | popoverOpen: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-popover | ||
+ | config: | ||
+ | class: | ||
+ | - timerpopover | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-stepper-card | ||
+ | config: | ||
+ | color: green | ||
+ | item: IrrigationHoursBeforeSundown | ||
+ | title: Минут после рассвета | ||
+ | min: 0 | ||
+ | max: 180 | ||
+ | step: 10 | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | margin-bottom: | ||
+ | font-size: 120% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: {} | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: " | ||
+ | style: | ||
+ | margin-right: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.IrrigationStartTime3.displayState | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | padding: 5px | ||
+ | margin: 0px | ||
+ | font-size: 120% | ||
+ | border: 1px solid green | ||
+ | border-radius: | ||
+ | display: inline | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-repeater | ||
+ | config: | ||
+ | fragment: false | ||
+ | for: item | ||
+ | sourceType: itemsInGroup | ||
+ | groupItem: GroupIrrigationValves | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin-top: 5px | ||
+ | display: flex | ||
+ | justify-content: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-link | ||
+ | config: | ||
+ | iconMaterial: | ||
+ | color: ' | ||
+ | iconSize: 25px | ||
+ | action: popover | ||
+ | popoverOpen: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-popover | ||
+ | config: | ||
+ | class: =' | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-block | ||
+ | config: | ||
+ | style: | ||
+ | animate: true | ||
+ | align-self: center | ||
+ | justify-self: | ||
+ | justify-content: | ||
+ | text-align: center | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Запуск вручную | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =items[loop.item.name].state | ||
+ | color: green | ||
+ | action: toggle | ||
+ | actionCommand: | ||
+ | actionCommandAlt: | ||
+ | actionItem: =loop.item.name | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =loop.item.label | ||
+ | action: analyzer | ||
+ | actionAnalyzerItems: | ||
+ | style: | ||
+ | --f7-button-hover-bg-color: | ||
+ | color: white | ||
+ | font-size: 20px | ||
+ | margin-left: | ||
+ | - component: oh-stepper | ||
+ | config: | ||
+ | item: =(loop.item.name + ' | ||
+ | title: Время полива | ||
+ | min: 0 | ||
+ | max: 180 | ||
+ | step: 1 | ||
+ | round: true | ||
+ | color: green | ||
+ | autorepeat: true | ||
+ | autorepeat-dynamic: | ||
+ | style: | ||
+ | margin-left: | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | iconF7: gear_alt_fill | ||
+ | color: ' | ||
+ | action: variable | ||
+ | actionVariable: | ||
+ | actionVariableValue: | ||
+ | - component: f7-segmented | ||
+ | config: | ||
+ | strong: true | ||
+ | small: true | ||
+ | outline: true | ||
+ | color: green | ||
+ | class: | ||
+ | - segmented-round | ||
+ | style: | ||
+ | --f7-segmented-strong-padding: | ||
+ | --f7-segmented-strong-between-buttons: | ||
+ | --f7-segmented-strong-button-font-weight: | ||
+ | --f7-segmented-strong-bg-color: | ||
+ | --f7-segmented-strong-button-hover-bg-color: | ||
+ | --f7-segmented-strong-button-active-bg-color: | ||
+ | margin-top: 5px | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-repeater | ||
+ | config: | ||
+ | fragment: true | ||
+ | for: day | ||
+ | sourceType: array | ||
+ | in: | ||
+ | - name: 1 | ||
+ | label: Пн | ||
+ | - name: 2 | ||
+ | label: Вт | ||
+ | - name: 3 | ||
+ | label: Ср | ||
+ | - name: 4 | ||
+ | label: Чт | ||
+ | - name: 5 | ||
+ | label: Пт | ||
+ | - name: 6 | ||
+ | label: Сб | ||
+ | - name: 7 | ||
+ | label: Вс | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =loop.day.label | ||
+ | action: toggle | ||
+ | actionCommand: | ||
+ | actionCommandAlt: | ||
+ | actionItem: =(loop.item.name + ' | ||
+ | fill: " | ||
+ | style: | ||
+ | font-weight: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | visible: =vars[loop.item.name + ' | ||
+ | style: | ||
+ | margin: 10px | ||
+ | display: flex | ||
+ | justify-content: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Коррекция | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: по температуре | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | margin-right: | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | color: green | ||
+ | item: =(loop.item.name + ' | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: по осадкам | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | margin: 0px 10px | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | color: green | ||
+ | item: =(loop.item.name + ' | ||
+ | - component: f7-block | ||
+ | config: | ||
+ | visible: =(vars.select == 3) | ||
+ | style: | ||
+ | animation: f7-fade-in 300ms | ||
+ | width: 99% | ||
+ | padding: 0px | ||
+ | margin: 5px | ||
+ | margin-right: | ||
+ | class: | ||
+ | - display-flex | ||
+ | - justify-content-space-between | ||
+ | - flex-direction-column | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | width: 99% | ||
+ | font-size: 120% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Дневной полив | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | item: IrrigationStartAtSpecificHour | ||
+ | color: green | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Время начала полива | ||
+ | - component: oh-link | ||
+ | config: | ||
+ | color: green | ||
+ | text: =items.IrrigationStartTime2.displayState | ||
+ | action: popup | ||
+ | actionModal: | ||
+ | actionModalConfig: | ||
+ | item: IrrigationStartTime2 | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | padding: 5px | ||
+ | margin: 0px | ||
+ | font-size: 120% | ||
+ | border: 1px solid green | ||
+ | border-radius: | ||
+ | display: inline | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-repeater | ||
+ | config: | ||
+ | fragment: false | ||
+ | for: item | ||
+ | sourceType: itemsInGroup | ||
+ | groupItem: GroupIrrigationValves | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin-top: 5px | ||
+ | display: flex | ||
+ | justify-content: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-link | ||
+ | config: | ||
+ | iconMaterial: | ||
+ | color: ' | ||
+ | iconSize: 25px | ||
+ | action: popover | ||
+ | popoverOpen: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-popover | ||
+ | config: | ||
+ | class: =' | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-block | ||
+ | config: | ||
+ | style: | ||
+ | animate: true | ||
+ | align-self: center | ||
+ | justify-self: | ||
+ | justify-content: | ||
+ | text-align: center | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Запуск вручную | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =items[loop.item.name].state | ||
+ | color: green | ||
+ | action: toggle | ||
+ | actionCommand: | ||
+ | actionCommandAlt: | ||
+ | actionItem: =loop.item.name | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =loop.item.label | ||
+ | action: analyzer | ||
+ | actionAnalyzerItems: | ||
+ | style: | ||
+ | --f7-button-hover-bg-color: | ||
+ | color: white | ||
+ | font-size: 20px | ||
+ | margin-left: | ||
+ | - component: oh-stepper | ||
+ | config: | ||
+ | item: =(loop.item.name + ' | ||
+ | title: Время полива | ||
+ | min: 0 | ||
+ | max: 180 | ||
+ | step: 1 | ||
+ | round: true | ||
+ | color: green | ||
+ | autorepeat: true | ||
+ | autorepeat-dynamic: | ||
+ | style: | ||
+ | margin-left: | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | iconF7: gear_alt_fill | ||
+ | color: ' | ||
+ | action: variable | ||
+ | actionVariable: | ||
+ | actionVariableValue: | ||
+ | - component: f7-segmented | ||
+ | config: | ||
+ | strong: true | ||
+ | small: true | ||
+ | outline: true | ||
+ | color: green | ||
+ | class: | ||
+ | - segmented-round | ||
+ | style: | ||
+ | --f7-segmented-strong-padding: | ||
+ | --f7-segmented-strong-between-buttons: | ||
+ | --f7-segmented-strong-button-font-weight: | ||
+ | --f7-segmented-strong-bg-color: | ||
+ | --f7-segmented-strong-button-hover-bg-color: | ||
+ | --f7-segmented-strong-button-active-bg-color: | ||
+ | margin-top: 5px | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-repeater | ||
+ | config: | ||
+ | fragment: true | ||
+ | for: day | ||
+ | sourceType: array | ||
+ | in: | ||
+ | - name: 1 | ||
+ | label: Пн | ||
+ | - name: 2 | ||
+ | label: Вт | ||
+ | - name: 3 | ||
+ | label: Ср | ||
+ | - name: 4 | ||
+ | label: Чт | ||
+ | - name: 5 | ||
+ | label: Пт | ||
+ | - name: 6 | ||
+ | label: Сб | ||
+ | - name: 7 | ||
+ | label: Вс | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-button | ||
+ | config: | ||
+ | text: =loop.day.label | ||
+ | action: toggle | ||
+ | actionCommand: | ||
+ | actionCommandAlt: | ||
+ | actionItem: =(loop.item.name + ' | ||
+ | fill: " | ||
+ | style: | ||
+ | font-weight: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | visible: =vars[loop.item.name + ' | ||
+ | style: | ||
+ | margin: 10px | ||
+ | display: flex | ||
+ | justify-content: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | align-items: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Коррекция | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: по температуре | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | margin-right: | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | color: green | ||
+ | item: =(loop.item.name + ' | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: по осадкам | ||
+ | style: | ||
+ | font-size: 12px | ||
+ | margin: 0px 10px | ||
+ | - component: oh-toggle | ||
+ | config: | ||
+ | color: green | ||
+ | item: =(loop.item.name + ' | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | tags: [] | ||
+ | props: | ||
+ | parameters: [] | ||
+ | parameterGroups: | ||
+ | timestamp: Sep 13, 2021, 11:51:23 PM | ||
+ | component: f7-card | ||
+ | config: | ||
+ | style: | ||
+ | border-radius: | ||
+ | box-shadow: 5px 5px 10px 1px rgba(0, | ||
+ | height: auto | ||
+ | margin: 5px | ||
+ | line-height: | ||
+ | font-family: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: f7-col | ||
+ | config: | ||
+ | style: | ||
+ | width: 100% | ||
+ | slots: | ||
+ | default: | ||
+ | - component: oh-chart | ||
+ | config: | ||
+ | chartType: "" | ||
+ | period: D | ||
+ | label: Температуры | ||
+ | slots: | ||
+ | title: | ||
+ | - component: oh-chart-title | ||
+ | config: | ||
+ | text: Температуры | ||
+ | top: 0px | ||
+ | middle: 0px | ||
+ | grid: | ||
+ | - component: oh-chart-grid | ||
+ | config: | ||
+ | width: 85% | ||
+ | includeLabels: | ||
+ | xAxis: | ||
+ | - component: oh-time-axis | ||
+ | config: | ||
+ | gridIndex: 0 | ||
+ | yAxis: | ||
+ | - component: oh-value-axis | ||
+ | config: | ||
+ | gridIndex: 0 | ||
+ | name: °C | ||
+ | min: -30 | ||
+ | series: | ||
+ | - component: oh-time-series | ||
+ | config: | ||
+ | name: Температура улица | ||
+ | gridIndex: 1 | ||
+ | xAxisIndex: 0 | ||
+ | yAxisIndex: 0 | ||
+ | type: line | ||
+ | item: TemperatureUlica | ||
+ | smooth: true | ||
+ | markPoint: | ||
+ | data: | ||
+ | - type: max | ||
+ | name: Максимальная | ||
+ | - type: min | ||
+ | name: Минимальная | ||
+ | - type: average | ||
+ | name: Средняя | ||
+ | - component: oh-time-series | ||
+ | config: | ||
+ | name: Температура теплица | ||
+ | gridIndex: 1 | ||
+ | xAxisIndex: 0 | ||
+ | yAxisIndex: 0 | ||
+ | type: line | ||
+ | min: -20 | ||
+ | item: TemperatureTeplicaCorrected | ||
+ | smooth: true | ||
+ | areaStyle: | ||
+ | color: | ||
+ | type: linear | ||
+ | x: 0 | ||
+ | y: 0 | ||
+ | x2: 0 | ||
+ | y2: 1 | ||
+ | colorStops: | ||
+ | - offset: 0 | ||
+ | color: rgb(70, 123, 168, 0.0) | ||
+ | - offset: 0.5 | ||
+ | color: rgb(70, 123, 168, 0.5) | ||
+ | - offset: 1 | ||
+ | color: rgb(70, 123, 168, 1.0) | ||
+ | tooltip: | ||
+ | - component: oh-chart-tooltip | ||
+ | config: | ||
+ | confine: true | ||
+ | smartFormatter: | ||
+ | visualMap: | ||
+ | - component: oh-chart-visualmap | ||
+ | config: | ||
+ | show: false | ||
+ | presetPalette: | ||
+ | orient: vertical | ||
+ | type: continuous | ||
+ | - component: oh-chart | ||
+ | config: | ||
+ | height: 180px | ||
+ | chartType: "" | ||
+ | period: D | ||
+ | label: Клапана полива | ||
+ | slots: | ||
+ | grid: | ||
+ | - component: oh-chart-grid | ||
+ | config: | ||
+ | includeLabels: | ||
+ | xAxis: | ||
+ | - component: oh-time-axis | ||
+ | config: | ||
+ | gridIndex: 0 | ||
+ | yAxis: | ||
+ | - component: oh-value-axis | ||
+ | config: | ||
+ | gridIndex: 0 | ||
+ | series: | ||
+ | - component: oh-time-series | ||
+ | config: | ||
+ | name: Газон | ||
+ | gridIndex: 0 | ||
+ | xAxisIndex: 0 | ||
+ | yAxisIndex: 0 | ||
+ | type: line | ||
+ | areaStyle: {} | ||
+ | slots: | ||
+ | markArea: | ||
+ | - component: oh-mark-area | ||
+ | config: | ||
+ | name: Газон | ||
+ | item: IrrigationValveZone3 | ||
+ | - component: oh-time-series | ||
+ | config: | ||
+ | name: Картошка | ||
+ | gridIndex: 0 | ||
+ | xAxisIndex: 0 | ||
+ | yAxisIndex: 0 | ||
+ | type: line | ||
+ | areaStyle: {} | ||
+ | slots: | ||
+ | markArea: | ||
+ | - component: oh-mark-area | ||
+ | config: | ||
+ | name: Картошка | ||
+ | item: IrrigationValveZone4 | ||
+ | - component: oh-time-series | ||
+ | config: | ||
+ | name: Клубника | ||
+ | gridIndex: 0 | ||
+ | xAxisIndex: 0 | ||
+ | yAxisIndex: 0 | ||
+ | type: line | ||
+ | areaStyle: {} | ||
+ | slots: | ||
+ | markArea: | ||
+ | - component: oh-mark-area | ||
+ | config: | ||
+ | name: Клубника | ||
+ | item: IrrigationValveZone2 | ||
+ | - component: oh-time-series | ||
+ | config: | ||
+ | name: Теплица | ||
+ | gridIndex: 0 | ||
+ | xAxisIndex: 0 | ||
+ | yAxisIndex: 0 | ||
+ | type: line | ||
+ | areaStyle: {} | ||
+ | slots: | ||
+ | markArea: | ||
+ | - component: oh-mark-area | ||
+ | config: | ||
+ | name: Теплица | ||
+ | item: IrrigationValveZone1 | ||
+ | tooltip: | ||
+ | - component: oh-chart-tooltip | ||
+ | config: | ||
+ | confine: true | ||
+ | smartFormatter: | ||
+ | legend: | ||
+ | - component: oh-chart-legend | ||
+ | config: | ||
+ | bottom: 3 | ||
+ | type: scroll | ||
+ | dataZoom: | ||
+ | - component: oh-chart-datazoom | ||
+ | config: | ||
+ | type: inside | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | padding: 5px | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Осадки сегодня | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.SumRainLast24h.state | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | padding: 5px | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Осадки завтра | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.SumRainNext24h.state | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 5px | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Сумма осадков | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.irrRainSum.state | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 7px | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Температурный коэффициент | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.IrrigationDurationCoefficientFactor.state | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 7px | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Время до конца полива текущей зоны | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: =items.IrrigationSectionRemainingTime.state+" | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 10px | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Лимит осадков | ||
+ | - component: oh-stepper | ||
+ | config: | ||
+ | item: MaxAllowedRain | ||
+ | round: true | ||
+ | color: green | ||
+ | step: 0.1 | ||
+ | style: | ||
+ | margin-left: | ||
+ | margin-right: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: мм | ||
+ | - component: f7-row | ||
+ | config: | ||
+ | style: | ||
+ | margin: 10px | ||
+ | align-items: | ||
+ | justify-content: | ||
+ | slots: | ||
+ | default: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: Максимальная скорость ветра | ||
+ | - component: oh-stepper | ||
+ | config: | ||
+ | round: true | ||
+ | color: green | ||
+ | item: MaxAllowedWindSpeed | ||
+ | style: | ||
+ | margin-left: | ||
+ | margin-right: | ||
+ | - component: Label | ||
+ | config: | ||
+ | text: км/ | ||
+ | |||
+ | ===== Правила ===== | ||
+ | |||
+ | < | ||
+ | * Irrigation rules | ||
+ | */ | ||
+ | |||
+ | |||
+ | |||
+ | val logName = " | ||
+ | var Timer irrigationTimer = null | ||
+ | var String timeOfDay = "" | ||
+ | var String timeNumber = "" | ||
+ | |||
+ | // watering time correction factor - based on the average temperature | ||
+ | var coefficientFactor = 1.0 | ||
+ | |||
+ | rule " | ||
+ | when | ||
+ | System started | ||
+ | then | ||
+ | // initiall default settings | ||
+ | |||
+ | if (SumRainLast24h.state == NULL) | ||
+ | SumRainLast24h.sendCommand(0) | ||
+ | |||
+ | if (SumRainNext24h.state == NULL) | ||
+ | SumRainNext24h.sendCommand(0) | ||
+ | |||
+ | if (MaxAllowedWindSpeed.state == NULL) | ||
+ | MaxAllowedWindSpeed.sendCommand(35) | ||
+ | |||
+ | if (MaxAllowedRain.state == NULL) | ||
+ | MaxAllowedRain.sendCommand(3) | ||
+ | |||
+ | if (IrrigationHoursAfterSunrise.state == NULL) | ||
+ | IrrigationHoursAfterSunrise.sendCommand(1) | ||
+ | |||
+ | if (IrrigationValveZone1Time.state == NULL) | ||
+ | IrrigationValveZone1Time.sendCommand(1) | ||
+ | |||
+ | if (IrrigationValveZone2Time.state == NULL) | ||
+ | IrrigationValveZone2Time.sendCommand(1) | ||
+ | |||
+ | if (IrrigationValveZone3Time.state == NULL) | ||
+ | IrrigationValveZone3Time.sendCommand(1) | ||
+ | |||
+ | if (IrrigationValveZone4Time.state == NULL) | ||
+ | IrrigationValveZone4Time.sendCommand(1) | ||
+ | |||
+ | if (IrrigationStartAtSpecificHour.state == NULL) | ||
+ | IrrigationStartAtSpecificHour.sendCommand(OFF) | ||
+ | |||
+ | if (IrrigationStartTime.state == NULL) | ||
+ | IrrigationStartTime.sendCommand(20) | ||
+ | |||
+ | if (IrrigationHoursBeforeSundown.state == NULL) | ||
+ | IrrigationHoursBeforeSundown.sendCommand(60) | ||
+ | |||
+ | if (IrrigationHoursBeforeSundown.state == NULL) | ||
+ | IrrigationHoursAfterSunrise.sendCommand(40) | ||
+ | |||
+ | if (IrrigationStartTime2.state == NULL) | ||
+ | IrrigationStartTime2.sendCommand(now()) | ||
+ | |||
+ | if (IrrigationStartTime3.state == NULL) | ||
+ | IrrigationStartTime.sendCommand(20) | ||
+ | |||
+ | // close all valves | ||
+ | GroupIrrigationValves.members.filter[valve | valve.state != OFF].forEach[valve | valve.sendCommand(OFF)] | ||
+ | |||
+ | IrrigationCurrentValve.postUpdate(OFF) | ||
+ | end | ||
+ | |||
+ | rule " | ||
+ | when | ||
+ | Time cron "0 * * ? * *" // every minute | ||
+ | then | ||
+ | var Number wateringHour = 25 | ||
+ | var Number wateringMinute = 61 | ||
+ | var Number wateringHour2 = 25 | ||
+ | var Number wateringMinute2 = 61 | ||
+ | var Number wateringHour3 = 25 | ||
+ | var Number wateringMinute3 = 61 | ||
+ | |||
+ | try { | ||
+ | logDebug(logName, | ||
+ | |||
+ | // calculate rainfall | ||
+ | SumRainLast24h.sendCommand((Forecast_Current_Rain.sumSince(now.minusHours(24), | ||
+ | SumRainNext24h.sendCommand(Forecast_ForecastTomorrow_Rain.state as Number) | ||
+ | |||
+ | // wait to propagate item states - not sure if necessary | ||
+ | Thread.sleep(200) | ||
+ | |||
+ | logDebug(logName, | ||
+ | logDebug(logName, | ||
+ | |||
+ | /////////////////// | ||
+ | // start calculations, | ||
+ | /////////////////// | ||
+ | |||
+ | // check for the manual lock | ||
+ | if (IrrigationLock.state == ON) { | ||
+ | logDebug(logName, | ||
+ | return | ||
+ | } | ||
+ | |||
+ | // check the week day | ||
+ | //val Number day = now.getDayOfWeek() | ||
+ | //val dayItem = ScriptServiceUtil.getItemRegistry.getItem(" | ||
+ | |||
+ | //if (dayItem === null || dayItem.state == OFF || dayItem.state == NULL) { | ||
+ | // | ||
+ | // return | ||
+ | //} | ||
+ | |||
+ | // set the default irrigation hour to X hours after the sunrise | ||
+ | val localSunrise = (IrrigationStartTime.state as DateTimeType).getZonedDateTime() | ||
+ | |||
+ | if (IrrigationStartAtSunrise.state == ON) { | ||
+ | wateringHour = localSunrise.getHour() | ||
+ | wateringMinute = localSunrise.getMinute() | ||
+ | logDebug(logName, | ||
+ | } | ||
+ | else { | ||
+ | wateringHour = 25 | ||
+ | wateringMinute = 61 | ||
+ | } | ||
+ | |||
+ | // set the default irrigation hour to X hours before the sundown | ||
+ | val localSunDown = (IrrigationStartTime3.state as DateTimeType).getZonedDateTime() | ||
+ | if (IrrigationStartAtSundown.state == ON) { | ||
+ | wateringHour3 = localSunDown.getHour() | ||
+ | wateringMinute3 = localSunDown.getMinute() | ||
+ | logDebug(logName, | ||
+ | } | ||
+ | else { | ||
+ | wateringHour3 = 25 | ||
+ | wateringMinute3 = 61 | ||
+ | } | ||
+ | |||
+ | // if there is a specific hour in settings, then use it | ||
+ | val specificHour = (IrrigationStartTime2.state as DateTimeType).getZonedDateTime() | ||
+ | if (IrrigationStartAtSpecificHour.state == ON) { | ||
+ | wateringHour2 = specificHour.getHour() | ||
+ | wateringMinute2 = specificHour.getMinute() | ||
+ | logDebug(logName, | ||
+ | } | ||
+ | else { | ||
+ | wateringHour2 = 25 | ||
+ | wateringMinute2 = 61 | ||
+ | } | ||
+ | |||
+ | // check if the current time is the watering time (full hour) | ||
+ | if ((now.getHour != wateringHour || now.getMinute != wateringMinute) && (now.getHour != wateringHour2 || now.getMinute != wateringMinute2) && (now.getHour != wateringHour3 || now.getMinute != wateringMinute3)) | ||
+ | // nope - good bye | ||
+ | logDebug(logName, | ||
+ | return | ||
+ | } | ||
+ | else if (now.getHour == wateringHour && now.getMinute == wateringMinute) { | ||
+ | timeOfDay = " | ||
+ | timeNumber = " | ||
+ | } | ||
+ | else if (now.getHour == wateringHour2 && now.getMinute == wateringMinute2) { | ||
+ | timeOfDay = " | ||
+ | timeNumber = "" | ||
+ | } | ||
+ | else if (now.getHour == wateringHour3 && now.getMinute == wateringMinute3) { | ||
+ | timeOfDay = " | ||
+ | timeNumber = " | ||
+ | } | ||
+ | logInfo(logName, | ||
+ | |||
+ | // check the weather, and based on that set the watering time coefficient factor | ||
+ | // if the temperature is to low, don't start watering | ||
+ | val avgTemperatureLast24h = (Forecast_Current_Temperature.averageSince(now.minusHours(24), | ||
+ | |||
+ | logInfo(logName, | ||
+ | |||
+ | if (avgTemperatureLast24h <= 10) { | ||
+ | logInfo(logName, | ||
+ | return | ||
+ | } | ||
+ | |||
+ | else { | ||
+ | // coefficient factor should be between 1 and 2 | ||
+ | // this part could, and should be better | ||
+ | coefficientFactor = (avgTemperatureLast24h / 20).floatValue | ||
+ | IrrigationDurationCoefficientFactor.sendCommand(coefficientFactor) | ||
+ | logInfo(logName, | ||
+ | } | ||
+ | |||
+ | /////////////////// | ||
+ | // ok, let's start watering, cascading all of the valves from the GroupIrrigationValves | ||
+ | /////////////////// | ||
+ | |||
+ | // starting with the Zone 1, other zones will be turned on in sequence by the separate rule | ||
+ | logDebug(logName, | ||
+ | IrrigationCurrentValve.sendCommand(IrrigationValveZone1.name) | ||
+ | } | ||
+ | catch (Exception e) { | ||
+ | logError(logName, | ||
+ | } | ||
+ | end | ||
+ | |||
+ | rule " | ||
+ | when | ||
+ | Item IrrigationCurrentValve received command | ||
+ | then | ||
+ | // check if the current wind speed is higher then the max allowed | ||
+ | logDebug(logName, | ||
+ | if (Forecast_Current_Windspeed.state > MaxAllowedWindSpeed.state as Number) { | ||
+ | logInfo(logName, | ||
+ | return | ||
+ | } | ||
+ | |||
+ | // if the rainfall sum for the last 24h and the forecast for 24h is higher then set, then we are not going to irrigate | ||
+ | val rainSum = (SumRainLast24h.state as Number).doubleValue + (SumRainNext24h.state as Number).doubleValue | ||
+ | logDebug(logName, | ||
+ | IrrigationMasterValve.sendCommand(ON) | ||
+ | if (WaterPump.state == " | ||
+ | WaterPump.sendCommand(OFF) | ||
+ | } | ||
+ | try { | ||
+ | // get the currently open valve | ||
+ | val currValve = GroupIrrigationValves.members.findFirst[valve | valve.name == receivedCommand.toString] | ||
+ | val currValveNum = Integer:: | ||
+ | val currValveMins = GroupIrrigationTimes.members.findFirst[t | t.name == currValve.name+" | ||
+ | logDebug(logName, | ||
+ | val currRainCorrection = Group_Irrigation_Settings.members.findFirst[t | t.name == currValve.name+" | ||
+ | val currDayOnOff = Group_Irrigation_Settings.members.findFirst[t | t.name == currValve.name+timeOfDay+now.getDayOfWeek.getValue ].state.toString | ||
+ | logDebug(logName, | ||
+ | // get the next valve in the sequence | ||
+ | val nextValveNum = currValveNum + 1 | ||
+ | val nextValveName = " | ||
+ | val nextValve = GroupIrrigationValves.members.findFirst[valve | valve.name == nextValveName] | ||
+ | |||
+ | // if there is no next valve in the sequence, then nextValve is null | ||
+ | if (nextValve === null) | ||
+ | logDebug(logName, | ||
+ | else | ||
+ | logDebug(logName, | ||
+ | |||
+ | // open the current valve | ||
+ | val currTimeCorrection = Group_Irrigation_Settings.members.findFirst[t | t.name == currValve.name+" | ||
+ | var Number valveOpenTime = 0 | ||
+ | if (currTimeCorrection != " | ||
+ | valveOpenTime = currValveMins * coefficientFactor | ||
+ | } | ||
+ | else { | ||
+ | valveOpenTime = currValveMins | ||
+ | } | ||
+ | |||
+ | if ((rainSum > (MaxAllowedRain.state as Number).doubleValue) && (currRainCorrection != " | ||
+ | logInfo(logName, | ||
+ | if (nextValve !== null) { | ||
+ | // this will invoke cascading valves, " | ||
+ | IrrigationCurrentValve.sendCommand(nextValve.name) | ||
+ | } | ||
+ | else { | ||
+ | IrrigationMasterValve.sendCommand(OFF) | ||
+ | IrrigationSecondaryValve.sendCommand(OFF) | ||
+ | if (DefenceSystem.state == " | ||
+ | WaterPump.sendCommand(OFF) | ||
+ | } | ||
+ | logInfo(logName, | ||
+ | } | ||
+ | } else if (currDayOnOff != " | ||
+ | logInfo(logName, | ||
+ | currValve.sendCommand(ON) | ||
+ | IrrigationSectionRemainingTime.postUpdate(valveOpenTime.intValue) | ||
+ | |||
+ | // set the timer, after expiring turn off the current valve and turn on the next one | ||
+ | irrigationTimer = createTimer(now.plusMinutes(valveOpenTime.intValue), | ||
+ | if (nextValve !== null) { | ||
+ | // this will invoke cascading valves, " | ||
+ | IrrigationCurrentValve.sendCommand(nextValve.name) | ||
+ | } | ||
+ | else { | ||
+ | IrrigationMasterValve.sendCommand(OFF) | ||
+ | IrrigationSecondaryValve.sendCommand(OFF) | ||
+ | if (DefenceSystem.state == " | ||
+ | WaterPump.sendCommand(OFF) | ||
+ | } | ||
+ | logInfo(logName, | ||
+ | } | ||
+ | |||
+ | // let's wait for propagating item values | ||
+ | Thread:: | ||
+ | // turn off current valve | ||
+ | logInfo(logName, | ||
+ | currValve.sendCommand(OFF) | ||
+ | |||
+ | irrigationTimer = null | ||
+ | ]) | ||
+ | } | ||
+ | |||
+ | else if (nextValve !== null) { | ||
+ | // this will invoke cascading valves, " | ||
+ | IrrigationCurrentValve.sendCommand(nextValve.name) | ||
+ | } | ||
+ | else { | ||
+ | IrrigationMasterValve.sendCommand(OFF) | ||
+ | IrrigationSecondaryValve.sendCommand(OFF) | ||
+ | if (DefenceSystem.state == " | ||
+ | WaterPump.sendCommand(OFF) | ||
+ | } | ||
+ | logInfo(logName, | ||
+ | } | ||
+ | } | ||
+ | catch (Exception e) { | ||
+ | logError(logName, | ||
+ | } | ||
+ | end | ||
+ | |||
+ | // for displaying remaining irrigation time purpose only | ||
+ | rule " | ||
+ | when | ||
+ | Time cron "0 * * ? * *" // every minute | ||
+ | then | ||
+ | if (IrrigationSectionRemainingTime.state as Number > 0) | ||
+ | IrrigationSectionRemainingTime.postUpdate((IrrigationSectionRemainingTime.state as Number) - 1) | ||
+ | end | ||
+ | |||
+ | rule " | ||
+ | when | ||
+ | Item GroupIrrigationValves changed to OFF | ||
+ | then | ||
+ | // set the current valve to OFF | ||
+ | logInfo(logName, | ||
+ | IrrigationCurrentValve.postUpdate(OFF) | ||
+ | |||
+ | // reset the remaining time | ||
+ | IrrigationSectionRemainingTime.postUpdate(0) | ||
+ | end | ||
+ | |||
+ | rule " | ||
+ | when | ||
+ | Item GroupIrrigationValves changed | ||
+ | then | ||
+ | // protection against overwatering | ||
+ | |||
+ | // log the state of all valves | ||
+ | GroupIrrigationValves.members.forEach [valve | | ||
+ | logInfo(logName, | ||
+ | ] | ||
+ | |||
+ | // a valve was turned on | ||
+ | if (GroupIrrigationValves.state == ON) { | ||
+ | if (IrrigationTimerMax.state == OFF) { | ||
+ | // timer is not set yet, start the timer | ||
+ | logInfo(logName, | ||
+ | IrrigationTimerMax.sendCommand(ON) | ||
+ | } | ||
+ | else { | ||
+ | // the timer is already running | ||
+ | logInfo(logName, | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | logInfo(logName, | ||
+ | IrrigationTimerMax.postUpdate(OFF) | ||
+ | } | ||
+ | // | ||
+ | end | ||
+ | |||
+ | rule " | ||
+ | when | ||
+ | Item IrrigationTimerMax changed to OFF | ||
+ | then | ||
+ | // protection timer expired - turn all valves off | ||
+ | logWarn(logName, | ||
+ | |||
+ | // close all valves from the group | ||
+ | GroupIrrigationValves.members.forEach [valve | | ||
+ | logInfo(logName, | ||
+ | valve.sendCommand(OFF) | ||
+ | ] | ||
+ | end</ | ||
+ | |||
+ | ===== Items ===== | ||
+ | |||
+ | <sxh cpp>// settings group | ||
+ | Group Group_Irrigation_Settings | ||
+ | |||
+ | // irrigation lock | ||
+ | Switch IrrigationLock " | ||
+ | |||
+ | // protection against too long watering, 2h default | ||
+ | Switch IrrigationTimerMax " | ||
+ | |||
+ | // all valves group | ||
+ | Group: | ||
+ | Group: | ||
+ | |||
+ | // cascading valves - current zone | ||
+ | String IrrigationCurrentValve " | ||
+ | |||
+ | // irrigation master valve switch | ||
+ | Switch IrrigationMasterValve " | ||
+ | // irrigation valves' | ||
+ | Switch IrrigationValveZone1 " | ||
+ | Switch IrrigationValveZone2 " | ||
+ | Switch IrrigationValveZone3 " | ||
+ | Switch IrrigationValveZone4 " | ||
+ | |||
+ | // irrigation times | ||
+ | Number IrrigationValveZone1Time " | ||
+ | Number IrrigationValveZone2Time " | ||
+ | Number IrrigationValveZone3Time " | ||
+ | Number IrrigationValveZone4Time " | ||
+ | Number IrrigationValveZone1Time1 " | ||
+ | Number IrrigationValveZone2Time1 " | ||
+ | Number IrrigationValveZone3Time1 " | ||
+ | Number IrrigationValveZone4Time1 " | ||
+ | Number IrrigationValveZone1Time2 " | ||
+ | Number IrrigationValveZone2Time2 " | ||
+ | Number IrrigationValveZone3Time2 " | ||
+ | Number IrrigationValveZone4Time2 " | ||
+ | Number IrrigationDurationCoefficientFactor " | ||
+ | Number IrrigationSectionRemainingTime " | ||
+ | |||
+ | // switch - whether to start at a particular hour or before the sunrise | ||
+ | Switch IrrigationStartAtSpecificHour " | ||
+ | Switch IrrigationStartAtSunrise " | ||
+ | Switch IrrigationStartAtSundown " | ||
+ | Number IrrigationStartTime " | ||
+ | Number IrrigationStartTime2 " | ||
+ | Number IrrigationStartTime3 " | ||
+ | Number IrrigationHoursAfterSunrise " | ||
+ | Nunber IrrigationHoursBeforeSundown " | ||
+ | |||
+ | // irrigation week days | ||
+ | Switch IrrigationDay1 " | ||
+ | Switch IrrigationDay2 " | ||
+ | Switch IrrigationDay3 " | ||
+ | Switch IrrigationDay4 " | ||
+ | Switch IrrigationDay5 " | ||
+ | Switch IrrigationDay6 " | ||
+ | Switch IrrigationDay7 " | ||
+ | |||
+ | Number: | ||
+ | Number: | ||
+ | |||
+ | Number: | ||
+ | Number: | ||
+ | |||
+ | Switch IrrigationValveZone1TimeCorrection " | ||
+ | Switch IrrigationValveZone2TimeCorrection " | ||
+ | Switch IrrigationValveZone3TimeCorrection " | ||
+ | Switch IrrigationValveZone4TimeCorrection " | ||
+ | |||
+ | Switch IrrigationValveZone1RainCorrection " | ||
+ | Switch IrrigationValveZone2RainCorrection " | ||
+ | Switch IrrigationValveZone3RainCorrection " | ||
+ | Switch IrrigationValveZone4RainCorrection " | ||
+ | |||
+ | Switch IrrigationValveZone1M1 " | ||
+ | Switch IrrigationValveZone1M2 " | ||
+ | Switch IrrigationValveZone1M3 " | ||
+ | Switch IrrigationValveZone1M4 " | ||
+ | Switch IrrigationValveZone1M5 " | ||
+ | Switch IrrigationValveZone1M6 " | ||
+ | Switch IrrigationValveZone1M7 " | ||
+ | Switch IrrigationValveZone2M1 " | ||
+ | Switch IrrigationValveZone2M2 " | ||
+ | Switch IrrigationValveZone2M3 " | ||
+ | Switch IrrigationValveZone2M4 " | ||
+ | Switch IrrigationValveZone2M5 " | ||
+ | Switch IrrigationValveZone2M6 " | ||
+ | Switch IrrigationValveZone2M7 " | ||
+ | Switch IrrigationValveZone3M1 " | ||
+ | Switch IrrigationValveZone3M2 " | ||
+ | Switch IrrigationValveZone3M3 " | ||
+ | Switch IrrigationValveZone3M4 " | ||
+ | Switch IrrigationValveZone3M5 " | ||
+ | Switch IrrigationValveZone3M6 " | ||
+ | Switch IrrigationValveZone3M7 " | ||
+ | Switch IrrigationValveZone4M1 " | ||
+ | Switch IrrigationValveZone4M2 " | ||
+ | Switch IrrigationValveZone4M3 " | ||
+ | Switch IrrigationValveZone4M4 " | ||
+ | Switch IrrigationValveZone4M5 " | ||
+ | Switch IrrigationValveZone4M6 " | ||
+ | Switch IrrigationValveZone4M7 " | ||
+ | Switch IrrigationValveZone1D1 " | ||
+ | Switch IrrigationValveZone1D2 " | ||
+ | Switch IrrigationValveZone1D3 " | ||
+ | Switch IrrigationValveZone1D4 " | ||
+ | Switch IrrigationValveZone1D5 " | ||
+ | Switch IrrigationValveZone1D6 " | ||
+ | Switch IrrigationValveZone1D7 " | ||
+ | Switch IrrigationValveZone2D1 " | ||
+ | Switch IrrigationValveZone2D2 " | ||
+ | Switch IrrigationValveZone2D3 " | ||
+ | Switch IrrigationValveZone2D4 " | ||
+ | Switch IrrigationValveZone2D5 " | ||
+ | Switch IrrigationValveZone2D6 " | ||
+ | Switch IrrigationValveZone2D7 " | ||
+ | Switch IrrigationValveZone3D1 " | ||
+ | Switch IrrigationValveZone3D2 " | ||
+ | Switch IrrigationValveZone3D3 " | ||
+ | Switch IrrigationValveZone3D4 " | ||
+ | Switch IrrigationValveZone3D5 " | ||
+ | Switch IrrigationValveZone3D6 " | ||
+ | Switch IrrigationValveZone3D7 " | ||
+ | Switch IrrigationValveZone4D1 " | ||
+ | Switch IrrigationValveZone4D2 " | ||
+ | Switch IrrigationValveZone4D3 " | ||
+ | Switch IrrigationValveZone4D4 " | ||
+ | Switch IrrigationValveZone4D5 " | ||
+ | Switch IrrigationValveZone4D6 " | ||
+ | Switch IrrigationValveZone4D7 " | ||
+ | Switch IrrigationValveZone1E1 " | ||
+ | Switch IrrigationValveZone1E2 " | ||
+ | Switch IrrigationValveZone1E3 " | ||
+ | Switch IrrigationValveZone1E4 " | ||
+ | Switch IrrigationValveZone1E5 " | ||
+ | Switch IrrigationValveZone1E6 " | ||
+ | Switch IrrigationValveZone1E7 " | ||
+ | Switch IrrigationValveZone2E1 " | ||
+ | Switch IrrigationValveZone2E2 " | ||
+ | Switch IrrigationValveZone2E3 " | ||
+ | Switch IrrigationValveZone2E4 " | ||
+ | Switch IrrigationValveZone2E5 " | ||
+ | Switch IrrigationValveZone2E6 " | ||
+ | Switch IrrigationValveZone2E7 " | ||
+ | Switch IrrigationValveZone3E1 " | ||
+ | Switch IrrigationValveZone3E2 " | ||
+ | Switch IrrigationValveZone3E3 " | ||
+ | Switch IrrigationValveZone3E4 " | ||
+ | Switch IrrigationValveZone3E5 " | ||
+ | Switch IrrigationValveZone3E6 " | ||
+ | Switch IrrigationValveZone3E7 " | ||
+ | Switch IrrigationValveZone4E1 " | ||
+ | Switch IrrigationValveZone4E2 " | ||
+ | Switch IrrigationValveZone4E3 " | ||
+ | Switch IrrigationValveZone4E4 " | ||
+ | Switch IrrigationValveZone4E5 " | ||
+ | Switch IrrigationValveZone4E6 " | ||
+ | Switch IrrigationValveZone4E7 " | ||
+ | |||
+ | Непричёсан для использования другими, | ||