stella.io
Class PollingRS485Server

java.lang.Object
  extended by util.PropertyContainer
      extended by util.PropertyResources
          extended by util.PropertyBundles
              extended by io.AbstractDriver
                  extended by io.AbstractSerialDriver
                      extended by stella.io.RS485Server
                          extended by stella.io.CastingRS485Server
                              extended by stella.io.WatchdogRS485Server
                                  extended by stella.io.PollingRS485Server
All Implemented Interfaces:
Driver, Cloneable, Remote, CacheChangedCaster, PollerQuery, RmiSerialCaster, ExitCleaning, Initializable, LocalizedSupplying, PropertySupplying, ResourceSupplying, RmiCaster
Direct Known Subclasses:
DummyRS485, JRS485Simulator

public class PollingRS485Server
extends WatchdogRS485Server
implements CacheChangedCaster, PollerQuery

An extension to a normal RS485-server. This server additionally reads its input channels in a repetitive thread. It therefore scans the values of its KEY_ACTIVEREAD and KEY_PASSIVEREAD, respectively, which points to a comma-separated list of command strings. These list can be altered during the live-time of the poller only with a call to the property container's PropertyContainer.setProperty(java.lang.String, java.lang.String) command followed by an appropriate switch-state command. In one cycle all of these strings are then sent as commands to the underlying serial port, the actual list used depending on the state of the poller, see setActive() and setPassive(). The incomming replies (i.e. the channel values) are stored in a hashtable for later retrieval. Users of this class can query the results with calls to the servers readChannel(java.lang.String) method. They must provide the correct read string otherwise lookup will fail.

Note that during the recurrent reading operations, no commands can be written to the serial port. Write commands are delayed until reading the channels has completed. To avoid dead-lock situations the polling intervall KEY_POLLBASE should not be set too small.

Two different polling states are distinguished, active and passive. As the name implies, active polling is meant for phases with rapid changes in the read-cache, like during roof movement. The passive phase is intended for low-resolution serial querying, e.g. during weather-only phases. For the read-list, at least one of the two read-keys, KEY_ACTIVEREAD or KEY_PASSIVEREAD must be given.


Nested Class Summary
static class PollingRS485Server.CacheDump
          Dumps the poller cache of a remote polling rs485.
static class PollingRS485Server.ConcurrentTest
          Test concurrent access to the serial line by polling and additionally using the CastingRS485Server.writeCommand(java.lang.String) method to additionally write commands and retrieve replies from the serial line.
static class PollingRS485Server.Interleave
          Writes the second argument on the command line to the polling rs 485 server bound to the registry with the name of the first command line argument.
protected  class PollingRS485Server.Poller
          The polling timer task.
static class PollingRS485Server.Test
          Testing purpose.
 
Nested classes/interfaces inherited from class stella.io.RS485Server
RS485Server.Checksum, RS485Server.Command, RS485Server.Info, RS485Server.Scan
 
Nested classes/interfaces inherited from class io.AbstractSerialDriver
AbstractSerialDriver.Available
 
Nested classes/interfaces inherited from class util.PropertyResources
PropertyResources.URLResource
 
Field Summary
protected  Map cache
          The hashtable linking read-commands to results.
protected  Map cachelisten
          The hashtable matching keys to registered cache changed listeners.
private static boolean DEFCASTPOLL
          The default value for casting polling commands (false).
private static int DEFDROP
          The default dropping rate.
private static long DEFPOLLBASE
          The default polling base time, 100 ms.
private static int DEFRESPONDMAX
          Maximum number of cycles for blocked reading.
private static boolean DEFSTARTOPEN
          The default value for starting polling at port open (true).
private  boolean isactive
          The poller state.
static String KEY_ACTIVEDROP
          The key to the number of steps dropped on active reads.
static String KEY_ACTIVEREAD
          The key linked to the commands sent to the serial port.
static String KEY_CASTPOLL
          The key defining event-casting for polling commands.
static String KEY_PASSIVEDROP
          The key to the number of steps dropped on passive reads.
static String KEY_PASSIVEREAD
          The key linked to the commands sent to the serial port.
static String KEY_POLLBASE
          The key for the basic polling time.
static String KEY_RESPONDMAX
          The key for the response-reading timeout (ms).
static String KEY_STARTOPEN
          Points to true if polling should start after opening of the port.
private  PollingRS485Server.Poller poll
          The polling thread.
protected  Map<String,Long> timecurrent
          The hashtable linking read-commands to last read-times.
protected  Map<String,Long> timemax
          The hashtable linking read-commands to read-time maxima.
protected  Map<String,Long> timemin
          The hashtable linking read-commands to read-time minima.
protected  Map validcache
          The hashtable linking read-commands to validity of results.
 
Fields inherited from class stella.io.WatchdogRS485Server
hosttimer, KEY_CASTOK, KEY_COOLDOWN, KEY_HOSTOK, KEY_INCREMENT, KEY_OKTIME, KEY_RESETONCLOSE, KEY_SAFETY, KEY_WATCHDOG, KEY_WATCHTIME
 
Fields inherited from class stella.io.CastingRS485Server
KEY_BIND
 
Fields inherited from class stella.io.RS485Server
KEY_CHECKCHAR, KEY_CHECKSUM, KEY_CLOSE, KEY_CR, KEY_ECHO, KEY_FAILTIME, KEY_FAILURES, KEY_INVALID, KEY_MAXBUFFER, KEY_MAXBUSY, KEY_QUERYTIME, KEY_REINIT, KEY_RESPONDTIME, KEY_STARTUP, KEY_TIMEBUSY, lock
 
Fields inherited from class io.AbstractSerialDriver
inport, KEY_BAUDRATE, KEY_CLOSETIMEOUT, KEY_DATABIT, KEY_FLOWCONTROL, KEY_INBUFFER, KEY_NOTIFYCOOLDOWN, KEY_OUTBUFFER, KEY_PARITYBIT, KEY_PORTNAME, KEY_RECEIVEFRAMING, KEY_RECEIVETHRESHOLD, KEY_RECEIVETIMEOUT, KEY_STOPBIT, KEY_TIMEOUT, outport, staticlock
 
Fields inherited from class io.AbstractDriver
KEY_DRIVERNAME
 
Fields inherited from class util.PropertyBundles
KEY_LOCALECOUNTRY, KEY_LOCALELANGUAGE, KEY_RESOURCEBUNDLES
 
Fields inherited from class util.PropertyResources
KEY_NOINITONCREATE, localurl, locate, POSTFIX_DIR, POSTFIX_EXT, POSTFIX_FILE, POSTFIX_LIST, POSTFIX_URL, urlset
 
Fields inherited from class util.PropertyContainer
KEY_LISTSEPARATOR, KEY_MAPKEYVALUECHAR, KEY_MAPSEPARATOR
 
Fields inherited from interface stella.rmi.RmiSerialCaster
NAMING_EXTENSION
 
Fields inherited from interface util.ResourceSupplying
KEY_URLRESOURCES, KEY_URLUSECONFIG, KEY_URLUSECURRENT, KEY_URLUSEHOME
 
Fields inherited from interface util.PropertySupplying
CONFIG, KEY_CLASS
 
Constructor Summary
PollingRS485Server(Map prop)
          Construct a new polling server.
 
Method Summary
 void addCacheChangedListener(CacheChangedListener ear, String key)
          Adds a new cache changed listener to this polling instance.
 String blockChannel(String command)
          Blocks until data is available on a certain channel.
 boolean close()
          Closes the port.
 void exit()
          Stops polling before closing the serial port.
 String getPollerCache()
          Dumps the current content of the polling cache to a string.
 void init()
          Opens the serial port.
protected  void initCache(Set list)
          Constructs a hashtable matching read commands to their actual results.
 String interleaveCommand(String cmd)
          Writes an arbitrary command to the serial port.
 boolean isActive()
          Returns the state of the poller, true if active, false if passive.
 boolean isPolling()
          Tests if this server is actually polling.
 boolean open()
          Start polling after opening the serial port, if requested.
 String readChannel(String command)
          Returns the value of the queried channel.
 void removeCacheChangedListener(CacheChangedListener ear, String key)
          Removes a cache changed listener from this polling instance.
 boolean setActive()
          Sets the poller in the active state.
 boolean setPassive()
          Sets the poller to passive state.
 boolean startPolling()
          Starts the polling.
 void stopPolling()
          Stops polling.
 String toString()
          Returns the driver name.
 boolean validChannel(String command)
          Returns true if the cache value associated with the command is valid.
 
Methods inherited from class stella.io.WatchdogRS485Server
resetWatchdog, startWatchdog
 
Methods inherited from class stella.io.CastingRS485Server
addRmiSerialListener, bindToRegistry, isValid, notifyListeners, removeRmiSerialListener, unbindFromRegistry, writeCommand, writeCommand, writeString
 
Methods inherited from class stella.io.RS485Server
deferCommand, ensureCommand, getCheckSum, getCheckSumming, isReading, readString, setCheckSumming, writeString
 
Methods inherited from class io.AbstractSerialDriver
createPortEventListener, createPortEventListener, deregisterSoleEventListener, disableEvent, enableEvent, getDriverName, isOpen, registerSoleEventListener, resetOriginalParameters
 
Methods inherited from class io.AbstractDriver
createDriver, equals, hashCode
 
Methods inherited from class util.PropertyBundles
clone, getLocalized, getLocalized, getLocalizedString, getLocalizedString, loadResource
 
Methods inherited from class util.PropertyResources
createFrom, createFrom, createFrom, getApplet, getAsResources, getLocalClassLoader, getPropertiesToKey, getPropertiesToKey, getResource, getResourceAsStream, getResourceFromKey, getResources, keyCreate, keyCreate, reload, setApplet
 
Methods inherited from class util.PropertyContainer
augment, augment, augment, defaultBoolean, defaultChar, defaultDouble, defaultFloat, defaultInt, defaultLong, defaultObject, defaultObject, defaultProperties, defaultProperty, getAsBoolean, getAsChar, getAsDouble, getAsEnums, getAsFloat, getAsInt, getAsList, getAsLong, getAsMap, getAsMap, getAsObject, getAsObject, getProperties, getProperty, has, isNew, parseObject, reload, removeProperty, rescanned, setObject, setProperties, setProperty, stringProperties
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface util.ResourceSupplying
getResource, getResourceAsStream, getResources
 
Methods inherited from interface util.PropertySupplying
defaultBoolean, defaultChar, defaultDouble, defaultFloat, defaultInt, defaultLong, defaultObject, defaultObject, defaultProperties, defaultProperty, getAsBoolean, getAsChar, getAsDouble, getAsFloat, getAsInt, getAsList, getAsLong, getAsMap, getAsObject, getAsObject, getProperties, getProperty, has, parseObject, removeProperty, setObject, setProperty, stringProperties
 

Field Detail

KEY_POLLBASE

public static final String KEY_POLLBASE
The key for the basic polling time. (ms).

See Also:
Constant Field Values

KEY_ACTIVEREAD

public static final String KEY_ACTIVEREAD
The key linked to the commands sent to the serial port.

See Also:
Constant Field Values

KEY_PASSIVEREAD

public static final String KEY_PASSIVEREAD
The key linked to the commands sent to the serial port.

See Also:
Constant Field Values

KEY_ACTIVEDROP

public static final String KEY_ACTIVEDROP
The key to the number of steps dropped on active reads.

See Also:
Constant Field Values

KEY_PASSIVEDROP

public static final String KEY_PASSIVEDROP
The key to the number of steps dropped on passive reads.

See Also:
Constant Field Values

KEY_STARTOPEN

public static final String KEY_STARTOPEN
Points to true if polling should start after opening of the port.

See Also:
Constant Field Values

KEY_CASTPOLL

public static final String KEY_CASTPOLL
The key defining event-casting for polling commands.

See Also:
Constant Field Values

KEY_RESPONDMAX

public static final String KEY_RESPONDMAX
The key for the response-reading timeout (ms).

See Also:
Constant Field Values

DEFPOLLBASE

private static final long DEFPOLLBASE
The default polling base time, 100 ms.

See Also:
Constant Field Values

DEFDROP

private static final int DEFDROP
The default dropping rate.

See Also:
Constant Field Values

DEFSTARTOPEN

private static final boolean DEFSTARTOPEN
The default value for starting polling at port open (true).

See Also:
Constant Field Values

DEFCASTPOLL

private static final boolean DEFCASTPOLL
The default value for casting polling commands (false).

See Also:
Constant Field Values

DEFRESPONDMAX

private static final int DEFRESPONDMAX
Maximum number of cycles for blocked reading.

See Also:
Constant Field Values

cache

protected Map cache
The hashtable linking read-commands to results.


validcache

protected Map validcache
The hashtable linking read-commands to validity of results.


timemax

protected Map<String,Long> timemax
The hashtable linking read-commands to read-time maxima.


timemin

protected Map<String,Long> timemin
The hashtable linking read-commands to read-time minima.


timecurrent

protected Map<String,Long> timecurrent
The hashtable linking read-commands to last read-times.


cachelisten

protected Map cachelisten
The hashtable matching keys to registered cache changed listeners.


poll

private PollingRS485Server.Poller poll
The polling thread.


isactive

private boolean isactive
The poller state.

Constructor Detail

PollingRS485Server

public PollingRS485Server(Map prop)
Construct a new polling server. During construction only the validity of the properties is checked. The method initCache(java.util.Set) is called at the end of the construction phase which sets up the cache hashtable. The polling itself is started after open() or with startPolling(). Polling is always started in the passive phase.

The following proerties get defaults if not preset:

Method Detail

init

public void init()
Opens the serial port. If KEY_STARTOPEN is enabled polling is started after opening was successful.

Specified by:
init in interface Initializable
Overrides:
init in class CastingRS485Server

open

public boolean open()
             throws IOException
Start polling after opening the serial port, if requested.

Specified by:
open in interface Driver
Overrides:
open in class RS485Server
Returns:
True if initialization was successful.
Throws:
IOException

exit

public void exit()
Stops polling before closing the serial port.

Specified by:
exit in interface ExitCleaning
Overrides:
exit in class CastingRS485Server

initCache

protected void initCache(Set list)
Constructs a hashtable matching read commands to their actual results. In the initializing phase, all values of the hash table are empty strings.

Additionally, a lookup-table matching the read commands to their reply length is constructed. The table is filled with the matches of the read-commands to integers in the polling server's properties. If for a given read command no match can be found zero is asumed which is interpreted as an unspecified number of reply bytes.


startPolling

public boolean startPolling()
Starts the polling. This method spawns an individual reader thread that permanently sends all read command strings to the serial server and stores it into this objects cache hashtable.

If either the port is not open or the I/O streams are not opened or ready this method returns silently.

Returns:
True if polling was successfully enabled.

stopPolling

public void stopPolling()
Stops polling. Calls the poller's cancel method. Note that after polling stopped calls can still be made to readChannel(java.lang.String) though they return out-of-date values. A call to startPolling() restarts the polling mechanism.


isPolling

public boolean isPolling()
                  throws RemoteException
Tests if this server is actually polling. Returns the isRunning status of the polling thread.

Specified by:
isPolling in interface PollerQuery
Throws:
RemoteException

setActive

public boolean setActive()
Sets the poller in the active state. This means setting the actual poll- drop of the poller to the KEY_ACTIVEDROP value and changing the command list to KEY_ACTIVEREAD. If the poller is alive, this method first synchronizes on the poller cache to avoid concurrent acces to the poller list and/or poller time.

Returns:
True, if poller state was changed successfully to active.

setPassive

public boolean setPassive()
Sets the poller to passive state. This means setting the actual poll- drop of the poller to the KEY_PASSIVEDROP value and changing the command list to KEY_PASSIVEREAD. If the poller is alive, this method first synchronizes on the poller cache to avoid concurrent acces to the poller list and/or poller time.

Returns:
True, if poller state was changed successfully to passive.

isActive

public boolean isActive()
Returns the state of the poller, true if active, false if passive.


blockChannel

public String blockChannel(String command)
Blocks until data is available on a certain channel. This method is intended to be called when a new channel has been added to the polling query and the calling object must ensure that data is available on this channel. If the command is not polled or polling is inactive this method returns immediately with the null String.

This method checks the mapping of the given key in the cache. As long as this mapping points to the empty String, this method falls into a sleep loop, sleeping period equal to the poller's polling interval.

Returns:
The valid channel reading.

getPollerCache

public String getPollerCache()
                      throws RemoteException
Dumps the current content of the polling cache to a string.

Specified by:
getPollerCache in interface PollerQuery
Throws:
RemoteException

readChannel

public String readChannel(String command)
Returns the value of the queried channel. The return value is the currently chached value. Even if polling of the channels has stopped (see isPolling()) data retrieval, though outdated, is still possible.
This method synchronizes on the cache hashtable to avoid concurrent value updating.


validChannel

public boolean validChannel(String command)
Returns true if the cache value associated with the command is valid. Note that during read-failures the cache value remains the same but the validity drops to false.
This method synchronizes on the valid hashtable to avoid concurrent value updating.

Returns:
False if the cached value is outdated or not in the cache at all.

interleaveCommand

public String interleaveCommand(String cmd)
                         throws RemoteException
Writes an arbitrary command to the serial port. This method should only be used for maintenance with a remote process. E.g. if the roof stucks and you do not yet want to kill the rs485 server, one can use this method from a remote VM.
In version 1.0, this method is hidden from the serial event listeneners.

Specified by:
interleaveCommand in interface PollerQuery
Throws:
RemoteException

close

public boolean close()
              throws IOException
Closes the port. Prior to closing the polling thread is ended.

Specified by:
close in interface Driver
Overrides:
close in class WatchdogRS485Server
Returns:
True if clean-up was successful.
Throws:
IOException

addCacheChangedListener

public void addCacheChangedListener(CacheChangedListener ear,
                                    String key)
Adds a new cache changed listener to this polling instance. Note that registering to keys that are not actually polled is allowed. Additionally, it is assumed that the listener's last cache value is null (what else?), so if the key is present in the cache and mapped to a string different to null, the listener is immediately notified that the cache has changed.

Specified by:
addCacheChangedListener in interface CacheChangedCaster
Parameters:
ear - The listener to be notified when the cache value changes.
key - The serial command this listenr is interested in.

removeCacheChangedListener

public void removeCacheChangedListener(CacheChangedListener ear,
                                       String key)
Removes a cache changed listener from this polling instance. If the listener has not been registered, nthing changes.

Specified by:
removeCacheChangedListener in interface CacheChangedCaster
Parameters:
ear - The listener to be notified when the cache value changes.
key - The serial command this listenr is interested in.

toString

public String toString()
Returns the driver name.

Overrides:
toString in class RS485Server