Radiation Monitor Python Script Documentation

From New IAC Wiki
Revision as of 20:02, 9 March 2011 by Buckminst (talk | contribs) (→‎reload_configuration)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The Radiation Monitor Python script is a DBus-enabled UDP forwarding and reporting script designed to interpret and rebroadcast the information provided by the Ludlum Measurement Inc. 375-9 series Radiation Monitors in use at the IAC and in the ISU Physics building. It utilizes the common iac.nagios. DBus service and /IAC/Nagios/ service path for statistic reporting to the IAC Nagios server.

Configuration And Use

Before first execution, the following directories will need to be created, with proper permissions for the nagios user to write to them:

  • /var/log/iac
  • /etc/iac

These directories will be common for the Radiation Monitoring script as well as the Cluster Room Temperature Monitor script.

Once /etc/iac exists, you will need to create the rad_monitors.cfg configuration file within that directory. The configuration file syntax is described below.

The Radiation Monitor script, if called without a configuration file, uses the following defaults:

  • Local Address: None
  • Listen Address: 255.255.255.255
  • Listen Port: 55555
  • Verbose Mode (Non-Daemon): False
  • Debug Mode: False
  • Daemon Mode: True
  • Log Mode: Append
  • Send Clients: None

The command to start the Radiation Monitoring script is simply rad_monitors.py. This script will need to be ran by the nagios user.

Configuration File

Example Configuration File

#local:134.50.87.179:55554
listen:255.255.255.255:55555
sendto:127.0.0.1:54321
#sendto:134.50.87.179:54321
#verbose
#debug
noforward
#nodaemon
#truncate

Lines beginning with # are ignored by the script and may be used for comments on lines seperate from directive lines, or to remove directives from active use. For comments on lines containing directives, please place them at the end and prepend a : before the comment.

Configuration Directives

local

This directive will allow you to bind to a specific IP address/interface and port number for purposes of UDP packet source information. By default the program will choose whichever interface is needed to talk to the send clients, as well as a random high port. The proper syntax for this directive is as follows:

local:local_ip:local_port

This directive cannot be changed during run-time.

listen

This directive will allow you to specify what interface/IP address and port to listen for packets on. By default this is set for UDP broadcasts on 255.255.255.255. The proper syntax for this directive is as follows:

listen:listen_ip:listen_port

This directive cannot be changed during run-time.

sendto

This directive will allow you to specify any number of clients to forward the UDP packets on to, one per directive line. The proper syntax for this directive is as follows:

sendto:target_ip:target_port

Additional send clients can be added while the script is running by sending SIGHUP or using the DBus reload_configuration method to reload the configuration file, or by using the DBus add_send_client method.

verbose

This directive sets the Radiation Monitor script into verbose interactive mode (non-daemonized), for the purposes of examining packet flow and diagnostics. This directive needs no arguments and can simply be specified in the configuration file.

This directive cannot be changed during run-time.

debug

This directive sets the Radiation Monitor script into a further debugging mode, for program flow and diagnostic purposes.

This directive can be changed during run-time by sending SIGHUP or using the DBus reload_configuration method to reload the configuration file.

noforward

This directive disables packet forwarding for the Radiation Monitor. This can be useful if you wish to run the script just for listening purposes, or for troubleshooting.

This directive can be changed during run-time by sending SIGHUP or using the DBus reload_configuration method to reload the configuration file.

nodaemon

This directive sets the Radiation Monitor script to run in interactive (non-daemonized) mode, but without verbose output. This can be useful for troubleshooting purposes or if you wish to run the process in a screen session.

This directive cannot be changed during run-time.

truncate

This directive requires the Radiation Monitor script to clear its log file at each session start, rather than appending (the default log method).

This directive cannot be changed during run-time.

API

DBus Quick Reference

Service Bus: SystemBus()

Service Name: iac.nagios.radmonitors

Service Path: /IAC/Nagios/RadMonitors

Exposed Methods

get_active_channels()
get_active_monitors()
get_active_monitor_count()
get_radiation_levels()
add_send_client(string)
reload_configuration()

DBus Interaction

Before you can interact with the Radiation Monitor's DBus service, you will need to load some prerequisite Python libraries:

import dbus

This is the minimum to connect to DBus. If you wish to do more than connect as a client, you will need to load the following libraries:

import dbus.service, gobject
from dbus import glib

It is also recommend that you initialize threading now if you are planning on performing threaded tasks:

gobject.threads_init()
glib.init_threads()

Connecting to the Radiation Monitor DBus service

To interact with the Radiation Monitor DBus service in Python, you will first need to connect to the DBus System bus:

dbus_bus = dbus.SystemBus()

Note: The Radiation Monitor script must be run as root to connect to the System bus.

Once you have successfully connected to the System bus, you will then want to get the DBus service object for the Radiation Monitor. This is done via the get_object bus method:

dbus_object = dbus_bus.get_object(service_name, service_path)

For our Radiation Monitor interface, the proper invocation is as follows:

dbus_object = dbus_bus.get_object("iac.nagios.radmonitors", "/IAC/Nagios/RadMonitors")

After this is done, you may choose to call the Radiation Monitor's DBus methods either through the service object itself, or you may create references to specific methods for use:

dbus_method_ref = dbus_object.get_dbus_method(method, service_name)

Example:

>>> remote_method = remote_object.get_dbus_method('get_active_monitor_count', 'iac.nagios.radmonitors')
>>> remote_method()
dbus.Int32(7)

Introspection Schema

The Radiation Monitor DBus service returns the following schema upon being called with its inherited Introspect() method:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/IAC/Nagios/RadMonitors">
  <interface name="iac.nagios.radmonitors">
    <method name="reload_configuration">
    </method>
    <method name="get_active_monitors">
    </method>
    <method name="get_active_monitor_count">
    </method>
    <method name="add_send_client">
      <arg direction="in"  type="v" name="new_client" />
    </method>
    <method name="get_radiation_levels">
    </method>
    <method name="get_active_channels">
    </method>
  </interface>
  <interface name="org.freedesktop.DBus.Introspectable">
    <method name="Introspect">
      <arg direction="out" type="s" />
    </method>
  </interface>
</node>

Methods

get_active_channels

This exposed DBus method will return a dbus.Array value representing the active channels the script sees. It is invoked in the following manner:

dbus_object.get_active_channels()

Example output:

>>> remote_object.get_active_channels()
dbus.Array([dbus.Int32(1), dbus.Int32(2), dbus.Int32(3), dbus.Int32(4), dbus.Int32(5), dbus.Int32(6), dbus.Int32(7)], signature=dbus.Signature('i'))

get_active_monitors

This exposed DBus method will return a dbus.Array value representing the IP address of all radiation monitors the script sees. It is invoked in the following manner:

dbus_object.get_active_monitors()

Example output:

>>> remote_object.get_active_monitors()
dbus.Array([dbus.String(u'192.168.40.155'), dbus.String(u'192.168.40.154'), dbus.String(u'192.168.40.121'), dbus.String(u'192.168.40.172'),
dbus.String(u'192.168.40.137'), dbus.String(u'192.168.40.159'), dbus.String(u'192.168.40.120')], signature=dbus.Signature('s'))

get_active_monitor_count

This exposed DBus method will return a dbus.Int32 value representing the total number of active monitors the script sees. It is invoked in the following manner:

dbus_object.get_active_monitor_count()

Example output:

>>> remote_object.get_active_monitor_count()
dbus.Int32(7)

get_radiation_levels

This exposed DBus method will return a dbus.Array value representing the current radiation level of all monitors the script sees. It is invoked in the following manner:

dbus_object.get_radiation_levels()

Example output:

>>> remote_object.get_radiation_levels()
dbus.Array([dbus.String(u'0.0'), dbus.String(u'0.0'), dbus.String(u'0.0'), dbus.String(u'0.0'), dbus.String(u'0.1'), dbus.String(u'0.1'),
dbus.String(u'0.1')], signature=dbus.Signature('s'))

add_send_client

This exposed DBus method will add a new send target client to a running instance of the script, allowing for on-the-fly addition of targets without restarting. It is invoked in the following manner:

dbus_object.add_send_client(string)

Where string is a string containing the IP address and destination port number of the send target, formatted as "ip:port". The function returns a dbus.Boolean value; True if the add is successful, False if not.

Note: This only adds the new send client to the in-memory send list. If you wish to retain this send client for future use, you will need to edit the configuration file and add the appropriate sendto directive for that client.

Example output:

>>> remote_object.add_send_client("134.50.87.179:55555")
dbus.Boolean(True)

reload_configuration

This exposed DBus method will cause a running instance of the script to reload its configuration file, as if having been sent signal SIGHUP. It is invoked in the following manner:

dbus_object.reload_configuration()

The function always returns dbus.Boolean True at this time.

Example output:

>>> remote_object.reload_configuration()
dbus.Boolean(True)