|
Mobile Sensor API Version 1.2 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface SensorConnection
The SensorConnection
is an abstraction of an actual
sensor. It provides the functionality to retrieve data from a sensor.
A sensor can be widely understood as any measurement data source. It provides a direct output to the physical stimuli such as heat, light, sound, pressure, magnetism, or motion. Alternatively, a sensor can be a virtual data source that supplies data, which is collected from various sources and manipulated.
The main task of a SensorConnection
is to enable
data retrieval from a sensor. The application can retrieve data either synchronously or
asynchronously. Synchronous mode means that the application is
iteratively calling getData(int)
/
getData(int, long, boolean, boolean, boolean)
methods.
Asynchronous mode requires the application to implement the
DataListener
interface.
When the application implements this interface and registers itself
with the setDataListener()
method, it starts to receive
DataListener.dataReceived()
notifications.
Both synchronous and asynchronous retrieval deliver the data
encapsulated in Data
objects.
The content of Data
objects can be configured with parameters of
getData()/setDataListener()
methods. The application is able to configure
the buffering of the data, and presence of the timestamp, the
uncertainty, and
the validity. Buffering can be controlled with a buffer
size parameter, or a buffering period, or both.
Data buffering with a larger buffer size is recommended
if the application is performance-critical.
Buffering has also a favorable effect of easing garbage
collection. If the sampling rate is, for example, 1000 Hz, by
setting the size of the buffer to 100, only 10 Data
objects per second are
created. This is far easier to handle than 1000 objects per
second. Omitting either the timestamp, or the uncertainty, or the
validity, or all of these
can also optimize the performance.
The maximum buffer size MUST be 256 in minimum for all the
sensors in all the devices. The maximum buffer size of this sensor
can be obtained with the method SensorInfo.getMaxBufferSize()
. The data retrieval methods will throw
an IllegalArgumentException
if the desired buffer size
exceeds defined maximum.
The SensorConnection
has three possible states:
Right after the SensorConnection
is opened,
it is in the STATE_OPENED
state.
When the DataListener
is registered, the state moves from
STATE_OPENED
to STATE_LISTENING
.
If the DataListener
is removed, the SensorConnection
returns back to the STATE_OPENED
state.
After the close()
method is called, the SensorConnection
is in its final state, STATE_CLOSED
. There
is no longer any way back to the other states. No data MUST
be provided for the application after the connection
is closed.
The states of
SensorConnection
are presented in the figure below.
Figure 3: The state machine of SensorConnection
class
Calling some methods may fail if the
SensorConnection
is not in an appropriate state for the
method. In the table below states and
corresponding illegal methods are depicted:
State | Illegal methods |
---|---|
STATE_OPENED |
- |
STATE_LISTENING |
getData() throws IllegalStateException
|
STATE_CLOSED |
getData() throws IOException
setDataListener() and
removeDataListener()
throw IllegalStateException |
The SensorConnection
may provide
simultaneous measurements from different channels,
and for clarity different measurements are stored into separate
Data
objects. The number of channels depends on the nature of the
sensor. For example, a thermometer
returns only one value representing temperature, so it has only one
channel.
A 3D compass returns a collection of three values each
representing orientation in one particular direction; therefore it is
a "three-channel" sensor.
In the case of a 3D compass having channels "heading", "pitch", and
"roll", it is
recommended to group these three channels to be in the same
SensorConnection
entity.
Of course, there is a chance that the application is only interested in the
"heading" values. If this is the case, the SensorConnection
dedicated to the "heading" values would serve best.
However, different, simultaneous modes would increase the complexity of the design and
implementation and offer only small benefits.
The different SensorConnection
implementations
should be aligned with the way the physical
sensors are measuring things. If a compass is measuring heading,
pitch, and roll values
together in one shot, these values should be channels of one
SensorConnection
.
The situation changes if the measuring device is capable of measuring
more than one quantity, for example, humidity and temperature.
In such a case it is recommended to offer the separate
SensorConnection
for
each quantity, and not one SensorConnection
with two
channels.
It is implementation dependent whether separate
SensorConnection
objects to the same device can be opened simultaneously.
The SensorConnection
is extended from a General Connection Framework's
Connection
to be aligned with a widely accepted convention and
to ease the application wakeup based on the usage of the MIDP
PushRegistry
.
A new URL scheme is defined for sensors, and it conforms to the URL format
described in RFC 2396. When the connection to a sensor is opened
using Connector.open()
, the URL must conform
to the EBNF syntax specified below.
If the URL passed to Connector.open()
defines the
"sensor:" scheme but is not valid according to the sensor URL scheme defined here,
an IllegalArgumentException
is thrown. Identical sensors, which
have the same model information, should provide location information
to enable to distinguish sensors from each other. Quantity is the only
mandatory parameter in the URL. Sensor examples and corresponding
quantities can be found
in the table of Appendix A "Finding sensors".
<sensor_url>
|
::= "sensor:"<sensor_id>
|
<sensor_id>
|
::= <quantity>[<contextType>][<model>][<location>]
|
<quantity>
|
::= ("temperature"|"acceleration"|...)
|
<contextType>
|
::= <separator>"contextType="("ambient"|"device"|"user"|"vehicle")
|
<model>
|
::= <separator>"model="<model_id>
|
<model_id>
|
::= <alphanum>*
|
<location>
|
::= <separator>"location="<location_id>
|
<location_id>
|
::= <alphanum>*
|
<separator> |
::= ";" |
Examples of sensor URLs for Connector.open():
sensor:temperature;contextType=ambient;model=ModelName;location=greenhouse
An air thermometer, the model of which is "ModelName" and which
is located in a greenhouse
sensor:pressure;contextType=ambient
A pressure meter for air
sensor:blood_pressure;contextType=user
A pressure meter for blood pressure
PushRegistry
URL
In MIDP 2.0 the PushRegistry
provides the push mechanism
to start the MIDlet based on some specific impulse.
More information about automatic launch can be found in the Appendix
C.
When registering sensors to the MIDP PushRegistry
, the URL must conform
to the EBNF syntax specified below.
When the PushRegistry.registerConnection()
is called
and the connection URL parameter specifies "sensor:" scheme but does
not conform to this syntax,
an IllegalArgumentException
is thrown.
<push_sensor_url> |
::= <sensor_url>[<params>]
|
<params> |
::= "?"<channel_list> |
<channel_list> |
::= <channel>[<separator2><channel>]* |
<channel> |
::= "channel="<channel_id><separator2><condition_list> |
<channel_id> |
::= <alphanum>+ |
<condition_list> |
::= <condition>[<separator2><condition>]* |
<condition> |
::= (<limit>|<range>) |
<limit> |
::= "limit="<double><separator2>"op="("eq"|"lt"|"le"|"ge"|"gt") |
<range> |
::="lowerLimit="<double><separator2>
"lowerOp="("ge"|"gt")<separator2>
"upperLimit="<double><separator2>
"upperOp="("le"|"lt") |
<separator2> |
::= "&" |
<double> |
::= "-"?(<integer>|<decimal>) |
<integer> |
::= <nonzero-digit><digit>* |
<decimal> |
::= <integer>"."<digit>+ |
<digit> |
::= "0"|<nonzero-digit> |
<nonzero-digit> |
::= "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
|
Examples of the sensor URLs for the PushRegistry
:
sensor:temperature;contextType=ambient?channel=temperature&limit=50.0&op=gt
An air thermometer with a limit condition: value > 50.0
sensor:humidity;contextType=ambient?channel=humidity&lowerLimit=10.0&lowerOp=gt&upperLimit=55.0&upperOp=lt
A humiditymeter with a range condition: 10.0 < value < 55.0
Setting conditions with a URL is analogous to
specifying them using the Condition
classes.
An ObjectCondition
or custom Condition
objects
cannot be used. The application is launched when any of the
conditions set in the URL are met.
Field Summary | |
---|---|
static int |
STATE_CLOSED
The SensorConnection state after the method close() is called; the end state. |
static int |
STATE_LISTENING
The SensorConnection state when the
asynchronous data retrieval mode is
on. |
static int |
STATE_OPENED
The SensorConnection state after successful instantiation of
the SensorConnection . |
Method Summary | |
---|---|
Channel |
getChannel(ChannelInfo channelInfo)
This method returns the Channel object that
maintains Condition objects attached to the
corresponding channel of the sensor. |
Data[] |
getData(int bufferSize)
Retrieves data in the synchronous mode. |
Data[] |
getData(int bufferSize,
long bufferingPeriod,
boolean isTimestampIncluded,
boolean isUncertaintyIncluded,
boolean isValidityIncluded)
Retrieves data in the synchronous mode. |
int[] |
getErrorCodes()
The method will return all the sensor specific error codes that the sensor is capable of reporting. |
java.lang.String |
getErrorText(int errorCode)
The method will return a sensor specific error description based on the error code given as a parameter. |
SensorInfo |
getSensorInfo()
Returns SensorInfo that contains information about the
sensor |
int |
getState()
Returns the current state of the SensorConnection . |
void |
removeDataListener()
Removes the DataListener registered to this
SensorConnection . |
void |
setDataListener(DataListener listener,
int bufferSize)
Registers a DataListener to receive collected data
asynchronously. |
void |
setDataListener(DataListener listener,
int bufferSize,
long bufferingPeriod,
boolean isTimestampIncluded,
boolean isUncertaintyIncluded,
boolean isValidityIncluded)
Registers a DataListener to receive collected data
asynchronously. |
Methods inherited from interface javax.microedition.io.Connection |
---|
close |
Field Detail |
---|
static final int STATE_OPENED
The SensorConnection
state after successful instantiation of
the SensorConnection
. The connection is open and data
can be retrieved.
static final int STATE_LISTENING
The SensorConnection
state when the
asynchronous data retrieval mode is
on. The application is listening to DataListener.dataReceived()
notifications.
static final int STATE_CLOSED
The SensorConnection
state after the method close()
is called; the end state.
Method Detail |
---|
Channel getChannel(ChannelInfo channelInfo)
This method returns the Channel
object that
maintains Condition
objects attached to the
corresponding channel of the sensor.
The channelInfo parameter is compared using instance equality and
therefore needs to be an instance previously returned from
SensorInfo.getChannelInfos()
method of the SensorInfo
object corresponding to this sensor.
channelInfo
- the ChannelInfo
object which
defines the channel
Channel
java.lang.IllegalArgumentException
- if SensorInfo
does not contain matching ChannelInfo
object
java.lang.NullPointerException
- if the channelInfo is
null
Data[] getData(int bufferSize) throws java.io.IOException
Retrieves data in the synchronous mode.
The collection of the data is started when the method is called.
When this getData()
method is used, timestamp,
validity, and
uncertainty values are not included in Data
objects. The method
will return when the size of the data value buffer equals the bufferSize
parameter. The bufferSize parameter defines the number of
samples inside each Data
object.
bufferSize
- the size of the data value buffer of the Data
object
- value must be > 0
Data
objects
returned as there are channels.
java.lang.IllegalArgumentException
- if bufferSize < 1 or if
bufferSize exceeds the maximum size of the buffer
java.io.IOException
- if the state is STATE_CLOSED
or if I/O operations on the SensorConnection
are being
blocked, which can happen, for example, when a sensor becomes
unavailable or when the SensorConnection
is closed
with the close()
method during a call to this
method. The IOException
MUST be thrown right away
after the sensor becomes unavailable.
java.lang.IllegalStateException
- if the state is STATE_LISTENING
Data[] getData(int bufferSize, long bufferingPeriod, boolean isTimestampIncluded, boolean isUncertaintyIncluded, boolean isValidityIncluded) throws java.io.IOException
Retrieves data in the synchronous mode. The data
is collected from the sensor according to the given parameters.
The collection of the data is started when the method is called.
If data cannot be retrieved then a zero-length
Data
array
is returned. This can happen, for example, when the bufferingPeriod
is very small and the measurement is slow.
The parameters of the method have an effect on retrieved Data
objects. The size of the data value buffer is defined and/or the
time period to buffer the data and
whether the additional information, such as timestamps,
uncertainties, and validities, should be included.
The data value buffer size is controlled with both parameters
bufferSize
and bufferingPeriod
.
A negative value indicates that the parameter is left undefined.
The bufferSize
and bufferingPeriod
have the
following relationship:
Data
object is determined by how much
data is retrieved from the sensor during the bufferingPeriod.
However, the size of the buffer MUST NOT exceed the
the maximum buffer size of the sensor, obtained with the
method SensorInfo.getMaxBufferSize()
.Data
object equals to bufferSize.Data
objects may differ a
lot. The size of the buffer can be equal to or less than
bufferSize.
bufferSize
- the size of the buffer of the data values,
bufferSize < 1 means the size is left undefinedbufferingPeriod
- the time to buffer values - given in
milliseconds, bufferingPeriod < 1 means the period is left
undefinedisTimestampIncluded
- if true
timestamps
should be included in returned Data
objectsisUncertaintyIncluded
- if true
uncertainties
should be included in returned Data
objectsisValidityIncluded
- if true
validities
should be included in returned Data
objects
Data
objects
returned as there are channels.
java.lang.IllegalArgumentException
- if the both, bufferSize and
bufferingPeriod, have values less than 1, or if
bufferSize exceeds the maximum size of the buffer
java.lang.IllegalStateException
- if the state is STATE_LISTENING
java.io.IOException
- if the state is STATE_CLOSED
or if I/O operations on the SensorConnection
are being
blocked, which can happen, for example, when a sensor becomes
unavailable or when the SensorConnection
is closed
with the close()
method during a call to this
method. The IOException
MUST be thrown right away
after the sensor becomes unavailable.int[] getErrorCodes()
The method will return all the sensor specific error codes that the sensor is capable of reporting. When adding a new sensor its error codes MUST be documented if the sensor is reporting errors.
int
array. If the
sensor is not reporting errors, i.e. the property
PROP_IS_REPORTING_ERRORS
is not set, then a zero-length
int
array
is returned. If the sensor reports errors, there MUST be at
least one error code returned.java.lang.String getErrorText(int errorCode)
The method will return a sensor specific error description based
on the error code given as a parameter. The description MUST NOT
be an empty string or null
.
errorCode
- the code of the error occured
java.lang.IllegalArgumentException
- if the given errorCode is not valid and always if the
property SensorInfo.PROP_IS_REPORTING_ERRORS
is not setSensorInfo getSensorInfo()
Returns SensorInfo
that contains information about the
sensor
SensorInfo
object containing information
about this sensorint getState()
Returns the current state of the SensorConnection
.
SensorConnection
; possible
return values are:
void removeDataListener()
Removes the DataListener
registered to this
SensorConnection
. The DataListener
stops getting dataReceived()
notifications.
The state changes from STATE_LISTENING to STATE_OPENED,
and data can now be retrieved synchronously using getData()
methods.
If there is no DataListener
and the state is
STATE_OPENED, the method returns silently.
java.lang.IllegalStateException
- if this
SensorConnection
is already closedvoid setDataListener(DataListener listener, int bufferSize)
Registers a DataListener
to receive collected data
asynchronously. The registered DataListener
receives data within
sequential dataReceived()
notifications. The notification
is sent when the number of collected data values equals a set size
of the buffer. To quit receiving
notifications the method removeDataListener()
has to be
called. Data MUST NOT be sent after the sensor becomes
unavailable.
If there is a DataListener
already set, it will be
replaced with the listener given as a parameter. When this
setDataListener()
method is used, timestamp,
validity, and
uncertainty values are not included in the Data
objects.
listener
- DataListener
to be registeredbufferSize
- size of the buffer, value must be > 0
java.lang.NullPointerException
- if the listener is null
java.lang.IllegalArgumentException
- if the
bufferSize < 1, or if
bufferSize exceeds the maximum size of the buffer
java.lang.IllegalStateException
- if this
SensorConnection
is already closedvoid setDataListener(DataListener listener, int bufferSize, long bufferingPeriod, boolean isTimestampIncluded, boolean isUncertaintyIncluded, boolean isValidityIncluded)
Registers a DataListener
to receive collected data
asynchronously. The registered DataListener
receives data within
sequential dataReceived()
notifications.
If there is a DataListener
already set, it will be
replaced with the given listener parameter. To quit receiving
notifications the method removeDataListener()
has to be
called.
The parameters of the method have an effect on retrieved Data
objects. The size of the data value buffer is defined and/or the
time period to buffer the data and
whether the additional information, such as timestamps,
uncertainties, and validities, should be included.
The data value buffer size is controlled with both parameters
bufferSize
and bufferingPeriod
.
A negative value indicates that the parameter is left undefined.
The bufferSize
and bufferingPeriod
have the
following relationship:
Data
object is determined by how much
data is retrieved from the sensor during the bufferingPeriod.
However, the size of the buffer MUST NOT exceed the
the maximum buffer size of the sensor, obtained with the
method SensorInfo.getMaxBufferSize()
.Data
object equals to bufferSize.dataReceived()
notification will be sent when either the size of the
data value buffer equals the bufferSize, or the collection time equals, or exceeds
the bufferingPeriod. That is, if the sampling rate of the sensor
fluctuates a lot,
then also the buffer sizes inside Data
objects may differ a
lot. The size of the buffer can be equal to or less than
bufferSize. Data MUST NOT be sent after the sensor becomes
unavailable.
listener
- the listener to be registeredbufferSize
- the size of the buffer of the data values,
bufferSize < 1 means the size is left undefinedbufferingPeriod
- the time in milliseconds to buffer
values inside one Data
object. bufferingPeriod <
1 means the period is left
undefined.isTimestampIncluded
- if true
timestamps
should be included in returned Data
objectsisUncertaintyIncluded
- if true
uncertainties
should be included in returned Data
objectsisValidityIncluded
- if true
validities
should be included in returned Data
objects
java.lang.NullPointerException
- if the listener is null
java.lang.IllegalArgumentException
- if the bufferSize and
the bufferingPeriod both are < 1 or if
bufferSize exceeds the maximum size of the buffer
java.lang.IllegalStateException
- if this
SensorConnection
is already closed
|
Mobile Sensor API Version 1.2 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |