Path: blob/master/docker/platerec_installer/stream_config.py
1091 views
import logging1from pathlib import Path23import requests4from configobj import ConfigObj, flatten_errors5from validate import ValidateError, Validator67DEFAULT_CONFIG = """# Instructions:8# https://app.platerecognizer.com/stream-docs910# List of TZ names on https://en.wikipedia.org/wiki/List_of_tz_database_time_zones11timezone = UTC1213[cameras]14# Full list of regions: http://docs.platerecognizer.com/#countries15# regions = fr, gb1617# Sample 1 out of X frames. A high number will result in less compute.18# A low number is preferred for a stream with fast moving vehicles19# sample = 22021# Maximum delay in seconds before a prediction is returned22# max_prediction_delay = 62324# Maximum time in seconds that a result stays in memory25# memory_decay = 3002627# Enable make, model and color prediction. Your account must have that option.28# mmc = true2930# Image file name, you can use any format codes from https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes31image_format = $(camera)_screenshots/%y-%m-%d/%H-%M-%S.%f.jpg3233# Webhook image type. Use "vehicle" to send only the vehicle image or "original" to34# send the full-size image. This setting can be used at the camera level too.35webhook_image_type = vehicle3637# When a webhook is sent, the request will time out after n seconds and retry later.38# webhook_request_timeout = 303940# Only accept the results that exactly match the templates of the specified regions.41# region_config = strict4243# Only accept license plates when a vehicle is also detected.44# detection_rule = strict4546# Beta - Detect vehicles without a license plate. One of: plate, vehicle47# detection_mode = plate4849# Advanced - Number of steps used to merge unique vehicles. A low number will increase compute.50# If set to -1, it is automatically picked (default).51# merge_buffer = -15253[[camera-1]]54active = yes55url = rtsp://192.168.0.108:8080/video/h2645657# Output methods. Uncomment/comment line to enable/disable.58# - Save to CSV file. The corresponding frame is stored as an image in the same directory.59csv_file = $(camera)_%y-%m-%d.csv6061# - Send to Webhook. The recognition data and vehicle image are encoded in62# multipart/form-data and sent to webhook_target.63# webhook_targets = http://webhook.site/64# webhook_image = yes65# webhook_caching = yes6667# - Send to ParkPow. See https://app.parkpow.com/accounts/token/68# - Save to file in JSONLines format. https://jsonlines.org/69# jsonlines_file = $(camera)_%y-%m-%d.jsonl7071"""727374def send_request(section):75if not section.get("webhook_target") or not section.get("webhook_header"):76return77if "/api/v1/webhook-receiver" not in section["webhook_target"]:78return79headers = {80"Authorization": f"Token {section['webhook_header'].split('Token ')[-1]}"81}82url = section["webhook_target"].replace("webhook-receiver", "parking-list")83try:84response = requests.get(url, headers=headers, timeout=10)85except (requests.Timeout, requests.ConnectionError) as exc:86raise ValidateError(87"[STR0019] The value in webhook_target in the config.ini file is incorrect. "88"Please check the webhook_target value and try again. "89"Go here for additional help "90"https://guides.platerecognizer.com/docs/stream/configuration#webhook-parameters."91) from exc92if response.status_code != 200:93raise ValidateError(94"[STR0020] The Token in webhook_header in the config.ini file is incorrect. "95"Please check the webhook_header value and try again. "96"Go here for additional help "97"https://guides.platerecognizer.com/docs/stream/configuration#webhook-parameters."98)99100101def check_token(config):102send_request(config)103for camera in config.sections:104if config[camera]["active"]:105send_request(config[camera])106107108def camera_spec():109camera_global = dict(110regions="force_list(default=list())",111webhook_target='string(default="")',112webhook_targets="force_list(default=list())",113webhook_header='string(default="")',114webhook_image="boolean(default=yes)",115webhook_caching="boolean(default=yes)",116webhook_image_type='option("vehicle", "original", default="vehicle")',117webhook_request_timeout="float(default=30)",118max_prediction_delay="float(default=6)",119memory_decay="float(default=300)",120image_format='string(default="$(camera)_screenshots/%y-%m-%d/%H-%M-%S.%f.jpg")',121sample="integer(default=2)",122total="integer(default=-1)",123mmc="boolean(default=no)",124csv_file='string(default="")',125jsonlines_file='string(default="")',126region_config='option("normal", "strict", default="normal")',127detection_rule='option("normal", "strict", default="normal")',128detection_mode='option("plate", "vehicle", default="plate")',129merge_buffer="integer(default=-1)",130)131132camera = dict(133url="string",134active="boolean(default=yes)",135# Overridable136regions="force_list(default=None)",137webhook_target="string(default=None)",138webhook_targets="force_list(default=None)",139webhook_header="string(default=None)",140webhook_image="boolean(default=None)",141webhook_caching="boolean(default=None)",142webhook_image_type='option("vehicle", "original", default=None)',143webhook_request_timeout="float(default=None)",144max_prediction_delay="float(default=None)",145memory_decay="float(default=None)",146image_format="string(default=None)",147sample="integer(default=None)",148total="integer(default=None)",149mmc="boolean(default=None)",150csv_file="string(default=None)",151jsonlines_file="string(default=None)",152region_config='option("normal", "strict", default=None)',153detection_rule='option("normal", "strict", default=None)',154detection_mode='option("plate", "vehicle", default=None)',155merge_buffer="integer(default=None)",156)157assert set(camera_global.keys()) <= set(camera.keys())158return dict(__many__=camera, **camera_global)159160161def base_config(config_path: Path, config=None):162spec = ConfigObj()163spec["timezone"] = 'string(default="UTC")'164spec["version"] = "integer(default=2)"165spec["cameras"] = camera_spec()166if not config_path.exists():167with open(config_path, "w") as fp:168fp.write(DEFAULT_CONFIG.replace("\n", "\r\n"))169try:170config = ConfigObj(171config.split("\n") if config else str(config_path),172configspec=spec,173raise_errors=True,174indent_type=" ",175)176config.newlines = "\r\n" # For Windows177except Exception as e:178return None, str(e)179result = config.validate(Validator(), preserve_errors=True)180errors = flatten_errors(config, result)181if errors:182error_message = "[STR0021] The config.ini file does not seem to be formatted correctly. \n [Error details] \n"183for section_list, key, error in errors:184if error is False:185error = f"key {key} is missing."186elif key is not None:187section_list.append(key)188section_string = "/".join(section_list)189logging.error("%s: %s", section_string, error)190error = f"{section_string}, param: {key}, message: {error}"191error_message += f"\n{error}"192return (193None,194error_message195+ "\n Go here for additional help https://guides.platerecognizer.com/docs/stream/configuration",196)197try:198check_token(config["cameras"])199except Exception as e:200return None, str(e)201return config, None202203204