From e82d84d323bb78462a7992cf2e3b31ea80d5043f Mon Sep 17 00:00:00 2001 From: Maik Hofmann Date: Sun, 14 Feb 2021 13:15:41 +0100 Subject: [PATCH] simple script to send notification on your phone on open door --- .gitignore | 1 + .../tools/opendooralert/opendooralert.py | 59 ++++ .../pushnotifier/PushNotifier.py | 278 ++++++++++++++++++ .../opendooralert/pushnotifier/__init__.py | 2 + .../__pycache__/PushNotifier.cpython-37.pyc | Bin 0 -> 7444 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 257 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 843 bytes .../opendooralert/pushnotifier/exceptions.py | 9 + .../bussniffer/tools/opendooralert/readme.txt | 8 + .../bussniffer/tools/opendooralert/runme.sh | 1 + 10 files changed, 358 insertions(+) create mode 100644 Investigation/bussniffer/tools/opendooralert/opendooralert.py create mode 100644 Investigation/bussniffer/tools/opendooralert/pushnotifier/PushNotifier.py create mode 100644 Investigation/bussniffer/tools/opendooralert/pushnotifier/__init__.py create mode 100644 Investigation/bussniffer/tools/opendooralert/pushnotifier/__pycache__/PushNotifier.cpython-37.pyc create mode 100644 Investigation/bussniffer/tools/opendooralert/pushnotifier/__pycache__/__init__.cpython-37.pyc create mode 100644 Investigation/bussniffer/tools/opendooralert/pushnotifier/__pycache__/exceptions.cpython-37.pyc create mode 100644 Investigation/bussniffer/tools/opendooralert/pushnotifier/exceptions.py create mode 100644 Investigation/bussniffer/tools/opendooralert/readme.txt create mode 100644 Investigation/bussniffer/tools/opendooralert/runme.sh diff --git a/.gitignore b/.gitignore index 1b830d4..2462003 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ HCPBridge/.vscode +Investigation/bussniffer/tools/opendooralert/opendooralert.py.bak diff --git a/Investigation/bussniffer/tools/opendooralert/opendooralert.py b/Investigation/bussniffer/tools/opendooralert/opendooralert.py new file mode 100644 index 0000000..d5781d6 --- /dev/null +++ b/Investigation/bussniffer/tools/opendooralert/opendooralert.py @@ -0,0 +1,59 @@ +import requests +import time +from pushnotifier import PushNotifier as pn + +# replace with your device ip +url="http://192.168.178.35/status" + +#create account on https://pushnotifier.de/notifications +api_key = "add your api key" +username = 'add your username' +password = 'add your password' +package = 'add your package' + +alerttime = 15 # alle 15 Minuten +intervall = 5 # alle 5 Minuten + +openstarttime = -1; + +def sendAlert(message): + session = pn.PushNotifier(username, password, package, api_key) + session.send_text(message, silent=False, devices=session.get_all_devices()) + +def millis(): + return round(time.time() * 1000) + +def handleOpenDoor(): + global openstarttime + if openstarttime == -1: + openstarttime = millis() + + if openstarttime+ alerttime*60*1000 < millis(): + sendAlert('Deine Garage ist offen!') + openstarttime = millis() + +def handleCloseDoor(): + global openstarttime + if openstarttime > -1: + sendAlert('Deine Garage wurde geschlossen') + openstarttime = -1; + + +while True: + print("get status...") + try: + r = requests.get(url) + if r.status_code < 400: + status = r.json() + if status["valid"]: + if status["doorstate"] != 0x40: + handleOpenDoor() + else: + handleCloseDoor() + else: + print("Status is invalid") + else: + print("invalid response code "+ r.status_code) + except requests.exceptions.RequestException as e: + print("error: " + e) + time.sleep(intervall*60) \ No newline at end of file diff --git a/Investigation/bussniffer/tools/opendooralert/pushnotifier/PushNotifier.py b/Investigation/bussniffer/tools/opendooralert/pushnotifier/PushNotifier.py new file mode 100644 index 0000000..fa68f56 --- /dev/null +++ b/Investigation/bussniffer/tools/opendooralert/pushnotifier/PushNotifier.py @@ -0,0 +1,278 @@ +import requests +import json +import base64 +import uuid +from pushnotifier.exceptions import * + + +class PushNotifier: + + def __init__(self, username, password, package_name, api_key): + """ + Initialize a new PushNotifier object + + Args: + username (str): your username for https://pushnotifier.de + password (str): your password for https://pushnotifier.de + package_name (str): the package you want to send the messages to + api_key (str): your api key (https://pushnotifier.de/account/api) + """ + self.base_url = 'https://api.pushnotifier.de/v2' + self.login_url = self.base_url + '/user/login' + self.devices_url = self.base_url + '/devices' + self.refresh_url = self.base_url + '/user/refresh' + self.send_text_url = self.base_url + '/notifications/text' + self.send_image_url = self.base_url + '/notifications/image' + self.username = username + self.package_name = package_name + self.api_key = api_key + self.app_token = self.__get_app_token(password) + self.headers = {'X-AppToken': self.app_token} + + def login(self, password): + """ + Used to verify everything is working fine + + Args: + password (str): your password for https://pushnotifier.de + + Returns: + dict: basic information about your account + """ + + login_data = { + 'username': self.username, + 'password': password + } + r = requests.post(self.login_url, json=login_data, auth=( + self.package_name, self.api_key), headers=self.headers) + return r.json() + + def __get_app_token(self, password): + login_data = { + 'username': self.username, + 'password': password + } + + r = requests.post(self.login_url, data=login_data, auth=(self.package_name, self.api_key)) + + if r.status_code == 401: + raise UnauthorizedError + elif r.status_code == 403: + raise IncorrectCredentialsError + elif r.status_code == 404: + raise UserNotFoundError + app_token = json.loads(r.text)['app_token'] + return app_token + + def refresh_token(self): + """ + Used to refresh your app token + + Returns: + str: new app token + """ + r = requests.get(self.refresh_url, auth=( + self.package_name, self.api_key), headers=self.headers) + new_token = r.json()['app_token'] + self.app_token = new_token + return new_token + + def get_all_devices(self): + """ + Get all devices linked with your account + + Returns: + list: list with all devices linked with your account + + """ + r = requests.get(self.devices_url, auth=( + self.package_name, self.api_key), headers=self.headers) + devices = r.json() + devices_array = [] + for index, _ in enumerate(devices): + devices_array.append(devices[index]['id']) + return devices_array + + def send_text(self, text, devices=None, silent=False): + """ + Sends a text to all devices specified + + Args: + text (str): the text you want to send + devices (list): a list of all devices you want to send the text to + silent (bool): if False the message triggers a sound + + Returns: + int: error code or 200 if everything went fine + + Raises: + MalformedRequestError: the request is malformed, i.e. missing content + DeviceNotFoundError: a device couldn\'t be found + + """ + + if devices == None: + body = { + "devices": self.get_all_devices(), + "content": text, + "silent": silent + } + else: + body = { + "devices": devices, + "content": text, + "silent": silent + } + + r = requests.put(self.send_text_url, json=body, auth=( + self.package_name, self.api_key), headers=self.headers) + if r.status_code == 200: + return 200 + elif r.status_code == 400: + raise MalformedRequestError + elif r.status_code == 404: + raise DeviceNotFoundError + + def send_url(self, url, devices=None, silent=False): + """ + Sends a url to all devices specified + + Args: + url (str): the url you want to send + devices (list): a list of all devices you want to send the url to + silent (bool): if False the message triggers a sound + + Returns: + int: error code or 200 if everything went fine + + Raises: + MalformedRequestError: the request is malformed, i.e. missing content + DeviceNotFoundError: a device couldn\'t be found + + """ + if devices == None: + body = { + "devices": self.get_all_devices(), + "content": url, + "silent": silent + } + else: + body = { + "devices": devices, + "content": url, + "silent": silent + } + + r = requests.put(self.send_text_url, json=body, auth=( + self.package_name, self.api_key), headers=self.headers) + + if r.status_code == 200: + return 200 + elif r.status_code == 400: + raise MalformedRequestError + elif r.status_code == 404: + raise DeviceNotFoundError + + def send_notification(self, text, url, devices=None, silent=False): + """ + Sends a notification (text + url) to all devices specified + + Args: + text (str): the text you want to send + url (str): the url you want to send + devices (list): a list of all devices you want to send the notification to + silent (bool): if False the message triggers a sound + + Returns: + int: error code or 200 if everything went fine + + Raises: + MalformedRequestError: the request is malformed, i.e. missing content + DeviceNotFoundError: a device couldn\'t be found + + """ + if devices == None: + body = { + "devices": self.get_all_devices(), + "content": text, + "url": url, + "silent": silent + } + else: + body = { + "devices": devices, + "content": text, + "url": url, + "silent": silent + } + + r = requests.put(self.send_text_url, json=body, auth=( + self.package_name, self.api_key), headers=self.headers) + + if r.status_code == 200: + return 200 + elif r.status_code == 400: + raise MalformedRequestError + elif r.status_code == 404: + raise DeviceNotFoundError + + def send_image(self, image_path, devices=None, silent=False): + """ + Thanks to @Logxn (github/logxn) for this method + Sends an image to all devices specified + + Args: + image_path (str): the path to the image you want to send + devices (list): a list of all devices you want to send the image to + silent (bool): if False the message triggers a sound + + Returns: + int: error code or 200 if everything went fine + + Raises: + MalformedRequestError: the request is malformed, i.e. missing content + DeviceNotFoundError: a device couldn\'t be found + PayloadTooLargeError: your image is too big (> 5 MB) + UnsupportedMediaTypeError: you passed an invalid file type or the device(s) you tried to send this image to can\'t receive images + """ + with open(image_path, 'rb') as image_file: + encoded_bytes = base64.b64encode(image_file.read()) + + # encoded_image are base64 encoded bytes of the image_file bytes + # since json can't handle raw bytes we need to decode them into a base64 string + encoded_image = encoded_bytes.decode() + + # generate random file name + file_name = str(uuid.uuid4()) + + if devices == None: + body = { + "devices": self.get_all_devices(), + "content": encoded_image, + "filename": file_name, + "silent": silent + } + else: + body = { + "devices": devices, + "content": encoded_image, + "filename": file_name, + "silent": silent + } + + r = requests.put(self.send_image_url, json=body, auth=( + self.package_name, self.api_key), headers=self.headers) + + if r.status_code == 200: + return 200 + elif r.status_code == 400: + raise MalformedRequestError + elif r.status_code == 404: + raise DeviceNotFoundError + elif r.status_code == 413: + raise PayloadTooLargeError + elif r.status_code == 415: + raise UnsupportedMediaTypeError + else: + raise UnknownError diff --git a/Investigation/bussniffer/tools/opendooralert/pushnotifier/__init__.py b/Investigation/bussniffer/tools/opendooralert/pushnotifier/__init__.py new file mode 100644 index 0000000..07c1549 --- /dev/null +++ b/Investigation/bussniffer/tools/opendooralert/pushnotifier/__init__.py @@ -0,0 +1,2 @@ +__author__ = "Tom Gaimann | github.com/tomg404" +__version__ = "1.2.2" diff --git a/Investigation/bussniffer/tools/opendooralert/pushnotifier/__pycache__/PushNotifier.cpython-37.pyc b/Investigation/bussniffer/tools/opendooralert/pushnotifier/__pycache__/PushNotifier.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcdfa4c413cb65418bbbfbc6703ecb875986c81f GIT binary patch literal 7444 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 bPezZKwpil+F#U`-U}@iA2s)0b literal 0 HcmV?d00001 diff --git a/Investigation/bussniffer/tools/opendooralert/pushnotifier/__pycache__/__init__.cpython-37.pyc b/Investigation/bussniffer/tools/opendooralert/pushnotifier/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..27ae4815f9769d08c0f59e063a0db8620f36b1db GIT binary patch literal 257 zcmXw!O-chn5QTdt3X&MlFxzY<8UlidXcCOsBmvDPv=r@hXQp(zYv>=r;Dx->Y`ujm zJAx11S3eI5YSQm_S=8nH?D;;{@5At~BsRCv?leNOEtAPMk?A8FboSX3>1-}g3uCg+ ztVCahm%Jc7^rXx2`FMYPk&p7xa*(!N01{^S=fv^aF*yV#l$hnvz#3Mi!M4@4h%b4gj>;9601)WDCZ+IfO)Kh35 z!x4;nof3H;VmwqJ3?E#GOe>h^48bppwd1HlRae_}ARh2mGv5<9G>o$tavg$AQpCEs zAk+(v8O^Tjv+rQ$hOP{twVW+U8MwAXC^8f-DrUT35n?bA{47!?mFt{T$nfyA(_A%A zzDO**CbPOb+H~Vx)uEHKLEOvk0U(DPY3 zAQ^IQu}jZ0;p6=po~7rOKJk@s>6`wrXSJGQ%I!_h3N!;E`!Yl8(;~Q;A+IMIZHgOV YT(?-R8qX`yj%)Er9Prer{q@y<0asET9smFU literal 0 HcmV?d00001 diff --git a/Investigation/bussniffer/tools/opendooralert/pushnotifier/exceptions.py b/Investigation/bussniffer/tools/opendooralert/pushnotifier/exceptions.py new file mode 100644 index 0000000..b394ee5 --- /dev/null +++ b/Investigation/bussniffer/tools/opendooralert/pushnotifier/exceptions.py @@ -0,0 +1,9 @@ +MalformedRequestError = Exception('the request is malformed, i.e. missing content') +DeviceNotFoundError = Exception('a device couldn\'t be found') +UserNotFoundError = Exception('user couldn\'t be found (incorrect username/password)') +IncorrectCredentialsError = Exception('credentials are incorrect') +UnauthorizedError = Exception('package name or api key is incorrect') +PayloadTooLargeError = Exception('your image is too big (> 5 MB)') +UnsupportedMediaTypeError = Exception('you passed an invalid file type or the device(s) you tried to send this image to can\'t receive images') + +UnknownError = Exception('an unknown error occured! please contact the author of this module!') diff --git a/Investigation/bussniffer/tools/opendooralert/readme.txt b/Investigation/bussniffer/tools/opendooralert/readme.txt new file mode 100644 index 0000000..b73cac0 --- /dev/null +++ b/Investigation/bussniffer/tools/opendooralert/readme.txt @@ -0,0 +1,8 @@ +#start cron editor +crontab -e + +#and add the line: +@reboot /usr/bin/python3 /home/pi/OpenDoorAlert/opendooralert.py + +Save and close, and then run +update-rc.d cron defaults \ No newline at end of file diff --git a/Investigation/bussniffer/tools/opendooralert/runme.sh b/Investigation/bussniffer/tools/opendooralert/runme.sh new file mode 100644 index 0000000..ded5b34 --- /dev/null +++ b/Investigation/bussniffer/tools/opendooralert/runme.sh @@ -0,0 +1 @@ +nohup python3 opendooralert.py &