External curtains automation via Python Scripting Add-on

Hi all,

I had the need of automating external curtains based on three weather conditions like rain, wind gust and illuminance.
I solved the issue with a Python script(via Python Scripting Add-on) as such:

from openhab import rule, Registry, logger
from openhab.triggers import when
from datetime import datetime, timedelta
import scope


def get_weather_values():
    rain = Registry.getItemState("piezo_rain_rate").floatValue()
    gust_current = Registry.getItemState("weather_speed_gust").floatValue()
    historic_item = (Registry.getItem("weather_speed_gust").getPersistence()
                     .persistedState(datetime.now() - timedelta(minutes=15)))
    gust_past = historic_item.getState().floatValue()
    logger.info("Current Gust: {}".format(round(gust_current,ndigits=2)))
    logger.info("Past Gust: {}".format(round(gust_past,ndigits=2)))
    irradiation_solar = Registry.getItemState("weather_irradiation_solar").floatValue()
    return rain, gust_current, gust_past, irradiation_solar


def get_front_target_position():
    rain, gust_current, gust_past, irradiation_solar = get_weather_values()

    # Logic to determine front target position
    if rain == 0 and gust_current <= 12.0 and gust_past <= 12.0 and irradiation_solar > 60.00:
        return 100 # Curtain opening

    if rain > 0 or gust_current > 18.0 or irradiation_solar < 10.00:
        return 0 # Curtain closing 
    return None


def get_rear_target_position():
    rain, gust_current, gust_past, irradiation_solar = get_weather_values()

    # Logic to determine rear target position
    if rain == 0 and gust_current <= 12.0 and gust_past <= 12.0 and irradiation_solar > 60.00:
        return 100

    if rain > 0 or gust_current > 18.0 or irradiation_solar < 30.00:
        return 0
    return None


def apply_front_shutter_position():
    target = get_front_target_position()
    logger.info("Front target position: {}".format(target))

    if target is None:
        return

    th_shutter_state = Registry.getItemState("iTH_shutter")

    if not isinstance(th_shutter_state, scope.UnDefType):
        th_shutter_state = th_shutter_state.intValue()
        logger.info("Current iTH_shutter position: {}".format(th_shutter_state))

    th_shutter_item = Registry.getItem("iTH_shutter")
    if th_shutter_state != target:
        th_shutter_item.sendCommand(target)
        logger.info("Command sent to iTH_shutter: {}".format(target))


def apply_rear_shutter_position():
    target = get_rear_target_position()
    logger.info("Rear target position: {}".format(target))

    if target is None:
        return

    tg_shutter_state = Registry.getItemState("iTG_shutter")

    if not isinstance(tg_shutter_state, scope.UnDefType):
        tg_shutter_state = tg_shutter_state.intValue()
        logger.info("Current iTG_shutter position: {}".format(tg_shutter_state))

    tg_shutter_item = Registry.getItem("iTG_shutter")
    if tg_shutter_state != target:
        tg_shutter_item.sendCommand(target)
        logger.info("Command sent to iTG_shutter: {}".format(target))


@rule("Python curtain automation script")
@when("Item piezo_rain_rate changed")
@when("Item weather_speed_gust changed")
@when("Item weather_irradiation_solar changed")
def job(module, input):
    apply_front_shutter_position()
    apply_rear_shutter_position()
`

I hope this could be useful to anyone needs such a kind of automation logic!

2 Likes