This repository has been archived on 2024-02-23. You can view files and clone it, but cannot push or open issues or pull requests.
memberPlumbing/events.py

100 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python3
from collections import defaultdict
from xml.etree import ElementTree as ET
import os
import re
import requests
from common import *
TARGET_IP = '172.18.51.11'
def getStrings():
"""Parses out the message strings from source."""
r = requests.get('https://' + TARGET_IP + '/html/en_EN/en_EN.js',
auth=requests.auth.HTTPDigestAuth(DOOR_USERNAME, DOOR_PASSWORD),
verify=False)
regex = re.compile(r'([0-9]+)="([^"]*)')
strings = [regex.search(s) for s in r.text.split(';')
if s.startswith('localeStrings.eventDetails')]
print({int(g.group(1)): g.group(2) for g in strings})
# hardcoded for less bandwidth usage
eventStrings = {
1022: 'Denied Access{6} Card Not Found {3}',
1023: 'Denied Access{6} Access PIN Not Found {3}',
2020: 'Granted Access{6} {2}',
2021: 'Granted Access{6} Extended Time {2}',
2024: 'Denied Access{6} Schedule {2}',
2029: 'Denied Access{6} Wrong PIN {2}',
2036: 'Denied Access{6} Card Expired {2}',
2042: 'Denied Access{6} PIN Lockout {2}',
2043: 'Denied Access{6} Unassigned Card {3}',
2044: 'Denied Access{6} Unassigned Access PIN {3}',
2046: 'Denied Access - PIN Expired {2}',
4051: 'REX Switch Alarm',
7020: 'Time Set to: {5}',
12031: 'Granted Access{6} Manual',
12032: 'Door Unlocked',
12033: 'Door Locked',
4034: 'Alarm Acknowledged',
4035: 'Door Locked-Scheduled',
4036: 'Door Unlocked-Scheduled',
4041: 'Door Forced Alarm',
4042: 'Door Held Alarm',
4043: 'Tamper Switch Alarm',
4044: 'AC Failure',
4045: 'Battery Failure',
}
def formatMessage(event):
att = defaultdict(str, event.attrib)
eventType = int(att["eventType"])
return att["timestamp"], eventStrings[eventType].format(
'ios-' + att['ioState'],
'status-' + att['commandStatus'],
att['forename'] + " " + att['surname'],
att['rawCardNumber'],
att['oldTime'],
att['newTime'],
" IN" if att['readerAddress'] == '0' else " OUT")
# get parameters for messages to get?
# honestly not really sure why this is required, their API is confusing
parXMLIn = ET.Element("VertXMessage")
ET.SubElement(parXMLIn, "hid:EventMessages", attrib={"action": "LR"})
parXMLOut = doXMLRequest(TARGET_IP, ET.tostring(parXMLIn))
root = None
if os.path.exists("log.xml"):
# read last log
tree = ET.ElementTree(None, "log.xml")
root = tree.getroot()
recordCount = int(parXMLOut[0].attrib["historyRecordMarker"]) - \
int(root[0][0].attrib["recordMarker"])
else:
# first run for this door
recordCount = 1000
print("Getting", recordCount, "records")
# get the actual messages
eventsXMLIn = ET.Element("VertXMessage")
ET.SubElement(eventsXMLIn, "hid:EventMessages",
attrib={"action": "LR",
"recordCount": str(recordCount),
"historyRecordMarker": parXMLOut[0].attrib["historyRecordMarker"],
"historyTimestamp": parXMLOut[0].attrib["historyTimestamp"]})
eventsXMLOut = doXMLRequest(TARGET_IP, ET.tostring(eventsXMLIn))
#TODO: handle modeRecords=true
for index, event in enumerate(eventsXMLOut[0]):
event.attrib["recordMarker"] = str(int(parXMLOut[0].attrib["historyRecordMarker"]) - index)
# print(formatMessage(event))
if root is None:
tree = ET.ElementTree(eventsXMLOut)
else:
for event in reversed(eventsXMLOut[0]):
root[0].insert(0, event)
tree.write("log.xml")