{"id":18750340,"url":"https://github.com/ntia/preselector","last_synced_at":"2025-07-30T20:05:03.515Z","repository":{"id":37853795,"uuid":"381166360","full_name":"NTIA/Preselector","owner":"NTIA","description":"A general software API to interface with RF preselectors.","archived":false,"fork":false,"pushed_at":"2024-09-06T18:47:16.000Z","size":647,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-20T11:08:30.892Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NTIA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-28T21:33:40.000Z","updated_at":"2023-01-20T23:40:36.000Z","dependencies_parsed_at":"2023-11-29T22:25:12.537Z","dependency_job_id":"9f2fa1e8-bca2-477d-b482-7394dd2f1697","html_url":"https://github.com/NTIA/Preselector","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/NTIA/Preselector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NTIA%2FPreselector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NTIA%2FPreselector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NTIA%2FPreselector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NTIA%2FPreselector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NTIA","download_url":"https://codeload.github.com/NTIA/Preselector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NTIA%2FPreselector/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267930639,"owners_count":24167475,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T17:11:28.293Z","updated_at":"2025-07-30T20:05:03.488Z","avatar_url":"https://github.com/NTIA.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NTIA/ITS Preselector API\n\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/NTIA/Preselector?display_name=tag\u0026sort=semver)\n![GitHub all releases](https://img.shields.io/github/downloads/NTIA/Preselector/total)\n![GitHub issues](https://img.shields.io/github/issues/NTIA/Preselector)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nThis repository provides a general software API to control preselectors regardless of their\ncomponents and control mechanisms.\n\nCurrently, this API provides a general abstract `Preselector` class that uses an `rf_path`\narray to describe the available combinations of calibration sources, filters, and amplifiers.\nA simple `set_state` method allows users to specify the state of the preselector by the state\nkey specified in the preselector config. Different switching control mechanisms are supported\nby extending the base `Preselector` class. Currently, this repository provides an implementation\nfor a `WebRelayPreselector` that includes an [x310 WebRelay](https://www.controlbyweb.com/x310/).\nSee below for additional details on using the `WebRelayPreselector`.\n\nThis software will grow over time to support additional components and control mechanisms.\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Usage](#usage)\n- [Development](#development)\n- [License](#license)\n- [Contact](#contact)\n\n## Introduction\n\nA preselector is a device, connected between an antenna and a signal analyzer, designed to\nimprove the RF performance and capability of a sensor. As illustrated in the diagram below,\nit may include a variety of components, e.g., filters, amplifiers, calibration sources, and\nswitches. An example preselector is shown in Figure 1. Just as the components within a preselector\nmay change, so too may the way in which the switching is controlled.\n\n![Preselector Diagram](/docs/img/preselector.png)\n\u003cfigcaption\u003eFigure 1: Block diagram showing an example RF measurement system with a preselector.\u003c/figcaption\u003e\n\n## Usage\n\nTo install this Python package, clone the repository and enter the directory of the\nproject in the command line. Execute the following commands depending on your OS (you may\nhave to adjust for your version of Python):\n\n```bash\n# Windows\npy -m pip install .\n\n# Linux\npython3 –m pip install .\n```\n\n### `WebRelayPreselector` Configuration\n\nThe `WebRelayPreselector` requires a [SigMF metadata file](https://Github.com/NTIA/sigmf-ns-ntia)\nthat describes the sensor preselector and a config file to describe the WebRelay\nsettings for the RF paths specified in the metadata and for any other desired sources.\nBelow is an example config file for the `WebRelayPreselector` to describe how it works:\n\n```json\n{\n  \"name\": \"preselector\",\n  \"base_url\" : \"http://192.168.1.2/state.xml\",\n  \"control_states\": {\n      \"noise_diode_on\" : \"1State=1,2State=1,3State=0,4State=0\",\n      \"noise_diode_off\" : \"1State=1,2State=0,3State=0,4State=0\",\n      \"antenna\" : \"1State=0,2State=0,3State=0,4State=0\"\n  },\n  \"status_states\": {\n    \"noise diode powered\" : \"relay2=1\",\n    \"antenna path enabled\": \"relay1=0\",\n    \"noise diode path enabled\": \"relay1=1\"\n  },\n  \"sensors\": {\n    \"internal_temp\": 1,\n    \"internal_humidity\": 2,\n    \"tec_intake_temp\": 3,\n    \"tec_exhaust_temp\": 4\n  },\n  \"digital_inputs\": {\n      \"ups_power\": 1,\n      \"ups_battery_level\": 2,\n      \"ups_trouble\": 3,\n      \"ups_battery_replace\": 4\n  },\n  \"analog_inputs\": {\n      \"door_sensor\": 1,\n      \"5vdc_monitor\": 2,\n      \"28vdc_monitor\": 3,\n      \"15vdc_monitor\": 4,\n      \"24vdc_monitor\": 5\n  }\n}\n```\n\nNote, the config above is specifically for a prelector with a `ControlByWebWebRelay.`\nOther Preselectors and WebRelays may require a different configuration.\nThe `base_url` and `name` keys are the only required keys for the `WebRelayPreselector`.\nThe `base_url` should map to the base URL to interact with the WebRelay\n(see [https://www.controlbyweb.com/x310](https://www.controlbyweb.com/x310)\nfor more info). The keys within the `control_states` key should correspond to RF paths\ndocumented in the SigMF metadata. The keys within the `status_states` should map to the\nRF paths documented in the SigMF metadata, or to understandable states of the\npreselector for which it is desired to determine whether they are enabled or disabled.\nThe `get_status` method of the preselector will provide each of the keys specified in the\n`status_states` entry mapped to a boolean indicating whether the preselector states match\nthose specified in the mapping. Each of the entries in the config provide mappings to the\nassociated web relay input states and every `RFPath` defined in the sensor definition json\nfile should have an entry in the preselector config.\nThe `sensors`, `digital_inputs`, and `analog_inputs` keys define the sensors,\ndigital inputs and analog inputs configured on the device. Within each of the sections,\neach key provides the name of the sensor or input and the value specifies the assigned\nsensor or input number. The `get_satus` method will provide each sensor/input value with\nthe specified label. Every status_state, sensor, and input must have a unique name.\nAttempting to create a`ControlByWebWebRelay` with duplicate status_states,\nsensors, or inputs will cause a `ConfigurationException.`\n\nIn this example, there are `noise_diode_on` and `noise_diode_off` keys to correspond to the\npreselector paths to turn the noise diode on and off, and an antenna key to indicate the\nweb relay states to connect to the antenna.\n\nNote: with this example configuration, you would have to set the path by the name of the\nsource rather than the index in the `rf_paths` array.\n\n### `WebRelayPreselector` Initialization\n\n```python\nimport json\nfrom its_preselector.web_relay_preselector import WebRelayPreselector\n\n\nwith open('config/metadata.sigmf-meta') as sensor_def_file:\n    sensor_def = json.load(sensor_def_file)\n\nwith open('config/config.json') as config_file:\n    preselector_config = json.load(config_file)\n\npreselector = WebRelayPreselector(sensor_def, preselector_config)\npreselector.set_state('antenna')\n```\n\n### Preselector Interactions\n\n#### Access instance properties\n\n- `preselector.amplifiers[0].gain`\n- ...\n\n#### Helper methods\n\n- `preselector.get_amplifier_gain(rf_path_index)`\n- `preselector.get_amplifier_noise_figure(rf_path_index)`\n- `preselector.get_frequency_low_passband(rf_path_index)`\n- `preselector.get_frequency_high_passband(rf_path_index)`\n- `preselector.get_frequency_low_stopband(rf_path_index)`\n- `preselector.get_frequency_high_stopband(rf_path_index)`\n\n#### Control\n\n- `preselector.set_state(rf_path_name)`\n\n## Development\n\nSet up a development environment using a tool like [Conda](https://docs.conda.io/en/latest/)\nor [venv](https://docs.python.org/3/library/venv.html#module-venv), with `python\u003e=3.7`. Then,\nfrom the cloned directory, install the development dependencies by running:\n\n```bash\npip install .[dev]\n```\n\nThis will install the project itself, along with development dependencies for pre-commit\nhooks, building distributions, and running tests. Set up pre-commit, which runs\nauto-formatting and code-checking automatically when you make a commit, by running:\n\n```bash\npre-commit install\n```\n\nThe pre-commit tool will auto-format Python code using [Black](https://github.com/psf/black)\nand [isort](https://github.com/pycqa/isort). Other pre-commit hooks are also enabled, and\ncan be found in [`.pre-commit-config.yaml`](.pre-commit-config.yaml).\n\n### Building New Releases\n\nThis project uses [Hatchling](https://github.com/pypa/hatch/tree/master/backend) as a backend.\nHatchling makes versioning and building new releases easy. The package version can be updated\neasily by using any of the following commands.\n\n```bash\nhatchling version major   # 1.0.0 -\u003e 2.0.0\nhatchling version minor   # 1.0.0 -\u003e 1.1.0\nhatchling version micro   # 1.0.0 -\u003e 1.0.1\nhatchling version \"X.X.X\" # 1.0.0 -\u003e X.X.X\n```\n\nTo build a new release (both wheel and sdist/tarball), run:\n\n```bash\nhatchling build\n```\n\n## License\n\nSee [LICENSE](LICENSE.md)\n\n## Contact\n\nFor technical questions, contact Doug Boulware, dboulware@ntia.gov\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fntia%2Fpreselector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fntia%2Fpreselector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fntia%2Fpreselector/lists"}