diff --git a/README.md b/README.md
index 8b1c306..465d8e3 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,8 @@ regardless of their components and control mechanisms.
This software will grow over time to support additional components and control mechanisms.
Currently, this API provides a general abstract Preselector class that uses an rf_path array to
describe the available combinations of calibration sources, filters,
-and amplifiers. A simple set_rf_path method allows users to specify the rf path by index or name.
+and amplifiers. A simple set_state method allows users to specify the state of the preselector
+by the state key specified in the preselector config.
Finally, different switching control mechanisms are supported by extending the base Preseelctor class.
Currently, this repository provides an implementation for a WebRelayPreselector that includes an [x310 WebRelay](https://www.controlbyweb.com/x310/). See below for additional details on using the WebRelayPreslector.
@@ -19,11 +20,11 @@ To install this Python package, clone the repository and enter the directory of
```
Windows:
py –m build
-py -m pip install dist/its-preselector-2.0.0.tar.gz
+py -m pip install dist/its-preselector-2.0.1.tar.gz
Linux:
python3 -m build
-Python3 –m pip install dist/its-preselector-2.0.0.tar.gz
+Python3 –m pip install dist/its-preselector-2.0.1.tar.gz
```
# WebRelayPreselector Configuration
@@ -31,7 +32,7 @@ The WebRelayPreselector requires a [SigMF metadata file](https://Github.com/NTIA
metadata and for any other desired sources. Below is an example config file for the WebRelayPreselector to describe how it works:
```
{
- "base_url" : "http://192.168.130.32/state.xml?relay",
+ "base_url" : "http://192.168.130.32/state.xml",
"noise_diode_on" : "1State=1,2State=1,3State=0,4State=0",
"noise_diode_off" : "1State=0,2State=1,3State=0,4State=0",
"antenna" : "1State=0,2State=0,3State=0,4State=0"
@@ -62,6 +63,7 @@ with open('config/config.json') as config_file:
preselector_config = json.load(config_file)
preselector = WebRelayPreselector(sensor_def, preselector_config)
+preselector.set_state('antenna')
```
# Preselector Interactions
@@ -84,7 +86,7 @@ preselector = WebRelayPreselector(sensor_def, preselector_config)
## Control:
-- preselector.set_rf_path(rf_path_name)
+- preselector.set_state(rf_path_name)
# License
diff --git a/config/config.json b/config/config.json
index 81adf82..f3f966e 100644
--- a/config/config.json
+++ b/config/config.json
@@ -1,9 +1,8 @@
{
- "base_url" : "http://192.168.130.32/state.xml?relay",
+ "base_url" : "http://192.168.1.2/state.xml",
"noise_diode_on" : "1State=1,2State=1,3State=0,4State=0",
- "noise_diode_off" : "1State=0,2State=1,3State=0,4State=0",
- "antenna" : "1State=0,2State=0,3State=0,4State=0",
- "1" : "1State=0,2State=1,3State=0,4State=0"
+ "noise_diode_off" : "1State=1,2State=0,3State=0,4State=0",
+ "antenna" : "1State=0,2State=0,3State=0,4State=0"
}
diff --git a/setup.cfg b/setup.cfg
index 32a8e69..18262e5 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = its-preselector
-version = 2.0.0
+version = 2.0.1
author = ITS
author_email = dboulware@ntia.gov
description = A package to control the ITS web relay based preselector
@@ -19,7 +19,7 @@ package_dir =
= src
packages =
its_preselector
-python_requires = >=3.6
+python_requires = >=3.7
install_requires =
requests>=2.25.1
diff --git a/src/its_preselector/preselector.py b/src/its_preselector/preselector.py
index 46cb18c..9dded99 100644
--- a/src/its_preselector/preselector.py
+++ b/src/its_preselector/preselector.py
@@ -116,7 +116,7 @@ def get_amplifier_noise_figure(self, rf_path_index):
return None
@abstractmethod
- def set_rf_path(self, i):
+ def set_state(self, i):
pass
def __get_filter(self, filter_id):
@@ -135,5 +135,7 @@ def __get_amplifier(self, amp_id):
return None
-
+ @abstractmethod
+ def get_sensor_value(sensor):
+ pass
diff --git a/src/its_preselector/test/test_web_relay_preselector.py b/src/its_preselector/test/test_web_relay_preselector.py
new file mode 100644
index 0000000..746b57d
--- /dev/null
+++ b/src/its_preselector/test/test_web_relay_preselector.py
@@ -0,0 +1,36 @@
+import unittest
+import json
+
+from its_preselector.web_relay_preselector import WebRelayPreselector
+
+
+class MyTestCase(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ file = open('test_metadata.sigmf-meta')
+ cls.sensor_def = json.load(file)
+ file.close()
+
+ def test_blank_base_url(self):
+ preselector = WebRelayPreselector(self.sensor_def, {'base_url': '', 'antenna' : '1State=0,2State=0,3State=0,4State=0' })
+ with self.assertRaises(Exception):
+ preselector.set_state('antenna')
+
+ def test_none_base_url(self):
+ preselector = WebRelayPreselector(self.sensor_def, {'base_url': None, 'antenna' : '1State=0,2State=0,3State=0,4State=0' })
+ with self.assertRaises(Exception):
+ preselector.set_state('antenna')
+
+ def test_invalid_base_url(self):
+ preselector = WebRelayPreselector(self.sensor_def, {'base_url': 'http://badpreselector.gov', 'antenna' : '1State=0,2State=0,3State=0,4State=0' })
+ with self.assertRaises(Exception):
+ preselector.set_state('antenna')
+
+ def test_healthy_false(self):
+ preselector = WebRelayPreselector(self.sensor_def, {'base_url': 'http://bad_preselector.gov',
+ 'antenna': '1State=0,2State=0,3State=0,4State=0'})
+ self.assertFalse(preselector.healthy())
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/its_preselector/web_relay_preselector.py b/src/its_preselector/web_relay_preselector.py
index c48a8f1..fa23ffc 100644
--- a/src/its_preselector/web_relay_preselector.py
+++ b/src/its_preselector/web_relay_preselector.py
@@ -1,5 +1,9 @@
+import logging
from its_preselector.preselector import Preselector
import requests
+import xml.etree.ElementTree as ET
+
+logger = logging.getLogger(__name__)
class WebRelayPreselector(Preselector):
@@ -9,14 +13,34 @@ def __init__(self, sigmf, config):
if 'base_url' in config:
self.base_url = config['base_url']
- def set_rf_path(self, i):
+ def set_state(self, i):
key = str(i)
if key in self.config:
switches = self.config[str(i)].split(',')
- if self.base_url:
+ if self.base_url and self.base_url != '':
for i in range(len(switches)):
- command = self.base_url + switches[i]
- print(command)
- requests.get(command)
+ command = self.base_url + '?relay' + switches[i]
+ logger.debug(command)
+ response = requests.get(command)
+ if response.status_code != requests.codes.ok:
+ raise Exception('Unable to set preselector state. Verify configuration and connectivity.')
+ else:
+ raise Exception('base_url is None or blank')
else:
raise Exception("RF path " + key + " configuration does not exist.")
+
+ def get_sensor_value(self, sensor_num):
+ sensor_num_string = str(sensor_num)
+ response = requests.get(self.base_url + '?sensor' + sensor_num_string)
+ sensor_tag = 'sensor' + sensor_num_string
+ root = ET.fromstring(response.text)
+ sensor = root.find(sensor_tag)
+ return sensor.text
+
+ def healthy(self):
+ try:
+ response = requests.get(self.base_url)
+ return response.status_code == requests.codes.ok
+ except:
+ logger.error("Unable to connect to preselector")
+ return False