taurus-org / taurus

Moved to https://gitlab.com/taurus-org/taurus
http://taurus-scada.org
43 stars 46 forks source link

Unsynchronised attr in Taurus with Tango device using pure events #1145

Closed vallsv closed 3 years ago

vallsv commented 3 years ago

Hi,

I have designed a Tango device a long time ago (5 years ago), based on events (explicitly emitting state, position (float position in an axis) and positionId (named position in this axis).

Basically the Tango device use explicitly set_change_event('state', True, True) and push_change_event("state", tangoState). And that's the same for other attributes.

I had a problem on custom widgets cause the state attribute was not synchronized in my GUI.

Checking monitoring with jive and astor everything looks fine. Events are sent, and jive display the right content.

Trying a pure taurus code with taurus form, i noticed few other things

Did you noticed the same thing? Do you have any idea where the problem come from?

Screenshot from 2020-08-25 15-27-10

vallsv commented 3 years ago

Here is the version i am using

In [3]: taurus.core.release.version
Out[3]: '4.6.5-alpha'

In [4]: taurus.core.release.revision
Out[4]: '0'
vallsv commented 3 years ago

In case, if you know how to enable programmatically a client side polling, it could be a very useful hack for me.

vallsv commented 3 years ago

For now i will use that on my widget. As i use a specific widget for this device it's fine.

model = self.getModelObj()
model.activatePolling(3000, force=True)
cpascual commented 3 years ago

In a hurry now. Will look at it later, but in the meanwhile, just note that by default a label background in taurus>4 shows the taurus state, not the tango state (see docs for more info, and run taurus demo )

vallsv commented 3 years ago

Here is a trace.

Basically i have requested to move an attribte from ` tofoil1(foil2was the previous value before ), here is the result with with theCHANGE` event.

You can notice the CHANGE event is received, the value is right: foil1, self._last_value is updated, the widget update is requested, but label.getDisplayValue(fragmentName=fgRole) returns foil2.

If you have an idea?

> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(109)handleEvent()
-> if evt_src == self.modelObj():
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(110)handleEvent()
-> if evt_type in (TaurusEventType.Change, TaurusEventType.Periodic):
(Pdb) TaurusEventType.Periodic
2
(Pdb) TaurusEventType.Change
0
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(111)handleEvent()
-> if self._last_value is None:
(Pdb) self._last_value
TangoAttrValue{'_TangoAttrValue__attrName': u'tango://nano.esrf.fr:20000/id16ni/foil/bpm3/positionId', 'wvalue': 'foil1', '_attrRef': <weakproxy at 0x7f809c629a10 to TangoAttribute at 0x7f80a4061450>, 'rvalue': '', '_TangoAttrValue__attrType': 2, '_pytango_dev_attr': DeviceAttribute(data_format = tango._tango.AttrDataFormat.SCALAR, dim_x = 1, dim_y = 0, has_failed = False, is_empty = False, name = 'positionId', nb_read = 1, nb_written = 1, quality = tango._tango.AttrQuality.ATTR_VALID, r_dimension = AttributeDimension(dim_x = 1, dim_y = 0), time = TimeVal(tv_nsec = 0, tv_sec = 1600176739, tv_usec = 181183), type = tango._tango.CmdArgType.DevString, value = '', w_dim_x = 1, w_dim_y = 0, w_dimension = AttributeDimension(dim_x = 1, dim_y = 0), w_value = 'foil1'), 'time': TimeVal(tv_nsec = 0, tv_sec = 1600176739, tv_usec = 181183), 'error': None, 'config': <weakproxy at 0x7f809c629a10 to TangoAttribute at 0x7f80a4061450>, 'quality': <AttrQuality.ATTR_VALID: 0>}
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(114)handleEvent()
-> self._last_value = evt_value
(Pdb) evt_value.rvalue
'foil1'
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(125)handleEvent()
-> self.update()
(Pdb) s
--Call--
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(139)update()
-> def update(self):
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(140)update()
-> widget = self.widget()
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(141)update()
-> self._updateConnections(widget)
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/tauruscontroller.py(142)update()
-> self._updateForeground(widget)
(Pdb) s
--Call--
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/display/tauruslabel.py(107)_updateForeground()
-> def _updateForeground(self, label):
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/display/tauruslabel.py(108)_updateForeground()
-> fgRole, value = label.fgRole, ''
(Pdb) label
<linecontrol.widget.taurus.TaurusFiltredLabel.TaurusFiltredLabel object at 0x7f80a40b0b90>
(Pdb) label.fgRole
'rvalue'
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/display/tauruslabel.py(111)_updateForeground()
-> if fgRole.lower() == 'state':
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/display/tauruslabel.py(116)_updateForeground()
-> elif fgRole.lower() in ('', 'none'):
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/display/tauruslabel.py(119)_updateForeground()
-> value = label.getDisplayValue(fragmentName=fgRole)
(Pdb) n
> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/display/tauruslabel.py(120)_updateForeground()
-> self._text = text = label.prefixText + value + label.suffixText
(Pdb) value
'foil2'
vallsv commented 3 years ago

Here i found the inconsistency

> /users/valls/workspace/id16/taurus.git/lib/taurus/qt/qtgui/base/taurusbase.py(910)getDisplayValue()
-> return self.displayValue(v)
(Pdb) self.displayValue(v)
'foil2'
(Pdb) v
'foil1'

The thing is TaurusLabel cache the result in self._permanentText, but it is never cleared. So the first result displayed is also the last one. I will make a ugly patch on my side. I guess there is nice way to fix that.

-> if self._permanentText is None:
(Pdb) self._permanentText    
'foil2'

I guess in permanentText you only expect to have the formatting?

vallsv commented 3 years ago

Or maybe _setPermanentText should never be called. Which make sense. But is called on my env. I will check that.

vallsv commented 3 years ago

Sorry. I am fully wrong. Here it was again a problem with inherited widgets.

And i am using your dev branch, which looks to work fine now.

I will check again the version i have pinpointed. But this issue can be closed.

cpascual commented 3 years ago

ok, glad to hear that this is not an issue in the develop branch. I then close the issue.

Still, just for he record, to answer your question about the permanentText: permanentText is there for customizing the text of the label. It can be used to show a static text, or it can contain replacement fields. AFAIKT, it should not have been set unless you explicitly customized it by calling TaurusLabel.setText(). Note that if you once set it, it may be stored in the configuration settings and therefore restored upon initialization.