ci-server-engineer/knowledge/manuals/IM36K10P40-01EN.md
cliu bf7d88a027 R1.05 re-check batch 3: alarms, audit, authorization, classes, HAC, reporting, pyTOOLS
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>
2026-10-09 10:21:36 +11:00

12 KiB


manual: IM 36K10P40-01EN title: pyTOOLS Programmer's Guide edition: 2nd Edition, Feb. 2026 (R1.05); new in R1.04 (1st Edition, Jan. 2025). Revision table: 2nd edition "layouts updated" only (manual new, no diff against R1.03) version: R1.05 status: from docs, plus read-only file checks on the R1.05 test server (2026-10-09) - dss.pyd, DSSSDAPY, dss.sup, dssana.sup checked; no Python on the R1.05 test server, so no function was run there (not tested, ISS-178). R1.03 dss.pyd loaded on the development machine with Python 3.12 (version(), busGetDirs() only; CI Server not running)

pyTOOLS Programmer's Guide (R1.05)

pyTOOLS is a Python extension module (dss) for scripts that read and change CI Server data through DSS (Data Set Services), exchange BUS Service messages and read item history. The module is the file %TLS_ROOT_PATH%\tls\exe\dss.pyd. Section numbers refer to the manual. Practical use: skill pytools.

1. Overview and operating environment (§1)

  • Runs on CI Core and CI Portal, not on CI View.
  • Always uses the local DSS: a script cannot reach another CI Core by node number (only the item history functions and BUS messages take an optional node number, §3.11, §3.13).
  • Supported Python: 64-bit Python 3.12 (IM 36K01C10-01EN §1.3.3, coexisting software list; summary IM36K01C10-01EN.md). Python is not part of the CI Server installation.

2. Setup (§2)

  1. Install 64-bit Python from python.org on the Core / Portal (run the installer as administrator).
  2. Add the Windows environment variable PYTHONPATH = the tls\exe folder of CI Server. The manual gives the default C:\Program Files (x86)\Yokogawa\CIServer\tls\exe; use %TLS_ROOT_PATH%\tls\exe of the actual installation (on the R1.05 test server the install root is C:\Yokogawa\CIServer, ISS-177).
  3. In Python: import dss.

Installed (checked 2026-10-09): the module links python3.dll (stable ABI), buslib64.dll and databaselib64.dll (both in tls\exe next to the module), so it is not tied to one Python 3.x minor version; Yokogawa only lists 3.12. dss.pyd already shipped with R1.03 (module 3.6, r10200M, Aug. 2023, 124,928 bytes; no dedicated DSS server, no Python Interface entry in dssana.sup); R1.05 has module 3.6.1 (r11609M, Jun. 2026, 137,728 bytes) with session-based logon, the PY_DSS_NOT_LOGGED_IN exception and the aggr_period history argument (ISS-174).

3. DSS interface (§3)

3.1 Function groups (§3.1)

Connect/logon, DSS properties, open/close datasets, read, modify, indexing, filtering, locking, event notification, BUS messages, date/time, item history, miscellaneous. All functions take the connection handle first (except version(), busGetDirs(), busSetName(), busSnap()).

3.2 Connecting (§3.2)

Function Purpose
dss.connect([user], [password]) Attach to BUS Service and DSS; returns the connection handle (a dict with the DSS connection id and optionally user/password). With a user, a password is required and a logon is done at once
dss.logon(conn, user, password) Log on (or switch to another user); a failed logon keeps the old rights
dss.logout(conn) Log out
dss.close(conn) Disconnect and free all DSS resources (also logs out)
  • One connection per script; a second connect() raises PY_DSS_ALREADY_CONN.
  • Without a logon DSS gives no data (default); a logon without user/password is refused.
  • The user name is used in the audit trail; pyTOOLS operations appear with source PYTOOLS. Installed R1.05: PYTOOLS audit classifiers exist for login / logout / login attempt, dataset insert / modify / delete and item value / status / quality changes (skill audit-trail, audit-checks.md, ISS-141).
  • Server side: pyTOOLS clients have their own DSS data access server, so they do not compete with other DSS clients (§3.2 figure). Installed R1.05: database_start.cmd starts dsssda -n dsssdapy; dss.sup routes DSSSDA_SRV = -1, "PYDSS*", "DSSSDAPY" (ISS-117).
  • Login method: dssana.sup User Interfaces tab has "Python Interface", "PYDSS" (audit id 18); Login control has <local> and <remote> → Manual CI Server (verified read-only on the R1.05 test server 2026-10-09; R1.03 dssana.sup has neither line). J10 §2.9.1: pyTOOLS supports only Manual CI Server (summary IM36K10J10-01EN.md); what happens with another method is not documented (ISS-179). A pyTOOLS client that is not in the User Interfaces list cannot connect (dssana.sup help).

3.3 DSS properties (§3.3)

getAvailableDatasets(conn) → list of dataset names; getFieldNames(conn, dataset) → list of field names; getFieldProperties(conn, dataset, field) → dict name, type, length. (Installed module also has getDatasetProperties(conn, dataset), not in the manual, ISS-176.)

3.4 Open / close (§3.4)

ds = dss.openDataset(conn, dataset, fields, mode) — fields is the list of fields of interest (only these are read and can be set); mode any of r, u, d, i, plus t = handle all time fields as UTC (default local civil time). Open the same dataset several times if needed. dss.closeDataset(conn, ds) frees it.

3.5 Reading (§3.5)

Function Returns
readNext(conn, ds) Next record (dict field → value) in the order of the active index, honouring an active filter; raises DSS-E-EOS at the end
readEqual(conn, ds, key) The record whose active index equals key (string, or dict for a composed index); first match on a non-unique index; filters ignored; the cursor moves past it
readRecords(conn, ds) List of all records (the manual's "Returns: None" is wrong, ISS-175)
rewindDataset(conn, ds) Cursor back to the first record

3.6 Modifying (§3.6)

insertRecord / insertRecords (dict or list of dicts; fields not opened get defaults), updateRecord / updateRecords (must contain the current index field), deleteRecord(conn, ds, key). The dataset must be opened with the matching mode letters (i, u, d). Changes go through DSS like any other client (validation, audit trail).

3.7 Indexing (§3.7)

getIndex(conn, dataset) → index names (e.g. STATUS_DF: NAME, STATUS_NUMBER); setIndex(conn, ds, index_name) changes the active index and thus the read order and the key used by readEqual. Default: the primary index.

3.8 Filtering (§3.8)

createFilter(conn, ds, expr) → activateFilter → reads → deactivateFilter → deleteFilter (an active filter cannot be deleted; one filter per open dataset). Expression: either a quoted wildcard string ("*.TANK1.*", applied to the current index field; * any string, ? one character), or comparisons <field> <op> <constant> with = != < <= > >= LIKE, joined by AND / OR, brackets allowed. String constants are case-sensitive and in double quotes (so wrap the whole expression in single quotes in Python); field names and operators are not; spaces around operators are required; maximum 252 characters.

3.9 Locking (§3.9)

lockRecords(conn, ds, [keys]) / unlockRecords(...) — other CI Server processes cannot change or delete a locked record; locking an already locked record raises an exception.

3.10 Event notification (§3.10)

  • Dataset level: datasetEventNotify(conn, ds, mode) with i, u, d; stop with datasetEventStop(conn, ds).
  • Record level: recordEventNotify(conn, ds, key, mode) with u, d; stop with recordEventStop(conn, ds, key).
  • Poll with eventRead(conn) → list of dicts ds_name, event (i/u/d), id (running number), record (record after the change), set_hnd. Empty list when nothing happened.
  • One queue per client; DSS clears the queue when it overflows (size from the DSS setup file — EVENT_Q_SLOTS in dss.sup, default 100, ISS-181), so poll often enough.
  • Overlapping requests give one event; a record can only have one request — stop it before changing the mode (PY_DSS_EVT_NOTIFY_DEF).

3.11 BUS Service messages (§3.11)

  • The script attaches to the BUS as PYDSS_<number> (new each run). To be addressable, call dss.busSetName('<NAME>') before connect(), every time. (Installed dss.sup routes only PYDSS* clients to DSSSDAPY; a script with its own name probably uses a general DSSSDA, not checked, ISS-180.)
  • busSend(conn, {'process':…, 'node':…, 'code':…, 'message':…}) (node and code optional; message always a string); busSendReceive waits up to 60 s for the reply (dict with message); busReceive(conn[, 'SYNC_WAIT']) → dict (process, node, reply, sys_type, code, message) or None; busReply(conn, msg) must answer within 60 s, passing reply and sys_type back unchanged.
  • durstp -p <name> stops a named pyTOOLS script: the script gets dss.error with code PY_DSS_STOP_REQUEST and should close and exit.
  • busSnap('GENERAL'|'QUEUE'|'NODE'|'LOCK') takes a snapshot, then busSnap('FIRST') / busSnap('NEXT') return the entries (None at the end). Local node only (on a Portal you see the Portal).

3.12 Date and time (§3.12)

  • DSS time = seconds since 1970-01-01 as a float with milliseconds.
  • dateString(conn, t[, fmt]) → text; tokens YYYY YY MMM MM M DDD DD D hh mm ss p…pppp; presets ANSI, JULIAN, EUROPE, GENERAL; default DD-MMM-YY hh:mm:ss.
  • dateDSS(conn, 'dd-mmm-yy hh:mm:ss.ppp') → DSS time (missing date or time = now); dateRelDSS(conn, '[-]days,[+|-]hh:mm…') → relative to now (e.g. -1:00 one hour ago, -1,08:00 yesterday 08:00).
  • dateConvert(conn, t, 'GMT_TO_LCT' | 'GMT_TO_LST' | 'LCT_TO_GMT' | 'LST_TO_GMT' | 'LCT_TO_LST' | 'LST_TO_LCT'). LST = standard time, LCT = with daylight saving.
  • Interval fields (e.g. REPORT_DF.LIFE_TIME) are <count>.<unit>: .0 s, .1 min, .2 h, .3 days, .4 weeks, .5 months, .6 years (same as dssutl, skill system-management).

3.13 Item history (§3.13)

Two functions bypass DSS and ask ITEM Service directly (faster than reading ITEM_HISTORY):

  • getHisGroupItems(conn, group[, node]) → item names in a storage group.
  • getItemHistory(conn, item, group, start, end, max_sample[, node=, interval=, attribute=, aggr_period=]) → list of tuples (time, value, status, option_bits, quality); the list ends with None when the period is complete, otherwise call again with the last time as start. interval = interpolation step in ms; attribute = VALUE (default), DEADBAND, limits, SCALE_LOW/HIGH, or for aggregation groups AGGR_MAX, AGGR_MIN, AGGR_AVERAGE, AGGR_INTG, AGGR_COUNT, AGGR_STDV, AGGR_DFMS; aggr_period = 30_MINUTES, HOUR, SHIFT, DAY, WEEK, MONTH, YEAR (only periods configured in the group). The manual's parameter list omits item (ISS-175).

3.14 Miscellaneous (§3.14)

getErrorStack(conn) (UMH stack as [code, text] pairs), version(), busGetDirs() (dict of TLS_* folders; installed also returns TLS_WAP, TLS_LOG), readSetup(conn, 'dur') (setup file without .sup as list of [keyword, args…]), logMessage(conn, text) (max 200 characters to the CI Server message log), umhLog(conn).

4. Exceptions (§4)

One exception class, dss.error, with args = (code, message):

  • CI Server errors: the last UMH message, e.g. DSS-E-EOS (end of dataset — the normal way to end a readNext loop), VIS-W-DUPLICATE (insert of an existing key).
  • Module errors PY_DSS_*: ALREADY_CONN, DS_IS_CLOSED, EVT_NOTIFY_DEF, FLT_DEF, FLT_NOT_ACTIV, FLT_NOT_FOUND, FLT_TOO_LONG (manual misprints FLY), MISG_IDX, NO_CHAN_OPEN, NO_EVT_DEF, NOT_CONN, NOT_LOGGED_IN, UNK_ERR, UNK_FLD, UNK_FLD_TYPE; the installed module has more (ISS-176).

Notes on the manual

The examples are carried over from an old Python 2 version (101L long integers, an old module version string, a FastTools install path) and contain typos (e.g. readEqual(con, dss, …) instead of the dataset handle, msg/mesg mixed up). They use dss.connect('admin',''); on a real system use a CI Server user with only the rights the script needs. Details: ISS-175.