Subscribe events from device with many attributes
|
|
---|---|
Andy Thanks for your kind explanation; When I tested with add_dynamic_attribute routine I have two questions; 1. How to set the set_event_abs_change for DEV_BOOLEAN It gives error that The property abs_change is not settable for the attribute data type 2. When I tried to delete the dynamic attribute pointere, it gives abnormal quit. Is it not recommended? // below caused abnormal quit!!Below is the code that I tested
|
|
|
---|---|
Hi, About your first question, you don't need to use set_event_abs_change for DEV_BOOLEAN attributes. If a client subscribes on CHANGE event on a DEV_BOOLEAN attribute, it will receive an event every time the value changes from true to false or from false to true. About your second question, it seems we don't have enough information to be able to help you. Where does DynamicFINSAttribute class come from? Is it a class you created? Kind regards Reynald
Rosenberg's Law: Software is easy to make, except when you want it to do something new.
Corollary: The only software that's worth making is software that does something new. |
|
|
---|---|
Reynald, Thanks for your response. Regarding the second question; The DynamicFINSAttribute class was actually copied and renamed from "ModbusDataViewer" under Communication. After digging into existing code, I found critical bug in there. The original code in DynamicAttributesHelper.cppis
The problem is when there's chances to add duplicate attribute. Then the add_attribute routine releases the attr without raise exception. So the program abnormally quitted at the code of _attr->get_name(). I'm not sure whether quick fix for this problem as below is the proper one;
I wish the add_attribute function returns result value, not just deleting the passed parameter silently. |
|
|
---|---|
There are some important lines missing in the code you pasted from DynamicAttributesHelper.cpp file. (https://sourceforge.net/p/tango-ds/code/HEAD/tree/DeviceClasses/Communication/ModbusDataViewer/trunk/src/DynamicAttributesHelper.cpp) There are some lines at the beginning of the method which are checking whether the attribute was already added, and if it was already added, the method throws an exception:
So it seems there is no chance to add a duplicate attribute with this code.
Rosenberg's Law: Software is easy to make, except when you want it to do something new.
Corollary: The only software that's worth making is software that does something new. |
|
|
---|---|
Reynald, The code that you mentioned is already there. It was clipped for clarification. So it seems there is no chance to add a duplicate attribute with this code. Unfortunately, this could happen when there's more than one device from the same server To reproduce the case when rep_find throws no exception but the attr_list has the attribute, create two devices of the same server. Then the first device passed without any problem, but the second device caught the situation. The call stack is at TOmronServer.exe!TOmronServerHC_ns::TOmronServerHCClass::device_factory(const Tango::DevVarStringArray * devlist_ptr=0x00000000008fe6f0) 줄 409 C++ See the captured picture which shows this case; |
|
|
---|---|
Hi, Indeed you are right. It seems the developer should not try to access to the attribute variable passed to add_attribute() after having invoked this method since, as you noticed, add_attribute() might release it if the attribute was previously already added (even by another device). This is not well documented. I think the documentation should be improved by giving examples on dynamic attributes management. I guess this is what you were looking for when you ended up re-using ModbusDataViewer code. I've never used this ModbusDataViewer device server, but it might be that in practice, it has never been used (or was not supposed to be used) with several devices per device server instance. Cheers, Reynald
Rosenberg's Law: Software is easy to make, except when you want it to do something new.
Corollary: The only software that's worth making is software that does something new. |
|
|
---|---|
I actually would not recommend the approach from ModbusDataViewer device server in recent Tango code. The recent versions of Tango have introduced the add_dynamic_attributes() method for a better and more standard way to handle dynamic attributes. Let's suppose your class is named Example. If you generate C++ code from POGO for a class named Example, you will notice that POGO generates a method named Example::add_dynamic_attributes() for you in Example.cpp Pogo will also generate some code to invoke this method during the device creation (after init_device() is executed). You can see this code in ExampleClass.cpp generated file in ExampleClass::device_factory() method. In ExampleClass.cpp, you will also notice that there is a method called ExampleClass::erase_dynamic_attributes() which will take care of erasing the dynamic attributes which were created during the previous call to add_dynamic_attributes(). So what you need to do is simply add the code to create the attributes in Example::add_dynamic_attributes() method. Tango will take care of cleaning the created attributes for you the next time the device is created again (typically when you invoke restart device). You don't need to maintain yourself a map containing the list of attributes you dynamically created and you don't need to remove them in Example::delete_device(). Please be aware that if you are using what I suggested above, if you invoke the Example::init command, Example::add_dynamic_attributes() will not be invoked. It is invoked when you click on restart device from jive though (equivalent to DevRestart command from admin device). I would recommend this approach since the recent tango code and recently added features like the Interface Change Events have been designed with this approach in mind I think. Hoping this helps, Reynald
Rosenberg's Law: Software is easy to make, except when you want it to do something new.
Corollary: The only software that's worth making is software that does something new. |