#!/usr/bin/env python3 import include_homekit import hikvision, xmeye from enum import Enum, auto from typing import Optional from argparse import ArgumentParser, ArgumentError from homekit.util import validate_ipv4_or_hostname from homekit.camera import IpcamConfig, CameraType ipcam_config = IpcamConfig() class Action(Enum): GET_NTP = auto() SET_NTP = auto() def process_camera(host: str, action: Action, login: str, password: str, camera_type: CameraType, ntp_server: Optional[str] = None): if camera_type.is_hikvision(): client = hikvision.ISAPIClient(host) try: client.auth(login, password) if action == Action.GET_NTP: print(f'[{host}] {client.get_ntp_server()}') return client.set_ntp_server(ntp_server) print(f'[{host}] done') except hikvision.AuthError as e: print(f'[{host}] ({str(e)})') except hikvision.ResponseError as e: print(f'[{host}] ({str(e)})') elif camera_type.is_xmeye(): try: client = xmeye.XMEyeCamera(hostname=host, username=login, password=password) client.login() if action == Action.GET_NTP: print(f'[{host}] {client.get_ntp_server()}') return client.set_ntp_server(ntp_server) print(f'[{host}] done') except OSError as e: print(f'[{host}] ({str(e)})') def main(): camera_types = ['hikvision', 'xmeye'] parser = ArgumentParser() parser.add_argument('--camera', type=str) parser.add_argument('--camera-type', type=str, choices=camera_types) parser.add_argument('--all', action='store_true') parser.add_argument('--all-of-type', type=str, choices=camera_types) parser.add_argument('--get-ntp-server', action='store_true') parser.add_argument('--set-ntp-server', type=str) parser.add_argument('--username', type=str) parser.add_argument('--password', type=str) args = parser.parse_args() if args.all and args.all_of_type: raise ArgumentError(None, 'you can\'t pass both --all and --all-of-type') if not args.camera and not args.all and not args.all_of_type: raise ArgumentError(None, 'either --all, --all-of-type or --camera is required') if not args.get_ntp_server and not args.set_ntp_server: raise ArgumentError(None, 'either --get-ntp-server or --set-ntp-server is required') action = Action.GET_NTP if args.get_ntp_server else Action.SET_NTP login = args.username if args.username else ipcam_config['web_creds']['login'] password = args.password if args.password else ipcam_config['web_creds']['password'] if action == Action.SET_NTP: if not args.set_ntp_server: raise ArgumentError(None, '--set-ntp-server is required') if not validate_ipv4_or_hostname(args.set_ntp_server): raise ArgumentError(None, 'input ntp server is neither ip address nor a valid hostname') kwargs = {} if args.set_ntp_server: kwargs['ntp_server'] = args.set_ntp_server if not args.all and not args.all_of_type: if not args.camera_type: raise ArgumentError(None, '--camera-type is required') if not ipcam_config.has_camera(int(args.camera)): raise ArgumentError(None, f'invalid camera {args.camera}') camera_host = ipcam_config.get_camera_ip(args.camera) if args.camera_type == 'hikvision': camera_type = CameraType.HIKVISION_264 elif args.camera_type == 'xmeye': camera_type = CameraType.XMEYE else: raise ValueError('invalid --camera-type') process_camera(camera_host, action, login, password, camera_type, **kwargs) else: for cam in ipcam_config.get_all_cam_names(): if not ipcam_config.is_camera_enabled(cam): continue cam_type = ipcam_config.get_camera_type(cam) if args.all_of_type == 'hikvision' and not cam_type.is_hikvision(): continue if args.all_of_type == 'xmeye' and not ipcam_config.get_camera_type(cam).is_xmeye(): continue process_camera(ipcam_config.get_camera_ip(cam), action, login, password, cam_type, **kwargs) if __name__ == '__main__': main()