├── LICENSE ├── README.md └── hubpackagev3 ├── capabilities ├── dscawayswitch3.yaml ├── dscdashswitch3.yaml ├── dscselectswitch3.yaml ├── dsctroubletype2.yaml ├── dsctroubletype3a.yaml ├── dscuser.yaml ├── partitioncommand3.yaml ├── partitionstatus3.yaml ├── partitionstatus3a.yaml ├── partyvoice23922.dscawayswitch3.json ├── partyvoice23922.dscawayswitch3.presentation.json ├── partyvoice23922.dscdashswitch3.json ├── partyvoice23922.dscdashswitch3.presentation.json ├── partyvoice23922.dscselectswitch3.json ├── partyvoice23922.dscselectswitch3.presentation.json ├── partyvoice23922.dscstayswitch3.json ├── partyvoice23922.dscstayswitch3.presentation.json ├── partyvoice23922.dsctroubletype.json ├── partyvoice23922.dsctroubletype.presentation.json ├── partyvoice23922.dsctroubletype2.json ├── partyvoice23922.dsctroubletype2.presentation.json ├── partyvoice23922.dsctroubletype3a.json ├── partyvoice23922.dsctroubletype3a.presentation.json ├── partyvoice23922.dscuser.json ├── partyvoice23922.dscuser.presentation.json ├── partyvoice23922.partitioncommand3.json ├── partyvoice23922.partitioncommand3.presentation.json ├── partyvoice23922.partitionstatus3.json ├── partyvoice23922.partitionstatus3.presentation.json ├── partyvoice23922.partitionstatus3a.json ├── partyvoice23922.partitionstatus3a.presentation.json ├── partyvoice23922.zonebypass3.json ├── partyvoice23922.zonebypass3.presentation.json ├── partyvoice23922.zonebypass3a.json ├── partyvoice23922.zonebypass3a.presentation.json ├── zonebypass3.yaml └── zonebypass3a.yaml ├── config.yml ├── profiles ├── dsccontactzone_v3.yaml ├── dsccozone_v3.yaml ├── dscmotionzone_v3.yaml ├── dscprimarypanel_v3d.yaml ├── dscsecondarypanel_v3d.yaml ├── dscsmokezone_v3.yaml └── dscwaterzone_v3.yaml └── src ├── common.lua ├── device_handler.lua ├── envisalink.lua ├── envisalinkdefs.lua └── init.lua /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SmartThings Edge Device Driver for DSC/Envisalink 2 | 3 | *06/20/23 UPDATE: Version 3.0 of the driver has now been released and this README has been updated to reflect the changes.* 4 | 5 | This Edge driver is targeted to users having a DSC security system with an Envisalink board connecting it to the local LAN. Edge drivers run directly on a SmartThings hub. The driver will connect with the Envisalink to create and update devices reflecting your DSC system partition panels and zones. 6 | 7 | *PLEASE NOTE: This driver only works with DSC systems. Those with Honeywell or Honeywell-compatable systems should check out an applicable driver [here](https://community.smartthings.com/t/st-edge-honeywell-ademco-vista-panel-envisalink/233766).* 8 | 9 | 10 | ### Old 'Alarmserver' Users 11 | Some may already have an existing solution using the 'Alarmserver' package. Alarmserver is a Python-based program that runs on a LAN-connected computer (often a Raspberry Pi) and connects to an Envisalink module to pass messages back and forth to SmartThings. However Alarmserver is based on the legacy DTH / SmartApp / graph callback implementation which is being sunset by SmartThings. This driver provides a migration path for those Alarmserver users and offers a number of additional benefits as outlined below. 12 | 13 | 14 | ### Benefits 15 | - Eliminates dependency on Groovy DTHs, which has been sunset 16 | - No SmartApp is required 17 | - Leverages 100% local execution of Edge platform (including related automations) 18 | - For old Alarmserver users: 19 | - Eliminates need for separate stay / away panel devices 20 | - Eliminates need for separate computer to run Envisalink interfacing code 21 | - Can be run in parallel with existing Alarmserver setup for low risk transition 22 | 23 | ### Pre-requisites 24 | - SmartThings hub V2 or later 25 | - **DSC** security system 26 | - Connected and running Envisalink interface (know its IP address and port number) 27 | 28 | ### Migrating from Alarmserver 29 | This package does not prereq the Alarmserver package. However if the user already has that running, there is a setup option where you can run both solutions in parallel. You must be running the latest Alarmserver package from Ralph Torchia (https://github.com/rtorchia/DSC-Envisalink/tree/master/alarmserver), to ensure a functioning proxy server. Then when configuring the Edge driver per instructions below, you can point the Edge driver to the IP address and port of the Alarmserver proxy server, which will provide a passthrough to the Envisalink. When you are happy with everything functioning with the new Edge driver configuration, you can change its IP configuration to point directly to the Envisalink device and shutdown Alarmserver. 30 | 31 | ## Setup Instructions 32 | 33 | ### Install the Envisalink Edge Driver to your hub 34 | Use this [channel invite](https://bestow-regional.api.smartthings.com/invite/d429RZv8m9lo). 35 | 36 | Sign in to SmartThings, enroll your hub to the channel, list the available drivers, and select to install '**Envisalink 3.0**'. 37 | 38 | ### Initialize and Configure the Driver 39 | 40 | Go to the SmartThings mobile app and do an *Add device / Scan for nearby devices*. 41 | A new device called ‘DSC Primary Panel’ should be created in the SmartThings room where your hub device is located. 42 | Go to the device Controls screen of the new panel device and tap the 3 vertical dots in the upper right corner, then tap Settings. 43 | 44 | 1. FIRST, if you have multiple partitions, set the Additional Partition field to the ADDITIONAL number of partitions you need (1 to 7 more). A new panel device will be created for each additional partition configured. If you have a single partition, leave this field alone. 45 | 2. NEXT, tap on each zone you want to configure and select the appropriate type. Note that you will not be able to change this once the zone device is created, so proceed carefully. As you define each zone, a new SmartThings device will be created. 46 | 3. When you are done configuring your zones, set your 4-6 digit DSC Alarm Code. This code will be used by the driver whenever you arm/disarm the system through SmartThings. Be sure it is one that has been configured in your DSC system; it can be the system master code, or any of the additional user codes. 47 | 4. If your Envisalink login password is the default ‘user’, you can leave that field alone, otherwise change it to whatever password you have set for your Envisalink. Note that this password is *not* your EyesOn web application password. 48 | 5. Other Settings options are available, which can be configured later and are described later in this document. 49 | 6. **LASTLY**, set your Envisalink LAN Address (ip:port). Once you make this change, the driver will attempt to go out and connect to your Envisalink. If it is able to connect it will then log in with the configured Envisalink password. If for some reason it fails to connect, then it will keep retrying every 15 seconds or so. 50 | Once you’ve successfully connected to the Envisalink, a refresh is issued to update the states of each of your zones and panel(s). At this point, you should be able to explore your newly created devices which should be reflecting the current DSC zone and partition status. 51 | 52 | ### Updating the Driver 53 | If there is an update pushed to your hub for the Envisalink Edge driver, the DSC devices originally created will not have to be re-created and you do not need to perfom an *Add device* again. When the updated driver is installed, it will automatically re-synch with the Envisalink. 54 | 55 | ## Using the SmartThings Devices in the Mobile App 56 | 57 | The first thing you will want to do after your DSC devices are created is to group them into a room representing your DSC alarm system and modify the zone device names to your liking. 58 | 59 | ### Zone Devices 60 | The zone devices have no action buttons on the dashboard view - just the status of the device (open/closed, motion/no motion, etc.). On the Controls screen, you'll see a zone status field, which most of the time will show the open/close-type state of the device, but may also show other status such as alarm, trouble, etc. Also on the details screen is a toggle button you can use to turn on and off bypass state for the zone. 61 | 62 | See additional info below regarding **alarms**. 63 | 64 | ### Partition Panel Device(s) 65 | The panel device has a bit more function. The button on the *dashboard* view is used to arm or disarm the partition. Whether it performs an arm-away or arm-stay is configured on the Controls screen (explained below). The state shown on the dashboard is whatever the DSC partition is reporting such as Ready, Not ready, Exit delay, Armed-away or Armed-stay, Alarm, Offline, etc. 66 | 67 | The panel device *Controls* screen has a number of fields: 68 | 69 | #### Partition status 70 | This is same value as what is shown on the dashboard, which reflects the overall state of the partition. 71 | 72 | #### Most recent user 73 | The field is used to display the name associated with the arm code that was last used to arm/disarm the system *from a physical DSC panel device*. 74 | 75 | You can configure a map of names back in the Settings screen of the panel device. Look for the 'Accesscode->Name Map' field. Here you provide a comma-separated list of access code 'slots' that have been configured for your DSC system. Slot 40 is always the 'Master' code, but you may have configured your DSC system for additional user access codes 01-32. For example, if you, your wife, and kids each have their own code, you can configure this field like this: 76 | ``` 77 | 40=Master, 01=Hubby, 02=Wifey, 03=Kids 78 | ``` 79 | * This of course this is assuming you have configured your DSC system with those three user access codes. 80 | * Note that you can use any configured access code you choose (master or user) for the one this driver uses to arm/disarm ('Access Code for Arm/Disarm' field in panel device Settings) 81 | 82 | #### Indicators 83 | This will show additional (panel LED) status items such as Trouble, Memory, Bypass, and Fire. 84 | 85 | #### Trouble type 86 | When the partition is in a Trouble state, this field will display the specific trouble being reported by the system, such as Battery, Bell, AC Power Lost, etc. 87 | 88 | *Special info regarding AC Power Lost detection: DSC systems have by default a 30 minute delay before an 'AC Power Lost' trouble type is reported. In the meantime a generic 'Service Required' trouble type may be displayed. To have an AC Power Lost reported immediately, the user will have to program section 377 Communication Variables of the DSC system, and setting 'AC Failure Communication Delay' to 0* 89 | 90 | #### Arm Stay, Arm Away 91 | These buttons are provided to arm the partition (or disarm afterwards) for either away or stay mode. 92 | 93 | #### Additional partition commands 94 | This is a button to bring up a list of additional (less-used) partition commands that can be invoked. 95 | 96 | #### Alarm type 97 | This field is used to provide a SmartThings-standard alarm state whenever the DSC system is alarming. It is a standard SmartThings capability, but for this driver it will only show either 'Off' or 'Siren'. Tapping any of the buttons has no effect; it is used for 'output' only to trigger automations. 98 | 99 | #### Configure dashboard button arm type 100 | This button is used to configure what happens when you tap the button on the panel device's **dashboard** card. It can be set to either type=arm-away or type=arm-stay, whichever you prefer. Remember you can always go to the Controls screen to explicitly arm either way, no matter how the dashboard button is configured. 101 | 102 | ### Alarms 103 | When an alarm occurs, the panel device dashboard view state will show "ALARM!!". The zone(s) that caused the alarm condition will show alarm status on the zone device *Controls* screen (the zone device *dashboard* card will continue to show the current state, i.e. open, motion, smoke, etc.). When the alarm is cleared (when the system is disarmed), the panel state will return to normal ('Ready'), and the Indicators field on the panel Controls screen will show 'Memory' until the next system arm. For the zone that had caused the alarm, its device *Controls* screen will continue to show an alarm status until the next time the system is armed. This implements the DSC 'memory' function, giving you a way to see what zone had caused the alarm even after the alarm is cleared on the panel. 104 | 105 | ## Automations 106 | Defining automation routines using the SmartThings app is easiest since it makes conditions and actions selection easy and straightforward, however Rules can also be used. 107 | 108 | ### Rules 109 | To define your rules JSON, following are examples of the most common partition triggers/commands: 110 | 111 | #### To trigger from partition state 112 | * component: main 113 | * capability: partyvoice23922.partitionstatus3a 114 | * attribute: partStatus 115 | * values: 116 | ``` 117 | Armed-away 118 | Armed-away (instant) 119 | Armed-stay 120 | Armed-stay (instant) 121 | Disarmed 122 | Ready 123 | Entry delay 124 | Exit delay 125 | ALARM!! 126 | Offline 127 | ``` 128 | 129 | #### To trigger from trouble type 130 | * component: main 131 | * capability: partyvoice23922.dsctroubletype3a 132 | * attribute: troubleType 133 | * values: 134 | ``` 135 | AC Power Lost 136 | Battery 137 | Bell 138 | Failure to Communicate 139 | Loss of Time 140 | Service Required 141 | Sensor/Zone Fault 142 | Sensor/Zone Tamper 143 | Sensor/Zone Battery 144 | Telephone Line Fault 145 | ``` 146 | 147 | #### To issue partition commands 148 | 149 | * component: main 150 | * capability: partyvoice23922.partitioncommand3 151 | * command: setPartitionCommand 152 | * valid argument values: 153 | ``` 154 | armstay 155 | armaway 156 | disarm 157 | panicfire 158 | panicamb 159 | panicpolice 160 | instantstay 161 | instantaway 162 | togglenight 163 | togglechime 164 | refresh 165 | reset 166 | pgm1 167 | pgm2 168 | pgm3 169 | pgm4 170 | ``` 171 | 172 | ### Envisalink connection monitoring 173 | A new feature in the V3.0 driver is the periodic monitoring of the network connection to the Envisalink. The frequency of the check can be configured in the primary panel device Settings screen under 'Periodic Connection Check'. This can be set for as often as every 5 minutes (default is every 15 minutes). If during this periodic check the Envisalink is not responding, all partition and zone devices will go into an offline state and the partition status will be set to 'Offline', enabling automations to be triggered. The driver will then continuously try to reconnect with the Envisalink every 15 seconds. Once connection is re-established, all devices will revert to online status and the partition status will be refreshed with the latest state reported by the DSC. 174 | 175 | ### Auxilary siren triggering 176 | It is possible to wire your DSC system to an auxilary siren or alarm and trigger it using one of the PGM commands to the DSC. To support this scenario, the partition device Settings screen includes two fields: one to define an auxilary trigger (PGM1-PGM4), and a second to set the duration for the trigger (in seconds). 177 | 178 | ### Auto-synching with STHM 179 | Warning: this feature has proven unreliable for many, so use with caution. 180 | 181 | You can have your DSC system automatically set whenever SmartThings Home Monitor is armed or disarmed. Use the 'Set arm mode from STHM' field in the partition device Settings screen to enable or disable this auto-synching. It is disabled by default. 182 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/dscawayswitch3.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.dscawayswitch3 2 | version: 1 3 | status: proposed 4 | name: dscawayswitch3 5 | ephemeral: false 6 | attributes: 7 | awaySwitch: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | enum: 14 | - 'On' 15 | - 'Off' 16 | additionalProperties: false 17 | required: 18 | - value 19 | enumCommands: 20 | - command: switchOn 21 | value: 'On' 22 | - command: switchOff 23 | value: 'Off' 24 | commands: 25 | switchOff: 26 | name: switchOff 27 | arguments: [] 28 | switchOn: 29 | name: switchOn 30 | arguments: [] 31 | setSwitch: 32 | name: setSwitch 33 | arguments: 34 | - name: state 35 | optional: false 36 | schema: 37 | type: string 38 | enum: 39 | - 'On' 40 | - 'Off' 41 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/dscdashswitch3.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.dscdashswitch3 2 | version: 1 3 | status: proposed 4 | name: dscdashswitch3 5 | ephemeral: false 6 | attributes: 7 | dashSwitch: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | enum: 14 | - 'On' 15 | - 'Off' 16 | additionalProperties: false 17 | required: 18 | - value 19 | enumCommands: 20 | - command: switchOn 21 | value: 'On' 22 | - command: switchOff 23 | value: 'Off' 24 | commands: 25 | switchOff: 26 | name: switchOff 27 | arguments: [] 28 | switchOn: 29 | name: switchOn 30 | arguments: [] 31 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/dscselectswitch3.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.dscselectswitch3 2 | version: 1 3 | status: proposed 4 | name: dscselectswitch3 5 | ephemeral: false 6 | attributes: 7 | selection: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | maxLength: 20 14 | additionalProperties: false 15 | required: 16 | - value 17 | setter: setSelection 18 | enumCommands: [] 19 | commands: 20 | setSelection: 21 | name: setSelection 22 | arguments: 23 | - name: value 24 | optional: false 25 | schema: 26 | type: string 27 | maxLength: 20 28 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/dsctroubletype2.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.dsctroubletype2 2 | version: 1 3 | status: proposed 4 | name: dsctroubletype2 5 | ephemeral: false 6 | attributes: 7 | troubleType: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | additionalProperties: false 14 | required: 15 | - value 16 | enumCommands: [] 17 | commands: {} 18 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/dsctroubletype3a.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.dsctroubletype3a 2 | version: 1 3 | status: proposed 4 | name: dsctroubletype3a 5 | ephemeral: false 6 | attributes: 7 | troubleType: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | additionalProperties: false 14 | required: 15 | - value 16 | enumCommands: [] 17 | commands: {} 18 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/dscuser.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.dscuser 2 | version: 1 3 | status: proposed 4 | name: dscuser 5 | ephemeral: false 6 | attributes: 7 | username: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | additionalProperties: false 14 | required: 15 | - value 16 | enumCommands: [] 17 | commands: {} 18 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partitioncommand3.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.partitioncommand3 2 | version: 1 3 | status: proposed 4 | name: partitioncommand3 5 | ephemeral: false 6 | attributes: 7 | partitionCommand: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | maxLength: 20 14 | additionalProperties: false 15 | required: 16 | - value 17 | setter: setPartitionCommand 18 | enumCommands: [] 19 | commands: 20 | setPartitionCommand: 21 | name: setPartitionCommand 22 | arguments: 23 | - name: value 24 | optional: false 25 | schema: 26 | type: string 27 | maxLength: 20 28 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partitionstatus3.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.partitionstatus3 2 | version: 1 3 | status: proposed 4 | name: partitionstatus3 5 | ephemeral: false 6 | attributes: 7 | partStatus: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | maxLength: 20 14 | additionalProperties: false 15 | required: 16 | - value 17 | setter: setPartStatus 18 | enumCommands: [] 19 | commands: 20 | setPartStatus: 21 | name: setPartStatus 22 | arguments: 23 | - name: value 24 | optional: false 25 | schema: 26 | type: string 27 | maxLength: 20 28 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partitionstatus3a.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.partitionstatus3a 2 | version: 1 3 | status: proposed 4 | name: partitionstatus3a 5 | ephemeral: false 6 | attributes: 7 | partStatus: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | maxLength: 20 14 | additionalProperties: false 15 | required: 16 | - value 17 | setter: setPartStatus 18 | enumCommands: [] 19 | commands: 20 | setPartStatus: 21 | name: setPartStatus 22 | arguments: 23 | - name: value 24 | optional: false 25 | schema: 26 | type: string 27 | maxLength: 20 28 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscawayswitch3.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dscawayswitch3", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dscawayswitch3", 6 | "ephemeral": false, 7 | "attributes": { 8 | "awaySwitch": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "enum": [ 15 | "On", 16 | "Off" 17 | ] 18 | } 19 | }, 20 | "additionalProperties": false, 21 | "required": [ 22 | "value" 23 | ] 24 | }, 25 | "enumCommands": [ 26 | { 27 | "command": "switchOn", 28 | "value": "On" 29 | }, 30 | { 31 | "command": "switchOff", 32 | "value": "Off" 33 | } 34 | ] 35 | } 36 | }, 37 | "commands": { 38 | "switchOff": { 39 | "name": "switchOff", 40 | "arguments": [] 41 | }, 42 | "switchOn": { 43 | "name": "switchOn", 44 | "arguments": [] 45 | }, 46 | "setSwitch": { 47 | "name": "setSwitch", 48 | "arguments": [ 49 | { 50 | "name": "state", 51 | "optional": false, 52 | "schema": { 53 | "type": "string", 54 | "enum": [ 55 | "On", 56 | "Off" 57 | ] 58 | } 59 | } 60 | ] 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscawayswitch3.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{awaySwitch.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "toggleSwitch", 14 | "toggleSwitch": { 15 | "command": { 16 | "on": "switchOn", 17 | "off": "switchOff" 18 | }, 19 | "state": { 20 | "value": "awaySwitch.value", 21 | "valueType": "string", 22 | "on": "On", 23 | "off": "Off", 24 | "label": "{{awaySwitch.value}}", 25 | "alternatives": [ 26 | { 27 | "key": "On", 28 | "value": "On", 29 | "type": "active" 30 | }, 31 | { 32 | "key": "Off", 33 | "value": "Off", 34 | "type": "inactive" 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ], 41 | "automation": { 42 | "conditions": [ 43 | { 44 | "label": "Arm Away", 45 | "displayType": "list", 46 | "list": { 47 | "alternatives": [ 48 | { 49 | "key": "On", 50 | "value": "Arm Away On (Armed)", 51 | "type": "active" 52 | }, 53 | { 54 | "key": "Off", 55 | "value": "Arm Away Off (Disarmed)", 56 | "type": "inactive" 57 | } 58 | ], 59 | "value": "awaySwitch.value", 60 | "valueType": "string" 61 | }, 62 | "emphasis": true 63 | } 64 | ], 65 | "actions": [ 66 | { 67 | "label": "Arm Away", 68 | "displayType": "list", 69 | "list": { 70 | "alternatives": [ 71 | { 72 | "key": "On", 73 | "value": "Arm Away", 74 | "type": "active" 75 | }, 76 | { 77 | "key": "Off", 78 | "value": "Disarm Away", 79 | "type": "inactive" 80 | } 81 | ], 82 | "command": "setSwitch", 83 | "argumentType": "string" 84 | }, 85 | "emphasis": true 86 | } 87 | ] 88 | }, 89 | "id": "partyvoice23922.dscawayswitch3", 90 | "version": 1 91 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscdashswitch3.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dscdashswitch3", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dscdashswitch3", 6 | "ephemeral": false, 7 | "attributes": { 8 | "dashSwitch": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "enum": [ 15 | "On", 16 | "Off" 17 | ] 18 | } 19 | }, 20 | "additionalProperties": false, 21 | "required": [ 22 | "value" 23 | ] 24 | }, 25 | "enumCommands": [ 26 | { 27 | "command": "switchOn", 28 | "value": "On" 29 | }, 30 | { 31 | "command": "switchOff", 32 | "value": "Off" 33 | } 34 | ] 35 | } 36 | }, 37 | "commands": { 38 | "switchOff": { 39 | "name": "switchOff", 40 | "arguments": [] 41 | }, 42 | "switchOn": { 43 | "name": "switchOn", 44 | "arguments": [] 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscdashswitch3.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [], 4 | "actions": [ 5 | { 6 | "displayType": "toggleSwitch", 7 | "toggleSwitch": { 8 | "command": { 9 | "on": "switchOn", 10 | "off": "switchOff" 11 | }, 12 | "state": { 13 | "value": "dashSwitch.value", 14 | "on": "On", 15 | "off": "Off", 16 | "valueType": "string" 17 | } 18 | } 19 | } 20 | ] 21 | }, 22 | "automation": { 23 | "conditions": [], 24 | "actions": [] 25 | }, 26 | "id": "partyvoice23922.dscdashswitch3", 27 | "version": 1 28 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscselectswitch3.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dscselectswitch3", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dscselectswitch3", 6 | "ephemeral": false, 7 | "attributes": { 8 | "selection": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "maxLength": 20 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "value" 20 | ] 21 | }, 22 | "setter": "setSelection", 23 | "enumCommands": [] 24 | } 25 | }, 26 | "commands": { 27 | "setSelection": { 28 | "name": "setSelection", 29 | "arguments": [ 30 | { 31 | "name": "value", 32 | "optional": false, 33 | "schema": { 34 | "type": "string", 35 | "maxLength": 20 36 | } 37 | } 38 | ] 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscselectswitch3.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [], 4 | "actions": [] 5 | }, 6 | "detailView": [ 7 | { 8 | "label": "{{i18n.label}}", 9 | "displayType": "list", 10 | "list": { 11 | "command": { 12 | "name": "setSelection", 13 | "alternatives": [ 14 | { 15 | "key": "away", 16 | "value": "Arm Away", 17 | "type": "active" 18 | }, 19 | { 20 | "key": "stay", 21 | "value": "Arm Stay", 22 | "type": "active" 23 | }, 24 | { 25 | "key": "none", 26 | "value": "No action", 27 | "type": "active" 28 | } 29 | ], 30 | "argumentType": "string" 31 | }, 32 | "state": { 33 | "value": "selection.value", 34 | "valueType": "string", 35 | "alternatives": [ 36 | { 37 | "key": "away", 38 | "value": "Arm Away", 39 | "type": "active" 40 | }, 41 | { 42 | "key": "stay", 43 | "value": "Arm Stay", 44 | "type": "active" 45 | }, 46 | { 47 | "key": "none", 48 | "value": "No action", 49 | "type": "active" 50 | } 51 | ] 52 | } 53 | } 54 | } 55 | ], 56 | "automation": { 57 | "conditions": [], 58 | "actions": [] 59 | }, 60 | "id": "partyvoice23922.dscselectswitch3", 61 | "version": 1 62 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscstayswitch3.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dscstayswitch3", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dscstayswitch3", 6 | "ephemeral": false, 7 | "attributes": { 8 | "staySwitch": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "enum": [ 15 | "On", 16 | "Off" 17 | ] 18 | } 19 | }, 20 | "additionalProperties": false, 21 | "required": [ 22 | "value" 23 | ] 24 | }, 25 | "enumCommands": [ 26 | { 27 | "command": "switchOn", 28 | "value": "On" 29 | }, 30 | { 31 | "command": "switchOff", 32 | "value": "Off" 33 | } 34 | ] 35 | } 36 | }, 37 | "commands": { 38 | "switchOff": { 39 | "name": "switchOff", 40 | "arguments": [] 41 | }, 42 | "switchOn": { 43 | "name": "switchOn", 44 | "arguments": [] 45 | }, 46 | "setSwitch": { 47 | "name": "setSwitch", 48 | "arguments": [ 49 | { 50 | "name": "state", 51 | "optional": false, 52 | "schema": { 53 | "type": "string", 54 | "enum": [ 55 | "On", 56 | "Off" 57 | ] 58 | } 59 | } 60 | ] 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscstayswitch3.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{staySwitch.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "toggleSwitch", 14 | "toggleSwitch": { 15 | "command": { 16 | "on": "switchOn", 17 | "off": "switchOff" 18 | }, 19 | "state": { 20 | "value": "staySwitch.value", 21 | "valueType": "string", 22 | "on": "On", 23 | "off": "Off", 24 | "label": "{{staySwitch.value}}", 25 | "alternatives": [ 26 | { 27 | "key": "On", 28 | "value": "On", 29 | "type": "active" 30 | }, 31 | { 32 | "key": "Off", 33 | "value": "Off", 34 | "type": "inactive" 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ], 41 | "automation": { 42 | "conditions": [ 43 | { 44 | "label": "Arm Stay", 45 | "displayType": "list", 46 | "list": { 47 | "alternatives": [ 48 | { 49 | "key": "On", 50 | "value": "Arm Stay On (Armed)", 51 | "type": "active" 52 | }, 53 | { 54 | "key": "Off", 55 | "value": "Arm Stay Off (Disarmed)", 56 | "type": "inactive" 57 | } 58 | ], 59 | "value": "staySwitch.value", 60 | "valueType": "string" 61 | }, 62 | "emphasis": true 63 | } 64 | ], 65 | "actions": [ 66 | { 67 | "label": "Arm Stay", 68 | "displayType": "list", 69 | "list": { 70 | "alternatives": [ 71 | { 72 | "key": "On", 73 | "value": "Arm Stay", 74 | "type": "active" 75 | }, 76 | { 77 | "key": "Off", 78 | "value": "Disarm Stay", 79 | "type": "inactive" 80 | } 81 | ], 82 | "command": "setSwitch", 83 | "argumentType": "string" 84 | }, 85 | "emphasis": true 86 | } 87 | ] 88 | }, 89 | "id": "partyvoice23922.dscstayswitch3", 90 | "version": 1 91 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dsctroubletype.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dsctroubletype", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dsctroubletype", 6 | "ephemeral": false, 7 | "attributes": { 8 | "troubleType": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string" 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "value" 19 | ] 20 | }, 21 | "enumCommands": [] 22 | } 23 | }, 24 | "commands": {} 25 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dsctroubletype.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{troubleType.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "state", 14 | "state": { 15 | "label": "{{troubleType.value}}" 16 | } 17 | } 18 | ], 19 | "automation": { 20 | "conditions": [ 21 | { 22 | "label": "Trouble type", 23 | "displayType": "list", 24 | "list": { 25 | "alternatives": [ 26 | { 27 | "key": "battery", 28 | "value": "Battery", 29 | "type": "active" 30 | }, 31 | { 32 | "key": "AC", 33 | "value": "AC", 34 | "type": "active" 35 | }, 36 | { 37 | "key": "bell", 38 | "value": "Bell", 39 | "type": "active" 40 | } 41 | ], 42 | "value": "troubleType.value", 43 | "valueType": "string" 44 | } 45 | } 46 | ], 47 | "actions": [] 48 | }, 49 | "id": "partyvoice23922.dsctroubletype", 50 | "version": 1 51 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dsctroubletype2.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dsctroubletype2", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dsctroubletype2", 6 | "ephemeral": false, 7 | "attributes": { 8 | "troubleType": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string" 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "value" 19 | ] 20 | }, 21 | "enumCommands": [] 22 | } 23 | }, 24 | "commands": {} 25 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dsctroubletype2.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{troubleType.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "state", 14 | "state": { 15 | "label": "{{troubleType.value}}" 16 | } 17 | } 18 | ], 19 | "automation": { 20 | "conditions": [ 21 | { 22 | "label": "Trouble type", 23 | "displayType": "list", 24 | "list": { 25 | "alternatives": [ 26 | { 27 | "key": "AC", 28 | "value": "AC Power Lost", 29 | "type": "active" 30 | }, 31 | { 32 | "key": "battery", 33 | "value": "Battery", 34 | "type": "active" 35 | }, 36 | { 37 | "key": "bell", 38 | "value": "Bell", 39 | "type": "active" 40 | }, 41 | { 42 | "key": "comms", 43 | "value": "Failure to Communicate", 44 | "type": "active" 45 | }, 46 | { 47 | "key": "time", 48 | "value": "Loss of Time", 49 | "type": "active" 50 | }, 51 | { 52 | "key": "service", 53 | "value": "Service Required", 54 | "type": "active" 55 | }, 56 | { 57 | "key": "fault", 58 | "value": "Sensor/Zone Fault", 59 | "type": "active" 60 | }, 61 | { 62 | "key": "tamper", 63 | "value": "Sensor/Zone Tamper", 64 | "type": "active" 65 | }, 66 | { 67 | "key": "sensorbatt", 68 | "value": "Sensor/Zone Battery", 69 | "type": "active" 70 | }, 71 | { 72 | "key": "telephone", 73 | "value": "Telephone Line Fault", 74 | "type": "active" 75 | } 76 | ], 77 | "value": "troubleType.value", 78 | "valueType": "string" 79 | } 80 | } 81 | ], 82 | "actions": [] 83 | }, 84 | "id": "partyvoice23922.dsctroubletype2", 85 | "version": 1 86 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dsctroubletype3a.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dsctroubletype3a", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dsctroubletype3a", 6 | "ephemeral": false, 7 | "attributes": { 8 | "troubleType": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string" 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "value" 19 | ] 20 | }, 21 | "enumCommands": [] 22 | } 23 | }, 24 | "commands": {} 25 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dsctroubletype3a.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{troubleType.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "state", 14 | "state": { 15 | "label": "{{troubleType.value}}" 16 | } 17 | } 18 | ], 19 | "automation": { 20 | "conditions": [ 21 | { 22 | "label": "Trouble type", 23 | "displayType": "list", 24 | "list": { 25 | "alternatives": [ 26 | { 27 | "key": "AC Power Lost", 28 | "value": "AC Power Lost", 29 | "type": "active" 30 | }, 31 | { 32 | "key": "Battery", 33 | "value": "Battery", 34 | "type": "active" 35 | }, 36 | { 37 | "key": "Bell", 38 | "value": "Bell", 39 | "type": "active" 40 | }, 41 | { 42 | "key": "Failure to Communicate", 43 | "value": "Failure to Communicate", 44 | "type": "active" 45 | }, 46 | { 47 | "key": "Loss of Time", 48 | "value": "Loss of Time", 49 | "type": "active" 50 | }, 51 | { 52 | "key": "Service Required", 53 | "value": "Service Required", 54 | "type": "active" 55 | }, 56 | { 57 | "key": "Sensor/Zone Fault", 58 | "value": "Sensor/Zone Fault", 59 | "type": "active" 60 | }, 61 | { 62 | "key": "Sensor/Zone Tamper", 63 | "value": "Sensor/Zone Tamper", 64 | "type": "active" 65 | }, 66 | { 67 | "key": "Sensor/Zone Battery", 68 | "value": "Sensor/Zone Battery", 69 | "type": "active" 70 | }, 71 | { 72 | "key": "Telephone Line Fault", 73 | "value": "Telephone Line Fault", 74 | "type": "active" 75 | } 76 | ], 77 | "value": "troubleType.value", 78 | "valueType": "string" 79 | } 80 | } 81 | ], 82 | "actions": [] 83 | }, 84 | "id": "partyvoice23922.dsctroubletype3a", 85 | "version": 1 86 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscuser.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.dscuser", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "dscuser", 6 | "ephemeral": false, 7 | "attributes": { 8 | "username": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string" 14 | } 15 | }, 16 | "additionalProperties": false, 17 | "required": [ 18 | "value" 19 | ] 20 | }, 21 | "enumCommands": [] 22 | } 23 | }, 24 | "commands": {} 25 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.dscuser.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{username.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "state", 14 | "state": { 15 | "label": "{{username.value}}" 16 | } 17 | } 18 | ], 19 | "automation": { 20 | "conditions": [ 21 | { 22 | "label": "User name", 23 | "displayType": "textField", 24 | "textField": { 25 | "value": "username.value", 26 | "valueType": "string" 27 | } 28 | } 29 | ], 30 | "actions": [] 31 | }, 32 | "id": "partyvoice23922.dscuser", 33 | "version": 1 34 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.partitioncommand3.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.partitioncommand3", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "partitioncommand3", 6 | "ephemeral": false, 7 | "attributes": { 8 | "partitionCommand": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "maxLength": 20 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "value" 20 | ] 21 | }, 22 | "setter": "setPartitionCommand", 23 | "enumCommands": [] 24 | } 25 | }, 26 | "commands": { 27 | "setPartitionCommand": { 28 | "name": "setPartitionCommand", 29 | "arguments": [ 30 | { 31 | "name": "value", 32 | "optional": false, 33 | "schema": { 34 | "type": "string", 35 | "maxLength": 20 36 | } 37 | } 38 | ] 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.partitioncommand3.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [], 4 | "actions": [] 5 | }, 6 | "detailView": [ 7 | { 8 | "label": "{{i18n.label}}", 9 | "displayType": "list", 10 | "list": { 11 | "command": { 12 | "name": "setPartitionCommand", 13 | "alternatives": [ 14 | { 15 | "key": "panicfire", 16 | "value": "Panic Fire", 17 | "type": "active" 18 | }, 19 | { 20 | "key": "panicamb", 21 | "value": "Panic Ambulance", 22 | "type": "active" 23 | }, 24 | { 25 | "key": "panicpolice", 26 | "value": "Panic Police", 27 | "type": "active" 28 | }, 29 | { 30 | "key": "instantstay", 31 | "value": "Arm-Stay Instant", 32 | "type": "active" 33 | }, 34 | { 35 | "key": "instantaway", 36 | "value": "Arm-Away Instant", 37 | "type": "active" 38 | }, 39 | { 40 | "key": "togglenight", 41 | "value": "Toggle Night Mode", 42 | "type": "active" 43 | }, 44 | { 45 | "key": "togglechime", 46 | "value": "Toggle Chime", 47 | "type": "active" 48 | }, 49 | { 50 | "key": "refresh", 51 | "value": "Refresh", 52 | "type": "active" 53 | }, 54 | { 55 | "key": "reset", 56 | "value": "Reset", 57 | "type": "active" 58 | }, 59 | { 60 | "key": "armstay", 61 | "value": "Arm Stay", 62 | "type": "active" 63 | }, 64 | { 65 | "key": "armaway", 66 | "value": "Arm Away", 67 | "type": "active" 68 | }, 69 | { 70 | "key": "disarm", 71 | "value": "Disarm", 72 | "type": "active" 73 | }, 74 | { 75 | "key": "pgm1", 76 | "value": "PGM1", 77 | "type": "active" 78 | }, 79 | { 80 | "key": "pgm2", 81 | "value": "PGM2", 82 | "type": "active" 83 | }, 84 | { 85 | "key": "pgm3", 86 | "value": "PGM3", 87 | "type": "active" 88 | }, 89 | { 90 | "key": "pgm4", 91 | "value": "PGM4", 92 | "type": "active" 93 | } 94 | ], 95 | "argumentType": "string" 96 | }, 97 | "state": { 98 | "value": "partitionCommand.value", 99 | "valueType": "string", 100 | "alternatives": [ 101 | { 102 | "key": "panicfire", 103 | "value": "Panic Fire", 104 | "type": "active" 105 | }, 106 | { 107 | "key": "panicamb", 108 | "value": "Panic Ambulance", 109 | "type": "active" 110 | }, 111 | { 112 | "key": "panicpolice", 113 | "value": "Panic Police", 114 | "type": "active" 115 | }, 116 | { 117 | "key": "instantstay", 118 | "value": "Arm-Stay Instant", 119 | "type": "active" 120 | }, 121 | { 122 | "key": "instantaway", 123 | "value": "Arm-Away Instant", 124 | "type": "active" 125 | }, 126 | { 127 | "key": "togglenight", 128 | "value": "Toggle Night Mode", 129 | "type": "active" 130 | }, 131 | { 132 | "key": "togglechime", 133 | "value": "Toggle Chime", 134 | "type": "active" 135 | }, 136 | { 137 | "key": "refresh", 138 | "value": "Refresh", 139 | "type": "active" 140 | }, 141 | { 142 | "key": "reset", 143 | "value": "Reset", 144 | "type": "active" 145 | }, 146 | { 147 | "key": "armstay", 148 | "value": "Arm Stay", 149 | "type": "active" 150 | }, 151 | { 152 | "key": "armaway", 153 | "value": "Arm Away", 154 | "type": "active" 155 | }, 156 | { 157 | "key": "disarm", 158 | "value": "Disarm", 159 | "type": "active" 160 | }, 161 | { 162 | "key": "pgm1", 163 | "value": "PGM1", 164 | "type": "active" 165 | }, 166 | { 167 | "key": "pgm2", 168 | "value": "PGM2", 169 | "type": "active" 170 | }, 171 | { 172 | "key": "pgm3", 173 | "value": "PGM3", 174 | "type": "active" 175 | }, 176 | { 177 | "key": "pgm4", 178 | "value": "PGM4", 179 | "type": "active" 180 | } 181 | ] 182 | } 183 | } 184 | } 185 | ], 186 | "automation": { 187 | "conditions": [], 188 | "actions": [ 189 | { 190 | "label": "Partition Commands:", 191 | "displayType": "list", 192 | "list": { 193 | "alternatives": [ 194 | { 195 | "key": "panicfire", 196 | "value": "Panic Fire", 197 | "type": "active" 198 | }, 199 | { 200 | "key": "panicamb", 201 | "value": "Panic Ambulance", 202 | "type": "active" 203 | }, 204 | { 205 | "key": "panicpolice", 206 | "value": "Panic Police", 207 | "type": "active" 208 | }, 209 | { 210 | "key": "instantstay", 211 | "value": "Arm-Stay Instant", 212 | "type": "active" 213 | }, 214 | { 215 | "key": "instantaway", 216 | "value": "Arm-Away Instant", 217 | "type": "active" 218 | }, 219 | { 220 | "key": "togglenight", 221 | "value": "Toggle Night Mode", 222 | "type": "active" 223 | }, 224 | { 225 | "key": "togglechime", 226 | "value": "Toggle Chime", 227 | "type": "active" 228 | }, 229 | { 230 | "key": "refresh", 231 | "value": "Refresh", 232 | "type": "active" 233 | }, 234 | { 235 | "key": "reset", 236 | "value": "Reset", 237 | "type": "active" 238 | }, 239 | { 240 | "key": "armstay", 241 | "value": "Arm Stay", 242 | "type": "active" 243 | }, 244 | { 245 | "key": "armaway", 246 | "value": "Arm Away", 247 | "type": "active" 248 | }, 249 | { 250 | "key": "disarm", 251 | "value": "Disarm", 252 | "type": "active" 253 | }, 254 | { 255 | "key": "pgm1", 256 | "value": "PGM1", 257 | "type": "active" 258 | }, 259 | { 260 | "key": "pgm2", 261 | "value": "PGM2", 262 | "type": "active" 263 | }, 264 | { 265 | "key": "pgm3", 266 | "value": "PGM3", 267 | "type": "active" 268 | }, 269 | { 270 | "key": "pgm4", 271 | "value": "PGM4", 272 | "type": "active" 273 | } 274 | ], 275 | "command": "setPartitionCommand", 276 | "argumentType": "string" 277 | } 278 | } 279 | ] 280 | }, 281 | "id": "partyvoice23922.partitioncommand3", 282 | "version": 1 283 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.partitionstatus3.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.partitionstatus3", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "partitionstatus3", 6 | "ephemeral": false, 7 | "attributes": { 8 | "partStatus": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "maxLength": 20 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "value" 20 | ] 21 | }, 22 | "setter": "setPartStatus", 23 | "enumCommands": [] 24 | } 25 | }, 26 | "commands": { 27 | "setPartStatus": { 28 | "name": "setPartStatus", 29 | "arguments": [ 30 | { 31 | "name": "value", 32 | "optional": false, 33 | "schema": { 34 | "type": "string", 35 | "maxLength": 20 36 | } 37 | } 38 | ] 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.partitionstatus3.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{partStatus.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "state", 14 | "state": { 15 | "label": "{{partStatus.value}}" 16 | } 17 | } 18 | ], 19 | "automation": { 20 | "conditions": [ 21 | { 22 | "label": "Partition Status", 23 | "displayType": "list", 24 | "list": { 25 | "alternatives": [ 26 | { 27 | "key": "Armed-away", 28 | "value": "Armed-away", 29 | "type": "active" 30 | }, 31 | { 32 | "key": "Armed-away (instant)", 33 | "value": "Armed-away (instant)", 34 | "type": "active" 35 | }, 36 | { 37 | "key": "Armed-stay", 38 | "value": "Armed-stay", 39 | "type": "active" 40 | }, 41 | { 42 | "key": "Armed-stay (instant)", 43 | "value": "Armed-stay (instant)", 44 | "type": "active" 45 | }, 46 | { 47 | "key": "Disarmed", 48 | "value": "Disarmed", 49 | "type": "active" 50 | }, 51 | { 52 | "key": "Ready", 53 | "value": "Ready", 54 | "type": "active" 55 | }, 56 | { 57 | "key": "Entry delay", 58 | "value": "Entry delay", 59 | "type": "active" 60 | }, 61 | { 62 | "key": "Exit delay", 63 | "value": "Exit delay", 64 | "type": "active" 65 | }, 66 | { 67 | "key": "ALARM!!", 68 | "value": "ALARM!!", 69 | "type": "active" 70 | } 71 | ], 72 | "value": "partStatus.value", 73 | "valueType": "string" 74 | } 75 | } 76 | ], 77 | "actions": [] 78 | }, 79 | "id": "partyvoice23922.partitionstatus3", 80 | "version": 1 81 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.partitionstatus3a.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.partitionstatus3a", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "partitionstatus3a", 6 | "ephemeral": false, 7 | "attributes": { 8 | "partStatus": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "maxLength": 20 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "value" 20 | ] 21 | }, 22 | "setter": "setPartStatus", 23 | "enumCommands": [] 24 | } 25 | }, 26 | "commands": { 27 | "setPartStatus": { 28 | "name": "setPartStatus", 29 | "arguments": [ 30 | { 31 | "name": "value", 32 | "optional": false, 33 | "schema": { 34 | "type": "string", 35 | "maxLength": 20 36 | } 37 | } 38 | ] 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.partitionstatus3a.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [ 4 | { 5 | "label": "{{partStatus.value}}" 6 | } 7 | ], 8 | "actions": [] 9 | }, 10 | "detailView": [ 11 | { 12 | "label": "{{i18n.label}}", 13 | "displayType": "state", 14 | "state": { 15 | "label": "{{partStatus.value}}" 16 | } 17 | } 18 | ], 19 | "automation": { 20 | "conditions": [ 21 | { 22 | "label": "Partition Status", 23 | "displayType": "list", 24 | "list": { 25 | "alternatives": [ 26 | { 27 | "key": "Armed-away", 28 | "value": "Armed-away", 29 | "type": "active" 30 | }, 31 | { 32 | "key": "Armed-away (instant)", 33 | "value": "Armed-away (instant)", 34 | "type": "active" 35 | }, 36 | { 37 | "key": "Armed-stay", 38 | "value": "Armed-stay", 39 | "type": "active" 40 | }, 41 | { 42 | "key": "Armed-stay (instant)", 43 | "value": "Armed-stay (instant)", 44 | "type": "active" 45 | }, 46 | { 47 | "key": "Disarmed", 48 | "value": "Disarmed", 49 | "type": "active" 50 | }, 51 | { 52 | "key": "Ready", 53 | "value": "Ready", 54 | "type": "active" 55 | }, 56 | { 57 | "key": "Entry delay", 58 | "value": "Entry delay", 59 | "type": "active" 60 | }, 61 | { 62 | "key": "Exit delay", 63 | "value": "Exit delay", 64 | "type": "active" 65 | }, 66 | { 67 | "key": "ALARM!!", 68 | "value": "ALARM!!", 69 | "type": "active" 70 | }, 71 | { 72 | "key": "Offline", 73 | "value": "Offline", 74 | "type": "active" 75 | } 76 | ], 77 | "value": "partStatus.value", 78 | "valueType": "string" 79 | } 80 | } 81 | ], 82 | "actions": [] 83 | }, 84 | "id": "partyvoice23922.partitionstatus3a", 85 | "version": 1 86 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.zonebypass3.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zonebypass3a", 3 | "ephemeral": false, 4 | "attributes": { 5 | "zoneBypass": { 6 | "schema": { 7 | "type": "object", 8 | "properties": { 9 | "value": { 10 | "type": "string", 11 | "enum": [ 12 | "On", 13 | "Off" 14 | ] 15 | } 16 | }, 17 | "additionalProperties": false, 18 | "required": [ 19 | "value" 20 | ] 21 | }, 22 | "setter": "setZoneBypass", 23 | "enumCommands": [ 24 | { 25 | "command": "switchOn", 26 | "value": "On" 27 | }, 28 | { 29 | "command": "switchOff", 30 | "value": "Off" 31 | } 32 | ] 33 | }, 34 | "mylabel": { 35 | "schema": { 36 | "type": "object", 37 | "properties": { 38 | "value": { 39 | "type": "string" 40 | } 41 | }, 42 | "additionalProperties": false, 43 | "required": [ 44 | "value" 45 | ] 46 | }, 47 | "enumCommands": [] 48 | } 49 | }, 50 | "commands": { 51 | "setZoneBypass": { 52 | "name": "setZoneBypass", 53 | "arguments": [ 54 | { 55 | "name": "value", 56 | "optional": false, 57 | "schema": { 58 | "type": "string", 59 | "enum": [ 60 | "On", 61 | "Off" 62 | ] 63 | } 64 | } 65 | ] 66 | }, 67 | "switchOff": { 68 | "name": "switchOff", 69 | "arguments": [] 70 | }, 71 | "switchOn": { 72 | "name": "switchOn", 73 | "arguments": [] 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.zonebypass3.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [], 4 | "actions": [] 5 | }, 6 | "detailView": [ 7 | { 8 | "label": "{{i18n.label}}", 9 | "displayType": "toggleSwitch", 10 | "toggleSwitch": { 11 | "command": { 12 | "on": "switchOn", 13 | "off": "switchOff" 14 | }, 15 | "state": { 16 | "value": "zoneBypass.value", 17 | "valueType": "string", 18 | "on": "On", 19 | "off": "Off", 20 | "label": "{{mylabel.value}}", 21 | "alternatives": [ 22 | { 23 | "key": "On", 24 | "value": "On", 25 | "type": "active" 26 | }, 27 | { 28 | "key": "Off", 29 | "value": "Off", 30 | "type": "inactive" 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | ], 37 | "automation": { 38 | "conditions": [ 39 | { 40 | "label": "Zone Bypass Status", 41 | "displayType": "list", 42 | "list": { 43 | "alternatives": [ 44 | { 45 | "key": "On", 46 | "value": "On", 47 | "type": "active" 48 | }, 49 | { 50 | "key": "Off", 51 | "value": "Off", 52 | "type": "inactive" 53 | } 54 | ], 55 | "value": "zoneBypass.value", 56 | "valueType": "string" 57 | } 58 | } 59 | ], 60 | "actions": [ 61 | { 62 | "label": "Zone Bypass Status", 63 | "displayType": "list", 64 | "list": { 65 | "alternatives": [ 66 | { 67 | "key": "On", 68 | "value": "On", 69 | "type": "active" 70 | }, 71 | { 72 | "key": "Off", 73 | "value": "Off", 74 | "type": "inactive" 75 | } 76 | ], 77 | "command": "setZoneBypass", 78 | "argumentType": "string" 79 | } 80 | } 81 | ] 82 | }, 83 | "id": "partyvoice23922.zonebypass3a", 84 | "version": 1 85 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.zonebypass3a.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "partyvoice23922.zonebypass3a", 3 | "version": 1, 4 | "status": "proposed", 5 | "name": "zonebypass3a", 6 | "ephemeral": false, 7 | "attributes": { 8 | "zoneBypass": { 9 | "schema": { 10 | "type": "object", 11 | "properties": { 12 | "value": { 13 | "type": "string", 14 | "enum": [ 15 | "On", 16 | "Off" 17 | ] 18 | } 19 | }, 20 | "additionalProperties": false, 21 | "required": [ 22 | "value" 23 | ] 24 | }, 25 | "setter": "setZoneBypass", 26 | "enumCommands": [ 27 | { 28 | "command": "switchOn", 29 | "value": "On" 30 | }, 31 | { 32 | "command": "switchOff", 33 | "value": "Off" 34 | } 35 | ] 36 | }, 37 | "mylabel": { 38 | "schema": { 39 | "type": "object", 40 | "properties": { 41 | "value": { 42 | "type": "string" 43 | } 44 | }, 45 | "additionalProperties": false, 46 | "required": [ 47 | "value" 48 | ] 49 | }, 50 | "enumCommands": [] 51 | } 52 | }, 53 | "commands": { 54 | "setZoneBypass": { 55 | "name": "setZoneBypass", 56 | "arguments": [ 57 | { 58 | "name": "value", 59 | "optional": false, 60 | "schema": { 61 | "type": "string", 62 | "enum": [ 63 | "On", 64 | "Off" 65 | ] 66 | } 67 | } 68 | ] 69 | }, 70 | "switchOff": { 71 | "name": "switchOff", 72 | "arguments": [] 73 | }, 74 | "switchOn": { 75 | "name": "switchOn", 76 | "arguments": [] 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/partyvoice23922.zonebypass3a.presentation.json: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": { 3 | "states": [], 4 | "actions": [] 5 | }, 6 | "detailView": [ 7 | { 8 | "label": "{{i18n.label}}", 9 | "displayType": "toggleSwitch", 10 | "toggleSwitch": { 11 | "command": { 12 | "on": "switchOn", 13 | "off": "switchOff" 14 | }, 15 | "state": { 16 | "value": "zoneBypass.value", 17 | "valueType": "string", 18 | "on": "On", 19 | "off": "Off", 20 | "label": "{{mylabel.value}}", 21 | "alternatives": [ 22 | { 23 | "key": "On", 24 | "value": "On", 25 | "type": "active" 26 | }, 27 | { 28 | "key": "Off", 29 | "value": "Off", 30 | "type": "inactive" 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | ], 37 | "automation": { 38 | "conditions": [ 39 | { 40 | "label": "Zone Bypass Status", 41 | "displayType": "list", 42 | "list": { 43 | "alternatives": [ 44 | { 45 | "key": "On", 46 | "value": "On", 47 | "type": "active" 48 | }, 49 | { 50 | "key": "Off", 51 | "value": "Off", 52 | "type": "inactive" 53 | } 54 | ], 55 | "value": "zoneBypass.value", 56 | "valueType": "string" 57 | } 58 | } 59 | ], 60 | "actions": [ 61 | { 62 | "label": "Zone Bypass Status", 63 | "displayType": "list", 64 | "list": { 65 | "alternatives": [ 66 | { 67 | "key": "On", 68 | "value": "On", 69 | "type": "active" 70 | }, 71 | { 72 | "key": "Off", 73 | "value": "Off", 74 | "type": "inactive" 75 | } 76 | ], 77 | "command": "setZoneBypass", 78 | "argumentType": "string" 79 | } 80 | } 81 | ] 82 | }, 83 | "id": "partyvoice23922.zonebypass3a", 84 | "version": 1 85 | } -------------------------------------------------------------------------------- /hubpackagev3/capabilities/zonebypass3.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.zonebypass3 2 | version: 1 3 | status: proposed 4 | name: zonebypass3 5 | ephemeral: false 6 | attributes: 7 | zoneBypass: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | enum: 14 | - 'On' 15 | - 'Off' 16 | additionalProperties: false 17 | required: 18 | - value 19 | setter: setZoneBypass 20 | enumCommands: 21 | - command: switchOn 22 | value: 'On' 23 | - command: switchOff 24 | value: 'Off' 25 | mylabel: 26 | schema: 27 | type: object 28 | properties: 29 | value: 30 | type: string 31 | additionalProperties: false 32 | required: 33 | - value 34 | enumCommands: [] 35 | commands: 36 | setZoneBypass: 37 | name: setZoneBypass 38 | arguments: 39 | - name: value 40 | optional: false 41 | schema: 42 | type: string 43 | enum: 44 | - 'On' 45 | - 'Off' 46 | switchOff: 47 | name: switchOff 48 | arguments: [] 49 | switchOn: 50 | name: switchOn 51 | arguments: [] 52 | -------------------------------------------------------------------------------- /hubpackagev3/capabilities/zonebypass3a.yaml: -------------------------------------------------------------------------------- 1 | id: partyvoice23922.zonebypass3a 2 | version: 1 3 | status: proposed 4 | name: zonebypass3a 5 | ephemeral: false 6 | attributes: 7 | zoneBypass: 8 | schema: 9 | type: object 10 | properties: 11 | value: 12 | type: string 13 | enum: 14 | - 'On' 15 | - 'Off' 16 | additionalProperties: false 17 | required: 18 | - value 19 | setter: setZoneBypass 20 | enumCommands: 21 | - command: switchOn 22 | value: 'On' 23 | - command: switchOff 24 | value: 'Off' 25 | mylabel: 26 | schema: 27 | type: object 28 | properties: 29 | value: 30 | type: string 31 | additionalProperties: false 32 | required: 33 | - value 34 | enumCommands: [] 35 | commands: 36 | setZoneBypass: 37 | name: setZoneBypass 38 | arguments: 39 | - name: value 40 | optional: false 41 | schema: 42 | type: string 43 | enum: 44 | - 'On' 45 | - 'Off' 46 | switchOff: 47 | name: switchOff 48 | arguments: [] 49 | switchOn: 50 | name: switchOn 51 | arguments: [] 52 | -------------------------------------------------------------------------------- /hubpackagev3/config.yml: -------------------------------------------------------------------------------- 1 | name: 'Envisalink 3.11' 2 | packageKey: 'envisalinkv3.0' 3 | permissions: 4 | lan: {} 5 | discovery: {} 6 | -------------------------------------------------------------------------------- /hubpackagev3/profiles/dsccontactzone_v3.yaml: -------------------------------------------------------------------------------- 1 | name: DSC.contactzone.v3 2 | components: 3 | - id: main 4 | label: "Contact Sensor Zone" 5 | capabilities: 6 | - id: contactSensor 7 | version: 1 8 | - id: partyvoice23922.contactstatus 9 | version: 1 10 | - id: partyvoice23922.zonebypass3a 11 | version: 1 12 | categories: 13 | - name: ContactSensor 14 | metadata: 15 | vid: 7457d7d5-1bda-3ca3-8cdb-9682886f36c9 16 | mnmn: fE4b 17 | 18 | -------------------------------------------------------------------------------- /hubpackagev3/profiles/dsccozone_v3.yaml: -------------------------------------------------------------------------------- 1 | name: DSC.cozone.v3 2 | components: 3 | - id: main 4 | label: "CO Detector Zone" 5 | capabilities: 6 | - id: carbonMonoxideDetector 7 | version: 1 8 | - id: partyvoice23922.costatus 9 | version: 1 10 | - id: partyvoice23922.zonebypass3a 11 | version: 1 12 | categories: 13 | - name: SmokeDetector 14 | metadata: 15 | vid: 8d2c179f-b8a6-3e0e-80f7-4023a374118d 16 | mnmn: fE4b 17 | 18 | -------------------------------------------------------------------------------- /hubpackagev3/profiles/dscmotionzone_v3.yaml: -------------------------------------------------------------------------------- 1 | name: DSC.motionzone.v3 2 | components: 3 | - id: main 4 | label: "Motion Sensor Zone" 5 | capabilities: 6 | - id: motionSensor 7 | version: 1 8 | - id: partyvoice23922.motionstatus 9 | version: 1 10 | - id: partyvoice23922.zonebypass3a 11 | version: 1 12 | categories: 13 | - name: MotionSensor 14 | metadata: 15 | vid: fb94c43e-4664-3c93-9a01-f2b753b8083d 16 | mnmn: fE4b 17 | 18 | -------------------------------------------------------------------------------- /hubpackagev3/profiles/dscprimarypanel_v3d.yaml: -------------------------------------------------------------------------------- 1 | name: DSC.primarypanel.v3d 2 | components: 3 | - id: main 4 | label: "Primary Partition" 5 | capabilities: 6 | - id: "partyvoice23922.partitionstatus3a" 7 | version: 1 8 | - id: "partyvoice23922.dscdashswitch3" 9 | version: 1 10 | - id: "partyvoice23922.ledstatus2" 11 | version: 1 12 | - id: "partyvoice23922.dscuser" 13 | version: 1 14 | - id: "partyvoice23922.dsctroubletype3a" 15 | version: 1 16 | - id: "partyvoice23922.dscstayswitch3" 17 | version: 1 18 | - id: "partyvoice23922.dscawayswitch3" 19 | version: 1 20 | - id: "partyvoice23922.partitioncommand3" 21 | version: 1 22 | - id: "partyvoice23922.dscselectswitch3" 23 | version: 1 24 | - id: alarm 25 | version: 1 26 | - id: securitySystem 27 | version: 1 28 | categories: 29 | - name: SecurityPanel 30 | metadata: 31 | vid: f1608f6c-d997-30cb-a9e9-03bf77fb8dff 32 | mnmn: fE4b 33 | preferences: 34 | - title: "Set arm mode from STHM" 35 | name: sthmsynch 36 | description: "Select behavior" 37 | required: true 38 | preferenceType: enumeration 39 | definition: 40 | options: 41 | yessynch: "Auto-synch" 42 | nosynch: "No auto-synch" 43 | default: nosynch 44 | - title: "Aux Siren Trigger" 45 | name: sirenpgm 46 | description: "Select PGM" 47 | required: true 48 | preferenceType: enumeration 49 | definition: 50 | options: 51 | pgm0: "none" 52 | pgm1: "Trigger: PGM1" 53 | pgm2: "Trigger: PGM2" 54 | pgm3: "Trigger: PGM3" 55 | pgm4: "Trigger: PGM4" 56 | default: pgm0 57 | - title: "Aux Siren Duration" 58 | name: sirenduration 59 | description: "Number of seconds" 60 | required: false 61 | preferenceType: integer 62 | definition: 63 | minimum: 1 64 | maximum: 255 65 | default: 60 66 | - title: "Additional Partitions" 67 | name: addlparts 68 | description: "Number of ADDITIONAL partitions" 69 | required: false 70 | preferenceType: integer 71 | definition: 72 | minimum: 0 73 | maximum: 7 74 | default: 0 75 | - title: "Envisalink login password" 76 | name: envPass 77 | description: "min 4-char alphanumeric password" 78 | required: true 79 | preferenceType: string 80 | definition: 81 | stringType: password 82 | minLength: 4 83 | maxLength: 10 84 | default: "user" 85 | - title: "Access Code for Arm/Disarm" 86 | name: alarmCode 87 | description: "4-6 digit code" 88 | required: true 89 | preferenceType: string 90 | definition: 91 | stringType: password 92 | minLength: 4 93 | maxLength: 6 94 | default: "1111" 95 | - title: "Access Code->Name Map" 96 | name: usermap 97 | descripion: "nn=xxxx, nn=xxxx, ..." 98 | required: false 99 | preferenceType: string 100 | definition: 101 | stringType: text 102 | default: "40=Master, 01=Myname" 103 | - title: "Periodic Connection Check" 104 | name: checkfreq 105 | description: "Poll frequency in minutes" 106 | required: true 107 | preferenceType: integer 108 | definition: 109 | minimum: 1 110 | maximum: 60 111 | default: 15 112 | - title: "Envisalink LAN Address" 113 | name: lanAddress 114 | description: "IP:port address of Envisalink" 115 | required: true 116 | preferenceType: string 117 | definition: 118 | stringType: text 119 | minLength: 12 120 | maxLength: 20 121 | default: '192.168.1.nnn:4025' 122 | - title: "Zone 1" 123 | name: zone1 124 | description: "Zone 1 Type" 125 | required: true 126 | preferenceType: enumeration 127 | definition: 128 | options: 129 | contact: "contact sensor" 130 | motion: "motion detector" 131 | smoke: "smoke detector" 132 | co: "carbon monoxide detector" 133 | water: "moisture detector" 134 | unused: "unused" 135 | default: unused 136 | - title: "Zone 2" 137 | name: zone2 138 | description: "Zone 2 Type" 139 | required: false 140 | preferenceType: enumeration 141 | definition: 142 | options: 143 | contact: "contact sensor" 144 | motion: "motion detector" 145 | smoke: "smoke detector" 146 | co: "carbon monoxide detector" 147 | water: "moisture detector" 148 | unused: "unused" 149 | default: unused 150 | - title: "Zone 3" 151 | name: zone3 152 | description: "Zone 3 Type" 153 | required: false 154 | preferenceType: enumeration 155 | definition: 156 | options: 157 | contact: "contact sensor" 158 | motion: "motion detector" 159 | smoke: "smoke detector" 160 | co: "carbon monoxide detector" 161 | water: "moisture detector" 162 | unused: "unused" 163 | default: unused 164 | - title: "Zone 4" 165 | name: zone4 166 | description: "Zone 4 Type" 167 | required: false 168 | preferenceType: enumeration 169 | definition: 170 | options: 171 | contact: "contact sensor" 172 | motion: "motion detector" 173 | smoke: "smoke detector" 174 | co: "carbon monoxide detector" 175 | water: "moisture detector" 176 | unused: "unused" 177 | default: unused 178 | - title: "Zone 5" 179 | name: zone5 180 | description: "Zone 5 Type" 181 | required: false 182 | preferenceType: enumeration 183 | definition: 184 | options: 185 | contact: "contact sensor" 186 | motion: "motion detector" 187 | smoke: "smoke detector" 188 | co: "carbon monoxide detector" 189 | water: "moisture detector" 190 | unused: "unused" 191 | default: unused 192 | - title: "Zone 6" 193 | name: zone6 194 | description: "Zone 6 Type" 195 | required: false 196 | preferenceType: enumeration 197 | definition: 198 | options: 199 | contact: "contact sensor" 200 | motion: "motion detector" 201 | smoke: "smoke detector" 202 | co: "carbon monoxide detector" 203 | water: "moisture detector" 204 | unused: "unused" 205 | default: unused 206 | - title: "Zone 7" 207 | name: zone7 208 | description: "Zone 7 Type" 209 | required: false 210 | preferenceType: enumeration 211 | definition: 212 | options: 213 | contact: "contact sensor" 214 | motion: "motion detector" 215 | smoke: "smoke detector" 216 | co: "carbon monoxide detector" 217 | water: "moisture detector" 218 | unused: "unused" 219 | default: unused 220 | - title: "Zone 8" 221 | name: zone8 222 | description: "Zone 8 Type" 223 | required: false 224 | preferenceType: enumeration 225 | definition: 226 | options: 227 | contact: "contact sensor" 228 | motion: "motion detector" 229 | smoke: "smoke detector" 230 | co: "carbon monoxide detector" 231 | water: "moisture detector" 232 | unused: "unused" 233 | default: unused 234 | - title: "Zone 9" 235 | name: zone9 236 | description: "Zone 9 Type" 237 | required: false 238 | preferenceType: enumeration 239 | definition: 240 | options: 241 | contact: "contact sensor" 242 | motion: "motion detector" 243 | smoke: "smoke detector" 244 | co: "carbon monoxide detector" 245 | water: "moisture detector" 246 | unused: "unused" 247 | default: unused 248 | - title: "Zone 10" 249 | name: zone10 250 | description: "Zone 10 Type" 251 | required: false 252 | preferenceType: enumeration 253 | definition: 254 | options: 255 | contact: "contact sensor" 256 | motion: "motion detector" 257 | smoke: "smoke detector" 258 | co: "carbon monoxide detector" 259 | water: "moisture detector" 260 | unused: "unused" 261 | default: unused 262 | - title: "Zone 11" 263 | name: zone11 264 | description: "Zone 11 Type" 265 | required: false 266 | preferenceType: enumeration 267 | definition: 268 | options: 269 | contact: "contact sensor" 270 | motion: "motion detector" 271 | smoke: "smoke detector" 272 | co: "carbon monoxide detector" 273 | water: "moisture detector" 274 | unused: "unused" 275 | default: unused 276 | - title: "Zone 12" 277 | name: zone12 278 | description: "Zone 12 Type" 279 | required: false 280 | preferenceType: enumeration 281 | definition: 282 | options: 283 | contact: "contact sensor" 284 | motion: "motion detector" 285 | smoke: "smoke detector" 286 | co: "carbon monoxide detector" 287 | water: "moisture detector" 288 | unused: "unused" 289 | default: unused 290 | - title: "Zone 13" 291 | name: zone13 292 | description: "Zone 13 Type" 293 | required: false 294 | preferenceType: enumeration 295 | definition: 296 | options: 297 | contact: "contact sensor" 298 | motion: "motion detector" 299 | smoke: "smoke detector" 300 | co: "carbon monoxide detector" 301 | water: "moisture detector" 302 | unused: "unused" 303 | default: unused 304 | - title: "Zone 14" 305 | name: zone14 306 | description: "Zone 14 Type" 307 | required: false 308 | preferenceType: enumeration 309 | definition: 310 | options: 311 | contact: "contact sensor" 312 | motion: "motion detector" 313 | smoke: "smoke detector" 314 | co: "carbon monoxide detector" 315 | water: "moisture detector" 316 | unused: "unused" 317 | default: unused 318 | - title: "Zone 15" 319 | name: zone15 320 | description: "Zone 15 Type" 321 | required: false 322 | preferenceType: enumeration 323 | definition: 324 | options: 325 | contact: "contact sensor" 326 | motion: "motion detector" 327 | smoke: "smoke detector" 328 | co: "carbon monoxide detector" 329 | water: "moisture detector" 330 | unused: "unused" 331 | default: unused 332 | - title: "Zone 16" 333 | name: zone16 334 | description: "Zone 16 Type" 335 | required: false 336 | preferenceType: enumeration 337 | definition: 338 | options: 339 | contact: "contact sensor" 340 | motion: "motion detector" 341 | smoke: "smoke detector" 342 | co: "carbon monoxide detector" 343 | water: "moisture detector" 344 | unused: "unused" 345 | default: unused 346 | - title: "Zone 17" 347 | name: zone17 348 | description: "Zone 17 Type" 349 | required: false 350 | preferenceType: enumeration 351 | definition: 352 | options: 353 | contact: "contact sensor" 354 | motion: "motion detector" 355 | smoke: "smoke detector" 356 | co: "carbon monoxide detector" 357 | water: "moisture detector" 358 | unused: "unused" 359 | default: unused 360 | - title: "Zone 18" 361 | name: zone18 362 | description: "Zone 18 Type" 363 | required: false 364 | preferenceType: enumeration 365 | definition: 366 | options: 367 | contact: "contact sensor" 368 | motion: "motion detector" 369 | smoke: "smoke detector" 370 | co: "carbon monoxide detector" 371 | water: "moisture detector" 372 | unused: "unused" 373 | default: unused 374 | - title: "Zone 19" 375 | name: zone19 376 | description: "Zone 19 Type" 377 | required: false 378 | preferenceType: enumeration 379 | definition: 380 | options: 381 | contact: "contact sensor" 382 | motion: "motion detector" 383 | smoke: "smoke detector" 384 | co: "carbon monoxide detector" 385 | water: "moisture detector" 386 | unused: "unused" 387 | default: unused 388 | - title: "Zone 20" 389 | name: zone20 390 | description: "Zone 20 Type" 391 | required: false 392 | preferenceType: enumeration 393 | definition: 394 | options: 395 | contact: "contact sensor" 396 | motion: "motion detector" 397 | smoke: "smoke detector" 398 | co: "carbon monoxide detector" 399 | water: "moisture detector" 400 | unused: "unused" 401 | default: unused 402 | - title: "Zone 21" 403 | name: zone21 404 | description: "Zone 21 Type" 405 | required: false 406 | preferenceType: enumeration 407 | definition: 408 | options: 409 | contact: "contact sensor" 410 | motion: "motion detector" 411 | smoke: "smoke detector" 412 | co: "carbon monoxide detector" 413 | water: "moisture detector" 414 | unused: "unused" 415 | default: unused 416 | - title: "Zone 22" 417 | name: zone22 418 | description: "Zone 22 Type" 419 | required: false 420 | preferenceType: enumeration 421 | definition: 422 | options: 423 | contact: "contact sensor" 424 | motion: "motion detector" 425 | smoke: "smoke detector" 426 | co: "carbon monoxide detector" 427 | water: "moisture detector" 428 | unused: "unused" 429 | default: unused 430 | - title: "Zone 23" 431 | name: zone23 432 | description: "Zone 23 Type" 433 | required: false 434 | preferenceType: enumeration 435 | definition: 436 | options: 437 | contact: "contact sensor" 438 | motion: "motion detector" 439 | smoke: "smoke detector" 440 | co: "carbon monoxide detector" 441 | water: "moisture detector" 442 | unused: "unused" 443 | default: unused 444 | - title: "Zone 24" 445 | name: zone24 446 | description: "Zone 24 Type" 447 | required: false 448 | preferenceType: enumeration 449 | definition: 450 | options: 451 | contact: "contact sensor" 452 | motion: "motion detector" 453 | smoke: "smoke detector" 454 | co: "carbon monoxide detector" 455 | water: "moisture detector" 456 | unused: "unused" 457 | default: unused 458 | - title: "Zone 25" 459 | name: zone25 460 | description: "Zone 25 Type" 461 | required: false 462 | preferenceType: enumeration 463 | definition: 464 | options: 465 | contact: "contact sensor" 466 | motion: "motion detector" 467 | smoke: "smoke detector" 468 | co: "carbon monoxide detector" 469 | water: "moisture detector" 470 | unused: "unused" 471 | default: unused 472 | - title: "Zone 26" 473 | name: zone26 474 | description: "Zone 26 Type" 475 | required: false 476 | preferenceType: enumeration 477 | definition: 478 | options: 479 | contact: "contact sensor" 480 | motion: "motion detector" 481 | smoke: "smoke detector" 482 | co: "carbon monoxide detector" 483 | water: "moisture detector" 484 | unused: "unused" 485 | default: unused 486 | - title: "Zone 27" 487 | name: zone27 488 | description: "Zone 27 Type" 489 | required: false 490 | preferenceType: enumeration 491 | definition: 492 | options: 493 | contact: "contact sensor" 494 | motion: "motion detector" 495 | smoke: "smoke detector" 496 | co: "carbon monoxide detector" 497 | water: "moisture detector" 498 | unused: "unused" 499 | default: unused 500 | - title: "Zone 28" 501 | name: zone28 502 | description: "Zone 28 Type" 503 | required: false 504 | preferenceType: enumeration 505 | definition: 506 | options: 507 | contact: "contact sensor" 508 | motion: "motion detector" 509 | smoke: "smoke detector" 510 | co: "carbon monoxide detector" 511 | water: "moisture detector" 512 | unused: "unused" 513 | default: unused 514 | - title: "Zone 29" 515 | name: zone29 516 | description: "Zone 29 Type" 517 | required: false 518 | preferenceType: enumeration 519 | definition: 520 | options: 521 | contact: "contact sensor" 522 | motion: "motion detector" 523 | smoke: "smoke detector" 524 | co: "carbon monoxide detector" 525 | water: "moisture detector" 526 | unused: "unused" 527 | default: unused 528 | - title: "Zone 30" 529 | name: zone30 530 | description: "Zone 30 Type" 531 | required: false 532 | preferenceType: enumeration 533 | definition: 534 | options: 535 | contact: "contact sensor" 536 | motion: "motion detector" 537 | smoke: "smoke detector" 538 | co: "carbon monoxide detector" 539 | water: "moisture detector" 540 | unused: "unused" 541 | default: unused 542 | - title: "Zone 31" 543 | name: zone31 544 | description: "Zone 31 Type" 545 | required: false 546 | preferenceType: enumeration 547 | definition: 548 | options: 549 | contact: "contact sensor" 550 | motion: "motion detector" 551 | smoke: "smoke detector" 552 | co: "carbon monoxide detector" 553 | water: "moisture detector" 554 | unused: "unused" 555 | default: unused 556 | - title: "Zone 32" 557 | name: zone32 558 | description: "Zone 32 Type" 559 | required: false 560 | preferenceType: enumeration 561 | definition: 562 | options: 563 | contact: "contact sensor" 564 | motion: "motion detector" 565 | smoke: "smoke detector" 566 | co: "carbon monoxide detector" 567 | water: "moisture detector" 568 | unused: "unused" 569 | default: unused 570 | - title: "Zone 33" 571 | name: zone33 572 | description: "Zone 33 Type" 573 | required: false 574 | preferenceType: enumeration 575 | definition: 576 | options: 577 | contact: "contact sensor" 578 | motion: "motion detector" 579 | smoke: "smoke detector" 580 | co: "carbon monoxide detector" 581 | water: "moisture detector" 582 | unused: "unused" 583 | default: unused 584 | - title: "Zone 34" 585 | name: zone34 586 | description: "Zone 34 Type" 587 | required: false 588 | preferenceType: enumeration 589 | definition: 590 | options: 591 | contact: "contact sensor" 592 | motion: "motion detector" 593 | smoke: "smoke detector" 594 | co: "carbon monoxide detector" 595 | water: "moisture detector" 596 | unused: "unused" 597 | default: unused 598 | - title: "Zone 35" 599 | name: zone35 600 | description: "Zone 35 Type" 601 | required: false 602 | preferenceType: enumeration 603 | definition: 604 | options: 605 | contact: "contact sensor" 606 | motion: "motion detector" 607 | smoke: "smoke detector" 608 | co: "carbon monoxide detector" 609 | water: "moisture detector" 610 | unused: "unused" 611 | default: unused 612 | - title: "Zone 36" 613 | name: zone36 614 | description: "Zone 36 Type" 615 | required: false 616 | preferenceType: enumeration 617 | definition: 618 | options: 619 | contact: "contact sensor" 620 | motion: "motion detector" 621 | smoke: "smoke detector" 622 | co: "carbon monoxide detector" 623 | water: "moisture detector" 624 | unused: "unused" 625 | default: unused 626 | - title: "Zone 37" 627 | name: zone37 628 | description: "Zone 37 Type" 629 | required: false 630 | preferenceType: enumeration 631 | definition: 632 | options: 633 | contact: "contact sensor" 634 | motion: "motion detector" 635 | smoke: "smoke detector" 636 | co: "carbon monoxide detector" 637 | water: "moisture detector" 638 | unused: "unused" 639 | default: unused 640 | - title: "Zone 38" 641 | name: zone38 642 | description: "Zone 38 Type" 643 | required: false 644 | preferenceType: enumeration 645 | definition: 646 | options: 647 | contact: "contact sensor" 648 | motion: "motion detector" 649 | smoke: "smoke detector" 650 | co: "carbon monoxide detector" 651 | water: "moisture detector" 652 | unused: "unused" 653 | default: unused 654 | - title: "Zone 39" 655 | name: zone39 656 | description: "Zone 39 Type" 657 | required: false 658 | preferenceType: enumeration 659 | definition: 660 | options: 661 | contact: "contact sensor" 662 | motion: "motion detector" 663 | smoke: "smoke detector" 664 | co: "carbon monoxide detector" 665 | water: "moisture detector" 666 | unused: "unused" 667 | default: unused 668 | - title: "Zone 40" 669 | name: zone40 670 | description: "Zone 40 Type" 671 | required: false 672 | preferenceType: enumeration 673 | definition: 674 | options: 675 | contact: "contact sensor" 676 | motion: "motion detector" 677 | smoke: "smoke detector" 678 | co: "carbon monoxide detector" 679 | water: "moisture detector" 680 | unused: "unused" 681 | default: unused 682 | - title: "Zone 41" 683 | name: zone41 684 | description: "Zone 41 Type" 685 | required: false 686 | preferenceType: enumeration 687 | definition: 688 | options: 689 | contact: "contact sensor" 690 | motion: "motion detector" 691 | smoke: "smoke detector" 692 | co: "carbon monoxide detector" 693 | water: "moisture detector" 694 | unused: "unused" 695 | default: unused 696 | - title: "Zone 42" 697 | name: zone42 698 | description: "Zone 42 Type" 699 | required: false 700 | preferenceType: enumeration 701 | definition: 702 | options: 703 | contact: "contact sensor" 704 | motion: "motion detector" 705 | smoke: "smoke detector" 706 | co: "carbon monoxide detector" 707 | water: "moisture detector" 708 | unused: "unused" 709 | default: unused 710 | - title: "Zone 43" 711 | name: zone43 712 | description: "Zone 43 Type" 713 | required: false 714 | preferenceType: enumeration 715 | definition: 716 | options: 717 | contact: "contact sensor" 718 | motion: "motion detector" 719 | smoke: "smoke detector" 720 | co: "carbon monoxide detector" 721 | water: "moisture detector" 722 | unused: "unused" 723 | default: unused 724 | - title: "Zone 44" 725 | name: zone44 726 | description: "Zone 44 Type" 727 | required: false 728 | preferenceType: enumeration 729 | definition: 730 | options: 731 | contact: "contact sensor" 732 | motion: "motion detector" 733 | smoke: "smoke detector" 734 | co: "carbon monoxide detector" 735 | water: "moisture detector" 736 | unused: "unused" 737 | default: unused 738 | - title: "Zone 45" 739 | name: zone45 740 | description: "Zone 45 Type" 741 | required: false 742 | preferenceType: enumeration 743 | definition: 744 | options: 745 | contact: "contact sensor" 746 | motion: "motion detector" 747 | smoke: "smoke detector" 748 | co: "carbon monoxide detector" 749 | water: "moisture detector" 750 | unused: "unused" 751 | default: unused 752 | - title: "Zone 46" 753 | name: zone46 754 | description: "Zone 46 Type" 755 | required: false 756 | preferenceType: enumeration 757 | definition: 758 | options: 759 | contact: "contact sensor" 760 | motion: "motion detector" 761 | smoke: "smoke detector" 762 | co: "carbon monoxide detector" 763 | water: "moisture detector" 764 | unused: "unused" 765 | default: unused 766 | - title: "Zone 47" 767 | name: zone47 768 | description: "Zone 47 Type" 769 | required: false 770 | preferenceType: enumeration 771 | definition: 772 | options: 773 | contact: "contact sensor" 774 | motion: "motion detector" 775 | smoke: "smoke detector" 776 | co: "carbon monoxide detector" 777 | water: "moisture detector" 778 | unused: "unused" 779 | default: unused 780 | - title: "Zone 48" 781 | name: zone48 782 | description: "Zone 48 Type" 783 | required: false 784 | preferenceType: enumeration 785 | definition: 786 | options: 787 | contact: "contact sensor" 788 | motion: "motion detector" 789 | smoke: "smoke detector" 790 | co: "carbon monoxide detector" 791 | water: "moisture detector" 792 | unused: "unused" 793 | default: unused 794 | - title: "Zone 49" 795 | name: zone49 796 | description: "Zone 49 Type" 797 | required: false 798 | preferenceType: enumeration 799 | definition: 800 | options: 801 | contact: "contact sensor" 802 | motion: "motion detector" 803 | smoke: "smoke detector" 804 | co: "carbon monoxide detector" 805 | water: "moisture detector" 806 | unused: "unused" 807 | default: unused 808 | - title: "Zone 50" 809 | name: zone50 810 | description: "Zone 50 Type" 811 | required: false 812 | preferenceType: enumeration 813 | definition: 814 | options: 815 | contact: "contact sensor" 816 | motion: "motion detector" 817 | smoke: "smoke detector" 818 | co: "carbon monoxide detector" 819 | water: "moisture detector" 820 | unused: "unused" 821 | default: unused 822 | - title: "Zone 51" 823 | name: zone51 824 | description: "Zone 51 Type" 825 | required: false 826 | preferenceType: enumeration 827 | definition: 828 | options: 829 | contact: "contact sensor" 830 | motion: "motion detector" 831 | smoke: "smoke detector" 832 | co: "carbon monoxide detector" 833 | water: "moisture detector" 834 | unused: "unused" 835 | default: unused 836 | - title: "Zone 52" 837 | name: zone52 838 | description: "Zone 52 Type" 839 | required: false 840 | preferenceType: enumeration 841 | definition: 842 | options: 843 | contact: "contact sensor" 844 | motion: "motion detector" 845 | smoke: "smoke detector" 846 | co: "carbon monoxide detector" 847 | water: "moisture detector" 848 | unused: "unused" 849 | default: unused 850 | - title: "Zone 53" 851 | name: zone53 852 | description: "Zone 53 Type" 853 | required: false 854 | preferenceType: enumeration 855 | definition: 856 | options: 857 | contact: "contact sensor" 858 | motion: "motion detector" 859 | smoke: "smoke detector" 860 | co: "carbon monoxide detector" 861 | water: "moisture detector" 862 | unused: "unused" 863 | default: unused 864 | - title: "Zone 54" 865 | name: zone54 866 | description: "Zone 54 Type" 867 | required: false 868 | preferenceType: enumeration 869 | definition: 870 | options: 871 | contact: "contact sensor" 872 | motion: "motion detector" 873 | smoke: "smoke detector" 874 | co: "carbon monoxide detector" 875 | water: "moisture detector" 876 | unused: "unused" 877 | default: unused 878 | - title: "Zone 55" 879 | name: zone55 880 | description: "Zone 55 Type" 881 | required: false 882 | preferenceType: enumeration 883 | definition: 884 | options: 885 | contact: "contact sensor" 886 | motion: "motion detector" 887 | smoke: "smoke detector" 888 | co: "carbon monoxide detector" 889 | water: "moisture detector" 890 | unused: "unused" 891 | default: unused 892 | - title: "Zone 56" 893 | name: zone56 894 | description: "Zone 56 Type" 895 | required: false 896 | preferenceType: enumeration 897 | definition: 898 | options: 899 | contact: "contact sensor" 900 | motion: "motion detector" 901 | smoke: "smoke detector" 902 | co: "carbon monoxide detector" 903 | water: "moisture detector" 904 | unused: "unused" 905 | default: unused 906 | - title: "Zone 57" 907 | name: zone57 908 | description: "Zone 57 Type" 909 | required: false 910 | preferenceType: enumeration 911 | definition: 912 | options: 913 | contact: "contact sensor" 914 | motion: "motion detector" 915 | smoke: "smoke detector" 916 | co: "carbon monoxide detector" 917 | water: "moisture detector" 918 | unused: "unused" 919 | default: unused 920 | - title: "Zone 58" 921 | name: zone58 922 | description: "Zone 58 Type" 923 | required: false 924 | preferenceType: enumeration 925 | definition: 926 | options: 927 | contact: "contact sensor" 928 | motion: "motion detector" 929 | smoke: "smoke detector" 930 | co: "carbon monoxide detector" 931 | water: "moisture detector" 932 | unused: "unused" 933 | default: unused 934 | - title: "Zone 59" 935 | name: zone59 936 | description: "Zone 59 Type" 937 | required: false 938 | preferenceType: enumeration 939 | definition: 940 | options: 941 | contact: "contact sensor" 942 | motion: "motion detector" 943 | smoke: "smoke detector" 944 | co: "carbon monoxide detector" 945 | water: "moisture detector" 946 | unused: "unused" 947 | default: unused 948 | - title: "Zone 60" 949 | name: zone60 950 | description: "Zone 60 Type" 951 | required: false 952 | preferenceType: enumeration 953 | definition: 954 | options: 955 | contact: "contact sensor" 956 | motion: "motion detector" 957 | smoke: "smoke detector" 958 | co: "carbon monoxide detector" 959 | water: "moisture detector" 960 | unused: "unused" 961 | default: unused 962 | - title: "Zone 61" 963 | name: zone61 964 | description: "Zone 61 Type" 965 | required: false 966 | preferenceType: enumeration 967 | definition: 968 | options: 969 | contact: "contact sensor" 970 | motion: "motion detector" 971 | smoke: "smoke detector" 972 | co: "carbon monoxide detector" 973 | water: "moisture detector" 974 | unused: "unused" 975 | default: unused 976 | - title: "Zone 62" 977 | name: zone62 978 | description: "Zone 62 Type" 979 | required: false 980 | preferenceType: enumeration 981 | definition: 982 | options: 983 | contact: "contact sensor" 984 | motion: "motion detector" 985 | smoke: "smoke detector" 986 | co: "carbon monoxide detector" 987 | water: "moisture detector" 988 | unused: "unused" 989 | default: unused 990 | - title: "Zone 63" 991 | name: zone63 992 | description: "Zone 63 Type" 993 | required: false 994 | preferenceType: enumeration 995 | definition: 996 | options: 997 | contact: "contact sensor" 998 | motion: "motion detector" 999 | smoke: "smoke detector" 1000 | co: "carbon monoxide detector" 1001 | water: "moisture detector" 1002 | unused: "unused" 1003 | default: unused 1004 | - title: "Zone 64" 1005 | name: zone64 1006 | description: "Zone 64 Type" 1007 | required: false 1008 | preferenceType: enumeration 1009 | definition: 1010 | options: 1011 | contact: "contact sensor" 1012 | motion: "motion detector" 1013 | smoke: "smoke detector" 1014 | co: "carbon monoxide detector" 1015 | water: "moisture detector" 1016 | unused: "unused" 1017 | default: unused 1018 | -------------------------------------------------------------------------------- /hubpackagev3/profiles/dscsecondarypanel_v3d.yaml: -------------------------------------------------------------------------------- 1 | name: DSC.secondarypanel.v3d 2 | components: 3 | - id: main 4 | label: "Secondary Partition" 5 | capabilities: 6 | - id: "partyvoice23922.partitionstatus3a" 7 | version: 1 8 | - id: "partyvoice23922.dscdashswitch3" 9 | version: 1 10 | - id: "partyvoice23922.ledstatus2" 11 | version: 1 12 | - id: "partyvoice23922.dscuser" 13 | version: 1 14 | - id: "partyvoice23922.dsctroubletype3a" 15 | version: 1 16 | - id: "partyvoice23922.dscstayswitch3" 17 | version: 1 18 | - id: "partyvoice23922.dscawayswitch3" 19 | version: 1 20 | - id: "partyvoice23922.partitioncommand3" 21 | version: 1 22 | - id: "partyvoice23922.dscselectswitch3" 23 | version: 1 24 | - id: alarm 25 | version: 1 26 | - id: securitySystem 27 | version: 1 28 | categories: 29 | - name: SecurityPanel 30 | metadata: 31 | vid: f1608f6c-d997-30cb-a9e9-03bf77fb8dff 32 | mnmn: fE4b 33 | preferences: 34 | - title: "Set arm mode from STHM" 35 | name: sthmsynch 36 | description: "Select behavior" 37 | required: true 38 | preferenceType: enumeration 39 | definition: 40 | options: 41 | yessynch: "Auto-synch" 42 | nosynch: "No auto-synch" 43 | default: nosynch 44 | - title: "Aux Siren Trigger" 45 | name: sirenpgm 46 | description: "Select PGM" 47 | required: true 48 | preferenceType: enumeration 49 | definition: 50 | options: 51 | pgm0: "none" 52 | pgm1: "Trigger: PGM1" 53 | pgm2: "Trigger: PGM2" 54 | pgm3: "Trigger: PGM3" 55 | pgm4: "Trigger: PGM4" 56 | default: pgm0 57 | - title: "Aux Siren Duration" 58 | name: sirenduration 59 | description: "Number of seconds" 60 | required: false 61 | preferenceType: integer 62 | definition: 63 | minimum: 1 64 | maximum: 255 65 | default: 60 66 | - title: "Zone 1" 67 | name: zone1 68 | description: "Zone 1 Type" 69 | required: false 70 | preferenceType: enumeration 71 | definition: 72 | options: 73 | contact: "contact sensor" 74 | motion: "motion detector" 75 | smoke: "smoke detector" 76 | co: "carbon monoxide detector" 77 | water: "moisture detector" 78 | unused: "unused" 79 | default: unused 80 | - title: "Zone 2" 81 | name: zone2 82 | description: "Zone 2 Type" 83 | required: false 84 | preferenceType: enumeration 85 | definition: 86 | options: 87 | contact: "contact sensor" 88 | motion: "motion detector" 89 | smoke: "smoke detector" 90 | co: "carbon monoxide detector" 91 | water: "moisture detector" 92 | unused: "unused" 93 | default: unused 94 | - title: "Zone 3" 95 | name: zone3 96 | description: "Zone 3 Type" 97 | required: false 98 | preferenceType: enumeration 99 | definition: 100 | options: 101 | contact: "contact sensor" 102 | motion: "motion detector" 103 | smoke: "smoke detector" 104 | co: "carbon monoxide detector" 105 | water: "moisture detector" 106 | unused: "unused" 107 | default: unused 108 | - title: "Zone 4" 109 | name: zone4 110 | description: "Zone 4 Type" 111 | required: false 112 | preferenceType: enumeration 113 | definition: 114 | options: 115 | contact: "contact sensor" 116 | motion: "motion detector" 117 | smoke: "smoke detector" 118 | co: "carbon monoxide detector" 119 | water: "moisture detector" 120 | unused: "unused" 121 | default: unused 122 | - title: "Zone 5" 123 | name: zone5 124 | description: "Zone 5 Type" 125 | required: false 126 | preferenceType: enumeration 127 | definition: 128 | options: 129 | contact: "contact sensor" 130 | motion: "motion detector" 131 | smoke: "smoke detector" 132 | co: "carbon monoxide detector" 133 | water: "moisture detector" 134 | unused: "unused" 135 | default: unused 136 | - title: "Zone 6" 137 | name: zone6 138 | description: "Zone 6 Type" 139 | required: false 140 | preferenceType: enumeration 141 | definition: 142 | options: 143 | contact: "contact sensor" 144 | motion: "motion detector" 145 | smoke: "smoke detector" 146 | co: "carbon monoxide detector" 147 | water: "moisture detector" 148 | unused: "unused" 149 | default: unused 150 | - title: "Zone 7" 151 | name: zone7 152 | description: "Zone 7 Type" 153 | required: false 154 | preferenceType: enumeration 155 | definition: 156 | options: 157 | contact: "contact sensor" 158 | motion: "motion detector" 159 | smoke: "smoke detector" 160 | co: "carbon monoxide detector" 161 | water: "moisture detector" 162 | unused: "unused" 163 | default: unused 164 | - title: "Zone 8" 165 | name: zone8 166 | description: "Zone 8 Type" 167 | required: false 168 | preferenceType: enumeration 169 | definition: 170 | options: 171 | contact: "contact sensor" 172 | motion: "motion detector" 173 | smoke: "smoke detector" 174 | co: "carbon monoxide detector" 175 | water: "moisture detector" 176 | unused: "unused" 177 | default: unused 178 | - title: "Zone 9" 179 | name: zone9 180 | description: "Zone 9 Type" 181 | required: false 182 | preferenceType: enumeration 183 | definition: 184 | options: 185 | contact: "contact sensor" 186 | motion: "motion detector" 187 | smoke: "smoke detector" 188 | co: "carbon monoxide detector" 189 | water: "moisture detector" 190 | unused: "unused" 191 | default: unused 192 | - title: "Zone 10" 193 | name: zone10 194 | description: "Zone 10 Type" 195 | required: false 196 | preferenceType: enumeration 197 | definition: 198 | options: 199 | contact: "contact sensor" 200 | motion: "motion detector" 201 | smoke: "smoke detector" 202 | co: "carbon monoxide detector" 203 | water: "moisture detector" 204 | unused: "unused" 205 | default: unused 206 | - title: "Zone 11" 207 | name: zone11 208 | description: "Zone 11 Type" 209 | required: false 210 | preferenceType: enumeration 211 | definition: 212 | options: 213 | contact: "contact sensor" 214 | motion: "motion detector" 215 | smoke: "smoke detector" 216 | co: "carbon monoxide detector" 217 | water: "moisture detector" 218 | unused: "unused" 219 | default: unused 220 | - title: "Zone 12" 221 | name: zone12 222 | description: "Zone 12 Type" 223 | required: false 224 | preferenceType: enumeration 225 | definition: 226 | options: 227 | contact: "contact sensor" 228 | motion: "motion detector" 229 | smoke: "smoke detector" 230 | co: "carbon monoxide detector" 231 | water: "moisture detector" 232 | unused: "unused" 233 | default: unused 234 | - title: "Zone 13" 235 | name: zone13 236 | description: "Zone 13 Type" 237 | required: false 238 | preferenceType: enumeration 239 | definition: 240 | options: 241 | contact: "contact sensor" 242 | motion: "motion detector" 243 | smoke: "smoke detector" 244 | co: "carbon monoxide detector" 245 | water: "moisture detector" 246 | unused: "unused" 247 | default: unused 248 | - title: "Zone 14" 249 | name: zone14 250 | description: "Zone 14 Type" 251 | required: false 252 | preferenceType: enumeration 253 | definition: 254 | options: 255 | contact: "contact sensor" 256 | motion: "motion detector" 257 | smoke: "smoke detector" 258 | co: "carbon monoxide detector" 259 | water: "moisture detector" 260 | unused: "unused" 261 | default: unused 262 | - title: "Zone 15" 263 | name: zone15 264 | description: "Zone 15 Type" 265 | required: false 266 | preferenceType: enumeration 267 | definition: 268 | options: 269 | contact: "contact sensor" 270 | motion: "motion detector" 271 | smoke: "smoke detector" 272 | co: "carbon monoxide detector" 273 | water: "moisture detector" 274 | unused: "unused" 275 | default: unused 276 | - title: "Zone 16" 277 | name: zone16 278 | description: "Zone 16 Type" 279 | required: false 280 | preferenceType: enumeration 281 | definition: 282 | options: 283 | contact: "contact sensor" 284 | motion: "motion detector" 285 | smoke: "smoke detector" 286 | co: "carbon monoxide detector" 287 | water: "moisture detector" 288 | unused: "unused" 289 | default: unused 290 | - title: "Zone 17" 291 | name: zone17 292 | description: "Zone 17 Type" 293 | required: false 294 | preferenceType: enumeration 295 | definition: 296 | options: 297 | contact: "contact sensor" 298 | motion: "motion detector" 299 | smoke: "smoke detector" 300 | co: "carbon monoxide detector" 301 | water: "moisture detector" 302 | unused: "unused" 303 | default: unused 304 | - title: "Zone 18" 305 | name: zone18 306 | description: "Zone 18 Type" 307 | required: false 308 | preferenceType: enumeration 309 | definition: 310 | options: 311 | contact: "contact sensor" 312 | motion: "motion detector" 313 | smoke: "smoke detector" 314 | co: "carbon monoxide detector" 315 | water: "moisture detector" 316 | unused: "unused" 317 | default: unused 318 | - title: "Zone 19" 319 | name: zone19 320 | description: "Zone 19 Type" 321 | required: false 322 | preferenceType: enumeration 323 | definition: 324 | options: 325 | contact: "contact sensor" 326 | motion: "motion detector" 327 | smoke: "smoke detector" 328 | co: "carbon monoxide detector" 329 | water: "moisture detector" 330 | unused: "unused" 331 | default: unused 332 | - title: "Zone 20" 333 | name: zone20 334 | description: "Zone 20 Type" 335 | required: false 336 | preferenceType: enumeration 337 | definition: 338 | options: 339 | contact: "contact sensor" 340 | motion: "motion detector" 341 | smoke: "smoke detector" 342 | co: "carbon monoxide detector" 343 | water: "moisture detector" 344 | unused: "unused" 345 | default: unused 346 | - title: "Zone 21" 347 | name: zone21 348 | description: "Zone 21 Type" 349 | required: false 350 | preferenceType: enumeration 351 | definition: 352 | options: 353 | contact: "contact sensor" 354 | motion: "motion detector" 355 | smoke: "smoke detector" 356 | co: "carbon monoxide detector" 357 | water: "moisture detector" 358 | unused: "unused" 359 | default: unused 360 | - title: "Zone 22" 361 | name: zone22 362 | description: "Zone 22 Type" 363 | required: false 364 | preferenceType: enumeration 365 | definition: 366 | options: 367 | contact: "contact sensor" 368 | motion: "motion detector" 369 | smoke: "smoke detector" 370 | co: "carbon monoxide detector" 371 | water: "moisture detector" 372 | unused: "unused" 373 | default: unused 374 | - title: "Zone 23" 375 | name: zone23 376 | description: "Zone 23 Type" 377 | required: false 378 | preferenceType: enumeration 379 | definition: 380 | options: 381 | contact: "contact sensor" 382 | motion: "motion detector" 383 | smoke: "smoke detector" 384 | co: "carbon monoxide detector" 385 | water: "moisture detector" 386 | unused: "unused" 387 | default: unused 388 | - title: "Zone 24" 389 | name: zone24 390 | description: "Zone 24 Type" 391 | required: false 392 | preferenceType: enumeration 393 | definition: 394 | options: 395 | contact: "contact sensor" 396 | motion: "motion detector" 397 | smoke: "smoke detector" 398 | co: "carbon monoxide detector" 399 | water: "moisture detector" 400 | unused: "unused" 401 | default: unused 402 | - title: "Zone 25" 403 | name: zone25 404 | description: "Zone 25 Type" 405 | required: false 406 | preferenceType: enumeration 407 | definition: 408 | options: 409 | contact: "contact sensor" 410 | motion: "motion detector" 411 | smoke: "smoke detector" 412 | co: "carbon monoxide detector" 413 | water: "moisture detector" 414 | unused: "unused" 415 | default: unused 416 | - title: "Zone 26" 417 | name: zone26 418 | description: "Zone 26 Type" 419 | required: false 420 | preferenceType: enumeration 421 | definition: 422 | options: 423 | contact: "contact sensor" 424 | motion: "motion detector" 425 | smoke: "smoke detector" 426 | co: "carbon monoxide detector" 427 | water: "moisture detector" 428 | unused: "unused" 429 | default: unused 430 | - title: "Zone 27" 431 | name: zone27 432 | description: "Zone 27 Type" 433 | required: false 434 | preferenceType: enumeration 435 | definition: 436 | options: 437 | contact: "contact sensor" 438 | motion: "motion detector" 439 | smoke: "smoke detector" 440 | co: "carbon monoxide detector" 441 | water: "moisture detector" 442 | unused: "unused" 443 | default: unused 444 | - title: "Zone 28" 445 | name: zone28 446 | description: "Zone 28 Type" 447 | required: false 448 | preferenceType: enumeration 449 | definition: 450 | options: 451 | contact: "contact sensor" 452 | motion: "motion detector" 453 | smoke: "smoke detector" 454 | co: "carbon monoxide detector" 455 | water: "moisture detector" 456 | unused: "unused" 457 | default: unused 458 | - title: "Zone 29" 459 | name: zone29 460 | description: "Zone 29 Type" 461 | required: false 462 | preferenceType: enumeration 463 | definition: 464 | options: 465 | contact: "contact sensor" 466 | motion: "motion detector" 467 | smoke: "smoke detector" 468 | co: "carbon monoxide detector" 469 | water: "moisture detector" 470 | unused: "unused" 471 | default: unused 472 | - title: "Zone 30" 473 | name: zone30 474 | description: "Zone 30 Type" 475 | required: false 476 | preferenceType: enumeration 477 | definition: 478 | options: 479 | contact: "contact sensor" 480 | motion: "motion detector" 481 | smoke: "smoke detector" 482 | co: "carbon monoxide detector" 483 | water: "moisture detector" 484 | unused: "unused" 485 | default: unused 486 | - title: "Zone 31" 487 | name: zone31 488 | description: "Zone 31 Type" 489 | required: false 490 | preferenceType: enumeration 491 | definition: 492 | options: 493 | contact: "contact sensor" 494 | motion: "motion detector" 495 | smoke: "smoke detector" 496 | co: "carbon monoxide detector" 497 | water: "moisture detector" 498 | unused: "unused" 499 | default: unused 500 | - title: "Zone 32" 501 | name: zone32 502 | description: "Zone 32 Type" 503 | required: false 504 | preferenceType: enumeration 505 | definition: 506 | options: 507 | contact: "contact sensor" 508 | motion: "motion detector" 509 | smoke: "smoke detector" 510 | co: "carbon monoxide detector" 511 | water: "moisture detector" 512 | unused: "unused" 513 | default: unused 514 | - title: "Zone 33" 515 | name: zone33 516 | description: "Zone 33 Type" 517 | required: false 518 | preferenceType: enumeration 519 | definition: 520 | options: 521 | contact: "contact sensor" 522 | motion: "motion detector" 523 | smoke: "smoke detector" 524 | co: "carbon monoxide detector" 525 | water: "moisture detector" 526 | unused: "unused" 527 | default: unused 528 | - title: "Zone 34" 529 | name: zone34 530 | description: "Zone 34 Type" 531 | required: false 532 | preferenceType: enumeration 533 | definition: 534 | options: 535 | contact: "contact sensor" 536 | motion: "motion detector" 537 | smoke: "smoke detector" 538 | co: "carbon monoxide detector" 539 | water: "moisture detector" 540 | unused: "unused" 541 | default: unused 542 | - title: "Zone 35" 543 | name: zone35 544 | description: "Zone 35 Type" 545 | required: false 546 | preferenceType: enumeration 547 | definition: 548 | options: 549 | contact: "contact sensor" 550 | motion: "motion detector" 551 | smoke: "smoke detector" 552 | co: "carbon monoxide detector" 553 | water: "moisture detector" 554 | unused: "unused" 555 | default: unused 556 | - title: "Zone 36" 557 | name: zone36 558 | description: "Zone 36 Type" 559 | required: false 560 | preferenceType: enumeration 561 | definition: 562 | options: 563 | contact: "contact sensor" 564 | motion: "motion detector" 565 | smoke: "smoke detector" 566 | co: "carbon monoxide detector" 567 | water: "moisture detector" 568 | unused: "unused" 569 | default: unused 570 | - title: "Zone 37" 571 | name: zone37 572 | description: "Zone 37 Type" 573 | required: false 574 | preferenceType: enumeration 575 | definition: 576 | options: 577 | contact: "contact sensor" 578 | motion: "motion detector" 579 | smoke: "smoke detector" 580 | co: "carbon monoxide detector" 581 | water: "moisture detector" 582 | unused: "unused" 583 | default: unused 584 | - title: "Zone 38" 585 | name: zone38 586 | description: "Zone 38 Type" 587 | required: false 588 | preferenceType: enumeration 589 | definition: 590 | options: 591 | contact: "contact sensor" 592 | motion: "motion detector" 593 | smoke: "smoke detector" 594 | co: "carbon monoxide detector" 595 | water: "moisture detector" 596 | unused: "unused" 597 | default: unused 598 | - title: "Zone 39" 599 | name: zone39 600 | description: "Zone 39 Type" 601 | required: false 602 | preferenceType: enumeration 603 | definition: 604 | options: 605 | contact: "contact sensor" 606 | motion: "motion detector" 607 | smoke: "smoke detector" 608 | co: "carbon monoxide detector" 609 | water: "moisture detector" 610 | unused: "unused" 611 | default: unused 612 | - title: "Zone 40" 613 | name: zone40 614 | description: "Zone 40 Type" 615 | required: false 616 | preferenceType: enumeration 617 | definition: 618 | options: 619 | contact: "contact sensor" 620 | motion: "motion detector" 621 | smoke: "smoke detector" 622 | co: "carbon monoxide detector" 623 | water: "moisture detector" 624 | unused: "unused" 625 | default: unused 626 | - title: "Zone 41" 627 | name: zone41 628 | description: "Zone 41 Type" 629 | required: false 630 | preferenceType: enumeration 631 | definition: 632 | options: 633 | contact: "contact sensor" 634 | motion: "motion detector" 635 | smoke: "smoke detector" 636 | co: "carbon monoxide detector" 637 | water: "moisture detector" 638 | unused: "unused" 639 | default: unused 640 | - title: "Zone 42" 641 | name: zone42 642 | description: "Zone 42 Type" 643 | required: false 644 | preferenceType: enumeration 645 | definition: 646 | options: 647 | contact: "contact sensor" 648 | motion: "motion detector" 649 | smoke: "smoke detector" 650 | co: "carbon monoxide detector" 651 | water: "moisture detector" 652 | unused: "unused" 653 | default: unused 654 | - title: "Zone 43" 655 | name: zone43 656 | description: "Zone 43 Type" 657 | required: false 658 | preferenceType: enumeration 659 | definition: 660 | options: 661 | contact: "contact sensor" 662 | motion: "motion detector" 663 | smoke: "smoke detector" 664 | co: "carbon monoxide detector" 665 | water: "moisture detector" 666 | unused: "unused" 667 | default: unused 668 | - title: "Zone 44" 669 | name: zone44 670 | description: "Zone 44 Type" 671 | required: false 672 | preferenceType: enumeration 673 | definition: 674 | options: 675 | contact: "contact sensor" 676 | motion: "motion detector" 677 | smoke: "smoke detector" 678 | co: "carbon monoxide detector" 679 | water: "moisture detector" 680 | unused: "unused" 681 | default: unused 682 | - title: "Zone 45" 683 | name: zone45 684 | description: "Zone 45 Type" 685 | required: false 686 | preferenceType: enumeration 687 | definition: 688 | options: 689 | contact: "contact sensor" 690 | motion: "motion detector" 691 | smoke: "smoke detector" 692 | co: "carbon monoxide detector" 693 | water: "moisture detector" 694 | unused: "unused" 695 | default: unused 696 | - title: "Zone 46" 697 | name: zone46 698 | description: "Zone 46 Type" 699 | required: false 700 | preferenceType: enumeration 701 | definition: 702 | options: 703 | contact: "contact sensor" 704 | motion: "motion detector" 705 | smoke: "smoke detector" 706 | co: "carbon monoxide detector" 707 | water: "moisture detector" 708 | unused: "unused" 709 | default: unused 710 | - title: "Zone 47" 711 | name: zone47 712 | description: "Zone 47 Type" 713 | required: false 714 | preferenceType: enumeration 715 | definition: 716 | options: 717 | contact: "contact sensor" 718 | motion: "motion detector" 719 | smoke: "smoke detector" 720 | co: "carbon monoxide detector" 721 | water: "moisture detector" 722 | unused: "unused" 723 | default: unused 724 | - title: "Zone 48" 725 | name: zone48 726 | description: "Zone 48 Type" 727 | required: false 728 | preferenceType: enumeration 729 | definition: 730 | options: 731 | contact: "contact sensor" 732 | motion: "motion detector" 733 | smoke: "smoke detector" 734 | co: "carbon monoxide detector" 735 | water: "moisture detector" 736 | unused: "unused" 737 | default: unused 738 | - title: "Zone 49" 739 | name: zone49 740 | description: "Zone 49 Type" 741 | required: false 742 | preferenceType: enumeration 743 | definition: 744 | options: 745 | contact: "contact sensor" 746 | motion: "motion detector" 747 | smoke: "smoke detector" 748 | co: "carbon monoxide detector" 749 | water: "moisture detector" 750 | unused: "unused" 751 | default: unused 752 | - title: "Zone 50" 753 | name: zone50 754 | description: "Zone 50 Type" 755 | required: false 756 | preferenceType: enumeration 757 | definition: 758 | options: 759 | contact: "contact sensor" 760 | motion: "motion detector" 761 | smoke: "smoke detector" 762 | co: "carbon monoxide detector" 763 | water: "moisture detector" 764 | unused: "unused" 765 | default: unused 766 | - title: "Zone 51" 767 | name: zone51 768 | description: "Zone 51 Type" 769 | required: false 770 | preferenceType: enumeration 771 | definition: 772 | options: 773 | contact: "contact sensor" 774 | motion: "motion detector" 775 | smoke: "smoke detector" 776 | co: "carbon monoxide detector" 777 | water: "moisture detector" 778 | unused: "unused" 779 | default: unused 780 | - title: "Zone 52" 781 | name: zone52 782 | description: "Zone 52 Type" 783 | required: false 784 | preferenceType: enumeration 785 | definition: 786 | options: 787 | contact: "contact sensor" 788 | motion: "motion detector" 789 | smoke: "smoke detector" 790 | co: "carbon monoxide detector" 791 | water: "moisture detector" 792 | unused: "unused" 793 | default: unused 794 | - title: "Zone 53" 795 | name: zone53 796 | description: "Zone 53 Type" 797 | required: false 798 | preferenceType: enumeration 799 | definition: 800 | options: 801 | contact: "contact sensor" 802 | motion: "motion detector" 803 | smoke: "smoke detector" 804 | co: "carbon monoxide detector" 805 | water: "moisture detector" 806 | unused: "unused" 807 | default: unused 808 | - title: "Zone 54" 809 | name: zone54 810 | description: "Zone 54 Type" 811 | required: false 812 | preferenceType: enumeration 813 | definition: 814 | options: 815 | contact: "contact sensor" 816 | motion: "motion detector" 817 | smoke: "smoke detector" 818 | co: "carbon monoxide detector" 819 | water: "moisture detector" 820 | unused: "unused" 821 | default: unused 822 | - title: "Zone 55" 823 | name: zone55 824 | description: "Zone 55 Type" 825 | required: false 826 | preferenceType: enumeration 827 | definition: 828 | options: 829 | contact: "contact sensor" 830 | motion: "motion detector" 831 | smoke: "smoke detector" 832 | co: "carbon monoxide detector" 833 | water: "moisture detector" 834 | unused: "unused" 835 | default: unused 836 | - title: "Zone 56" 837 | name: zone56 838 | description: "Zone 56 Type" 839 | required: false 840 | preferenceType: enumeration 841 | definition: 842 | options: 843 | contact: "contact sensor" 844 | motion: "motion detector" 845 | smoke: "smoke detector" 846 | co: "carbon monoxide detector" 847 | water: "moisture detector" 848 | unused: "unused" 849 | default: unused 850 | - title: "Zone 57" 851 | name: zone57 852 | description: "Zone 57 Type" 853 | required: false 854 | preferenceType: enumeration 855 | definition: 856 | options: 857 | contact: "contact sensor" 858 | motion: "motion detector" 859 | smoke: "smoke detector" 860 | co: "carbon monoxide detector" 861 | water: "moisture detector" 862 | unused: "unused" 863 | default: unused 864 | - title: "Zone 58" 865 | name: zone58 866 | description: "Zone 58 Type" 867 | required: false 868 | preferenceType: enumeration 869 | definition: 870 | options: 871 | contact: "contact sensor" 872 | motion: "motion detector" 873 | smoke: "smoke detector" 874 | co: "carbon monoxide detector" 875 | water: "moisture detector" 876 | unused: "unused" 877 | default: unused 878 | - title: "Zone 59" 879 | name: zone59 880 | description: "Zone 59 Type" 881 | required: false 882 | preferenceType: enumeration 883 | definition: 884 | options: 885 | contact: "contact sensor" 886 | motion: "motion detector" 887 | smoke: "smoke detector" 888 | co: "carbon monoxide detector" 889 | water: "moisture detector" 890 | unused: "unused" 891 | default: unused 892 | - title: "Zone 60" 893 | name: zone60 894 | description: "Zone 60 Type" 895 | required: false 896 | preferenceType: enumeration 897 | definition: 898 | options: 899 | contact: "contact sensor" 900 | motion: "motion detector" 901 | smoke: "smoke detector" 902 | co: "carbon monoxide detector" 903 | water: "moisture detector" 904 | unused: "unused" 905 | default: unused 906 | - title: "Zone 61" 907 | name: zone61 908 | description: "Zone 61 Type" 909 | required: false 910 | preferenceType: enumeration 911 | definition: 912 | options: 913 | contact: "contact sensor" 914 | motion: "motion detector" 915 | smoke: "smoke detector" 916 | co: "carbon monoxide detector" 917 | water: "moisture detector" 918 | unused: "unused" 919 | default: unused 920 | - title: "Zone 62" 921 | name: zone62 922 | description: "Zone 62 Type" 923 | required: false 924 | preferenceType: enumeration 925 | definition: 926 | options: 927 | contact: "contact sensor" 928 | motion: "motion detector" 929 | smoke: "smoke detector" 930 | co: "carbon monoxide detector" 931 | water: "moisture detector" 932 | unused: "unused" 933 | default: unused 934 | - title: "Zone 63" 935 | name: zone63 936 | description: "Zone 63 Type" 937 | required: false 938 | preferenceType: enumeration 939 | definition: 940 | options: 941 | contact: "contact sensor" 942 | motion: "motion detector" 943 | smoke: "smoke detector" 944 | co: "carbon monoxide detector" 945 | water: "moisture detector" 946 | unused: "unused" 947 | default: unused 948 | - title: "Zone 64" 949 | name: zone64 950 | description: "Zone 64 Type" 951 | required: false 952 | preferenceType: enumeration 953 | definition: 954 | options: 955 | contact: "contact sensor" 956 | motion: "motion detector" 957 | smoke: "smoke detector" 958 | co: "carbon monoxide detector" 959 | water: "moisture detector" 960 | unused: "unused" 961 | default: unused 962 | -------------------------------------------------------------------------------- /hubpackagev3/profiles/dscsmokezone_v3.yaml: -------------------------------------------------------------------------------- 1 | name: DSC.smokezone.v3 2 | components: 3 | - id: main 4 | label: "Smoke Detector Zone" 5 | capabilities: 6 | - id: smokeDetector 7 | version: 1 8 | - id: partyvoice23922.smokestatus 9 | version: 1 10 | - id: partyvoice23922.zonebypass3a 11 | version: 1 12 | categories: 13 | - name: SmokeDetector 14 | metadata: 15 | vid: 3e701cca-d10d-33fc-815d-907f82287afe 16 | mnmn: fE4b 17 | 18 | -------------------------------------------------------------------------------- /hubpackagev3/profiles/dscwaterzone_v3.yaml: -------------------------------------------------------------------------------- 1 | name: DSC.waterzone.v3 2 | components: 3 | - id: main 4 | label: "Moisture Sensor Zone" 5 | capabilities: 6 | - id: waterSensor 7 | version: 1 8 | - id: partyvoice23922.waterstatus 9 | version: 1 10 | - id: partyvoice23922.zonebypass3a 11 | version: 1 12 | categories: 13 | - name: LeakSensor 14 | metadata: 15 | vid: d6441e30-a323-3797-88bf-26c2bf7f687f 16 | mnmn: fE4b 17 | 18 | -------------------------------------------------------------------------------- /hubpackagev3/src/common.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright 2023 Todd Austin 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | except in compliance with the License. You may obtain a copy of the License at: 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed under the 10 | License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 11 | either express or implied. See the License for the specific language governing permissions 12 | and limitations under the License. 13 | 14 | 15 | DESCRIPTION 16 | 17 | Samsung SmartThings Edge Driver for Envisalink - module for common routines 18 | 19 | --]] 20 | 21 | local function onoffline(status) 22 | 23 | local device_list = evlDriver:get_devices() 24 | 25 | for _, device in ipairs(device_list) do 26 | if status == 'online' then 27 | device:online() 28 | elseif status == 'offline' then 29 | device:offline() 30 | end 31 | end 32 | 33 | end 34 | 35 | 36 | return { 37 | onoffline = onoffline, 38 | } 39 | -------------------------------------------------------------------------------- /hubpackagev3/src/device_handler.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright 2021, 2022, 2023 Todd Austin 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | except in compliance with the License. You may obtain a copy of the License at: 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed under the 10 | License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 11 | either express or implied. See the License for the specific language governing permissions 12 | and limitations under the License. 13 | 14 | 15 | DESCRIPTION 16 | 17 | Samsung SmartThings Edge Driver for Envisalink - module to handle SmartThings device setup and state updates 18 | based on Envisalink messages 19 | 20 | --]] 21 | 22 | 23 | local capabilities = require "st.capabilities" 24 | local log = require "log" 25 | local cosock = require "cosock" -- cosock used only for sleep timer in this module 26 | local socket = require "cosock.socket" 27 | 28 | local evlClient = require "envisalink" 29 | 30 | -- Device capability profiles 31 | local profiles = { 32 | ["primarypanel"] = "DSC.primarypanel.v3d", 33 | ["secondarypanel"] = "DSC.secondarypanel.v3d", 34 | ["contact"] = "DSC.contactzone.v3", 35 | ["motion"] = "DSC.motionzone.v3", 36 | ["smoke"] = "DSC.smokezone.v3", 37 | ["co"] = "DSC.cozone.v3", 38 | ["water"] = "DSC.waterzone.v3", 39 | } 40 | 41 | -- Device metadata 42 | local MFG_NAME = 'Digital Security Controls' 43 | local PANEL_MODEL = 'DSC panel' 44 | local VEND_LABEL = 'PowerSeries' 45 | 46 | -- Module variables 47 | local ALARMMEMORY = {} 48 | local STpartitionstatus = {[1]='', [2]='', [3]='', [4]='', [5]='', [6]='', [7]='', [8]=''} 49 | 50 | 51 | local function emitSensorState(msg, sensorstate) 52 | 53 | local device_list = evlDriver:get_devices() 54 | for _, device in ipairs(device_list) do 55 | if device.device_network_id:match('^DSC:Z(%d+)') == msg.value then 56 | local zonetype = device.model:match('^DSC%-(%w+)') 57 | if zonetype == 'contact' then 58 | device:emit_event(capabilities.contactSensor.contact(sensorstate)) 59 | 60 | elseif zonetype == 'motion' then 61 | device:emit_event(capabilities.motionSensor.motion(sensorstate)) 62 | 63 | elseif zonetype == 'smoke' then 64 | device:emit_event(capabilities.smokeDetector.smoke(sensorstate)) 65 | 66 | elseif zonetype == 'co' then 67 | device:emit_event(capabilities.carbonMonoxideDetector.carbonMonoxide(sensorstate)) 68 | 69 | elseif zonetype == 'water' then 70 | device:emit_event(capabilities.waterSensor.water(sensorstate)) 71 | 72 | end 73 | end 74 | end 75 | end 76 | 77 | 78 | local function emitZoneStatus(msg, zonestatus) 79 | 80 | local device_list = evlDriver:get_devices() 81 | for _, device in ipairs(device_list) do 82 | if device.device_network_id:match('^DSC:Z(%d+)') == msg.value then 83 | local zonetype = device.model:match('^DSC%-(%w+)') 84 | if zonetype == 'contact' then 85 | device:emit_event(cap_contactstatus.contactStatus(zonestatus)) 86 | 87 | elseif zonetype == 'motion' then 88 | device:emit_event(cap_motionstatus.motionStatus(zonestatus)) 89 | 90 | elseif zonetype == 'smoke' then 91 | device:emit_event(cap_smokestatus.smokeStatus(zonestatus)) 92 | 93 | elseif zonetype == 'co' then 94 | device:emit_event(cap_costatus.coStatus(zonestatus)) 95 | 96 | elseif zonetype == 'water' then 97 | device:emit_event(cap_waterstatus.waterStatus(zonestatus)) 98 | 99 | end 100 | end 101 | end 102 | end 103 | 104 | 105 | local function proc_zone_msg(msg) 106 | 107 | local SENSORSTATE = { 108 | ['contact'] = { ['open'] = 'open', ['closed'] = 'closed' }, 109 | ['motion'] = { ['open'] = 'active', ['closed'] = 'inactive' }, 110 | ['smoke'] = { ['open'] = 'detected', ['closed'] = 'clear' }, 111 | ['co'] = { ['open'] = 'detected', ['closed'] = 'clear' }, 112 | ['water'] = { ['open'] = 'wet', ['closed'] = 'dry' }, 113 | } 114 | 115 | local ZONESTATUS = { 116 | ['contact'] = { ['open'] = 'Open', ['closed'] = 'Closed' }, 117 | ['motion'] = { ['open'] = 'Motion', ['closed'] = 'No motion' }, 118 | ['smoke'] = { ['open'] = 'Smoke detected', ['closed'] = 'Clear' }, 119 | ['co'] = { ['open'] = 'CO detected', ['closed'] = 'Clear' }, 120 | ['water'] = { ['open'] = 'Wet', ['closed'] = 'Dry' }, 121 | } 122 | 123 | local zonetype = conf.zones[tonumber(msg.value)].type 124 | 125 | log.debug (string.format('Processing zone update; zonetype= >>%s<<', zonetype)) 126 | 127 | if zonetype ~= nil then 128 | 129 | if (msg.status == 'open') or (msg.status == 'closed') or 130 | (msg.status == 'smoke') or (msg.status == 'clear') then 131 | 132 | local sensstate = SENSORSTATE[zonetype][msg.status] 133 | if sensstate == nil then; sensstate = msg.status; end 134 | 135 | emitSensorState(msg, sensstate) 136 | end 137 | 138 | if msg.status == 'alarm' then 139 | ALARMMEMORY[tonumber(msg.value)] = true 140 | emitZoneStatus(msg, 'ALARM!') 141 | end 142 | 143 | if not ALARMMEMORY[tonumber(msg.value)] then 144 | local zonestat = ZONESTATUS[zonetype][msg.status] 145 | if zonestat == nil then; zonestat = msg.status; end 146 | 147 | emitZoneStatus(msg, zonestat) 148 | end 149 | else 150 | log.warn (string.format('Zone %d device not configured', tonumber(msg.value))) 151 | end 152 | end 153 | 154 | 155 | local function proc_bypass_msg(msg) 156 | 157 | local bypass = msg.parameters 158 | local BYPASSSTATE = { 159 | ['on'] = 'Bypass is on', 160 | ['off'] = 'Bypass is off', 161 | } 162 | 163 | local device_list = evlDriver:get_devices() 164 | 165 | for _, device in ipairs(device_list) do 166 | local zonenum = device.device_network_id:match('^DSC:Z(%d+)') 167 | if zonenum then 168 | local bypassvalue = bypass[zonenum] 169 | if bypassvalue then 170 | device:emit_event(cap_zonebypass.mylabel(BYPASSSTATE[bypassvalue])) 171 | if bypassvalue == 'on' then 172 | device:emit_event(cap_zonebypass.zoneBypass('On', { visibility = { displayed = false } })) 173 | else 174 | device:emit_event(cap_zonebypass.zoneBypass('Off', { visibility = { displayed = false } })) 175 | end 176 | end 177 | end 178 | end 179 | 180 | end 181 | 182 | 183 | local function reset_bypass(partition) 184 | 185 | local device_list = evlDriver:get_devices() 186 | 187 | for _, device in ipairs(device_list) do 188 | local partnum = device.device_network_id:match('^DSC:Z%d+_(%d)') 189 | if partnum == partition then 190 | device:emit_event(cap_zonebypass.mylabel('Bypass is off')) 191 | device:emit_event(cap_zonebypass.zoneBypass('Off', { visibility = { displayed = false } })) 192 | end 193 | end 194 | 195 | end 196 | 197 | 198 | local function arm_reset(device) 199 | 200 | device:emit_event(cap_dscstayswitch.staySwitch('Off')) 201 | device:emit_event(capabilities.alarm.alarm('off')) 202 | device:emit_event(cap_dscawayswitch.awaySwitch('Off')) 203 | device:emit_event(cap_dscdashswitch.dashSwitch('Off')) 204 | 205 | end 206 | 207 | 208 | local function update_troublemsg(troubletext, options) 209 | 210 | local device_list = evlDriver:get_devices() 211 | for _, device in ipairs(device_list) do 212 | 213 | if device.device_network_id:find('DSC:P', 1) then 214 | device:emit_event(cap_trouble.troubleType(troubletext, options)) 215 | --if troubletext == ' ' then 216 | --device:emit_event(cap_partitionstatus.partStatus('Trouble restore')) 217 | --STpartitionstatus[tonumber(device.device_network_id:match('DSC:P(%d)'))] = 'Trouble restore' 218 | --end 219 | end 220 | end 221 | 222 | end 223 | 224 | 225 | local function proc_troublestate(msg) 226 | 227 | local troubletext 228 | local options = nil 229 | 230 | local trouble_text = { 231 | ['AC'] = 'AC Power Lost', 232 | ['battery'] = 'Battery', 233 | ['bell'] = 'Bell' 234 | } 235 | 236 | if msg.status:find('trouble_', 1) then 237 | troubletext = trouble_text[msg.status:match('trouble_(%w+)$')] 238 | elseif msg.status:find('restore_', 1) then 239 | troubletext = ' ' 240 | options = { visibility = { displayed = false } } 241 | end 242 | 243 | update_troublemsg(troubletext, options) 244 | 245 | end 246 | 247 | 248 | local function proc_verbosetrouble(device, msg) 249 | 250 | log.debug ('Current trouble type: ', device.state_cache.main[TROUBLETYPE_CAPNAME].troubleType.value) 251 | -- If Battery or Bell trouble type already set, then ignore verbose trouble (probably a 'Service Required') 252 | if (device.state_cache.main[TROUBLETYPE_CAPNAME].troubleType.value == 'Battery') or 253 | (device.state_cache.main[TROUBLETYPE_CAPNAME].troubleType.value == 'Bell') then 254 | return 255 | end 256 | 257 | local troubletext = '' 258 | local sep = '' 259 | local options = nil 260 | 261 | for vtrouble, state in pairs(msg.parameters) do 262 | 263 | if state == 'on' then 264 | troubletext = troubletext .. sep .. verboseTroubleText[vtrouble] 265 | sep = ', ' 266 | end 267 | end 268 | 269 | if troubletext == '' then 270 | troubletext = ' ' 271 | options = { visibility = { displayed = false } } 272 | end 273 | 274 | update_troublemsg(troubletext, options) 275 | 276 | end 277 | 278 | 279 | local function proc_partition_msg(msg) 280 | 281 | local device_list = evlDriver:get_devices() 282 | 283 | for _, device in ipairs(device_list) do 284 | 285 | if device.device_network_id:match('^DSC:P(%d+)') == msg.value then 286 | 287 | if msg.status then 288 | 289 | if msg.status == 'led' then 290 | 291 | local ledstat = msg.parameters 292 | local indicators = '' 293 | local options = nil 294 | 295 | if ledstat.fire == 'on' then 296 | indicators = indicators .. 'Fire*' 297 | end 298 | if ledstat.trouble == 'on' then 299 | indicators = indicators .. 'Trouble*' 300 | end 301 | if ledstat.memory == 'on' then 302 | indicators = indicators .. 'Memory*' 303 | end 304 | if ledstat.bypass == 'on' then 305 | indicators = indicators .. 'Bypass*' 306 | end 307 | 308 | if indicators:len() > 0 then 309 | indicators = indicators:sub(1,-2) 310 | else 311 | indicators = '-' 312 | options = { visibility = { displayed = false } } 313 | end 314 | 315 | -- these can change quickly, so to prevent rate limits, schedule in 1 second 316 | evlDriver:call_with_delay(1, function() 317 | device:emit_event(cap_ledstatus.ledStatus(indicators, options)) 318 | end) 319 | 320 | elseif msg.status:find('trouble_', 1) or msg.status:find('restore_', 1) then 321 | 322 | proc_troublestate(msg) 323 | 324 | elseif msg.status == 'verbosetrouble' then 325 | 326 | proc_verbosetrouble(device, msg) 327 | 328 | elseif msg.status == 'restoreled' then 329 | update_troublemsg(' ', { visibility = { displayed = false } }) 330 | 331 | elseif (msg.status ~= 'ledflash') and (msg.status ~= 'restoreled') and (msg.status ~= 'specialclose') then 332 | 333 | local DISPLAY = { 334 | ['ready'] = 'Ready', 335 | ['restore'] = 'Restore', 336 | ['notready'] = 'Not ready', 337 | ['cantarm'] = 'Not ready to arm', 338 | ['notarmed'] = 'Not armed', 339 | ['forceready'] = 'Ready', 340 | ['exitdelay'] = 'Exit delay', 341 | ['entrydelay'] = 'Entry delay', 342 | ['stay'] = 'Armed-stay', 343 | ['instantstay'] = 'Armed-stay (instant)', 344 | ['away'] = 'Armed-away', 345 | ['instantaway'] = 'Armed-away (instant)', 346 | ['armed'] = 'Armed', 347 | ['disarm'] = 'Disarmed', 348 | ['alarm'] = 'ALARM!!', 349 | ['chime'] = 'Chime on', 350 | ['nochime'] = 'Chime off', 351 | ['troubleled'] = 'Trouble', 352 | ['restoreled'] = 'Restore LED', 353 | ['specialclose'] = 'Special close', 354 | } 355 | 356 | local display_status = DISPLAY[msg.status] 357 | if display_status == nil then 358 | display_status = msg.status 359 | end 360 | 361 | local priorstatus = STpartitionstatus[tonumber(msg.value)] 362 | 363 | if display_status == 'Restore' then 364 | if priorstatus ~= 'Trouble' then 365 | display_status = priorstatus 366 | end 367 | end 368 | 369 | STpartitionstatus[tonumber(msg.value)] = display_status 370 | log.debug(string.format('Processing Partition #%s %s (%s): priorstatus=%s', msg.value, msg.status, display_status, priorstatus)) 371 | 372 | if (display_status == 'Ready') then 373 | if priorstatus ~= 'Ready' then 374 | device:emit_event(cap_partitionstatus.partStatus(display_status)) 375 | end 376 | 377 | if priorstatus == 'ALARM!!' then 378 | arm_reset(device) 379 | end 380 | 381 | elseif msg.status == 'stay' or msg.status == 'instantstay' then 382 | device:emit_event(cap_dscdashswitch.dashSwitch('On')) 383 | device:emit_event(cap_dscstayswitch.staySwitch('On')) 384 | device:emit_event(cap_partitionstatus.partStatus(display_status)) 385 | 386 | elseif msg.status == 'away' or msg.status == 'instantaway' then 387 | device:emit_event(cap_dscdashswitch.dashSwitch('On')) 388 | device:emit_event(cap_dscawayswitch.awaySwitch('On')) 389 | device:emit_event(cap_partitionstatus.partStatus(display_status)) 390 | 391 | elseif (msg.status == 'disarm') then 392 | arm_reset(device) 393 | device:emit_event(cap_partitionstatus.partStatus(display_status)) 394 | reset_bypass(msg.value) 395 | 396 | else 397 | if (msg.status ~= 'armed') then 398 | device:emit_event(cap_partitionstatus.partStatus(display_status)) 399 | if msg.status == 'cantarm' then 400 | arm_reset(device) 401 | elseif msg.status == 'alarm' then 402 | device:emit_event(capabilities.alarm.alarm('siren')) 403 | end 404 | end 405 | end 406 | 407 | -- Display username if available 408 | 409 | if (msg.status == 'userclose') or (msg.status == 'useropen') then 410 | device:emit_event(cap_username.username(msg.username)) 411 | end 412 | 413 | 414 | if msg.status == 'exitdelay' then 415 | 416 | -- Clear last username 417 | device:emit_event(cap_username.username(' ',{visibility={displayed=false}})) 418 | 419 | -- Reset any zones with alarm memory 420 | 421 | for zonenum, zone in ipairs(conf.zones) do 422 | if (zone.partition == tonumber(msg.value)) then 423 | if ALARMMEMORY[zonenum] == true then 424 | local _msg = { ['value'] = tostring(zonenum) } 425 | if (zone.type == 'contact') then 426 | emitZoneStatus(_msg, 'Closed') 427 | elseif (zone.type == 'motion') then 428 | emitZoneStatus(_msg, 'No motion') 429 | elseif (zone.type == 'smoke') or (zone.type == 'co') then 430 | emitZoneStatus(_msg, 'Clear') 431 | elseif (zone.type == 'water') then 432 | emitZoneStatus(_msg, 'Dry') 433 | end 434 | end 435 | 436 | ALARMMEMORY[zonenum] = false 437 | end 438 | end 439 | end 440 | 441 | end 442 | end 443 | break 444 | 445 | end 446 | end 447 | 448 | end 449 | 450 | local function codereq(msg) 451 | 452 | log.info('Sending access code') 453 | evlClient.send_command('200', conf.alarmcode) 454 | 455 | end 456 | 457 | 458 | local function process_message(msg) 459 | 460 | if msg.type == 'partition' then 461 | 462 | proc_partition_msg(msg) 463 | 464 | elseif msg.type == 'zone' then 465 | 466 | proc_zone_msg(msg) 467 | 468 | elseif msg.type == 'bypass' then 469 | 470 | proc_bypass_msg(msg) 471 | 472 | elseif msg.type == 'codereq' then 473 | 474 | codereq(msg) 475 | 476 | else 477 | 478 | log.error ('Unrecognized message - ignoring') 479 | 480 | end 481 | 482 | end 483 | 484 | 485 | local function createpanel(partnum) 486 | 487 | -- Create panel device 488 | 489 | local id = 'DSC:P' .. tostring(partnum) 490 | local devprofile 491 | local devlabel 492 | 493 | if partnum == 1 then 494 | devprofile = profiles['primarypanel'] 495 | conf.partitions[partnum] = 'DSC Primary Panel' 496 | devlabel = conf.partitions[partnum] 497 | else 498 | devprofile = profiles['secondarypanel'] 499 | devlabel = string.format('DSC P%d Panel', partnum) 500 | end 501 | 502 | local create_device_msg = { 503 | type = "LAN", 504 | device_network_id = id, 505 | label = devlabel, 506 | profile = devprofile, 507 | manufacturer = MFG_NAME, 508 | model = PANEL_MODEL, 509 | vendor_provided_label = VEND_LABEL, 510 | } 511 | 512 | log.info(string.format("Creating Partition #%d Panel (%s): '%s'", partnum, id, devlabel)) 513 | 514 | assert (evlDriver:try_create_device(create_device_msg), "failed to create panel device") 515 | 516 | end 517 | 518 | 519 | -- Process Settings changes for zone preferences 520 | local function proczonesetting(device, zonenum, oldztype, newztype, partnum) 521 | 522 | log.debug (string.format('Zone %d setting change from %s to %s', zonenum, oldztype, newztype)) 523 | 524 | local alreadyexists = false 525 | 526 | local device_list = evlDriver:get_devices() 527 | 528 | for _, device in ipairs(device_list) do 529 | 530 | if tonumber(device.device_network_id:match('^DSC:Z(%d+)')) == zonenum then 531 | alreadyexists = true 532 | break 533 | end 534 | end 535 | 536 | if alreadyexists then 537 | if newztype == 'unused' then 538 | conf.zones[zonenum].name = nil 539 | conf.zones[zonenum].type = nil 540 | conf.zones[zonenum].partition = nil 541 | log.warn (string.format('Zone %d disabled', zonenum)) 542 | else 543 | log.error ('Cannot change device type; user delete required') 544 | end 545 | -- can't change type of exisiting zone to anything but 'unused' 546 | 547 | -- It's a new zone device 548 | elseif newztype ~= 'unused' then 549 | 550 | -- Create zone device 551 | 552 | local id = 'DSC:Z' .. tostring(zonenum) .. '_' .. tostring(partnum) 553 | local name = string.format ('Partition %d Zone %d', partnum, zonenum) 554 | local devprofile = profiles[newztype] 555 | local create_device_msg = { 556 | type = "LAN", 557 | device_network_id = id, 558 | label = name, 559 | profile = devprofile, 560 | manufacturer = MFG_NAME, 561 | model = 'DSC-' .. newztype, 562 | vendor_provided_label = VEND_LABEL, 563 | } 564 | 565 | log.info(string.format("Creating %s device (%s); type=%s", name, id, newztype)) 566 | 567 | assert (evlDriver:try_create_device(create_device_msg), "failed to create zone device") 568 | end 569 | end 570 | 571 | 572 | local function onoffline(status) 573 | 574 | local device_list = evlDriver:get_devices() 575 | 576 | for _, device in ipairs(device_list) do 577 | 578 | if status == 'online' then 579 | device:online() 580 | 581 | elseif status == 'offline' then 582 | -- Note: Offline status will be displayed for partition 1 only 583 | if device.device_network_id:find('DSC:P', 1, 'plaintext') then 584 | device:emit_event(cap_partitionstatus.partStatus('Offline')) 585 | STpartitionstatus[1] = 'Offline' 586 | end 587 | device:offline() 588 | end 589 | end 590 | 591 | end 592 | 593 | 594 | return { 595 | createpanel = createpanel, 596 | proczonesetting = proczonesetting, 597 | process_message = process_message, 598 | onoffline = onoffline, 599 | } 600 | -------------------------------------------------------------------------------- /hubpackagev3/src/envisalink.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Copyright 2021, 2022, 2023 Todd Austin 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 | except in compliance with the License. You may obtain a copy of the License at: 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed under the 10 | License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 11 | either express or implied. See the License for the specific language governing permissions 12 | and limitations under the License. 13 | 14 | 15 | DESCRIPTION 16 | 17 | Samsung SmartThings Edge Driver for Envisalink - module to (1) handle incoming Envisalink messages, (2) create 18 | json tables & log messages based on them, and (3) send commands to Envisalink 19 | 20 | ** The Envisalink message-parsing code here is ported from the alarmserver Python package 21 | originally developed by donnyk+envisalink@gmail.com, which also included subsequent modifications/enhancements by 22 | leaberry@gmail.com, jordan@xeron.cc, and ralphtorchia1@gmail.com 23 | 24 | --]] 25 | 26 | 27 | local evl = require "envisalinkdefs" 28 | local log = require "log" 29 | 30 | local cosock = require "cosock" 31 | local socket = require "cosock.socket" 32 | 33 | -- Constants 34 | local MAXPARTITIONS = 4 35 | local MAXZONES = 16 36 | local MAXEVENTS = 10 37 | local MAXALLEVENTS = 100 38 | local MAXALARMUSERS = 10 39 | local TIMETOWAIT = 2 40 | 41 | -- Module variables 42 | local devhandler 43 | local clientsock 44 | local connected = false 45 | local loggedin = false 46 | local reconnect_timer 47 | 48 | 49 | local function getMessageType(code) 50 | return evl.ResponseTypes[code] 51 | end 52 | 53 | local function to_chars(instr) 54 | chars = {} 55 | for c in string.gmatch(instr, ".") do 56 | table.insert(chars, string.byte(c)) 57 | end 58 | return chars 59 | end 60 | 61 | local function get_checksum(code, data) 62 | local sum = 0 63 | 64 | for _, x in ipairs(to_chars(code)) do 65 | sum = sum + x 66 | end 67 | for _, x in ipairs(to_chars(data)) do 68 | sum = sum + x 69 | end 70 | 71 | return string.sub(string.format('%02X', sum), -2) 72 | end 73 | 74 | local msghandler -- forward reference to msghandler function 75 | 76 | local function connect() 77 | 78 | local listen_ip = "0.0.0.0" 79 | local listen_port = 0 80 | 81 | local client = assert(socket.tcp(), "create LAN socket") 82 | 83 | assert(client:bind(listen_ip, listen_port), "LAN socket setsockname") 84 | 85 | assert(client:setoption('keepalive', true)) 86 | 87 | local ret, msg = client:connect(conf.envisalink.ip, conf.envisalink.port) 88 | 89 | if ret == nil then 90 | log.error ('Could not connect to EnvisaLink:', msg) 91 | client:close() 92 | else 93 | client:settimeout(0) 94 | connected = true 95 | clientsock = client 96 | evlDriver:register_channel_handler(client, msghandler, 'LAN client handler') 97 | return client 98 | end 99 | end 100 | 101 | 102 | local function disconnect() 103 | 104 | connected = false 105 | loggedin = false 106 | 107 | if timers.reconnect then 108 | evlDriver:cancel_timer(timers.reconnect) 109 | end 110 | if timers.waitlogin then 111 | evlDriver:cancel_timer(timers.waitlogin) 112 | end 113 | timers.reconnect = nil 114 | socket.sleep(.1) 115 | timers.waitlogin = nil 116 | 117 | if clientsock then 118 | evlDriver:unregister_channel_handler(clientsock) 119 | clientsock:close() 120 | end 121 | devhandler.onoffline('offline') 122 | 123 | end 124 | 125 | 126 | local doreconnect -- Forward reference 127 | 128 | 129 | local function resetconnection() 130 | 131 | log.warn('Resetting connection') 132 | disconnect() 133 | 134 | timers.reconnect = evlDriver:call_with_delay(15, doreconnect, 'Re-connect timer') 135 | 136 | end 137 | 138 | -- This function invoked by delayed timer 139 | local function dowaitlogin() 140 | 141 | timers.waitlogin = nil 142 | if not loggedin then 143 | log.warn('Failed to log into Envisalink; connect retry in 15 seconds') 144 | resetconnection() 145 | end 146 | end 147 | 148 | -- This function invoked by delayed timer 149 | doreconnect = function() 150 | 151 | log.info ('Attempting to reconnect to EnvisaLink') 152 | timers.reconnect = nil 153 | local client = connect() 154 | 155 | if client then 156 | 157 | log.info ('Re-connected to Envisalink') 158 | devhandler.onoffline('online') 159 | 160 | timers.waitlogin = evlDriver:call_with_delay(3, dowaitlogin, 'Wait for Login') 161 | 162 | else 163 | timers.reconnect = evlDriver:call_with_delay(15, doreconnect, 'Re-connect timer') 164 | end 165 | end 166 | 167 | 168 | local function send_command(code, data, checksum, force) 169 | 170 | if loggedin or force then 171 | 172 | local to_send 173 | 174 | if checksum == nil then; checksum = true; end 175 | 176 | if checksum == true then 177 | to_send = code .. data .. get_checksum(code, data) .. '\r\n' 178 | else 179 | to_send = code .. data .. '\r\n' 180 | end 181 | 182 | log.debug ('TX > ' .. to_send) 183 | 184 | clientsock:send(to_send) 185 | 186 | else 187 | if not connected then 188 | log.warn ('Cannot send commands to Envisalink: not connected') 189 | else 190 | log.warn ('Cannot send commands to Envisalink: not logged in') 191 | end 192 | end 193 | 194 | end 195 | 196 | 197 | local function bin(x) 198 | local ret = '' 199 | while x ~= 1 and x ~= 0 do 200 | ret = tostring(x%2) .. ret 201 | x=math.modf(x/2) 202 | end 203 | ret = tostring(x) .. ret 204 | 205 | return string.format('%08d', ret) 206 | end 207 | 208 | 209 | local function ends_with(str, ending) 210 | 211 | return ending == "" or str:sub(-#ending) == ending 212 | 213 | end 214 | 215 | 216 | local function getusername(parameters) 217 | 218 | local usercode = tonumber(parameters:sub(2,5)) 219 | log.debug ('getusername: usercode=', usercode) 220 | if not usercode then 221 | return parameters:sub(2,5) 222 | 223 | else 224 | return conf.usernames[usercode] 225 | end 226 | 227 | end 228 | 229 | 230 | local function get_partition_device(partition) 231 | 232 | local device_list = evlDriver:get_devices() 233 | 234 | for _, device in ipairs(device_list) do 235 | if device.device_network_id:match('^DSC:P(%d)') == partition then 236 | return device 237 | end 238 | end 239 | 240 | end 241 | 242 | 243 | local function refresh_bypass(partition, delay) 244 | 245 | local partstr = tostring(partition) 246 | 247 | evlDriver:call_with_delay(delay, function() 248 | send_command('071', partstr .. '*1') 249 | evlDriver:call_with_delay(3, function() 250 | send_command('071', partstr .. '#') 251 | end) 252 | end) 253 | 254 | end 255 | 256 | 257 | local function refresh_all() 258 | 259 | send_command('001', '', true, true) 260 | 261 | evlDriver:call_with_delay(6, function() 262 | for partnum = 1, #conf.partitions do 263 | local partitiondevice = get_partition_device(tostring(partnum)) 264 | if (partitiondevice.state_cache.main[STAYSWITCH_CAPNAME].staySwitch.value == 'Off') and 265 | (partitiondevice.state_cache.main[AWAYSWITCH_CAPNAME].awaySwitch.value == 'Off') then 266 | refresh_bypass(partnum, partnum * 5) 267 | else 268 | log.info ('Bypass refresh skipped since system is armed') 269 | end 270 | end 271 | end) 272 | end 273 | 274 | 275 | local function build_event_table(code, parms, event, message) 276 | 277 | local update = {} 278 | local parameters = parms.modparms 279 | 280 | if evl.ResponseTypes[code] then 281 | 282 | if code == 620 then 283 | update = { 284 | ['type'] = 'partition', 285 | ['value'] = '1', 286 | ['status'] = 'duress' 287 | } 288 | elseif code == 616 then 289 | update = { 290 | ['type'] = 'bypass', 291 | ['status'] = 'bypass', 292 | ['parameters'] = {} 293 | } 294 | 295 | local index = 1 296 | local count = 9 297 | local binary = bin(tonumber(tostring(parameters:sub(index, index+1)),16)) 298 | 299 | for zone = 1, MAXZONES do 300 | if count < 2 then 301 | count = 9 302 | index = index + 2 303 | binary = bin(tonumber(tostring(parameters:sub(index, index+1)),16)) 304 | end 305 | 306 | count = count-1 307 | 308 | if conf.zones[zone] then 309 | if conf.zones[zone].name then 310 | local value 311 | if binary:sub(count,count) == '1' then 312 | value = 'on' 313 | else 314 | value = 'off' 315 | end 316 | update['parameters'][tostring(zone)] = value 317 | end 318 | end 319 | end 320 | 321 | elseif (code == 502) then 322 | if parameters == '024' then 323 | update = { 324 | ['type'] = 'partition', 325 | ['value'] = '1', 326 | ['status'] = 'cantarm' 327 | } 328 | elseif parameters == '023' then 329 | update = { 330 | ['type'] = 'partition', 331 | ['value'] = '1', 332 | ['status'] = 'notarmed' 333 | } 334 | end 335 | 336 | elseif (code == 510) or (code == 511) then 337 | 338 | local codeMap = { [510] = 'led', [511] = 'ledflash' } 339 | 340 | local ledMap = { 'backlight', 'fire', 'program', 'trouble', 'bypass', 'memory', 'armed', 'ready' } 341 | 342 | update = { 343 | ['type'] = 'partition', 344 | ['value'] = '1', 345 | ['status'] = codeMap[code], 346 | ['parameters'] = {} 347 | } 348 | 349 | local binary = bin(tonumber(tostring(parameters), 16)) 350 | 351 | for i = 1, 8 do 352 | local value 353 | if binary:sub(i,i) == '1' then 354 | value = 'on' 355 | else 356 | value = 'off' 357 | end 358 | update['parameters'][ledMap[i]] = value 359 | end 360 | 361 | elseif code == 849 then 362 | 363 | update = { 364 | ['type'] = 'partition', 365 | ['value'] = '1', 366 | ['status'] = 'verbosetrouble', 367 | ['parameters'] = {} 368 | } 369 | 370 | local binary = bin(tonumber(tostring(parameters), 16)) 371 | 372 | for i = 1, 8 do 373 | if binary:sub(i,i) == '1' then 374 | update['parameters'][verboseTroubleMap[i]] = 'on' 375 | else 376 | update['parameters'][verboseTroubleMap[i]] = 'off' 377 | end 378 | end 379 | 380 | elseif code == 900 then 381 | 382 | update = { 383 | ['type'] = 'codereq', 384 | ['status'] = 'codereq' 385 | } 386 | 387 | elseif event.type == 'system' then 388 | 389 | local codeMap = { 390 | [621] = 'keyfirealarm', 391 | [622] = 'keyfirerestore', 392 | [623] = 'keyauxalarm', 393 | [624] = 'keyauxrestore', 394 | [625] = 'keypanicalarm', 395 | [626] = 'keypanicsrestore', 396 | [800] = 'trouble_battery', 397 | [801] = 'restore_battery', 398 | [802] = 'trouble_AC', 399 | [803] = 'restore_AC', 400 | [806] = 'trouble_bell', 401 | [807] = 'restore_bell', 402 | } 403 | update = { 404 | ['type'] = 'partition', 405 | ['value'] = '1', 406 | ['status'] = codeMap[code] 407 | } 408 | if update.status == nil then 409 | update.status = 'systemnotice' 410 | end 411 | 412 | elseif event.type == 'partition' then 413 | 414 | local partnum = tonumber(parameters:sub(1,1)) 415 | 416 | if conf.partitions[partnum] then 417 | --if code == 655 then 418 | -- refresh_bypass(partnum, 2.5) -- this has proven to be unreliable 419 | --end 420 | 421 | local codeMap = { 422 | [650] = 'ready', 423 | [651] = 'notready', 424 | [653] = 'forceready', 425 | [654] = 'alarm', 426 | [655] = 'disarm', 427 | [656] = 'exitdelay', 428 | [657] = 'entrydelay', 429 | [663] = 'chime', 430 | [664] = 'nochime', 431 | [700] = 'userclose', 432 | [701] = 'specialclose', 433 | [702] = 'partialclose', 434 | [750] = 'useropen', 435 | [751] = 'specialopen', 436 | [840] = 'troubleled', 437 | [841] = 'restoreled' 438 | } 439 | update = { 440 | ['type'] = 'partition', 441 | ['name'] = conf.partitions[partnum], 442 | ['value'] = tostring(partnum) 443 | } 444 | 445 | if code == 652 then 446 | if ends_with(message,'Zero Entry Away') then 447 | update['status'] = 'instantaway' 448 | elseif ends_with(message,'Zero Entry Stay') then 449 | update['status'] = 'instantstay' 450 | elseif ends_with(message,'Away') then 451 | update['status'] = 'away' 452 | elseif ends_with(message,'Stay') then 453 | update['status'] = 'stay' 454 | else 455 | update['status'] = 'armed' 456 | end 457 | 458 | else 459 | update['status'] = codeMap[code] 460 | end 461 | 462 | if (code == 700) or (code == 750) then 463 | update['username'] = getusername(parms.allparms) 464 | log.debug('user open/close; username=', update.username) 465 | end 466 | 467 | else 468 | return -- not a configured partition 469 | end 470 | 471 | elseif event.type == 'zone' then 472 | 473 | local zonenum = tonumber(parameters) 474 | 475 | if conf.zones[zonenum] then 476 | if conf.zones[zonenum].name then 477 | 478 | local codeMap = { 479 | [601] = 'alarm', 480 | [602] = 'noalarm', 481 | [603] = 'tamper', 482 | [604] = 'restore', 483 | [605] = 'fault', 484 | [606] = 'restore', 485 | [609] = 'open', 486 | [610] = 'closed', 487 | [631] = 'smoke', 488 | [632] = 'clear' 489 | } 490 | 491 | update = { 492 | ['type'] = 'zone', 493 | ['name'] = conf.zones[zonenum].name, 494 | ['value'] = tostring(zonenum), 495 | ['status'] = codeMap[code] 496 | } 497 | else 498 | log.error (string.format('Zone name for zone %s not configured',zonenum)) 499 | return 500 | end 501 | else 502 | return --not a configured zone 503 | end 504 | else 505 | return --- unprocessed event 506 | end 507 | 508 | else 509 | log.error ('Unknown event code encountered') 510 | return 511 | end 512 | 513 | return update 514 | 515 | end 516 | 517 | 518 | -- Login to Envisalink; once successful, send Refresh request 519 | local function handle_login(code, parameters, event, message) 520 | 521 | if parameters == '3' then 522 | log.debug ('Received login password request; sending password') 523 | send_command('005', conf.envisalink.pass, true, true) 524 | elseif parameters == '1' then 525 | log.info('Successfully logged in to Envisalink; synching devices...') 526 | loggedin = true 527 | refresh_all() 528 | 529 | elseif parameters == '0' then 530 | log.error ('Envisalink login failed - incorrect password') 531 | return 532 | end 533 | end 534 | 535 | 536 | local function format_msg(event, parameters) 537 | 538 | if event.type then 539 | 540 | if event.type == 'partition' then 541 | 542 | local partition_num = tonumber(parameters:sub(1,1)) 543 | local partition_name 544 | if partition_num <= #conf.partitions then 545 | partition_name = conf.partitions[partition_num] 546 | else 547 | partition_name = tostring(partition_num) 548 | end 549 | 550 | if partition_name then 551 | local paramlen = tostring(parameters):len() 552 | 553 | if paramlen == 5 then 554 | 555 | return string.format(event.name, partition_name, getusername(parameters)) 556 | 557 | elseif paramlen == 2 then 558 | 559 | local armmode = evl.ArmModes[tonumber(parameters:sub(2,2))] 560 | return string.format(event.name, partition_name, armmode) 561 | 562 | elseif paramlen == 1 then 563 | return string.format(event.name, partition_name) 564 | else 565 | return string.format(event.name, partition_name, tonumber(parameters:sub(2))) 566 | end 567 | end 568 | 569 | elseif event.type == 'zone' then 570 | local zonenum = tonumber(parameters) 571 | if conf.zones[zonenum] then 572 | if conf.zones[zonenum].name then 573 | return string.format(event.name, conf.zones[zonenum].name) 574 | end 575 | end 576 | end 577 | end 578 | 579 | return string.format(event.name, tostring(parameters)) 580 | 581 | end 582 | 583 | 584 | local function prettyprint(eventtab) 585 | 586 | local buildstr='' 587 | 588 | if eventtab.type then 589 | 590 | if eventtab.type == 'partition' then 591 | 592 | if eventtab.name then 593 | if eventtab.status then 594 | buildstr = ' {type: partition, name: ' .. eventtab.name .. ', value: ' .. eventtab.value .. ', status: ' .. eventtab.status 595 | else 596 | buildstr = ' {type: partition, name: ' .. eventtab.name .. ', value: ' .. eventtab.value 597 | end 598 | else 599 | buildstr = ' {type: partition, value: ' .. eventtab.value .. ', status: ' .. eventtab.status 600 | end 601 | 602 | if (eventtab.status == 'led') or (eventtab.status == 'ledflash') then 603 | buildstr = buildstr .. '\n\tparameters: {backlight: ' .. eventtab.parameters.backlight .. ', fire: ' .. eventtab.parameters.fire .. ', program: ' .. eventtab.parameters.program .. ', trouble: ' .. eventtab.parameters.trouble .. ', bypass: ' .. eventtab.parameters.bypass .. ', memory: ' .. eventtab.parameters.memory .. ', armed: ' .. eventtab.parameters.armed .. ', ready: ' .. eventtab.parameters.ready .. '}}' 604 | else 605 | buildstr = buildstr .. '}' 606 | end 607 | 608 | elseif eventtab.type == 'zone' then 609 | 610 | buildstr = ' {type: zone, name: ' .. eventtab.name .. ', value: ' .. eventtab.value .. ', status: ' .. eventtab.status .. '}' 611 | 612 | elseif eventtab.type == 'bypass' then 613 | 614 | buildstr = ' {type: bypass, status: ' .. eventtab.status .. ',' 615 | buildstr = buildstr .. '\n\tparameters: {' 616 | 617 | local n = 1 618 | for x, y in pairs(eventtab.parameters) do 619 | for zone, state in pairs(eventtab.parameters) do 620 | if tonumber(zone) == n then 621 | buildstr = buildstr .. zone .. ': ' .. state .. ', ' 622 | break 623 | end 624 | end 625 | n = n + 1 626 | end 627 | buildstr = buildstr:sub(1, buildstr:len()-2) .. '}}' 628 | 629 | else 630 | for key, value in pairs(eventtab) do 631 | if type(value) ~= 'table' then 632 | buildstr = buildstr .. key .. ': ' .. value .. '\n' 633 | else 634 | buildstr = buildstr .. key .. ':\n' 635 | for key2, value2 in pairs(value) do 636 | buildstr = buildstr .. '\t' .. key2 .. ': ' .. value2 637 | end 638 | end 639 | end 640 | end 641 | end 642 | 643 | return buildstr 644 | 645 | end 646 | 647 | 648 | local function handle_line(input) 649 | 650 | if input then 651 | 652 | local code = tonumber(input:sub(1,3)) 653 | local parameters = input:sub(4,-3) 654 | local event = evl.ResponseTypes[code] 655 | local message = format_msg(event, parameters) 656 | 657 | log.info ('RX < ' .. tostring(code) .. ' - ' .. parameters .. ' - ' .. message) 658 | 659 | if code == 500 then 660 | if timers.pollreset then 661 | evlDriver:cancel_timer(timers.pollreset) 662 | timers.pollreset = nil 663 | end 664 | end 665 | 666 | local errcode 667 | if code == 502 then -- System error 668 | errcode = tonumber(input:sub(4,6)) 669 | print (' => ' .. message .. ' = ' .. evl.ErrorCodes[errcode]) 670 | end 671 | 672 | local modparms = parameters 673 | local handler = evl.ResponseTypes[code]['handler'] 674 | 675 | if handler then 676 | if handler == 'login' then 677 | handle_login(code, parameters, event, message) 678 | return 679 | else 680 | if handler == 'zone' then 681 | modparms = parameters:sub(2) 682 | elseif handler == 'partition' then 683 | modparms = parameters:sub(1,1) 684 | end 685 | end 686 | end 687 | 688 | local eventtable = build_event_table(code, {modparms=modparms, allparms=parameters}, event, message) 689 | 690 | if eventtable then 691 | --[[ 692 | log.debug ('==================================================') 693 | for key, value in pairs(eventtable) do 694 | if type(value) ~= 'table' then 695 | log.debug (key, value) 696 | else 697 | log.debug (key .. ':') 698 | for key2, value2 in pairs(value) do 699 | log.debug ('\t' .. key2, value2) 700 | end 701 | end 702 | end 703 | log.debug ('==================================================') 704 | --]] 705 | log.info (prettyprint(eventtable)) 706 | 707 | devhandler.process_message(eventtable) 708 | 709 | end 710 | end 711 | end 712 | 713 | 714 | local function reconnect() 715 | 716 | devhandler.onoffline('offline') 717 | 718 | if timers.reconnect then 719 | evlDriver:cancel_timer(timers.reconnect) 720 | timers.reconnect = nil 721 | end 722 | 723 | timers.reconnect = evlDriver:call_with_delay(15, doreconnect, 'Re-connect timer') 724 | 725 | end 726 | 727 | ------------------------------------------------------------------------ 728 | -- Channel Handler 729 | ------------------------------------------------------------------------ 730 | 731 | msghandler = function(_, sock) 732 | 733 | recvbuf, recverr = sock:receive('*l') 734 | 735 | if recverr ~= nil then 736 | log.debug ('Receive status =', recverr) 737 | end 738 | 739 | if (recverr ~= 'timeout') and recvbuf then 740 | log.debug ('RAW DATA RECEIVED: ' .. recvbuf) 741 | 742 | handle_line(recvbuf) 743 | 744 | elseif (recverr ~= 'timeout') and (recverr ~= nil) then 745 | log.error ('Socket Receive Error occured: ', recverr) 746 | 747 | if recverr == 'closed' then 748 | log.warn ('Envisalink has disconnected') 749 | disconnect() 750 | reconnect() 751 | 752 | end 753 | end 754 | end 755 | 756 | 757 | synch = function() 758 | 759 | send_command('001', '') 760 | 761 | end 762 | 763 | 764 | local function is_loggedin() 765 | 766 | return loggedin 767 | 768 | end 769 | 770 | local function is_connected() 771 | 772 | return connected 773 | 774 | end 775 | 776 | local function inithandler(dev_handler) 777 | 778 | devhandler = dev_handler 779 | 780 | end 781 | 782 | 783 | local function periodic_check() 784 | 785 | if connected then -- if we THINK we're connected, try pinging the Envisalink... 786 | send_command('000', '') 787 | -- This timer will be canceled when poll command acknowledgement is received 788 | timers.pollreset = evlDriver:call_with_delay(5, resetconnection) 789 | 790 | elseif timers.reconnect == nil then 791 | -- if for some reason we're no longer connected AND a re-connect timer isn't active, 792 | -- then reset the connection 793 | log.warn('Periodic check discovered Envisalink not connected') 794 | resetconnection() 795 | end 796 | 797 | end 798 | 799 | 800 | return { 801 | inithandler = inithandler, 802 | connect = connect, 803 | disconnect = disconnect, 804 | reconnect = reconnect, 805 | msghandler = msghandler, 806 | devicesetup = devicesetup, 807 | synch = synch, 808 | send_command = send_command, 809 | is_connected = is_connected, 810 | is_loggedin = is_loggedin, 811 | periodic_check = periodic_check, 812 | refresh_bypass = refresh_bypass, 813 | get_partition_device = get_partition_device, 814 | } 815 | 816 | -------------------------------------------------------------------------------- /hubpackagev3/src/envisalinkdefs.lua: -------------------------------------------------------------------------------- 1 | local Defaults = { 2 | ['zone'] = { 3 | ['open'] = false, 4 | ['fault'] = false, 5 | ['alarm'] = false, 6 | ['tamper'] = false 7 | }, 8 | ['partition'] = { 9 | ['ready'] = false, 10 | ['trouble'] = false, 11 | ['exit_delay'] = false, 12 | ['entry_delay'] = false, 13 | ['armed'] = false, 14 | ['armed_bypass'] = false, 15 | ['alarm'] = false, 16 | ['tamper'] = false, 17 | ['chime'] = false, 18 | ['trouble_led'] = false 19 | }, 20 | ['system'] = { 21 | ['fire_key_alarm'] = false, 22 | ['aux_key_alarm'] = false, 23 | ['panic_key_alarm'] = false, 24 | ['2wire_alarm'] = false, 25 | ['battery_trouble'] = false, 26 | ['ac_trouble'] = false, 27 | ['system_bell_trouble'] = false, 28 | ['system_tamper'] = false, 29 | ['fire_trouble'] = false 30 | } 31 | } 32 | 33 | 34 | local ArmModes = { [0] = 'Away', [1] = 'Stay', [2] = 'Zero Entry Away', [3] = 'Zero Entry Stay' } 35 | 36 | 37 | local ResponseTypes = { 38 | [500] = { ['name'] = 'Command Acknowledge', ['description'] = 'A command has been received successfully.' }, 39 | [501] = { ['name'] = 'Command Error', ['description'] = 'A command has been received with a bad checksum.' }, 40 | [502] = { ['name'] = 'System Error %s' , ['description'] = 'An error has been detected.' }, 41 | [505] = { ['name'] = 'Login Interaction' , ['description'] = 'Sent During Session Login Only.', ['handler'] = 'login' }, 42 | [510] = { ['name'] = 'Keypad Led State' , ['description'] = 'Output when the TPI has detected a change of state in the Partition 1 keypad LEDs.' }, 43 | [511] = { ['name'] = 'Keypad Led Flash State' , ['description'] = 'Output when the TPI has detected a change of state in the Partition 1 keypad LEDs as to whether to flash or not. Overrides 510. That is, if 511 says the PROGRAM LED is flashing, then it does not matter what 510 says.' }, 44 | [550] = { ['name'] = 'Time/Date Broadcast' , ['description'] = 'Outputs the current security system time.' }, 45 | [560] = { ['name'] = 'Ring Detected' , ['description'] = 'The Panel has detected a ring on the telephone line. Note: This command will only be issued if an ESCORT 5580xx module is present.' }, 46 | [561] = { ['name'] = 'Indoor Temperature Broadcast' , ['description'] = 'If an ESCORT 5580TC is installed, and at least one ENERSTAT thermostat, this command displays the interior temperature and the thermostat number.' }, 47 | [562] = { ['name'] = 'Outdoor Temperature Broadcast' , ['description'] = 'If an ESCORT 5580TC is installed, and at least one ENERSTAT thermostat, this command displays the exterior temperature and the thermostat number.' }, 48 | [601] = { ['type'] = 'zone' , ['name'] = 'Partition {0[0]} Zone {0[1]}{0[2]}{0[3]} Alarm', ['description'] = 'A zone has gone into alarm.', ['handler'] = 'zone', ['status'] = { ['alarm'] = true } }, 49 | [602] = { ['type'] = 'zone' , ['name'] = 'Partition {0[0]} Zone {0[1]}{0[2]}{0[3]} Alarm Restore' , ['description'] = 'A zone alarm has been restored.', ['handler'] = 'zone', ['status'] = { ['alarm'] = false } }, 50 | [603] = { ['type'] = 'zone' , ['name'] = 'Partition {0[0]} Zone {0[1]}{0[2]}{0[3]} Tamper' , ['description'] = 'A zone has a tamper condition.', ['handler'] = 'zone', ['status'] = { ['tamper'] = true } }, 51 | [604] = { ['type'] = 'zone' , ['name'] = 'Partition {0[0]} Zone {0[1]}{0[2]}{0[3]} Tamper Restore' , ['description'] = 'A zone tamper condition has been restored.', ['handler'] = 'zone', ['status'] = { ['tamper'] = false } }, 52 | [605] = { ['type'] = 'zone' , ['name'] = 'Zone %s Fault' , ['description'] = 'A zone has gone into alarm.', ['status'] = { ['fault'] = true } }, 53 | [606] = { ['type'] = 'zone' , ['name'] = 'Zone %s Fault Restore' , ['description'] = 'A zone fault condition has been restored.', ['status'] = { ['fault'] = false } }, 54 | [609] = { ['type'] = 'zone' , ['name'] = 'Zone %s Open' , ['description'] = 'General status of the zone.', ['status'] = { ['open'] = true } }, 55 | [610] = { ['type'] = 'zone' , ['name'] = 'Zone %s Restored' , ['description'] = 'General status of the zone.', ['status'] = { ['open'] = false } }, 56 | [615] = { ['name'] = 'Envisalink Zone Timer Dump' , ['description'] = "This command contains the raw zone timers used inside the Envisalink. The dump is a 256 character packed HEX string representing 64 UINT16 (little endian) zone timers. Zone timers count down from 0xFFFF (zone is open) to 0x0000 (zone is closed too long ago to remember). Each 'tick' of the zone time is actually 5 seconds so a zone timer of 0xFFFE means '5 seconds ago'. Remember, the zone timers are LITTLE ENDIAN so the above example would be transmitted as FEFF." }, 57 | [616] = { ['name'] = 'Bypassed Zones Bitfield Dump', ['description'] = "This command is issued upon leaving Zone Bypass programming (*1 on the keypad). It is a 16 character HEX string representing an 8 byte bitfield. This bitfield indicates which zones are currently in bypass. A '1' indicates the zone is in bypass. The lower 8 zones are in the first position of the bitfield. The developer can force this dump by using the keystring commands to enter and leave zone bypassing. i.e. '*1#'" }, 58 | [620] = { ['name'] = 'Duress Alarm', ['description'] = 'A duress code has been entered on a system keypad.' }, 59 | [621] = { ['type'] = 'system', ['name'] = '[F] Key Alarm', ['description'] = 'A Fire key alarm has been detected.', ['status'] = { ['fire_key_alarm'] = true } }, 60 | [622] = { ['type'] = 'system', ['name'] = '[F] Key Alarm', ['description'] = 'A Fire key alarm has been restored (sent automatically).', ['status'] = { ['fire_key_alarm'] = false } }, 61 | [623] = { ['type'] = 'system', ['name'] = '[A] Key Alarm', ['description'] = 'An Auxillary key alarm has been detected.', ['status'] = { ['aux_key_alarm'] = true} }, 62 | [624] = { ['type'] = 'system', ['name'] = '[A] Key Alarm', ['description'] = 'An Auxillary key alarm has been restored (sent automatically).', ['status'] = { ['aux_key_alarm'] = false } }, 63 | [625] = { ['type'] = 'system', ['name'] = '[P] Key Alarm', ['description'] = 'A Panic key alarm has been detected.', ['status'] = { ['panic_key_alarm'] = true } }, 64 | [626] = { ['type'] = 'system', ['name'] = '[P] Key Alarm', ['description'] = 'A Panic key alarm has been restored (sent automatically).', ['status'] = { ['panic_key_alarm'] = false } }, 65 | [631] = { ['type'] = 'system', ['name'] = '2-Wire Smoke/Aux Alarm', ['description'] = 'A 2-wire smoke/Auxiliary alarm has been activated.', ['status'] = { ['2wire_alarm'] = true } }, 66 | [632] = { ['type'] = 'system', ['name'] = '2-Wire Smoke/Aux Restore', ['description'] = 'A 2-wire smoke/Auxiliary alarm has been restored.', ['status'] = { ['2wire_alarm'] = false } }, 67 | [650] = { ['type'] = 'partition', ['name'] = 'Partition %s Ready', ['description'] = 'Partition can now be armed (all zones restored, no troubles, etc). Also issued at the end of Bell Timeout if the partition was READY when an alarm occurred.', ['status'] = { ['ready'] = true, ['pgm_output'] = false } }, 68 | [651] = { ['type'] = 'partition', ['name'] = 'Partition %s Not Ready', ['description'] = 'Partition cannot be armed (zones open, trouble present, etc).', ['status'] = { ['ready'] = false } }, 69 | [652] = { ['type'] = 'partition', ['name'] = 'Partition %s Armed Mode %s', ['description'] = 'Partition has been armed - sent at the end of exit delay Also sent after an alarm if the Bell Cutoff Timer expires Mode is appended to indicate whether the partition is armed AWAY, STAY, ZERO-ENTRY-AWAY, or ZERO-ENTRY-STAY.', ['handler'] = 'partition', ['status'] = { ['armed'] = true, ['exit_delay'] = false } }, 70 | [653] = { ['type'] = 'partition', ['name'] = 'Partition %s Ready - Force Arming Enabled', ['description'] = 'Partition can now be armed (all zones restored, no troubles, etc). Also issued at the end of Bell Timeout if the partition was READY when an alarm occurred.', ['status'] = { ['ready'] = true } }, 71 | [654] = { ['type'] = 'partition', ['name'] = 'Partition %s In Alarm', ['description'] = 'A partition is in alarm.', ['status'] = { ['alarm'] = true } }, 72 | [655] = { ['type'] = 'partition', ['name'] = 'Partition %s Disarmed', ['description'] = 'A partition has been disarmed.', ['status'] = { ['alarm'] = false, ['armed'] = false, ['exit_delay'] = false, ['entry_delay'] = false } }, 73 | [656] = { ['type'] = 'partition', ['name'] = 'Partition %s Exit Delay in Progress', ['description'] = 'A partition is in Exit Delay.', ['status'] = { ['exit_delay'] = true } }, 74 | [657] = { ['type'] = 'partition', ['name'] = 'Partition %s Entry Delay in Progress', ['description'] = 'A partition is in Entry Delay.', ['status'] = { ['entry_delay'] = true } }, 75 | [658] = { ['type'] = 'partition', ['name'] = 'Partition %s Keypad Lock-out', ['description'] = 'A partition is in Keypad Lockout due to too many failed user code attempts.'}, 76 | [659] = { ['type'] = 'partition', ['name'] = 'Partition %s Failed to Arm', ['description'] = 'An attempt to arm the partition has failed.'}, 77 | [660] = { ['type'] = 'partition', ['name'] = 'Partition %s PGM Output is in Progress', ['description'] = '*71, *72, *73, or *74 has been pressed.', ['status']= { ['pgm_output'] = true } }, 78 | [663] = { ['type'] = 'partition', ['name'] = 'Partition %s Chime Enabled', ['description'] = 'The door chime feature has been enabled.', ['status'] = { ['chime'] = true } }, 79 | [664] = { ['type'] = 'partition', ['name'] = 'Partition %s Chime Disabled', ['description'] = 'The door chime feature has been disabled.', ['status'] = { ['chime'] = false } }, 80 | [670] = { ['type'] = 'partition', ['name'] = 'Partition %s Invalid Access Code', ['description'] = 'Invalid Access Code.' }, 81 | [671] = { ['type'] = 'partition', ['name'] = 'Partition %s Function Not Available', ['description'] = 'A partition is in Entry delay.' }, 82 | [672] = { ['type'] = 'partition', ['name'] = 'Partition %s Failure to Arm', ['description'] = 'An attempt was made to arm the partition and it failed.' }, 83 | [673] = { ['type'] = 'partition', ['name'] = 'Partition %s is Busy', ['description'] = 'The partition is busy (another keypad is programming or an installer is programming).' }, 84 | [674] = { ['type'] = 'partition', ['name'] = 'Partition %s System Arming in Progress', ['description'] = 'This system is auto-arming and is in arm warning delay.' }, 85 | [680] = { ['name'] = 'System in installers mode', ['description'] = 'System has entered installers mode' }, 86 | [700] = { ['type'] = 'partition', ['name'] = 'Partition %s User %s Closing', ['description'] = 'A partition has been armed by a user - sent at the end of exit delay.', ['handler'] = 'partition', ['status'] = { ['armed'] = true, ['exit_delay'] = false } }, 87 | [701] = { ['type'] = 'partition', ['name'] = 'Partition %s Special Closing', ['description'] = 'A partition has been armed by one of the following methods= Quick Arm, Auto Arm, Keyswitch, DLS software, Wireless Key.', ['status'] = { ['armed'] = true, ['exit_delay'] = false } }, 88 | [702] = { ['type'] = 'partition', ['name'] = 'Partition %s Partial Closing', ['description'] = 'A partition has been armed but one or more zones have been bypassed.', ['status'] = { ['armed'] = true, ['exit_delay'] = false } }, 89 | [750] = { ['type'] = 'partition', ['name'] = 'Partition %s User %s Opening', ['description'] = 'A partition has been disarmed by a user.', ['handler'] = 'partition', ['status'] = { ['armed'] = false, ['entry_delay'] = false } }, 90 | [751] = { ['type'] = 'partition', ['name'] = 'Partition %s Special Opening', ['description'] = 'A partition has been disarmed by one of the following methods= Keyswitch, DLS software, Wireless Key.', ['status'] = { ['armed'] = false, ['entry_delay'] = false } }, 91 | [800] = { ['type'] = 'system', ['name'] = 'Panel Battery Trouble', ['description'] = 'The panel has a low battery.', ['status'] = { ['battery_trouble'] = true } }, 92 | [801] = { ['type'] = 'system', ['name'] = 'Panel Battery Trouble Restore', ['description'] = "The panel's low battery has been restored.", ['status'] = { ['battery_trouble'] = false } }, 93 | [802] = { ['type'] = 'system', ['name'] = 'Panel AC Trouble', ['description'] = 'AC power to the panel has been removed.', ['status'] = { ['ac_trouble'] = true } }, 94 | [803] = { ['type'] = 'system', ['name'] = 'Panel AC Restore', ['description'] = 'AC power to the panel has been restored.', ['status'] = { ['ac_trouble'] = false } }, 95 | [806] = { ['type'] = 'system', ['name'] = 'System Bell Trouble', ['description'] = 'An open circuit has been detected across the bell terminals.', ['status'] = { ['system_bell_trouble'] = true } }, 96 | [807] = { ['type'] = 'system', ['name'] = 'System Bell Trouble Restoral', ['description'] = 'The bell trouble has been restored.', ['status'] = { ['system_bell_trouble'] = false } }, 97 | [814] = { ['name'] = 'FTC Trouble', ['description'] = 'The panel has failed to communicate successfully to the monitoring.'}, 98 | [816] = { ['name'] = 'Buffer Near Full', ['description'] = "Sent when the panel's Event Buffer is 75% full from when it was last uploaded to DLS."}, 99 | [829] = { ['type'] = 'system', ['name'] = 'General System Tamper', ['description'] = 'A tamper has occurred with one of the following modules= Zone Expander, PC5132, PC5204, PC5208, PC5400, PC59XX, LINKS 2X50, PC5108L, PC5100, PC5200.', ['status'] = { ['system_tamper'] = true } }, 100 | [830] = { ['type'] = 'system', ['name'] = 'General System Tamper Restore', ['description'] = 'A general system Tamper has been restored.', ['status'] = { ['system_tamper'] = false } }, 101 | [840] = { ['type'] = 'partition', ['name'] = 'Partition %s Trouble LED ON', ['description'] = 'This command shows the general trouble status that the trouble LED on a keypad normally shows. When ON, it means there is a trouble on this partition. This command when the LED transitions from OFF, to ON.', ['status'] = { ['trouble'] = true } }, 102 | [841] = { ['type'] = 'partition', ['name'] = 'Partition %s Trouble LED OFF', ['description'] = 'This command shows the general trouble status that the trouble LED on a keypad normally shows. When the LED is OFF, this usually means there are no troubles present on this partition but certain modes will blank this LED even in the presence of a partition trouble. This command when the LED transitions from ON, to OFF.', ['status'] = { ['trouble'] = false } }, 103 | [842] = { ['type'] = 'system', ['name'] = 'Fire Trouble Alarm', ['description'] = 'Fire Trouble Alarm', ['status'] = { ['fire_trouble'] = true } }, 104 | [843] = { ['type'] = 'system', ['name'] = 'Fire Trouble Alarm Restore', ['description'] = 'Fire Trouble Alarm Restore', ['status'] = { ['fire_trouble'] = false } }, 105 | [849] = { ['name'] = 'Verbose Trouble Status', ['description'] = 'This command is issued when a trouble appears on the system and roughly every 5 minutes until the trouble is cleared. The two characters are a bitfield (similar to 510,511). The meaning of each bit is the same as what you see on an LED keypad (see the user manual).' }, 106 | [900] = { ['name'] = 'Code Required', ['description'] = 'This command will tell the API to enter an access code. Once entered, the 200 command will be sent to perform the required action. The code should be entered within the window time of the panel.' }, 107 | [912] = { ['name'] = 'Command Output Pressed', ['description'] = 'This command will tell the API to enter an access code. Once entered, the 200 command will be sent to perform the required action. The code should be entered within the window time of the panel.' }, 108 | [921] = { ['name'] = 'Master Code Required', ['description'] = 'This command will tell the API to enter a master access code. Once entered, the 200 command will be sent to perform the required action. The code should be entered within the window time of the panel.' }, 109 | [922] = { ['name'] = 'Installers Code Required', ['description'] = 'This command will tell the API to enter an installers access code. Once entered, the 200 command will be sent to perform the required action. The code should be entered within the window time of the panel.' }, 110 | } 111 | 112 | local ErrorCodes = { 113 | [0] = 'No Error', 114 | [1] = 'RS-232 Receive Buffer Overrun (a command is received while another is still being processed)', 115 | [2] = 'RS-232 Receive Buffer Overflow', 116 | [3] = 'RS-232 Transmit Buffer Overflow', 117 | [10] = 'Keybus Transmit Buffer Overrun', 118 | [11] = 'Keybus Transmit Time Timeout', 119 | [12] = 'Keybus Transmit Mode Timeout', 120 | [13] = 'Keybus Transmit Keystring Timeout', 121 | [14] = 'Keybus Not Functioning (the S5401D cannot communicate with the security system)', 122 | [15] = 'Keybus Busy (Attempting to Disarm or Arm with user code)', 123 | [16] = 'Keybus Busy – Lockout (The panel is currently in Keypad Lockout – too many disarm attempts)', 124 | [17] = 'Keybus Busy – Installers Mode (Panel is in installers mode, most functions are unavailable)', 125 | [18] = 'Keybus Busy – General Busy (The partition requested is busy)', 126 | [20] = 'API Command Syntax Error', 127 | [21] = 'API Command Partition Error (Requested Partition is out of bounds)', 128 | [22] = 'API Command Not Supported', 129 | [23] = 'API System Not Armed (sent in response to a disarm command)', 130 | [24] = 'API System Not Ready to Arm (system is either busy, or already armed)', 131 | [25] = 'API Command Invalid Length', 132 | [26] = 'API User Code not Required', 133 | [27] = 'API Invalid Characters in Command (no alpha characters are allowed except for checksum)' 134 | } 135 | 136 | return { 137 | Defaults = Defaults, 138 | ArmModes = ArmModes, 139 | ResponseTypes = ResponseTypes, 140 | ErrorCodes = ErrorCodes 141 | } 142 | --------------------------------------------------------------------------------