Skip to content

Commit

Permalink
#14 all working now
Browse files Browse the repository at this point in the history
  • Loading branch information
jimboca committed Aug 5, 2022
1 parent 45df9ee commit 41b62c7
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 65 deletions.
36 changes: 20 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,10 @@ By default only the area one, is added, change the areas configuraion if you hav
- The last user to access any keypad with a code. See "Syncing profile changes" section for more information.
- Chime Mode
- driver:GV2
- Unknown
- Silent
- Single Beep
- Constantly Beeping
- Single Beep while Constantly Beeping
- Single Chime
- Single Chime with Single Beep
- Single Chime with Constantly Beeping
- Single Chime with Single Beep and Constantly Beeping
- Off
- Chime
- Voice
- ChimeAndVoice
- Additional Trigger
- driver:GV10
- The ELK only sends a triggered zone when a violated zone actually triggers an alarm. If this option is True, which is the default, the Node server will also set Last Triggered Zone when an approriate zone is violated and the ELK is in an Alarm State.
Expand Down Expand Up @@ -235,6 +230,17 @@ There is a Keypad node for each keypad found and they are by default grouped und
- Last KeyPress
- The last key pressed on the keypad
- driver: GV3
- Last Key
- The last key pressed on the keypad
- driver: GV3
- Last Function Key
- The last function pressed on the keypad
- driver: GV4
- Includes: F1, F2, F3, F4, F5, F6, Astrick, and Chime

Commands:
- Query
- Chime, presses the chime button on the keypad

#### Zone Node

Expand Down Expand Up @@ -374,22 +380,20 @@ This can be adapated to your prefered notification method.
https://github.com/UniversalDevicesInc-PG3/udi-poly-ELK/issues

## Release Notes
- 3.4.0: 07/28/2022 - BETA
- 3.4.1: 08/04/2022 - BETA
- More documentation cleanup, still needs more.
- Added driver's to many Nodes, still more to go.
- Added driver's to many Nodes, still more to go
- When node is queried the values are passed to PG3 with force option so they always update ISY
- This helps set initial ISY driver values during query-all on restart
- This helps set initial ISY driver values during query-all on ISY restart
- Updates to work with latest elkm1_lib
- [Allow user to control Chime Mode](https://github.com/UniversalDevicesInc-PG3/udi-poly-ELK/issues/14)
- [ELM M1G System Trouble Status](https://github.com/UniversalDevicesInc-PG3/udi-poly-ELK/issues/78)
- See [ELK Controller](#ElkController) System Trouble Status
- [Add Remote Programming Status](https://github.com/UniversalDevicesInc-PG3/udi-poly-ELK/issues/80)
- See [ELK Controller](#ElkController) Remote Programming Status
- [Allow Elk NS to Recognize Keypad Presses](https://github.com/UniversalDevicesInc-PG3/udi-poly-ELK/issues)
- [Add ERROR driver to controller](https://github.com/UniversalDevicesInc-PG3/udi-poly-ELK/issues/62)
- See [ELK Controller](#ELKController) Node server errors
- []()
- []()
- []()
- []()
- 3.3.8: 07/25/2022
- Fixed to work with udi-interface 3.0.47
- Fixed longPoll/shortPoll not working properly
Expand Down
27 changes: 14 additions & 13 deletions nodes/Area.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ def start(self):
self.set_drivers(force=True)
self.reportDrivers()
# elkm1_lib uses zone numbers starting at zero.
# for zn in range(Max.ZONES.value):
# LOGGER.debug(f'{self.lpfx} index={zn} area={self.controller.elk.zones[zn].area} definition={self.controller.elk.zones[zn].definition}')
# # Add zones that are in my area, and are defined.
# if self.controller.elk.zones[zn].definition != ZoneType.DISABLED and self.controller.elk.zones[zn].area == self.elk.index:
# LOGGER.info(f"{self.lpfx} area {self.elk.index} {self.elk.name} node={self.name} adding zone node {zn} '{self.controller.elk.zones[zn].name}'")
# address = f'zone_{zn+1}'
# node = self.controller.add_node(address, ZoneNode(self.controller, self, address, self.controller.elk.zones[zn]))
# if node is not None:
# self._zone_nodes[zn] = node
for zn in range(Max.ZONES.value):
LOGGER.debug(f'{self.lpfx} index={zn} area={self.controller.elk.zones[zn].area} definition={self.controller.elk.zones[zn].definition}')
# Add zones that are in my area, and are defined.
if self.controller.elk.zones[zn].definition != ZoneType.DISABLED and self.controller.elk.zones[zn].area == self.elk.index:
LOGGER.info(f"{self.lpfx} area {self.elk.index} {self.elk.name} node={self.name} adding zone node {zn} '{self.controller.elk.zones[zn].name}'")
address = f'zone_{zn+1}'
node = self.controller.add_node(address, ZoneNode(self.controller, self, address, self.controller.elk.zones[zn]))
if node is not None:
self._zone_nodes[zn] = node
for n in range(Max.KEYPADS.value):
if self.controller.elk.keypads[n].area == self.elk.index:
LOGGER.info(f"{self.lpfx} area {self.elk.index} {self.elk.name} node={self.name} adding keypad node {n} '{self.controller.elk.keypads[n]}'")
Expand Down Expand Up @@ -85,7 +85,7 @@ def longPoll(self):
# Area:callback: area_1:Home: cs={'last_log': {'event': 1174, 'number': 1, 'index': 0, 'timestamp': '2021-02-06T14:47:00+00:00', 'user_number': 1}}
# user_number=1 was me
def callback(self, element, changeset):
LOGGER.warning(f'{self.lpfx} cs={changeset}')
LOGGER.info(f'{self.lpfx} cs={changeset}')
try:
for cs in changeset:
if cs == 'alarm_state':
Expand All @@ -100,8 +100,9 @@ def callback(self, element, changeset):
self.set_user(int(changeset[cs]['user_number']))
elif cs == 'chime_mode':
# chime_mode=('Chime', <ChimeMode.Chime: 1>)
# So pass element 1 which is the enum
self.set_chime_mode(changeset[cs])
# elk.chime_mode=('OFF', <ChimeMode.OFF: 0>)
LOGGER.debug(f"key={changeset[cs][0]} val={changeset[cs][1]}")
self.set_chime_mode(changeset[cs][1])
else:
LOGGER.warning(f'{self.lpfx} Unknown callback {cs}={changeset[cs]}')
except Exception as ex:
Expand Down Expand Up @@ -198,7 +199,7 @@ def set_arm_up_state(self,val=None,force=False):

def set_chime_mode(self,val=None,force=False):
LOGGER.warning(f'{self.lpfx} {val} elk.chime_mode={self.elk.chime_mode}')
self.set_driver('GV2', val, restore=False,default=self.elk.chime_mode,force=force)
self.set_driver('GV2', val, restore=False,default=self.elk.chime_mode[1],force=force)

def set_poll_voltages(self,val=None, force=False):
LOGGER.info(f'{self.lpfx} {val}')
Expand Down
71 changes: 46 additions & 25 deletions nodes/Keypad.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
'status': 'ST',
'user': 'GV1',
'temperature': 'GV2',
'keypress': 'GV3'
'keypress': 'GV3',
'function_key': 'GV4',
}

class KeypadNode(BaseNode):

def __init__(self, controller, parent, address, elk):
LOGGER.debug(f'KeypadNode:init: {elk}')
LOGGER.info(f'KeypadNode:init: {elk} index={elk.index}')
self.elk = elk
self.controller = controller
self.parent = parent
Expand All @@ -35,12 +36,14 @@ def __init__(self, controller, parent, address, elk):
DNAMES['user']: 25,
DNAMES['temperature']: self.controller.temperature_uom,
DNAMES['keypress']: 25,
DNAMES['function_key']:25,
}
self.drivers = [
# On/Off
{'driver': DNAMES['status'], 'value': 0, 'uom': self.uoms[DNAMES['status']]},
{'driver': DNAMES['user'], 'value': -1, 'uom': self.uoms[DNAMES['user']]}, # Last User
{'driver': DNAMES['keypress'], 'value': -1, 'uom': self.uoms[DNAMES['keypress']]}, # Last Keypress
{'driver': DNAMES['function_key'],'value': -1, 'uom': self.uoms[DNAMES['function_key']]}, # Last Function Key
]
LOGGER.debug(f'KeypadNode:init: name="{name}" uom={self.uoms}')
if self.has_temperature:
Expand All @@ -50,8 +53,8 @@ def __init__(self, controller, parent, address, elk):
super(KeypadNode, self).__init__(controller, parent.address, address, name)
controller.poly.subscribe(controller.poly.START, self.start, address)
except Exception as ex:
LOGGER.error(f'{self.lpfx}',exc_info=True)
self.inc_error(f"{self.lpfx} {ex}")
LOGGER.error('KeypadNode:init',exc_info=True)
self.inc_error(f"KeypadNode:init {ex}")

def start(self):
try:
Expand All @@ -60,42 +63,60 @@ def start(self):
self.set_drivers(force=True,reportCmd=False)
self.reportDrivers()
self.elk.add_callback(self.callback)
self.elk.get_chime_mode()
except Exception as ex:
LOGGER.error(f'{self.lpfx}',exc_info=True)
self.inc_error(f"{self.lpfx} {ex}")

# 2022-07-26 21:08:36,625 ELK-6095 udi_interface DEBUG Keypad:callback: keypad_2:Down Hall: changeset={'last_keypress': ('ELK', 21)}
def callback(self, obj, changeset):
LOGGER.info(f'{self.lpfx} changeset={changeset}')
# Catch this since it causes the ELK connection to crash
try:
LOGGER.debug(f'{self.lpfx} changeset={changeset}')
if 'last_user' in changeset:
self.set_user(int(changeset['last_user']) + 1)
self.area.set_keypad(self.elk.index + 1)
elif 'last_log' in changeset:
if 'user_number' in changesset['last_log']:
self.set_user(int(changeset['last_log']['user_number']) + 1)
for cs in changeset:
if cs == 'last_user':
self.set_user(int(changeset[cs]) + 1)
self.area.set_keypad(self.elk.index + 1)
elif 'last_keypress' in changeset:
# changeset={'last_keypress': ('ELK', 21)}
kp = changeset['last_keypress']
i = 0
while i < len(kp):
LOGGER.debug(f"key={kp[i]} val={kp[i+1]}")
self.set_key(kp[i+1])
i += 2
elif cs == 'last_log':
if 'user_number' in changesset[cs]:
self.set_user(int(changeset[cs]['user_number']) + 1)
self.area.set_keypad(self.elk.index + 1)
elif cs == 'last_keypress':
# changeset={'last_keypress': ('ELK', 21)}
kp = changeset[cs]
i = 0
while i < len(kp):
LOGGER.debug(f"key={kp[i]} val={kp[i+1]}")
self.set_key(kp[i+1])
i += 2
elif cs == 'last_function_key':
self.set_last_function_key(changeset[cs][1].value)
else:
LOGGER.warning(f'{self.lpfx} Unknown callback {cs}={changeset[cs]}')
except Exception as ex:
LOGGER.error(f'{self.lpfx}',exc_info=True)
self.inc_error(f"{self.lpfx} {ex}")

def set_drivers(self,force=False,reportCmd=True):
LOGGER.debug(f'{self.lpfx} force={force} reportCmd={reportCmd}')
self.elk.get_chime_mode()
# self.set_driver(DNAMES['status'],1,force=force)
# self.set_user(force=force)
# self.set_temperature(force=force)
# self.set_key(force=force)
# self.elk.get_chime_mode()
self.set_driver(DNAMES['status'],1,force=force)
self.set_user(force=force)
self.set_temperature(force=force)
self.set_key(force=force)
self.set_last_function_key(force=force)

def set_last_function_key(self,val=None,force=False):
LOGGER.debug(f'{self.lpfx} val={val} force={force}')
if val is None:
if hasattr(self.elk.last_function_key,'value'):
val = self.elk.last_function_key.value
else:
val = 0
if val == "*":
val = 7
elif val == "C":
val = 8
self.set_driver(DNAMES['function_key'],val,force=force)

def set_key(self,val=None,force=False):
LOGGER.debug(f'{self.lpfx} val={val} force={force}')
Expand Down
4 changes: 2 additions & 2 deletions nodes/Light.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def __init__(self, controller, address, elk):
super(LightNode, self).__init__(controller, controller.address, address, name)
controller.poly.subscribe(controller.poly.START, self.start, address)
except Exception as ex:
LOGGER.error(f'{self.lpfx}',exc_info=True)
self.inc_error(f"{self.lpfx} {ex}")
LOGGER.error('LightNode:init',exc_info=True)
self.inc_error(f"LightNode:init {ex}")

def start(self):
try:
Expand Down
4 changes: 2 additions & 2 deletions nodes/Output.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def __init__(self, controller, address, elk):
super(OutputNode, self).__init__(controller, controller.address, address, name)
controller.poly.subscribe(controller.poly.START, self.start, address)
except Exception as ex:
LOGGER.error(f'{self.lpfx}',exc_info=True)
self.inc_error(f"{self.lpfx} {ex}")
LOGGER.error('OutputNode:init:',exc_info=True)
self.inc_error(f"OutputNode:init: {ex}")

def start(self):
try:
Expand Down
4 changes: 2 additions & 2 deletions nodes/Task.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def __init__(self, controller, address, elk):
super(TaskNode, self).__init__(controller, controller.address, address, name)
controller.poly.subscribe(controller.poly.START, self.start, address)
except Exception as ex:
LOGGER.error(f'{self.lpfx}',exc_info=True)
self.inc_error(f"{self.lpfx} {ex}")
LOGGER.error('TaskNode:init:',exc_info=True)
self.inc_error(f"TaskNode:init {ex}")

def start(self):
try:
Expand Down
4 changes: 2 additions & 2 deletions nodes/ZoneOff.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ def __init__(self, controller, parent_address, address, name, physical_status, l
super(ZoneOffNode, self).__init__(controller, parent_address, address, name)
controller.poly.subscribe(controller.poly.START, self.start, address)
except Exception as ex:
LOGGER.error(f'{self.lpfx}',exc_info=True)
self.inc_error(f"{self.lpfx} {ex}")
LOGGER.error(f'ZoneOffNode:init',exc_info=True)
self.inc_error("ZoneOffNode:init: {ex}")

def start(self):
try:
Expand Down
3 changes: 3 additions & 0 deletions profile/editor/editors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
<editor id="keyp">
<range uom="25" subset="-2-0,11-28" nls="KEY"/>
</editor>
<editor id="fkey">
<range uom="25" subset="0,8" nls="FKEY"/>
</editor>
<editor id="sp_words">
<range uom="25" subset="1-472" nls="SPW"/>
</editor>
Expand Down
2 changes: 2 additions & 0 deletions profile/nodedef/nodedefs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@
<st id="ST" editor="bool" />
<st id="GV1" editor="I_LAST_USER" />
<st id="GV3" editor="keyp" />
<st id="GV4" editor="fkey" />
</sts>
<cmds>
<sends>
Expand All @@ -295,6 +296,7 @@
<st id="GV1" editor="I_LAST_USER" />
<st id="GV2" editor="I_TEMP" />
<st id="GV3" editor="keyp" />
<st id="GV4" editor="fkey" />
</sts>
<cmds>
<sends>
Expand Down
4 changes: 2 additions & 2 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"cloud": false,
"prem": true,
"discover": true,
"profile_version": "3.4.0k",
"profile_version": "3.4.1",
"customParams": {
"temperature_unit": "F",
"host": "",
Expand All @@ -24,7 +24,7 @@
{
"title": "ELK: A NodeServer for ISY and ELK Alarm Panel Integration",
"author": "JimBoCA",
"version": "3.4.0",
"version": "3.4.1",
"date": "November 12, 2021",
"source": "https://github.com/jimboca/udi-poly-elk/tree/pg3",
"license": "https://github.com/jimboca/udi-poly-elk/blob/pg3/LICENSE"
Expand Down
14 changes: 13 additions & 1 deletion template/en_us.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ KEY-26: F6
KEY-27: F5
KEY-28: Data Key Mode

FKEY-0: None
FKEY-1: F1
FKEY-2: F2
FKEY-3: F3
FKEY-4: F4
FKEY-5: F5
FKEY-6: F6
FKEY-7: Astrick
FKEY-8: Chime

# Debug/Logger Modes
CDM-9 = Debug + elkm1_lib
CDM-10 = Debug
Expand Down Expand Up @@ -143,7 +153,8 @@ ND-keypad-ICON = Arm
ST-keypad-ST-NAME = Keypad Status
ST-keypad-GV1-NAME = Last User
ST-keypad-GV2-NAME = Temperature
ST-keypad-GV3-NAME = Last Keypress
ST-keypad-GV3-NAME = Last Key
ST-keypad-GV4-NAME = Last Function Key
CMD-keypad-KEY_CHIME-NAME = Chime

# keypad
Expand All @@ -153,6 +164,7 @@ ST-keypadT-ST-NAME = Keypad Status
ST-keypadT-GV1-NAME = Last User
ST-keypadT-GV2-NAME = Temperature
ST-keypadT-GV3-NAME = Last Keypress
ST-keypadT-GV4-NAME = Last Function Key
CMD-keypadT-KEY_CHIME-NAME = Chime

# area
Expand Down

0 comments on commit 41b62c7

Please sign in to comment.