Full manual diffs (L15, C20, E30, L25, J40, C10 §2, L10, P10, P11, J20, C30, P20, R40, E10) and read-only checks on the shared R1.05 test server. Skills and summaries moved to R1.05; new skill pytools (IM 36K10P40) from docs (no Python on the test server). Issues ISS-132..181; corrections to version-differences (E10, E30, P11, dss_ath_grp_u0104); C10 summary lists the 3 new authorization actions; r105-verification V10-V17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 KiB
| task | version | source | status |
|---|---|---|---|
| Wait for value or record changes with DSS event notification in a Python script | R1.05 | IM 36K10P40-01EN §3.10, §3.11 (stop request), §4 (2nd ed., Feb. 2026); `EVENT_Q_SLOTS` in the installed `dss.sup` (R1.03 and R1.05) | from docs, not tested (no Python on the R1.05 test server) |
Event notification
Start from setup-first-script.md. The example only reads; it leaves nothing behind when it
ends (notifications stopped, dataset and connection closed).
1. How it works
- Request: per record
dss.recordEventNotify(conn, ds, <key>, 'u')(uupdate,ddelete), or per datasetdss.datasetEventNotify(conn, ds, 'iud')(alsoiinsert). - DSS puts each change in one queue per client; the script must poll it with
dss.eventRead(conn)→ list of dicts{'ds_name', 'event', 'id', 'record', 'set_hnd'}(record= the record after the change, only the fields opened). Empty list = nothing new. - If the queue overflows, DSS empties it (events lost). Size:
EVENT_Q_SLOTSindss.sup(default 100); poll often and keep the number of watched records reasonable. - One request per record; to change the mode, stop it first (
PY_DSS_EVT_NOTIFY_DEF). - Stop with
recordEventStop/datasetEventStop, then close.
2. Example: print value changes of two items
import os, sys, time, getpass
sys.path.insert(0, os.path.join(os.environ['TLS_ROOT_PATH'], 'tls', 'exe'))
import dss
ITEMS = ['CI-Eng-Sample.TANK1.LEVEL', 'CI-Eng-Sample.PUMP1.RUNNING'] # or <Section>.<Tag>
RUN_SECONDS = 60 # 0 = until Ctrl+C
conn = dss.connect(os.environ.get('CI_USER') or input('User: '),
os.environ.get('CI_PASSWORD') if 'CI_PASSWORD' in os.environ
else getpass.getpass('Password: '))
watched = []
try:
ds = dss.openDataset(conn, 'ITEM_VAL', ['NAME', 'ITEM_VALUE', 'STATUS', 'UPDATE_TIME'], 'r')
try:
for name in ITEMS:
dss.recordEventNotify(conn, ds, name, 'u')
watched.append(name)
t_end = time.time() + RUN_SECONDS
try:
while not RUN_SECONDS or time.time() < t_end:
time.sleep(1)
for ev in dss.eventRead(conn):
r = ev['record']
print(dss.dateString(conn, r['UPDATE_TIME'], 'GENERAL'),
r['NAME'], r['ITEM_VALUE'], r['STATUS'])
except KeyboardInterrupt:
pass
finally:
for name in watched:
dss.recordEventStop(conn, ds, name)
dss.closeDataset(conn, ds)
finally:
dss.close(conn)
Expected: one line per value update of the two items (with the sample's live-data feed
running, TANK1.LEVEL changes every few seconds); nothing for unchanged items. Ends after
60 s or Ctrl+C.
3. Long-running scripts
- Give the script a fixed BUS name before connecting:
dss.busSetName('PYWATCH'). It can then be stopped cleanly from a command prompt withdurstp -p PYWATCH; inside the script this raisesdss.errorwith codePY_DSS_STOP_REQUEST— catch it, stop the notifications, close and exit. Without a name the process isPYDSS_<number>(new each run). Check whether it runs withdurwfp -p PYWATCH -t 0(skillsystem-management,bus-utilities.md). - Instead of
time.sleeppolling, a script that also serves BUS messages can block indss.busReceive(conn, 'SYNC_WAIT')(manual §3.11); then events are only read between messages. - Do not leave test watchers running on a shared or production server.
4. Not tested / to verify
On a test Core with Python and the sample feed (user): run §2 (expect changes of
TANK1.LEVEL); start it with a BUS name and stop it with durstp (expect a clean exit via
PY_DSS_STOP_REQUEST); check whether the R1.05 module still names unnamed scripts
PYDSS_<n> (the dss.sup routing PYDSS* → DSSSDAPY relies on it, while a script with
its own BUS name such as PYWATCH may be routed to a general DSSSDA instead, ISS-180).