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>
116 lines
6.7 KiB
Markdown
116 lines
6.7 KiB
Markdown
---
|
||
task: Set up Python and pyTOOLS, check the server side, run a first read-only script
|
||
version: R1.05
|
||
source: IM 36K10P40-01EN §1, §2, §3.2, §3.4, §3.5, §3.12, §3.14, §4 (2nd ed., Feb. 2026); IM 36K01C10-01EN §1.3.3 (5th ed., Feb. 2026, Python 3.12); IM 36K10J10-01EN §2.9.1 (5th ed., Feb. 2026, login method); installed files on the R1.05 test server (2026-10-09)
|
||
status: from docs, not tested (no Python on the R1.05 test server). Verified read-only on the R1.05 test server 2026-10-09 - `tls\exe\dss.pyd` (module 3.6.1), `DSSSDAPY` started by `database_start.cmd`, `dss.sup` routing, `dssana.sup` Python Interface lines; no Python installed there (only the 0-byte Microsoft Store aliases). R1.03 (development machine 2026-10-09): R1.03 `dss.pyd` imports under Python 3.12.10, `version()` and `busGetDirs()` work without CI Server running
|
||
---
|
||
|
||
# Set up pyTOOLS and run a first script
|
||
|
||
## 1. Check the server side (read-only)
|
||
|
||
| Check | Command | Expected (R1.05) |
|
||
|---|---|---|
|
||
| Module present | `dir "%TLS_ROOT_PATH%\tls\exe\dss.pyd"` | 137,728 bytes, Jun. 2026 (R1.03: 124,928 bytes, Aug. 2023) |
|
||
| Dedicated DSS server running | `durwfp -p DSSSDAPY -t 0` then `echo %ERRORLEVEL%` (separate commands) | `0` |
|
||
| Started by | `findstr /i dsssdapy "%TLS_ROOT_PATH%\tls\com\database_start.cmd"` | `start /B /NORMAL ...\dsssda -n dsssdapy` |
|
||
| Client routing | `findstr /i PYDSS "%TLS_ROOT_PATH%\tls\sup\dss.sup"` | `DSSSDA_SRV = -1, "PYDSS*", "DSSSDAPY"` |
|
||
| Allowed as user interface + login method | `findstr /c:"Python Interface" "%TLS_ROOT_PATH%\tls\sup\dssana.sup"` | `USER_INTERFACE = "Python Interface", "PYDSS", 18, ...` and `LOGIN_METHOD = "<local>"` / `"<remote>"`, `"Python Interface", Manual CI Server, NO,` |
|
||
| Python | `where python` and `py -0p` | a real `python.exe` (a 0-byte file under `...\WindowsApps` is only the Store alias = **no Python**) |
|
||
|
||
If the *Python Interface* lines are missing (e.g. after a merge of an old `dssana.sup` during an
|
||
upgrade), pyTOOLS cannot log on: compare with `tls\sup\dssana.sup` of a clean R1.05 install
|
||
(skill `portal-setup`, setup-file merge).
|
||
|
||
## 2. Install Python and the environment (user, administrator)
|
||
|
||
> **Action needed (administrator, on the CI Core / CI Portal):**
|
||
> 1. Install **64-bit Python 3.12** from python.org (right-click the installer › *Run as
|
||
> administrator*; tick *Add python.exe to PATH* or use the `py` launcher). Python 3.12 is the
|
||
> version listed as allowed coexisting software in IM 36K01C10.
|
||
> 2. Add the **system** variable `PYTHONPATH` = `%TLS_ROOT_PATH%\tls\exe` with the real path
|
||
> (e.g. `C:\Yokogawa\CIServer\tls\exe`; the manual's `C:\Program Files (x86)\...` is only the
|
||
> default). PowerShell (admin):
|
||
> `[Environment]::SetEnvironmentVariable('PYTHONPATH', "$env:TLS_ROOT_PATH\tls\exe", 'Machine')`
|
||
> 3. Open a **new** command prompt and run `python -c "import dss; print(dss.version())"`.
|
||
> Expected on R1.05: `pyTOOLS DSSmodule 3.6.1 r11609M [Jun 10 2026, ...]`.
|
||
|
||
Without changing the system variable, a script can add the folder itself (used in the examples
|
||
below): `sys.path.insert(0, os.path.join(os.environ['TLS_ROOT_PATH'], 'tls', 'exe'))`.
|
||
`TLS_ROOT_PATH` is set by the CI Server installation. The module finds its CI Server DLLs
|
||
(`buslib64.dll`, `databaselib64.dll`) in the same folder.
|
||
|
||
## 3. First read-only script
|
||
|
||
Needs a CI Server user (any authorization group that may read items; e.g. the sample's `CIENG`
|
||
user, which has no password). Save as `first_read.py` in a scratch folder.
|
||
|
||
```python
|
||
import os, sys, getpass
|
||
sys.path.insert(0, os.path.join(os.environ['TLS_ROOT_PATH'], 'tls', 'exe'))
|
||
import dss
|
||
|
||
ITEM = 'CI-Eng-Sample.TANK1.LEVEL' # or <Section>.<Tag>
|
||
|
||
print(dss.version()) # works without a connection
|
||
user = os.environ.get('CI_USER') or input('CI Server user: ')
|
||
pwd = os.environ.get('CI_PASSWORD')
|
||
if pwd is None:
|
||
pwd = getpass.getpass('Password: ')
|
||
|
||
conn = dss.connect(user, pwd) # connect + logon (Manual CI Server)
|
||
try:
|
||
ds = dss.openDataset(conn, 'LOCAL_NODE_DF',
|
||
['NAME', 'NODE_NUMBER', 'VERSION_MAJOR', 'VERSION_MINOR',
|
||
'VERSION_PACK', 'STARTUP_TIME'], 'r')
|
||
try:
|
||
node = dss.readNext(conn, ds)
|
||
print('Node %s (%d), CI Server R%d.%02d.%02d, started %s' % (
|
||
node['NAME'], node['NODE_NUMBER'], node['VERSION_MAJOR'],
|
||
node['VERSION_MINOR'], node['VERSION_PACK'],
|
||
dss.dateString(conn, node['STARTUP_TIME'], 'GENERAL')))
|
||
finally:
|
||
dss.closeDataset(conn, ds)
|
||
|
||
ds = dss.openDataset(conn, 'ITEM_VAL',
|
||
['NAME', 'ITEM_VALUE', 'STATUS', 'UPDATE_TIME'], 'r')
|
||
try:
|
||
rec = dss.readEqual(conn, ds, ITEM)
|
||
print('%s = %s (%s) at %s' % (rec['NAME'], rec['ITEM_VALUE'], rec['STATUS'],
|
||
dss.dateString(conn, rec['UPDATE_TIME'], 'GENERAL')))
|
||
except dss.error as e:
|
||
code, text = e.args
|
||
print('Cannot read %s: %s %s' % (ITEM, code, text))
|
||
finally:
|
||
dss.closeDataset(conn, ds)
|
||
finally:
|
||
dss.close(conn) # also logs out
|
||
```
|
||
|
||
Run: `python first_read.py` (with `CI_USER=CIENG` and `CI_PASSWORD=` set, or answer the
|
||
prompts). Expected: the module version, one line for the local node (version matching the
|
||
`system-check` result) and the current value of the item. An unknown item gives a `dss.error`
|
||
from DSS (record not found) instead of a crash.
|
||
|
||
## 4. Typical first errors
|
||
|
||
| Symptom | Cause |
|
||
|---|---|
|
||
| `ModuleNotFoundError: No module named 'dss'` | `PYTHONPATH` / `sys.path` does not point to `tls\exe`, or an old prompt without the new variable |
|
||
| `ImportError: DLL load failed` / not a valid Win32 application | 32-bit Python, or CI Server DLLs missing (not a CI Core / Portal) |
|
||
| `PY_DSS_NOT_LOGGED_IN` | `dss.connect()` without user/password, then a dataset call: DSS gives no data without a logon |
|
||
| `PY_DSS_ALREADY_CONN` | a second `dss.connect()` in the same script |
|
||
| Logon refused | wrong password, user unknown, or the *Python Interface* login method is not *Manual CI Server* / missing (§1) |
|
||
| `DSS-E-EOS` | end of dataset in a `readNext` loop: normal, catch it (task `read-items-history.md`) |
|
||
|
||
Check afterwards: the audit trail shows the logon/logout with source `PYTOOLS` (skill
|
||
`audit-trail`).
|
||
|
||
## 5. User verification (R1.05, not yet done)
|
||
|
||
1. §1 checks (all read-only) → expected values as in the table.
|
||
2. §2 on a test Core with Python 3.12 64-bit → version string as above.
|
||
3. §3 with a read-only user → node line + item value; then confirm in the audit trail that the
|
||
logon and logout were recorded with source `PYTOOLS`.
|
||
4. Also try `dss.connect()` without user followed by `openDataset` → expect
|
||
`PY_DSS_NOT_LOGGED_IN` (ISS-178).
|