123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- """
- """
- import argparse
- import logging
- import os
- import subprocess
- import sys
- from datetime import datetime as dt
- from evdev import InputDevice, ecodes
- from rfidacd import __version__
- __author__ = "Thomas Verchow"
- __copyright__ = "Thomas Verchow"
- __license__ = "MIT"
- _logger = logging.getLogger(__name__)
- SHELL = os.getenv("SHELL", "/bin/sh")
- def parse_args(args):
- """
- """
- def dir_path(path: str):
- if os.path.isdir(path):
- return path
- else:
- parser.error(f"{path} is not a readable directory")
- parser = argparse.ArgumentParser(description="RFID action commander daemon")
- parser.add_argument(
- "--version", action="version", version="rfidacd {ver}".format(ver=__version__),
- )
- parser.add_argument(
- "-d", "--device", help="device to listen", type=argparse.FileType("r")
- )
- parser.add_argument(
- "-p", "--path", default=".", help="path to action scripts", type=dir_path
- )
- parser.add_argument(
- "-s", "--seconds", default=5, help="seconds between same rfid", type=int
- )
- parser.add_argument(
- "-v",
- "--verbose",
- dest="loglevel",
- help="set loglevel to INFO",
- action="store_const",
- const=logging.INFO,
- )
- parser.add_argument(
- "-vv",
- "--very-verbose",
- dest="loglevel",
- help="set loglevel to DEBUG",
- action="store_const",
- const=logging.DEBUG,
- )
- return parser.parse_args(args)
- def read_rfid(device):
- combined_string = ""
- for event in InputDevice(device.name).read_loop():
- if event.type == ecodes.EV_KEY and event.value == 0: # value 0 = release key
- if event.code == 28: # code 28 = KEY_ENTER
- return combined_string
- # [4:5]? .. KEY[] starts with 'KEY_' and we expect one char
- combined_string += ecodes.KEY[event.code][4:5]
- def run_action(script: str):
- _logger.info(f"RFID action: run '{SHELL} {script}'")
- try:
- r = subprocess.call([SHELL, script])
- except Exception as err:
- _logger.info(err)
- last_rfid = None
- def main(args):
- args = parse_args(args)
- logging.basicConfig(level=args.loglevel)
- _logger.debug(f"Device to read from: {args.device}")
- _logger.debug(f"Shell to execute commands: {SHELL}")
- _logger.debug(f"Expect scripts to run in {args.path}")
- last_rfid = None
- last_ts = dt.now()
- while True:
- rfid = read_rfid(args.device)
- seconds_gone = (dt.now() - last_ts).total_seconds()
- script = os.path.join(args.path, rfid)
- if os.path.islink(script): # special RFID - always run!
- _logger.info(f"Action script {script} is special/link.")
- run_action(script)
- continue
- if not os.path.isfile(script):
- _logger.info(f"Action script {script} not found.")
- continue
- if rfid == last_rfid and seconds_gone <= args.seconds:
- _logger.info(f"Same RFID after {seconds_gone:.1f} seconds. Do nothing.")
- continue
- last_ts = dt.now()
- last_rfid = rfid
- run_action(script)
- def run():
- main(sys.argv[1:])
- if __name__ == "__main__":
- run()
|