Init and Delete Device#
The basic lifecycle of a Tango device can be simplified into two parts: initialisation and clean-up. This happens within the operating system process that is called the device server.
As you saw in the previous lesson there is an init_device()
method. Your device can also have a delete_device()
method. Both of these override the default implementation in the base class Device
.
from tango.server import Device
class MegaCoffee3k(Device):
def __init__(self, *args, **kwargs):
print("MegaCoffee3k: __init__ start")
super().__init__(*args, **kwargs)
print("MegaCoffee3k: __init__ end")
def init_device(self):
super().init_device()
print("MegaCoffee3k: init_device")
def delete_device(self):
print("MegaCoffee3k: delete_device")
super().delete_device()
if __name__ == "__main__":
MegaCoffee3k.run_server()
Sorry, still TODO!
Sorry, still TODO!
Here the init_device
and delete_device
methods simply print a message.
The__init__
method is included with some print statements to show when it is called in the lifecycle.
Tip
It is important to still call the super class methods, as shown. init_device
at the
start of your method, and delete_device
at the end of your method.
Bonus tip: __init__
Device methods that use the Tango “machinery” cannot be called
before Device.__init__
has completed. E.g., the logging methods like info_stream
,
and things like push_change_event
, which you’ll learn about later.
Run this example server, and you’ll see the output:
MegaCoffee3k: __init__ start
MegaCoffee3k: init_device
MegaCoffee3k: __init__ end
Ready to accept request
MegaCoffee3k started on port 8888 with properties {}
Device access: tango://127.0.0.1:8888/test/nodb/megacoffee3k#dbase=no
Server access: tango://127.0.0.1:8888/dserver/MegaCoffee3k/megacoffee3k#dbase=no
The “init_device” message is printed before the device is ready to accept requests.
In this Python example, the init_device
call came from the base class constructor, Device.__init__
.
In a second terminal, use the device proxy client and send the built-in
Init()
command, which will re-initialise the device.
>>> dp.Init()
>>>
MegaCoffee3k: __init__ start
MegaCoffee3k: init_device
MegaCoffee3k: __init__ end
Ready to accept request
MegaCoffee3k started on port 8888 with properties {}
Device access: tango://127.0.0.1:8888/test/nodb/megacoffee3k#dbase=no
Server access: tango://127.0.0.1:8888/dserver/MegaCoffee3k/megacoffee3k#dbase=no
MegaCoffee3k: delete_device
MegaCoffee3k: init_device
To re-initialise the MegaCoffee3k device, Tango first calls the delete_device
method, and then the init_device
method. The constructor, __init__
, is not called, so
you still have the same Python object instance.
Finally, use the keyboard combination Ctrl
+C
to end the Tango device server application.
MegaCoffee3k: __init__ start
MegaCoffee3k: init_device
MegaCoffee3k: __init__ end
Ready to accept request
MegaCoffee3k started on port 8888 with properties {}
Device access: tango://127.0.0.1:8888/test/nodb/megacoffee3k#dbase=no
Server access: tango://127.0.0.1:8888/dserver/MegaCoffee3k/megacoffee3k#dbase=no
MegaCoffee3k: delete_device
MegaCoffee3k: init_device
^CMegaCoffee3k: delete_device
Done
You can see that delete_device
method was called again during the graceful shutdown.
Tip
Variables needed for the device state are normally initialised in init_device
rather than
in __init__
, since init_device
gets called again when the Init()
command is used.
Tip
If any system resources (memory, connections, file handles, etc.) need to be released when
the device shuts down, this kind of clean-up is usually done in delete_device
.
Restarting the device#
Using the admin device, you can restart the device completely, while
the device server, i.e., operating system process, remains running. This is typically done
less often than calling Init()
on the device.
Start your example device server again.
Create another client, this time using the Server access Tango resource locator.
Send the built-in DevRestart()
command, with the name of the device: test/nodb/megacoffee3k
.
>>> import tango
>>> ap = tango.DeviceProxy("tango://127.0.0.1:8888/dserver/MegaCoffee3k/megacoffee3k#dbase=no")
>>> ap.DevRestart("test/nodb/megacoffee3k")
>>>
You’ll see the following output:
MegaCoffee3k: __init__ start
MegaCoffee3k: init_device
MegaCoffee3k: __init__ end
Ready to accept request
MegaCoffee3k started on port 8888 with properties {}
Device access: tango://127.0.0.1:8888/test/nodb/megacoffee3k#dbase=no
Server access: tango://127.0.0.1:8888/dserver/MegaCoffee3k/megacoffee3k#dbase=no
MegaCoffee3k: delete_device
MegaCoffee3k: __init__ start
MegaCoffee3k: init_device
MegaCoffee3k: __init__ end
This time you notice a second call to __init__
, so a new instance of the Python object
representing the device has been created.
Bonus tip: RestartServer
The admin device also has a RestartServer()
command than can be used to restart all
the devices in a server, without naming a specific one. In this example ap.RestartServer()
.
Summary#
There are various ways of restarting/re-initialising a Tango device. From least to most drastic:
What? |
How? |
Process |
Object |
---|---|---|---|
Re-initialise device |
Send |
Unchanged |
Unchanged |
Re-start device |
Send |
Unchanged |
New |
Re-start device server |
Terminate operating system process and run it again |
New |
New |