|
|
Experimental Physics and
| ||||||||||||||||
|
|
Hi Jesse, Sorry for the delay. What I do is fairly simple. For each sensor, I load a small record into a softIOC with dbLoadRecords("esensor.db","P=13IDE:,Q=Esensor") in the startup script and with the "esensor.db" of (also attached): #### # record used for Esensor temperature, humidity sensors record(ai,"$(P)$(Q):TempF") { field(DESC, "Temperature (F)") field(VAL, "0") } record(ai,"$(P)$(Q):TempC") { field(DESC, "Temperature (C)") field(VAL, "0") } record(ai,"$(P)$(Q):Humid") { field(DESC, "Humidity (percent)") field(VAL, "0") } record(stringin, "$(P)$(Q):TimeStamp") { field(DESC, "Timestamp of last update") field(VAL, "") } #### Then, I run a Python script (attached) to read the sensor (over plain HTTP), parse the results, and push to PVs. The script handles both older Esensors that send data as XML, and newer ones that send JSON data. You could probably put that script inside procServ or something like that but I just have it running as a simple background script. --Matt On Fri, Nov 10, 2023 at 4:15 PM Jesse Hopkins <[email protected]> wrote:
--Matt Newville <newville at cars.uchicago.edu> 630-327-7411 Attachment:
esensor.db #!/usr/bin/env python
import requests
import time
import json
import xml.etree.ElementTree as ET
from epics import get_pv
class ESensor:
""" read Esensor data, push to Epics PVs"""
def __init__(self, label, url, prefix, format="xml"):
self.label = label
self.url = url
self.prefix = prefix
self.format = format
self.tempf_pv = get_pv(f"{prefix:s}:TempF.VAL")
self.tempc_pv = get_pv(f"{prefix:s}:TempC.VAL")
self.humid_pv = get_pv(f"{prefix:s}:Humid.VAL")
self.timestamp_pv = get_pv(f"{prefix:s}:TimeStamp.VAL")
self.tattr = "tm0"
self.tunit = "tun0"
self.hattr = "hu0"
self.reader = ET.fromstring
if format == "json":
self.tattr = "tmp"
self.hattr = "hum"
self.tunit = "tun"
self.reader = json.loads
def getval(self, source, attr, force_float=True):
if self.format == "xml":
try:
val = source.find(attr).text
except:
val = "-1"
elif self.format == "json":
try:
val = source.get(attr, -1.0)
except:
val = "-1"
if force_float:
try:
val = float(val)
except:
val = -1.0
return val
def read(self):
resp = requests.get(self.url, timeout=0.25)
tdat = self.reader(resp.content.decode("utf-8"))
tunt = self.getval(tdat, self.tunit, force_float=False)
tval = self.getval(tdat, self.tattr)
hval = self.getval(tdat, self.hattr)
return tval, tunt, hval
def update(self):
tval, tunit, hval = self.read()
if tunit in (0, '0', 'F'):
tval_f = tval
tval_c = (tval - 32)*5.0/9.0
else:
tval_c = tval
tval_f = (tval_c * 9.0/5) + 32
tval_f = float("%.3f" % tval_f)
tval_c = float("%.3f" % tval_c)
hval = float("%.3f" % hval)
if self.tempf_pv.connected:
self.tempf_pv.put(tval_f)
self.tempc_pv.put(tval_c)
self.humid_pv.put(hval)
self.timestamp_pv.put(time.ctime())
print(time.ctime(), self.label, tval_c, hval)
#
if __name__ == '__main__':
esensors = [ESensor("13-ID-E", "http://164.54.160.168/sensorLogUpdate.xml", "13IDE:Esensor", format="xml"),
ESensor("13-ID-C", "http://10.54.160.76/status.json", "13IDC:Esensor", format="json"),
]
while True:
try:
[e.update() for e in esensors]
except:
pass
time.sleep(0.5)
| ||||||||||||||||
| ANJ, 19 Mar 2026 |
·
Home
·
News
·
About
·
Talk
·
Base
·
Modules
·
Extensions
·
· Distributions · Download · Documents · Links · Licensing · |