{"id":34017789,"url":"https://github.com/yfaway/zone-apis","last_synced_at":"2025-12-13T14:48:45.060Z","repository":{"id":57478487,"uuid":"320942580","full_name":"yfaway/zone-apis","owner":"yfaway","description":"Reusable Home Automation rules for OpenHab via HABapp.","archived":false,"fork":false,"pushed_at":"2025-08-24T12:35:57.000Z","size":554,"stargazers_count":2,"open_issues_count":8,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-29T09:30:14.240Z","etag":null,"topics":["framework","home-automation","openhab","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yfaway.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-12-12T23:09:29.000Z","updated_at":"2025-08-24T12:36:00.000Z","dependencies_parsed_at":"2025-04-18T16:40:09.224Z","dependency_job_id":null,"html_url":"https://github.com/yfaway/zone-apis","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/yfaway/zone-apis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yfaway%2Fzone-apis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yfaway%2Fzone-apis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yfaway%2Fzone-apis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yfaway%2Fzone-apis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yfaway","download_url":"https://codeload.github.com/yfaway/zone-apis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yfaway%2Fzone-apis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27707443,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-13T02:00:09.769Z","response_time":147,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework","home-automation","openhab","python"],"created_at":"2025-12-13T14:48:44.348Z","updated_at":"2025-12-13T14:48:45.048Z","avatar_url":"https://github.com/yfaway.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Quick intro and setup instructions](#quick-intro-and-setup-instructions)\n    * [1. Install the libraries](#1-install-the-libraries)\n    * [2. Configure HABapp](#2-configure-habapp)\n    * [3. Create the zone-api configuration file.](#3-create-the-zone-api-configuration-file)\n    * [4. Create a HABapp rule to integrate with ZoneApi.](#4-create-a-habapp-rule-to-integrate-with-zoneapi)\n    * [5. Change OpenHab item names to patterns recognized by the default Zone API parser](#5-change-openhab-item-names-to-patterns-recognized-by-the-default-zone-api-parser)\n    * [6. Start HABapp and observe the action via the log file](#6-start-habapp-and-observe-the-action-via-the-log-file)\n* [Zone API - an alternative approach to writing rules](#zone-api---an-alternative-approach-to-writing-rules)\n* [Core concepts and API](#core-concepts-and-api)\n    * [ZoneManager](#zonemanager)\n    * [Zone](#zone)\n    * [Devices](#devices)\n    * [Events](#events)\n    * [Actions](#actions)\n    * [ZoneParser and the default OpenHab item naming conventions](#zoneparser-and-the-default-openhab-item-naming-conventions)\n        * [OpenHab zone items](#openhab-zone-items)\n        * [OpenHab device items](#openhab-device-items)\n            * [Astro sensor](#astro-sensor)\n            * [Computer](#computer)\n            * [Ecobee thermostat](#ecobee-thermostat)\n            * [Light switches](#light-switches)\n            * [Fan switches](#fan-switches)\n            * [Motion sensors](#motion-sensors)\n            * [Light sensors](#light-sensors)\n            * [Plugs](#plugs)\n            * [Security alarm](#security-alarm)\n            * [Doors](#doors)\n            * [Windows](#windows)\n            * [Humidity sensors](#humidity-sensors)\n            * [Temperature sensors](#temperature-sensors)\n            * [Natural gas sensors](#natural-gas-sensors)\n            * [CO2 sensors](#co2-sensors)\n            * [Smoke sensors](#smoke-sensors)\n            * [Google Chromecasts](#google-chromecasts)\n            * [Network presences](#network-presences)\n            * [Televisions](#televisions)\n            * [Water leak sensors](#water-leak-sensors)\n            * [Weather](#weather)\n* [Common services](#common-services)\n    * [Alert](#alert)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n# Quick intro and setup instructions\nThis framework contains a set of reusable rules for OpenHab. It contains the following components:\n1. The item definitions and bindings in OpenHab.\n2. The [HABApp](https://habapp.readthedocs.io/en/latest/installation.html) process that communicates with OpenHab via\n   the REST API. \n3. This Zone API Python library, integrated with HABapp via a single HABApp rule.\n\nIt is a more complicated architecture compared to having everything running within OpenHab process,\nbut on the other hand, we can use Python 3 libraries. See [here](https://community.openhab.org/t/habapp-vs-jsr223-jython/112914)\nfor the comparison between HABApp and JSR223 Jython.\n\n## 1. Install the libraries\n```bash\n  sudo apt-get install python3-venv # to install python3-venv library\n  python3 -m venv my-home # this will create 'my-home' folder\n  cd my-home\n  source bin/activate\n  python3 -m pip install zone-api # this will install zone-api and its dependencies including HABapp\n```\n\nRefer to the instructions on the [official HABApp website](https://habapp.readthedocs.io/en/latest/installation.html).\nfor additional clarifications.\n\n## 2. Configure HABapp\nFirst run the following commands within the `my-home` folder to start HABapp and to generate the HABapp configuration\nfiles.\n```bash\n  mkdir habapp\n  ./bin/habapp --config habapp/ # HABapp will create the config.yml and logging.yml files.\n```\n\nNow that the config files have been created, press Ctrl-C to kill HABapp. We will change the following 4 values in\n`config.yml` file to specify the OpenHab server.\n```\n  host: localhost  # the OpenHab server IP address\n  port: 8080                                                                  \n  user: ''         # the OpenHab3 username\n  password: ''     # the OpenHab3 password\n```\n\nNext, add a new logger for Zone API to the file `logging.xml` under the section \"**loggers:**\".\n```\n  ZoneApis:                                                                     \n    level: INFO                                                                 \n    handlers:                                                                   \n      - HABApp_default                                                          \n    propagate: False \n```\n\nSee [the HABApp website](https://habapp.readthedocs.io) for additional detail.\n\n## 3. Create the zone-api configuration file.\nCreate the file `my-home/habapp/zone-api-config.yml` with the content below:\n```yaml\nsystem:\n  activity-times:\n    wakeup: '6:35 - 9'\n    lunch: '12:00 - 13:30'\n    quiet: '20:00 - 22:59'\n    dinner: '17:50 - 20:00'\n    sleep: '23:00 - 7:00'\n    auto-arm-stay: '20:00 - 2:00'\n    turn-off-plugs: '23:00 - 2:00'\n\n  email-service:\n    smtp-server: smtp.gmail.com\n    port: 465\n    sender-email: sender@gmail.com\n    sender-password: password\n\n  alerts:\n    email:\n      owner-email-addresses:\n        - recipient@gmail.com\n      admin-email-addresses:\n        - recipient@gmail.com\n\n# Contains the parameters for each named actions.\naction-parameters:\n  AlertOnBadComputerStates:\n    maxCpuTemperatureInDegree: 60\n```\nThe latest version of this file can be found [here](https://github.com/yfaway/zone-apis/blob/master/habapp/zone-api-config.yml).\n\n## 4. Create a HABapp rule to integrate with ZoneApi.\nNext create the file `configure_zone_manager.py` under `my-home/habapp/rules` (HABapp created this folder earlier). Copy\nthe following content into that file.\n```python\nimport HABApp\nimport os\nimport yaml\n\nfrom zone_api import zone_parser as zp\nfrom zone_api import platform_encapsulator as pe\n\n\nclass ConfigureZoneManagerRule(HABApp.Rule):\n    def __init__(self):\n        super().__init__()\n\n        self.run.soon(self.configure_zone_manager)\n\n    # noinspection PyMethodMayBeStatic\n    def configure_zone_manager(self):\n        config_file = './habapp/zone-api-config.yml'\n        if not os.path.exists(config_file):\n            raise ValueError(\"Missing zone-api-config.yml file.\")\n\n        pe.log_info(f\"Reading zone-api configuration from '{config_file}'\")\n\n        with open(config_file, 'r') as file:\n            config = yaml.safe_load(file)\n\n        zm = zp.parse(config)\n        pe.add_zone_manager_to_context(zm)\n\n        pe.log_info(str(pe.get_zone_manager_from_context()))\n\n\nConfigureZoneManagerRule()\n```\nThis is the only rule that is needed to bootstrap the framework. It reads the configuration from the yaml file in the\nsection above.\nThe latest version of this file can be found [here](https://github.com/yfaway/zone-apis/blob/master/habapp/rules/configure_zone_manager.py).\n\n## 5. Change OpenHab item names to patterns recognized by the default Zone API parser\nLet's adjust the OpenHab items files to something like this:\n```\nString Zone_Office { level=\"FF\" }\nSwitch FF_Office_LightSwitch \"Office Light\"\n  { channel=\"zwave:device:9e4ce05e:node8:switch_binary\",                                            \n    durationInMinutes=\"15\" }                                                                        \nSwitch FF_Office_LightSwitch_MotionSensor \"Office Motion Sensor\"                                    \n  { channel=\"mqtt:topic:myBroker:xiaomiMotionSensors:OfficeMotionSensor\"}\n```\nZone API groups items into devices and organizes devices into zones. The items above define a zone names `Office` on the\nfirst floor (`FF` abbreviation). The next two items define a [Light](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/devices/switch.py)\ndevice and a [MotionSensor](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/devices/motion_sensor.py)\nin the `Office` zone (via the convention `FF_Office` prefix).\n\n## 6. Start HABapp and observe the action via the log file\nRestart HABapp with `./bin/habapp --config habapp/` and then monitor the HABapp activity via `tail -F habapp/log/HABApp.log`.\nYou should see something like this:\n```\n[2021-06-20 22:42:06,155] [             HABApp.Rules]     INFO | Added rule \"ConfigureZoneManagerRule\" from rules/configure_zone_manager.py\nZone: Office, floor: FIRST_FLOOR, internal, 2 devices\n  Light: FF_Office_LightSwitch, duration: 15 minutes, illuminance: 8\n  MotionSensor: FF_Office_LightSwitch_MotionSensor, battery powered\n\n  Action: MOTION -\u003e TurnOnSwitch\n  Action: SWITCH_TURNED_ON -\u003e TurnOffAdjacentZones\n```\n\nBased on the zone attributes, and the devices available, certain actions will be enabled. In this case, the action\n`TurnOnSwitch` and `TurnOffAdjacentZones` are triggered on the `MOTION` and `SWITCH_TURNED_ON` events. At this point\nyou have light management including turning on the light when the motion sensor triggers, and a timer to turn off the\nlight after 15 minutes of idle. You have just re-used a rule!\n\nSee [here](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/devices) for the full list of supported\ndevices, and [here](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/actions) for the list of built-in\nactions.\n\nThe rest of this document goes into the rationale and design of the library.\n\n# Zone API - an alternative approach to writing rules\nIn OpenHab, items are defined in a flat manner in the *.items* files under the */etc/openhab/items folder*.\nThey are typically linked to a channel exposed by the underlying hardware.\nThis flat structure has an impact on how rules (whether in Xtend or Jython) are organized. As there\nis no higher level abstraction, rules tend to listen to changes from the specific devices. When the\nrules need to interact with multiple devices of the same type, they can utilize the \n[group concept](https://www.openhab.org/docs/configuration/items.html#groups). An example of good\nusage of group is to turn off all lights. By linking all smart lights to a group switch, turning off\nall the lights can be done by changing the state of the group switch to OFF.\n                                                                                \nWhat is more tricky is when rules need to interact with different devices within the same area. The\ntypical solution is to group unrelated items that belong to the same zone either by using a naming\npattern, or by dedicated groups. For example, the light switch and motion sensor in the Foyer area\ncan be named like this: \"FF_Foyer_Light\", and \"FF_Foyer_MotionSensor\". When a sensor is triggered,\nthe zone can be derived from the name of the triggering item, and other devices/sensors can be\nretrieved using that naming convention. This works but as there is not sufficient abstraction, the\nrules are highly coupled to the naming pattern.\n                                                                                \nThe [Zone API](https://github.com/yfaway/zone-apis) provides another approach. It is a layer\nabove the devices / sensors. Each [ZoneManager](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/immutable_zone_manager.py)\n(i.e. a house) contains multiple [zones](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/zone.py)\n(i.e. rooms), and each zone contains multiple [devices](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/devices).\nEach zone is associated with a set of [actions](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/actions) \nthat are triggered by certain [events](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/zone_event.py).\nThe usual OpenHab events are routed in this manner:\n\n```\nOpenHab events --\u003e ZoneManager --\u003e Zones --\u003e Actions\n```\n\nThe actions operate on the abstract devices and do not concern about the specific naming of the items or\nthe underlying hardware. They replace the traditional OpenHab rules. Actions can be unit-tested with\nvarious levels of mocking.\n\n**Most importantly, it enables reusing of action logics.** There is no need to reinvent the wheels for \ncommon rules such as turning on/off the lights. All ones need to do is to populate the zones and\ndevices / sensors, and the applicable actions will be added and processed automatically.\n\nZoneApi comes with a set of built-in [actions](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/actions).\nThere is no need to determine what action to add to a system. Instead, they are added automatically based on the\nzones structure and based on the type of devices available in each zone.\n\nHere is a sample info log that illustrate the structure of the managed objects.\n```text\nZone: Kitchen, floor: FIRST_FLOOR, internal, displayIcon: kitchen, displayOrder: 3, 7 devices\n  AstroSensor: VT_Time_Of_Day                                                   \n  HumiditySensor: FF_Kitchen_Humidity                                           \n  IlluminanceSensor: FF_Kitchen_LightSwitch_Illuminance                         \n  Light: FF_Kitchen_LightSwitch, duration: 5 mins, illuminance: 8               \n  MotionSensor: FF_Kitchen_SecurityMotionSensor, battery powered                \n  MotionSensor: FF_Kitchen_LightSwitch_PantryMotionSensor, battery powered      \n  TemperatureSensor: FF_Kitchen_Temperature                                     \n                                                                                \n  Action: HUMIDITY_CHANGED -\u003e AlertOnHumidityOutOfRange                         \n  Action: MOTION -\u003e TurnOnSwitch                                                \n  Action: MOTION -\u003e AnnounceMorningWeatherAndPlayMusic                          \n  Action: MOTION -\u003e PlayMusicAtDinnerTime                                       \n  Action: SWITCH_TURNED_ON -\u003e TurnOffAdjacentZones                              \n  Action: TEMPERATURE_CHANGED -\u003e AlertOnTemperatureOutOfRange                   \n  Action: TIMER -\u003e TellKidsToGoToBed                                            \n                                                                                \n  Neighbor: FF_Foyer, OPEN_SPACE                                                \n  Neighbor: FF_GreatRoom, OPEN_SPACE_MASTER\nZone: Foyer, floor: FIRST_FLOOR, internal, displayIcon: groundfloor, displayOrder: 4, 6 devices\n  AlarmPartition: FF_Foyer_AlarmPartition, armMode: ARM_STAY                    \n  AstroSensor: VT_Time_Of_Day                                                   \n  Door: FF_Foyer_Door                                                           \n  Light: FF_Foyer_LightSwitch, duration: 5 mins, illuminance: 8, no premature turn-off time range: 0-23:59\n  MotionSensor: FF_Foyer_LightSwitch_ClosetMotionSensor, battery powered        \n  MotionSensor: FF_Foyer_LightSwitch_MotionSensor, battery powered              \n                                                                                \n  Action: MOTION -\u003e TurnOnSwitch                                                \n  Action: MOTION -\u003e DisarmOnInternalMotion                                      \n  Action: MOTION -\u003e ManagePlugs                                                 \n  Action: PARTITION_ARMED_AWAY -\u003e ChangeThermostatBasedOnSecurityArmMode        \n  Action: PARTITION_ARMED_AWAY -\u003e ManagePlugs                                   \n  Action: PARTITION_ARMED_AWAY -\u003e TurnOffDevicesOnAlarmModeChange               \n  Action: PARTITION_DISARMED_FROM_AWAY -\u003e ChangeThermostatBasedOnSecurityArmMode\n  Action: PARTITION_DISARMED_FROM_AWAY -\u003e ManagePlugs                           \n  Action: PARTITION_DISARMED_FROM_AWAY -\u003e TurnOffDevicesOnAlarmModeChange       \n  Action: SWITCH_TURNED_ON -\u003e TurnOffAdjacentZones                              \n  Action: TIMER -\u003e ArmStayIfNoMovement                                          \n  Action: TIMER -\u003e ArmStayInTheNight                                            \n  Action: TIMER -\u003e ManagePlugs                                                  \n                                                                                \n  Neighbor: SF_Lobby, OPEN_SPACE                                                \n  Neighbor: FF_Office, OPEN_SPACE_MASTER \n```\n\n\n**Running on top of HABApp:**\n\u003e [The original Zone API modules](https://github.com/yfaway/openhab-rules/tree/master/legacy-jython-code)\n\u003e were written in Jython. It was then migrated over to the [HABApp](https://habapp.readthedocs.io/en/latest/installation.html)\n\u003e framework with minimal changes needed to the core code. See [here](https://community.openhab.org/t/habapp-vs-jsr223-jython/112914)\n\u003e for the comparison between HABApp and JSR223 Jython.\n\u003e \n\u003e There are several peripheral modules that are tightly coupled to the HABApp API. The rest of the modules\n\u003e is framework neutral. It is possible to migrate Zone API to another framework running on top of GravVM when it is\n\u003e available. Zone API is now written in Python 3 and thus is not compatible with Jython (equivalent to Python 2.8).\n\n# Core concepts and API\n## ZoneManager\nContains a set of zones and is responsible for dispatching the events to the zones.\n\n## Zone\nContains a set of devices, actions, and is responsible for dispatching the events to the actions.\n\nA zone is aware of its neighbors. Certain rules such as the [turning on/off of the lights](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/actions/turn_on_switch.py)\nis highly dependent on the layout of the zones. The following [neighbor](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/neighbor.py)\ntypes are available.\n1. ```CLOSED_SPACE```\n2. ```OPEN_SPACE```\n3. ```OPEN_SPACE_MASTER```\n4. ```OPEN_SPACE_SLAVE```\n\n## Devices\nThe [devices](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/devices)\ncontains one or more underlying OpenHab items. Rather than operating on a SwitchItem or on a\nNumberItem, the device represents meaningful concrete things such as a [MotionSensor](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/devices/motion_sensor.py),\nor a [Light](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/devices/switch.py).\nDevices contain both attributes (e.g. 'is the door open') and behaviors (e.g. 'arm the security\nsystem').\n\n## Events\nSimilar to the abstraction for the devices, the events are also more concrete. Zone API maps the\nOpenHab items events to the event enums in [ZoneEvent](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/zone_event.py)\nsuch as ```ZoneEvent.HUMIDITY_CHANGED``` or ```ZoneEvent.PARTITION_ARMED_AWAY```.\nThere is also the special event ```ZoneEvent.TIMER``` that represents triggering from a scheduler.\n\nThe event is dispatched to the appropriate zones which then invokes the actions registered for that\nevent. See [EventInfo](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/event_info.py)\nfor more info.\n\n## Actions\nAll the [actions](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/actions) implement the [Action](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/core/action.py) interface.\nThe action's life cycle is represented by the three functions: \n1. ```on_startup()``` - invoked after the ZoneManager has been fully populated, via the event\n   ```ZoneEvent.STARTUP```.\n2. ```on_action()``` - invoked where the device generates an event or when a timer event is\n   triggered (via ```ZoneEvent.TIMER```).\n3. ```on_destroy()``` - currently not invoked.\n\nThe ```@action``` decorator provides execution rules for the action as well as basic validations.\nIf the condition (based on the execution rules) does not match, the action won't be executed.\nBelow are the currently supported decorator parameters:\n1. *devices* - the list of devices the zone must have in order to invoke the action.\n2. *events* - the list of events for which the action will response to.\n3. *internal* - if set, this action is only applicable for internal zone\n4. *external* - if set, this action is only applicable for external zone\n5. *levels* - the zone levels that this action is applicable to. the empty list default value indicates that the action is applicable to all zone levels.\n6. *unique_instance* - if set, do not share the same action instance across zones. This is the case when the action is stateful.\n7. *zone_name_pattern* - if set, the zone name regular expression that is applicable to this action.\n8. *external_events* - the list of events from other zones that this action processes. These events won't be filtered using the same mechanism as the internal events as they come from other zones.\n9. *priority* - the action priority with respect to other actions within the same zone. Actions with lower priority values are executed first.\n10. *activity_types* - the list of ActivityType that the action can trigger. If the current time is not in the\ntime range of one of these activities, the action won't trigger.\n11. *excluded_activity_types* - the list of ActivityType that the action won't trigger. If the current time is in\n    the time range of one of these activities, the action won't trigger.\n\nThese parameters are also available to the action and can be used as a filtering mechanism\nto ensure that the action is only added to the applicable zones. See [ZoneParser::add_actions](https://github.com/yfaway/zone-apis/blob/dc3894780a1715b8845460be87ffff5c0c219afa/src/zone_api/zone_parser.py#L176).\n\nHere is a simple action to disarm the security system when a motion sensor is triggered:\n\n```python\nfrom zone_api import security_manager as sm\nfrom zone_api.core.devices.activity_times import ActivityTimes\nfrom zone_api.core.devices.motion_sensor import MotionSensor\nfrom zone_api.core.zone_event import ZoneEvent\nfrom zone_api.core.action import action, Action\nfrom zone_api.core.devices.alarm_partition import AlarmPartition\n\n\n@action(events=[ZoneEvent.MOTION], devices=[AlarmPartition, MotionSensor])\nclass DisarmOnInternalMotion(Action):\n    \"\"\"\n    Automatically disarm the security system when the motion sensor in the zone containing the\n    security panel is triggered and the current time is not in the auto-arm-stay or sleep\n    time periods.\n    \"\"\"\n\n    def on_action(self, event_info):\n        events = event_info.get_event_dispatcher()\n        zone_manager = event_info.get_zone_manager()\n\n        if not sm.is_armed_stay(zone_manager):\n            return False\n\n        activity = zone_manager.get_first_device_by_type(ActivityTimes)\n        if activity is None:\n            self.log_warning(\"Missing activities time; can't determine wake-up time.\")\n            return False\n\n        if activity.is_auto_arm_stay_time() or (activity.is_sleep_time() and not activity.is_wakeup_time()):\n            return False\n\n        sm.disarm(zone_manager, events)\n        return True\n```\n\nThe decorator for the action above indicates that it is triggered by the motion event, and should\nonly be added to a zone that contains both the AlarmPartition and the Motion devices.\n\nActions can read parameters from the ```zone-api-config.yml``` file (see section 3 above).\n\nParameters available to all actions:\n - disabled (optional boolean; default: false): if set to true, the action is excluded from all zones. This parameter\n   is useful to disable certain actions, either temporarily or permanently when importing a large number of external actions from a library.\n - notificationAudiences (optional string; default: 'users'): configure whether the notification (if any) should go to\n   regular users or the administrators. To take advantage of this parameter, actions need to use\n  ```Action::send_notification(zone_manager, alert)```. Possible values: 'users', or 'administrators'.\n  \nEach actions might also have their own parameters; see the method ```supported_parameters``` in each action.\n\n## ZoneParser and the default OpenHab item naming conventions\nThis is the default parser that retrieves items from OpenHab and creates the appropriate zones and \ndevices based on specific naming conventions. Note that this is just a default parser, it is \npossible to create zones and devices using a different naming convention, or even manually. The\nZone API is not dependent on any specific naming pattern.\n\nSee [sample.items](https://github.com/yfaway/openhab-rules/blob/master/items/) files that is\nparsable by ZoneParser.\n\n### OpenHab zone items\nThe zones are defined as a String items with this pattern Zone_{name}:\n```    \nString Zone_GreatRoom                                                           \n    { level=\"FF\", displayIcon=\"player\", displayOrder=\"1\", openSpaceSlaveNeighbors=\"FF_Kitchen\" } \n```\nThe levels are the reversed mapping of the enums in Zone::Level.\n\nHere are the list of supported attributes:\n* level: reversed mapping of the enums in Zone::Level. 'FF', 'SF', 'TF', 'BM' for first floor,\n  second floor, third floor, basement.\n* external: 'true' or 'false'\n* openSpaceNeighbors: a list of open space adjacent zone ids such as 'FF_Kitchen', where 'FF' is\n  the level and 'Kitchen' is the zone name.\n* openSpaceMasterNeighbors: a list of adjacent master zone ids. When a master zone's light is\n  turned on, all the slave zones' light will be turned off.\n* openSpaceSlaveNeighbors: a list of adjacent slave zone ids.\n* displayIcon: an OpenHab icon name.\n* displayOrder: an integer; the lower the value the higher the order.\n       \n### OpenHab device items\nThe individual OpenHab items are named after this convention: ```{zone_id}_{device_type}_{device_name}```.\n\nFor the full list of supported devices, see [ZoneParser](https://github.com/yfaway/zone-apis/blob/master/src/zone_api/zone_parser.py#L57).\n\nTo see the functions supported by each device, view the [device classes](https://github.com/yfaway/zone-apis/tree/master/src/zone_api/core/devices).\n\n#### Astro sensor\nPattern: `[^g].*_TimeOfDay$`\n\nThis is a virtual device that rely on the Time of Day rule and the Astro binding.\n\nExample:\n```\nString FF_Virtual_TimeOfDay \"Current Time of Day [%s]\"\"]\"\n```\n\n#### Computer\nPattern: `.*_Computer_[^_]+$`\n\nSupported attributes:\n* name: the computer name.\n* alwaysOn: a 'true' or 'false' value that indicates if the computer is ON all the time.\n\nAdditional items are derived from the primary item name with the following additional suffix:\n\"_CpuTemperature\", \"_GpuTemperature\", \"_GpuFanSpeed\".\n\nExample:\n```\nString FF_Office_Computer_Dell\n  { name=\"Dell G5\", alwaysOn=\"true\" }\nNumber FF_Office_Computer_Dell_GpuFanSpeed \"Dell GPU Fan Speed [%d %%]\"\n  { channel=\"mqtt:topic:myBroker:office:dellG5GfxFanSpeed\", autoReport=\"true\" }\nNumber FF_Office_Computer_Dell_GpuTemperature \"Dell GPU Temperature [%d °C]\"\n  { channel=\"mqtt:topic:myBroker:office:dellG5GfxTemperature\", autoReport=\"true\" }\nDateTime FF_Office_Computer_Dell_UpdatedTimestamp \"Dell Last Updated [%1tb %1$td %1$tY %1$tH:%1$tM]\"\n  { channel=\"mqtt:topic:myBroker:office:dellUpdatedTimestamp\", autoReport=\"true\" }\n```\n\n#### Ecobee thermostat\nPattern: `.*_Thermostat_EcobeeName$`\n\nExample:\n```\n```\n\n#### Light switches\nPattern: `[^g].*LightSwitch.*`\n\nAdditional firstEvent item is retrieved by replacing the word \"EcobeeName\" by \"FirstEvent_Type\"\nin the primary item name.\n\nExample:\n```\nString FF_GreatRoom_Thermostat_EcobeeName \"Name [%s]\"                                               \n  { channel=\"ecobee:thermostat:account:411222197263:info#name\" }\nString FF_GreatRoom_Thermostat_FirstEvent_Type \"First Event Type [%s]\"                              \n  { channel=\"ecobee:thermostat:account:411222197263:events#type\" }\n```\n\nSupported attributes:\n* durationInMinutes: numeric value.\n* disableTriggeringFromMotionSensor: 'true' or 'false'; false if not present. \n* noPrematureTurnOffTimeRange: time range string such as '7-9' or 7 AM to 9AM; don't turn of the\n  light on timer expires during these period.\n* dimmable: complex structure to map the lux with a time ranges.\n  E.g.: `dimmable=\"true\" [level=2, timeRanges=\"20-8\"]`\n\nExample:\n```    \nSwitch FF_Office_LightSwitch \"Office Light\" (gWallSwitch, gLightSwitch, gFirstFloorLightSwitch)\n  [shared-motion-sensor]                                                        \n  { channel=\"zwave:device:9e4ce05e:node8:switch_binary\",                        \n  durationInMinutes=\"15\" }                                                    \n```\n\n#### Fan switches\nPattern: `.*FanSwitch.*`\n\nSupported attributes: same as with the light switches.\n\n#### Motion sensors\nPattern: `[^g].*MotionSensor$`\n\nExample:\n```\nSwitch SF_Lobby_LightSwitch_MotionSensor \"Second Floor Lobby Motion Sensor\"                         \n  { channel=\"mqtt:topic:myBroker:xiaomiMotionSensors:SecondFloorLobbyMotionSensor\"}\n```\n\n#### Light sensors\nPattern: `[^g].*_Illuminance.*`\n\nExample: `Number SF_Lobby_LightSwitch_Illuminance { channel=\"...\" }`\n\n#### Plugs\nPattern: `[^g].*_Plug$`\n\nAdditional optional power reading item with the primary item name + \"_Power\".\n\nExample:\n```\nSwitch FF_Office_Plug \"Office Plug\"                                                                 \n  { alwaysOn=\"true\", channel=\"tplinksmarthome:hs110:office:switch\"}                                 \nNumber FF_Office_Plug_Power \"Office Plug Power [%d Watts]\" (gPlugPower)                             \n  { channel=\"tplinksmarthome:hs110:office:power\"}\n```\n\n#### Security alarm\nPattern: `.*AlarmPartition$`\n\nAdditional arm mode item: via the primary item name + the suffix '_ArmMode'.\n\nExample:\n```\nSwitch FF_Foyer_AlarmPartition                                                                      \n  {channel=\"dscalarm:partition:706cd89d:partition1:partition_in_alarm\"}                             \nNumber FF_Foyer_AlarmPartition_ArmMode                                                              \n  {channel=\"dscalarm:partition:706cd89d:partition1:partition_arm_mode\"}\n```\n#### Doors\nPattern: `.*Door$`\n\nExamples:\n```\nSwitch FF_Porch_Door {channel=\"dscalarm:zone:706cd89d:zone1:zone_tripped\"}\n```\n\n#### Windows\nPattern: `[^g].*_Window$`\n\n#### Humidity sensors\nPattern: `[^g](?!.*Weather).*Humidity$`\n\nExample:\n```\nNumber SF_Bedroom2_Humidity \"Bedroom2 Humidity [%d %%]\"                                             \n  { channel=\"mqtt:topic:myBroker:bedroom2:humidity\", wifi=\"true\", autoReport=\"true\" }  \n```\n\n#### Temperature sensors\nPattern: `[^g](?!.*Computer)(?!.*Weather).*Temperature$`\n\nExample:\n```\nNumber SF_Bedroom2_Temperature \"Bedroom2 Temperature [%.1f °C]\"                                     \n  { channel=\"mqtt:topic:myBroker:bedroom2:temperature\", wifi=\"true\", autoReport=\"true\" }\n```\n\n#### Natural gas sensors\nPattern: `[^g].*_NaturalGas$`\n\nAdditional state item using the primary name + \"State\" suffix.\n\nExample:\n```\nNumber BM_Utility_NaturalGas \"Natural Gas Value [%d]\"                                               \n  { channel=\"mqtt:topic:myBroker:utilityRoom:naturalGasValue\", wifi=\"true\", autoReport=\"true\" }                                                                \n                                                                                                    \nSwitch BM_Utility_NaturalGasState \"Natural Gas Detected [%s]\"                                       \n  { channel=\"mqtt:topic:myBroker:utilityRoom:naturalGasState\", wifi=\"true\", autoReport=\"true\" }\n```\n\n#### CO2 sensors\nPattern: `[^g].*_Co2$`\n\nOtherwise similar to Natural Gas Sensors.\n\n#### Smoke sensors\nPattern: `[^g].*_Smoke$`\n\nOtherwise similar to Natural Gas Sensors.\n\n#### Google Chromecasts\nPattern: `.*_ChromeCast$`\n\nSupported attributes:\n* sinkName: string value; additional items are retrieved via this name.\n\nExamples:\n```\nString FF_GreatRoom_ChromeCast { sinkName = \"chromecast:audio:greatRoom\" }                          \n                                                                                                    \nString FF_GreatRoom_ChromeCastStreamTitle \"Stream [%s]\"                                             \nPlayer FF_GreatRoom_ChromeCastPlayer \"Player\" (gCastPlayer)                                         \n  { channel=\"chromecast:audio:greatRoom:control\" }                                                  \nDimmer FF_GreatRoom_ChromeCastVolume \"Volume\" (gCastVolume)                                         \n  { channel=\"chromecast:audio:greatRoom:volume\" }                                                   \nString FF_GreatRoom_ChromeCastPlayUri \"Play URI [%s]\"                                               \n  { channel=\"chromecast:audio:greatRoom:playuri\" }                                                  \nSwitch FF_GreatRoom_ChromeCastIdling \"Idling\"                                                       \n  { channel=\"chromecast:audio:greatRoom:idling\" }     \n```\n\n\n\n#### Network presences\nPattern: `[^g].*_NetworkPresence.*`\n\nExample:\n```\nSwitch FF_Virtual_NetworkPresenceOwner1Phone \"Owner1's Phone\"\n  { channel=\"network:pingdevice:192_168_0_100:online\" } \n```\n\n#### Televisions\nPattern: `.*_Tv$`\n\nOnly support determining if the TV is on.\n\nExample:\n```\nSwitch FF_GreatRoom_Tv \"TV\" {channel=\"sony:scalar:15611113d7d2:system#powerstatus\"}\n```\n\n#### Water leak sensors\nPattern: `[^g].*WaterLeakState$`\n\nExample:\n```\nSwitch BM_Utility_WaterLeakState \"Water Leak Detected [%s]\"\n  { channel=\"mqtt:topic:myBroker:utilityRoom:leakSensorState\" }\n```\n\n#### Weather\n\nPattern: `.*_Weather_Temperature$`\n\nAdditional items are retrieved using the various suffixes.\n\nExample:\n```\nNumber:Temperature FF_Virtual_Weather_Temperature \"Temperature [%.1f %unit%]\" (gWeather)            \n  { channel=\"ecobee:thermostat:account:411222197263:forecast0#temperature\" }                        \nString FF_Virtual_Weather_Condition \"Condition [%s]\" (gWeather)                                     \n  { channel=\"ecobee:thermostat:account:411222197263:forecast0#condition\" }                          \nNumber FF_Virtual_Weather_Humidity \"Relative Humidity [%d %%]\" (gWeather)                           \n  { channel=\"ecobee:thermostat:account:411222197263:forecast0#relativeHumidity\" }                   \nDateTime FF_Virtual_Weather_LastUpdate \"Last update [%1$tA, %1$tm/%1$td/%1$tY %1$tl:%1$tM %1$tp]\"\n  { channel=\"ecobee:thermostat:account:411222197263:weather#timestamp\" }\nNumber:Temperature FF_Virtual_Weather_ForecastTempMin \"Forecast Min Temperature [%.1f %unit%]\"      \n  { channel=\"ecobee:thermostat:account:411222197263:forecast0#tempLow\" }                            \nNumber:Temperature FF_Virtual_Weather_ForecastTempMax \"Forecast Max Temperature [%.1f %unit%]\"      \n  { channel=\"ecobee:thermostat:account:411222197263:forecast0#tempHigh\" }\nString FF_Virtual_Weather_Alert_Title \"Alert [%s]\"                                                \n  {channel=\"feed:feed:envCanada:latest-title\"}\n```\n# Common services\n## Alert\nThis is a common service to send various notifications such as security violation or temperature / humidity getting too\nhigh. The actions just need to classify whether an alert is info, warning, or critical. The service will provide\nappropriate implementation.\n\nCurrently three mechanisms are supported:\n1. Email: send an email notification to either the owners or the administrators.\n   See [zone-api-config.yml](https://github.com/yfaway/zone-apis/blob/master/habapp/zone-api-config.yml) for more info.\n\n2. Audio: send a text-to-speed (TTS) to one or more connected audio devices. The volume is set based on the criticality\n   of the alert.\n\n3. Light: if a critical alert occurs during the night, the internal lights are turned on.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyfaway%2Fzone-apis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyfaway%2Fzone-apis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyfaway%2Fzone-apis/lists"}