paulscherrerinstitute/pcaspy

pysh.py example in the tutorial does not work (caput'ed value is garbage).

CarlosCumming opened this issue · 3 comments

The pysh.py example in the pcaspy tutorial fails on both of my Linux machines (Ubuntu, centos7) using both python2 and python3, and epics 3.15.9. The following code produces this output with a "caput MTEST:COMMAND date":

$ ./pysh.py
('WRITE', 'COMMAND', '\xda')

This code is from the example stripped down to it's bare minimum, including removing the async example code.

#!/usr/bin/env python

import time
import sys
from pcaspy import Driver, SimpleServer

prefix = 'MTEST:'
pvdb = {
    'COMMAND' : {
        'type' : 'char',
        'count': 128,
    },
}

import math
class myDriver(Driver):
    def __init__(self):
        Driver.__init__(self)
        self.tid = None

    def write(self, reason, value):
        print("WRITE", reason, value)
        self.setParam(reason, value)
        return True

if __name__ == '__main__':
    server = SimpleServer()
    server.createPV(prefix, pvdb)
    driver = myDriver()

    while True:
        # process CA transactions
        server.process(0.1)

For PVs of char array, use the -S switch of caget/caput command.

$ caput -S MTEST:COMMAND "a long command to run"
Old : MTEST:COMMAND 
New : MTEST:COMMAND a long command to run

For string type, channel access limits the string length to 40. They are reported as DBF_STRING by cainfo command. In EPICS IOC database, they can be the VAL field of stringin/stringout records, or DESC, INP, OUT fields to name a few. In pcaspy program, they are PVs configured as {"type": "string"}.

To work with long strings, use char arrays. They are reported as DBF_CHAR with the count as the string length. In EPICS IOC database, they are mostly configured as waveform records with FTVL=CHAR and NELM=<length>. Also adding a $ suffix to the DBF_STRING type will also retrieve as char arrays. In pcaspy program, they are PVs configured as {"type": "char", "count": <length>}.

E.g. this is a char array record in EPICS IOC,

record(waveform, "MTEST:COMMAND")
{
    field (FTVL, "CHAR")
    field (NELM, "128")
}

Here shows how -S switch treats it as a string.

$ cainfo MTEST:COMMAND
MTEST:COMMAND
...
    Native data type: DBF_CHAR
    Request type:     DBR_CHAR
    Element count:    128

$ caget MTEST:COMMAND
MTEST:COMMAND 128 100 97 116 101 116 105 109 101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

$ caget -S MTEST:COMMAND
MTEST:COMMAND datetime