DiamondLightSource / pythonSoftIOC

Embed an EPICS IOC in a Python process
Apache License 2.0
31 stars 9 forks source link

Modifying "RVAL" for an AI Record #148

Closed XavSPM closed 8 months ago

XavSPM commented 8 months ago

Hello,

I'm doing some tests to familiarize myself with pythonSoftIOC.

In one of my tests, I wanted to modify "RVAL" of an AI record in order to use "ASLO" for value conversion. Unfortunately, I get an error.

Is it possible to do this with pythonSoftIOC? Is there something I'm not doing correctly?

Xavier

Error return:

############################################################################
## EPICS 7.0.7.0
## Rev. 7.0.7.99.0.2
## Rev. Date 7.0.7.99.0.2
############################################################################
iocRun: All initialization complete
Python 3.12.1 (main, Dec  8 2023, 00:00:00) [GCC 13.2.1 20231205 (Red Hat 13.2.1-6)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> NON : PULSING:AO Valeur : 99.0 Vrai : 603
ERROR:root:Exception when running dispatched callback
Traceback (most recent call last):
  File "/home/xgoiziou@arronax.com/Projet/IOC/pulsing/V_Python/python3/lib64/python3.12/site-packages/softioc/asyncio_dispatcher.py", line 45, in async_wrapper
    await ret
  File "/home/xgoiziou@arronax.com/Projet/IOC/pulsing/V_Python/ioc_pulseur.py", line 9, in update_ao
    ai.set_field('RVAL',str(ao.get_field('RVAL')))
  File "/home/xgoiziou@arronax.com/Projet/IOC/pulsing/V_Python/python3/lib64/python3.12/site-packages/softioc/device.py", line 106, in set_field
    db_put_field(name, fields.DBF_STRING, addressof(data), 1)
  File "/home/xgoiziou@arronax.com/Projet/IOC/pulsing/V_Python/python3/lib64/python3.12/site-packages/softioc/imports.py", line 24, in db_put_field
    return _extension.db_put_field(name, dbr_type, pbuffer, length)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: dbPutField failed for PULSING:AI.RVAL

My code :

from softioc import softioc, builder, asyncio_dispatcher
import asyncio

dispatcher = asyncio_dispatcher.AsyncioDispatcher()
builder.SetDeviceName("PULSING")

async def update_ao(value, pv):
    print('NON : {0} Valeur : {1} Vrai : {2}'.format(pv, value, ao.get_field('RVAL')))
    ai.set_field('RVAL',str(ao.get_field('RVAL')))
    print('NON : {0} Valeur : {1} Vrai : {2}'.format(pv, ai.get(), ai.get_field('RVAL')))

ao = builder.aOut('AO',
                ASLO="0.1642",
                EGU="us", 
                DRVH="2820934519.356", 
                DRVL="0.1642", 
                PREC="4",
                on_update_name=update_ao)

ai = builder.aIn('AI', 
                ASLO="0.1642", 
                EGU="us", 
                HOPR="2820934519.356", 
                LOPR="0.1642", 
                PREC="4"
                )

builder.LoadDatabase()
softioc.iocInit(dispatcher)

#async def update():
#    while True:
#        ai.set(ai.get() + 1)
#        await asyncio.sleep(1)

#dispatcher(update)
softioc.interactive_ioc(globals())
Araneidae commented 8 months ago

There are a couple of issues here.

First of all, all channel access writes to In records are automatically disabled by pythonSoftIOC (by setting .DISA), because doing this is almost always a mistake ... as it is here!

Secondly, softIOC device ai/ao records do not use RVAL or any record scaling features, instead device support works directly on the underlying floating point value.

If you really want ai/ao records with value conversion support you can always use softioc.builder.records to create records without softIOC device support.