-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from kaulketh/develop
Develop
- Loading branch information
Showing
15 changed files
with
333 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,9 @@ | ||
# RingPi-Bot | ||
# RingPi-Bot | ||
|
||
When the doorbell rings, a message is sent to a private Telegram chat group. | ||
|
||
Based on RaspBerryPi Zero and switching a GPIO via optocoupler through 12VAC | ||
from the doorbell, see [wiring.png](hardware/wiring.png) | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# __init__.py | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
from .ring_bot import * | ||
from .singleton import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# bot | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
import os | ||
import signal | ||
import time | ||
from multiprocessing import Process | ||
|
||
import telepot | ||
from telepot.loop import MessageLoop | ||
|
||
from bot import singleton | ||
from config import RING_BOT_TOKEN, RING_BOT_NAME, RING_RING_GROUP, \ | ||
THK # no public deployment (secret.py) | ||
from config import switch_state, DING_DONG, WELCOME, RUNNING, STOPPED, \ | ||
UNKNOWN_CMD, UNKNOWN_TYPE, CMD_START, CMD_STOP, CMD_REBOOT, REBOOT, \ | ||
START, STARTED, STOPPING | ||
from logger import LOGGER | ||
|
||
|
||
class RingBot(singleton.Singleton): | ||
""" Bot class using telepot framework | ||
(https://telepot.readthedocs.io), | ||
Python >= 3 | ||
""" | ||
|
||
def __init__(self, token, admin): | ||
self.__log = LOGGER | ||
self.__log.debug(f"Initialize instance of {self.__class__.__name__}") | ||
self.__token = token | ||
self.__admin = admin | ||
self.__bot = telepot.Bot(self.__token) | ||
self.__ding_dong = DING_DONG.format(RING_BOT_NAME) | ||
self.__receiver = RING_RING_GROUP | ||
self.__checker = None | ||
|
||
def __check_bell(self, timeout=.25): | ||
while True: | ||
if switch_state(): | ||
self.__log.info(switch_state()) | ||
self.__send(self.__receiver, self.__ding_dong) | ||
time.sleep(timeout) | ||
|
||
def __send(self, chat_id, text): | ||
self.__log.debug( | ||
f"Message posted: " | ||
f"{chat_id}|{text}".replace("\n", " ")) | ||
self.__bot.sendMessage(chat_id, text) | ||
|
||
def __handle(self, msg): | ||
content_type, chat_type, chat_id = telepot.glance(msg) | ||
self.__log.debug(msg) | ||
# check user | ||
if chat_id != self.__admin: | ||
# TODO: wrong id | ||
pass | ||
return | ||
# check content | ||
if content_type == 'text': | ||
command = msg['text'] | ||
self.__log.info(f"Got command '{command}'") | ||
# commands | ||
# start | ||
if command == CMD_START: | ||
if self.__checker is None: | ||
self.__checker = Process(target=self.__check_bell) | ||
self.__checker.start() | ||
self.__send(self.__admin, STARTED) | ||
self.__send(self.__admin, RUNNING) | ||
# stop | ||
elif command == CMD_STOP: | ||
if isinstance(self.__checker, Process): | ||
self.__checker.terminate() | ||
self.__checker = None | ||
self.__send(self.__admin, STOPPING) | ||
self.__send(self.__admin, STOPPED) | ||
elif command == CMD_REBOOT: | ||
self.__send(self.__admin, REBOOT.format(RING_BOT_NAME)) | ||
os.system("sudo reboot") | ||
else: | ||
self.__send(self.__admin, UNKNOWN_CMD) | ||
else: | ||
self.__send(self.__admin, UNKNOWN_TYPE) | ||
|
||
def start(self): | ||
try: | ||
MessageLoop(self.__bot, | ||
{'chat': self.__handle}).run_as_thread() | ||
self.__log.info(START) | ||
self.__send(self.__admin, WELCOME.format(RING_BOT_NAME)) | ||
while True: | ||
try: | ||
signal.pause() | ||
except KeyboardInterrupt: | ||
self.__log.warning('Program interrupted') | ||
exit() | ||
except Exception as e: | ||
self.__log.error(f"An error occurred: {e}") | ||
exit() | ||
|
||
|
||
def run(): | ||
RingBot(RING_BOT_TOKEN, THK).start() | ||
|
||
|
||
if __name__ == '__main__': | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# singleton | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
class _Singleton(type): | ||
""" A metaclass that creates a Singleton base class when called. """ | ||
_instances = {} | ||
|
||
def __call__(cls, *args, **kwargs): | ||
if cls not in cls._instances: | ||
cls._instances[cls] = super(_Singleton, cls).__call__(*args, | ||
**kwargs) | ||
return cls._instances[cls] | ||
|
||
|
||
class Singleton(_Singleton('SingletonMeta', (object,), {})): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# __init__.py | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
from .constants import * | ||
from .gpio import * | ||
from .secret import * # no public deployment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# constants | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
CHECK_NAME = "Klingel-Überwachung" | ||
|
||
CMD_START = "/start" | ||
CMD_STOP = "/stop" | ||
CMD_REBOOT = "/reboot" | ||
|
||
UNKNOWN_CMD = "UNKNOWN COMMAND!" | ||
UNKNOWN_TYPE = "UNKNOWN CONTENT TYPE!" | ||
|
||
REBOOT = "{} wird neu gestarte!" | ||
START = "Bot is running..." | ||
WELCOME = "{} einsatzbereit!\n Starten mit '/start'!" | ||
|
||
STARTED = f"{CHECK_NAME} gestartet." | ||
RUNNING = f"{CHECK_NAME} läuft..." | ||
STOPPING = f"{CHECK_NAME} wird angehalten." | ||
STOPPED = f"{CHECK_NAME} gestoppt!" | ||
|
||
DING_DONG = "{}\n\n\U0001F514 DING DONG \U0001F514\nEs hat an der Tür " \ | ||
"geklingelt\U00002755" | ||
|
||
# CMD_LIST_BOT_FATHER = | ||
# start - Start Klingel-Check | ||
# stop - Stop Klingel-Check | ||
# reboot - Reboot Thk1220RingBot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# gpio | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
import RPi.GPIO as GPIO | ||
|
||
PIN = 23 | ||
GPIO.setmode(GPIO.BCM) | ||
GPIO.setup(PIN, GPIO.IN) | ||
|
||
|
||
def switch_state(): | ||
return False if GPIO.input(PIN) == 0 else True | ||
|
||
|
||
if __name__ == '__main__': | ||
pass |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# __init__.py | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
from .logger import get_logger | ||
|
||
LOGGER = get_logger() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[loggers] | ||
keys = root | ||
|
||
[handlers] | ||
keys = consoleHandler | ||
|
||
[formatters] | ||
keys = sampleFormatter | ||
|
||
[logger_root] | ||
level = DEBUG | ||
handlers = consoleHandler | ||
|
||
[handler_consoleHandler] | ||
class = StreamHandler | ||
level = DEBUG | ||
formatter = sampleFormatter | ||
args = (sys.stdout,) | ||
|
||
[formatter_sampleFormatter] | ||
format = %(asctime)s %(levelname)-7s %(module)s.%(funcName)s (linenr.%(lineno)s) %(message)s | ||
datefmt = %Y-%m-%d %H:%M:%S |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# logger | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
import errno | ||
import logging | ||
import os | ||
from logging.config import fileConfig | ||
|
||
# runtime location | ||
this_folder = os.path.dirname(os.path.abspath(__file__)) | ||
# define log folder related to location | ||
log_folder = os.path.join(this_folder, '../logs') | ||
|
||
# define ini and log files | ||
ini_file = 'debug.ini' | ||
info_log_file = log_folder + '/info.log' | ||
error_log_file = log_folder + '/error.log' | ||
|
||
# check if exists or create log folder | ||
try: | ||
os.makedirs(log_folder, exist_ok=True) # Python>3.2 | ||
except TypeError: | ||
try: | ||
os.makedirs(log_folder) | ||
except OSError as exc: # Python >2.5 | ||
if exc.errno == errno.EEXIST and os.path.isdir(log_folder): | ||
pass | ||
else: | ||
raise | ||
|
||
# setup configuration | ||
config_file = os.path.join(this_folder, ini_file) | ||
fileConfig(config_file, disable_existing_loggers=True) | ||
|
||
# create handlers | ||
handler_info = logging.FileHandler(os.path.join(this_folder, info_log_file)) | ||
handler_error = logging.FileHandler(os.path.join(this_folder, error_log_file)) | ||
# set levels | ||
handler_info.setLevel(logging.INFO) | ||
handler_error.setLevel(logging.ERROR) | ||
|
||
# create formatters and add to handlers | ||
format_info = \ | ||
logging.Formatter('%(asctime)s %(levelname)s ' | ||
'[ %(module)s.%(funcName)s linenr.%(lineno)s ] ' | ||
'%(message).180s', datefmt='%Y-%m-%d %H:%M:%S') | ||
format_error = \ | ||
logging.Formatter( | ||
'%(asctime)s %(levelname)s ' | ||
'[ %(module)s.%(funcName)s linenr.%(lineno)s ] ' | ||
'[ thread: %(threadName)s ] %(message)s') | ||
handler_info.setFormatter(format_info) | ||
handler_error.setFormatter(format_error) | ||
|
||
|
||
def get_logger(name: str = __name__): | ||
logger = logging.getLogger(name) | ||
# add handler | ||
logger.addHandler(handler_info) | ||
logger.addHandler(handler_error) | ||
return logger | ||
|
||
|
||
if __name__ == '__main__': | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/usr/bin/python3 | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------- | ||
# main | ||
# created 01.10.2021 | ||
# Thomas Kaulke, [email protected] | ||
# https://github.com/kaulketh | ||
# ----------------------------------------------------------- | ||
from bot import run | ||
|
||
if __name__ == '__main__': | ||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
telepot~=12.7 |