Public Access
make temperature proxy host and port configurable in the configuration tab
This commit is contained in:
1 parent
f562255c75
commit
5f558e4f03
4 files changed
+62
-12
No files matched your search
+3
-2
@@ -51,12 +51,13 @@ Following is a short description of the options:
|
||||
10. Filename of the data pool file
|
||||
11. Write interval after which the data pool is rewritten
|
||||
12. Compression settings
|
||||
13. Authors, License and version numbers of used components
|
||||
13. Host and port of the temperature proxy service
|
||||
14. Authors, License and version numbers of used components
|
||||
|
||||
Temperature History
|
||||
===================
|
||||
|
||||
DAMARIS automatically retrieves one temperature history for the complete experiment from the local ``tempproxy`` service at ``http://localhost:8000/v1/readings`` after the experiment finishes. The proxy controls the temperature device; no controller, serial device, or polling interval needs to be configured in DAMARIS. Successful readings are stored under the ``temperature`` DataPool key with elapsed seconds on the x-axis and the proxy's ``pv`` values unchanged on the y-axis, so units depend on the configured controller. If the proxy is unavailable or has no readings for the experiment, the history is omitted and the experiment's other data is still saved.
|
||||
DAMARIS automatically retrieves one temperature history for the complete experiment from the ``tempproxy`` service at ``http://<host>:<port>/v1/readings`` after the experiment finishes. Host and port are configured in the Configuration tab, the defaults are ``127.0.0.1`` and ``18007``. The proxy controls the temperature device; no controller, serial device, or polling interval needs to be configured in DAMARIS. Successful readings are stored under the ``temperature`` DataPool key with elapsed seconds on the x-axis and the proxy's ``pv`` values unchanged on the y-axis, so units depend on the configured controller. If the proxy is unavailable or has no readings for the experiment, the history is omitted and the experiment's other data is still saved.
|
||||
|
||||
Experiment Script
|
||||
=================
|
||||
|
||||
@@ -871,7 +871,10 @@ class DamarisGUI:
|
||||
temperature_history_start = self.temperature_history_start
|
||||
self.temperature_history_start = None
|
||||
self.data.pop("temperature", None)
|
||||
temperature = TemperatureProxyClient().get_history(
|
||||
proxy_config = self.config.get( )
|
||||
temperature = TemperatureProxyClient(
|
||||
host=proxy_config["tempproxy_host"],
|
||||
port=proxy_config["tempproxy_port"]).get_history(
|
||||
temperature_history_start, time.time())
|
||||
if temperature is not None:
|
||||
self.data["temperature"] = temperature
|
||||
@@ -2379,6 +2382,27 @@ class ConfigTab:
|
||||
backend_vbox.pack_start(self.config_adc_bit_depth_hbox, False, False, 0)
|
||||
self.config_adc_bit_depth_hbox.show_all()
|
||||
|
||||
# temperature proxy settings
|
||||
self.config_tempproxy_hbox = gtk.Box(orientation=gtk.Orientation.HORIZONTAL, spacing=6)
|
||||
self.config_tempproxy_host_label = gtk.Label(label="Temp proxy host:")
|
||||
self.config_tempproxy_host_entry = gtk.Entry()
|
||||
self.config_tempproxy_host_entry.set_text("127.0.0.1")
|
||||
self.config_tempproxy_host_entry.set_tooltip_text("Host of the tempproxy service reading the temperature controller")
|
||||
self.config_tempproxy_host_entry.connect("key-press-event", self.config_keypress)
|
||||
self.config_tempproxy_port_label = gtk.Label(label="port:")
|
||||
self.config_tempproxy_port_spinbutton = gtk.SpinButton.new_with_range(1, 65535, 1)
|
||||
self.config_tempproxy_port_spinbutton.set_value(18007)
|
||||
self.config_tempproxy_port_spinbutton.set_tooltip_text("Port of the tempproxy service, /v1/readings is requested there")
|
||||
self.config_tempproxy_port_spinbutton.connect("key-press-event", self.config_keypress)
|
||||
self.config_tempproxy_hbox.pack_start(self.config_tempproxy_host_label, False, False, 0)
|
||||
self.config_tempproxy_hbox.pack_start(self.config_tempproxy_host_entry, False, False, 0)
|
||||
self.config_tempproxy_hbox.pack_start(self.config_tempproxy_port_label, False, False, 0)
|
||||
self.config_tempproxy_hbox.pack_start(self.config_tempproxy_port_spinbutton, False, False, 0)
|
||||
frontend_vbox = self.xml_gui.get_object("vbox7")
|
||||
if frontend_vbox:
|
||||
frontend_vbox.pack_start(self.config_tempproxy_hbox, False, False, 0)
|
||||
self.config_tempproxy_hbox.show_all()
|
||||
|
||||
# insert version informations
|
||||
components_text = """
|
||||
operating system %(os)s
|
||||
@@ -2485,7 +2509,9 @@ pygobject version %(pygobject)s
|
||||
"data_pool_complib": complib,
|
||||
"data_pool_comprate": self.config_data_pool_comprate.get_value_as_int( ),
|
||||
"script_font": self.config_script_font_button.get_font_name( ),
|
||||
"adc_bit_depth": self.config_adc_bit_depth_spinbutton.get_value_as_int()
|
||||
"adc_bit_depth": self.config_adc_bit_depth_spinbutton.get_value_as_int(),
|
||||
"tempproxy_host": self.config_tempproxy_host_entry.get_text( ),
|
||||
"tempproxy_port": self.config_tempproxy_port_spinbutton.get_value_as_int( )
|
||||
}
|
||||
ADC_Result.default_bit_depth = actual_config["adc_bit_depth"]
|
||||
return actual_config
|
||||
@@ -2520,6 +2546,10 @@ pygobject version %(pygobject)s
|
||||
ADC_Result.default_bit_depth = int(config["adc_bit_depth"])
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
if "tempproxy_host" in config:
|
||||
self.config_tempproxy_host_entry.set_text( str( config[ "tempproxy_host" ] ) )
|
||||
if "tempproxy_port" in config:
|
||||
self.config_tempproxy_port_spinbutton.set_value( float( config[ "tempproxy_port" ] ) )
|
||||
|
||||
if "data_pool_complib" in config:
|
||||
# find combo-box entry and make it active...
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Read experiment temperature history from the local tempproxy service.
|
||||
"""Read experiment temperature history from the tempproxy service.
|
||||
|
||||
Example:
|
||||
client = TemperatureProxyClient()
|
||||
client = TemperatureProxyClient() # defaults to http://127.0.0.1:18007
|
||||
temperature = client.get_history(start_epoch, end_epoch)
|
||||
"""
|
||||
|
||||
@@ -18,11 +18,18 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TemperatureProxyClient:
|
||||
"""Retrieve experiment-bounded readings from ``localhost:8000``."""
|
||||
"""Retrieve experiment-bounded readings from a configurable tempproxy host/port."""
|
||||
|
||||
URL = "http://localhost:8000/v1/readings"
|
||||
TIMEOUT = 5
|
||||
|
||||
def __init__(self, host: str = "127.0.0.1", port: int = 18007):
|
||||
"""Create a client for ``http://<host>:<port>/v1/readings``.
|
||||
|
||||
Example:
|
||||
client = TemperatureProxyClient(host="192.168.1.5", port=18007)
|
||||
"""
|
||||
self.url = f"http://{host}:{port}/v1/readings"
|
||||
|
||||
def get_history(self, start_epoch: float, end_epoch: float) -> TemperatureResult | None:
|
||||
"""Return temperature history relative to the experiment start, or ``None``.
|
||||
|
||||
@@ -33,7 +40,7 @@ class TemperatureProxyClient:
|
||||
temperature = TemperatureProxyClient().get_history(1000.0, 1060.0)
|
||||
"""
|
||||
query = urlencode({"start": start_epoch, "end": end_epoch})
|
||||
url = f"{self.URL}?{query}"
|
||||
url = f"{self.url}?{query}"
|
||||
|
||||
try:
|
||||
with urlopen(url, timeout=self.TIMEOUT) as response:
|
||||
|
||||
@@ -22,7 +22,7 @@ class TestTemperatureProxyClient(unittest.TestCase):
|
||||
return io.BytesIO(json.dumps(payload).encode("utf-8"))
|
||||
|
||||
@patch("damaris.gui.TemperatureProxyClient.urlopen")
|
||||
def test_get_history_uses_fixed_endpoint_and_converts_readings(self, mock_urlopen):
|
||||
def test_get_history_uses_default_endpoint_and_converts_readings(self, mock_urlopen):
|
||||
mock_urlopen.return_value = self.response({
|
||||
"readings": [
|
||||
{"t": 101.5, "pv": 293.15},
|
||||
@@ -35,13 +35,25 @@ class TestTemperatureProxyClient(unittest.TestCase):
|
||||
args, kwargs = mock_urlopen.call_args
|
||||
parsed_url = urlparse(args[0])
|
||||
self.assertEqual(parsed_url.scheme, "http")
|
||||
self.assertEqual(parsed_url.netloc, "localhost:8000")
|
||||
self.assertEqual(parsed_url.netloc, "127.0.0.1:18007")
|
||||
self.assertEqual(parsed_url.path, "/v1/readings")
|
||||
self.assertEqual(parse_qs(parsed_url.query), {"start": ["100.0"], "end": ["110.0"]})
|
||||
self.assertEqual(kwargs, {"timeout": TemperatureProxyClient.TIMEOUT})
|
||||
self.assertEqual(result.x, [1.5, 4.0])
|
||||
self.assertEqual(result.y, [293.15, 294.25])
|
||||
|
||||
@patch("damaris.gui.TemperatureProxyClient.urlopen")
|
||||
def test_custom_host_and_port_are_used(self, mock_urlopen):
|
||||
mock_urlopen.return_value = self.response({"readings": [{"t": 101.0, "pv": 293.0}]})
|
||||
|
||||
client = TemperatureProxyClient(host="proxy.example.org", port=9000)
|
||||
client.get_history(100.0, 110.0)
|
||||
|
||||
args, _ = mock_urlopen.call_args
|
||||
parsed_url = urlparse(args[0])
|
||||
self.assertEqual(parsed_url.netloc, "proxy.example.org:9000")
|
||||
self.assertEqual(parsed_url.path, "/v1/readings")
|
||||
|
||||
@patch("damaris.gui.TemperatureProxyClient.urlopen")
|
||||
def test_empty_readings_return_none(self, mock_urlopen):
|
||||
mock_urlopen.return_value = self.response({"readings": []})
|
||||
@@ -62,7 +74,7 @@ class TestTemperatureProxyClient(unittest.TestCase):
|
||||
OSError("connection refused"),
|
||||
TimeoutError("request timed out"),
|
||||
http.client.BadStatusLine("not an HTTP response"),
|
||||
HTTPError(TemperatureProxyClient.URL, 500, "server error", {}, None),
|
||||
HTTPError(self.client.url, 500, "server error", {}, None),
|
||||
)
|
||||
for failure in failures:
|
||||
with self.subTest(failure=failure):
|
||||
|
||||
Reference in new issue
Block a user