Home2L - C/C++ API v1.4-0-g38cc (2024-05-25)
Smart Tools for a Private Home
Friends | List of all members
CResource Class Reference

Description

Home2L Resource.

This is the central class of the library. A 'Resource' may represent a sensor, an actor, a stored value, a virtual device, a mutex, an event trigger - almost anything. Resources are identified by a uniform resource identifier (URI). Their values are generally read by subscribing to them and written to by placing requests.

The methods of this calls can be divided into three main categories:

Definition at line 909 of file resources.H.

#include "resources.H"

Friends

class CRcSubscriber
 

(App) Obtaining and managing resources ...

static CResourceGet (const char *uri, bool allowWait=false)
 Look up a resource by its URI and return a reference to it. More...
 
static void GarbageCollection ()
 Remove all unregistered resources. More...
 

(Drv) Registration and life cycle management of local resources ...

static CResourceRegister (CRcDriver *_rcDriver, const char *_lid, ERcType _type, bool _writable, void *_data=NULL)
 Register a new local resource for a driver. More...
 
static CResourceRegister (CRcDriver *_rcDriver, const char *_lid, const char *rcTypeDef, void *_data=NULL)
 Register a new local resource for a driver based on a textual type description. 'rcTypeDef' is a textual type definition, syntax: <type> (ro|wr). Details can be found in the base variant of CResource::Register() .
 
void SetDefault (CRcValueState *vs)
 Set a default value.
 
void SetDefault (bool valBool)
 
void SetDefault (int valInt)
 
void SetDefault (float valFloat)
 
void SetDefault (const char *valString)
 
void SetDefault (TTicks valTime)
 
void Unregister ()
 Unregister a resource. More...
 

(App) Identification (static) ...

const char * Uri ()
 Get the URI (aka global ID / GID).
 
const char * Gid ()
 Get the global ID.
 
const char * Lid ()
 Get the local ID (LID). This is the path relative to a) 'this's host (remote resource) or b) driver (local resource).
 
bool Is (const char *uri)
 Check identity by exact match.
 
bool Is (CResource *rc)
 Check identity (for Python & eventual wrapper classes).
 
bool IsLike (const char *pattern)
 Check identity by pattern.
 
bool IsWritable ()
 

(App) Stringification ...

const char * ToStr (CString *ret, bool pathLocal=false)
 

(App) Getting the current value and state ...

Access methods to get the last known value and state.

The following '[Get]*'-methods immediately return the last known value/state of the resource, without querying the driver. To trigger a regular transport of data from a sensor/resource here, a subscription must be placed (see below).

Note: The value and state may change any time. Each of the following methods returns a value/state consistent by itself.

void GetValueState (CRcValueState *retValueState)
 Get the value and state.
 
ERcState GetValue (bool *retBool, TTicks *retTimeStamp=NULL)
 Get a value of type "Bool" or a type based on it. More...
 
ERcState GetValue (int *retInt, TTicks *retTimeStamp=NULL)
 Get a value of type "int" or a type based on it.
 
ERcState GetValue (float *retFloat, TTicks *retTimeStamp=NULL)
 Get a value of type "float" or a type based on it.
 
ERcState GetValue (CString *retString, TTicks *retTimeStamp=NULL)
 Get a value of type "string" or a type based on it.
 
ERcState GetValue (TTicks *retTime)
 Get a value of type "time".
 
bool ValidBool (bool defaultVal=false, TTicks *retTimeStamp=NULL)
 Get a valid Boolean value. This and the following methods are shortcuts for first obtaining the 'ValueState' and then use the same methods of CRcValueState on that object.
 
int ValidInt (int defaultVal=0, TTicks *retTimeStamp=NULL)
 Get a valid integer value.
 
float ValidFloat (float defaultVal=0.0, TTicks *retTimeStamp=NULL)
 Get a valid float value.
 
const char * ValidString (CString *ret, const char *defaultVal=CString::emptyStr, TTicks *retTimeStamp=NULL)
 Get a valid string value.
 
TTicks ValidTime (TTicks defaultVal=0, TTicks *retTimeStamp=NULL)
 Get a valid time value.
 
int ValidTrigger (int defaultVal=0, TTicks *retTimeStamp=NULL)
 Get a valid trigger value.
 
const char * ValidMutex (CString *ret, const char *defaultVal=CString::emptyStr, TTicks *retTimeStamp=NULL)
 Get a valid mutex value.
 
int ValidUnitInt (ERcType _type, int defaultVal=0, TTicks *retTimeStamp=NULL)
 Get a valid unit-type integer value.
 
float ValidUnitFloat (ERcType _type, float defaultVal=0.0, TTicks *retTimeStamp=NULL)
 Get a valid unit-type float value.
 
int ValidEnumIdx (ERcType _type, int defaultVal=0, TTicks *retTimeStamp=NULL)
 Get a valid enumeration value index.
 
ERcType Type () const
 
ERcState State () const
 
TTicks TimeStamp () const
 
bool IsValid () const
 State is rcsValid, neither rcsBusy nor rcsUnknown.
 
bool IsBusy () const
 State is rcsBusy, neither rcsValid nor rcsUnknown.
 
bool IsKnown () const
 State is either rcsValid or rcsBusy; In other words: the value can be retrieved.
 
bool Equals (const CRcValueState *vs2)
 Strict comparison: state, type and value must match exactly; time stamps are not compared.
 
bool ValueEquals (const CRcValueState *vs2)
 Relaxed comparison: type and value must match exactly; state and time stamps are not compared.
 

(App) Subscriptions ...

The usual way to query values is to place a subscription.

As long as the subscription exists, up-to-date values will be forwarded to the application by means of a callback function or an event mechanism as defined by the CRcSubscriber class.

In the case of 'rceValueStateChanged' events, the returned event reflects the exact state of the resource at the time the event was caused. This important to not miss any event (e.g. 0-1-0 transitions). In contrast, if the actual state and value are queried using the 'Get...' methods above, the state at the time of the 'Get...' call, which may have changed again since the time of the event. This way, more up-to-date information may be obtained, but state/value transitions may be missed.

CResourceSubscribe (CRcSubscriber *subscr)
 Subscribe to this resource. The caller remains owner of 'subscr'. More...
 
void Unsubscribe (CRcSubscriber *subscr)
 Unsubscribe to this resource.
 

(App) Requests ...

In order to accomodate multiple concurrent "write" operations to the same resource, a concept of "requests" is applied here.

Each participant can add (and later remove) a request for a certain value to the resource, and the system will always select the value of request with the highest priority according to its attributes.

void SetRequestFromObj (CRcRequest *_request)
 
void SetRequest (CRcRequest *_request)
 Add or replace a request (generic version). More...
 
void SetRequest (CRcValueState *value, const char *reqGid=NULL, int priority=rcPrioNone, TTicks t0=NEVER, TTicks t1=NEVER, TTicks repeat=NEVER, TTicks hysteresis=NEVER)
 Add or replace a request (generic value, direct parameters). The request attributes are explaind in the Home2L Book. More...
 
void SetRequest (bool valBool, const char *reqGid=NULL, int priority=rcPrioNone, TTicks t0=NEVER, TTicks t1=NEVER, TTicks repeat=NEVER, TTicks hysteresis=NEVER)
 Add or replace a request (direct value and parameters).
 
void SetRequest (int valInt, const char *reqGid=NULL, int priority=rcPrioNone, TTicks t0=NEVER, TTicks t1=NEVER, TTicks repeat=NEVER, TTicks hysteresis=NEVER)
 Add or replace a request (direct value and parameters).
 
void SetRequest (float valFloat, const char *reqGid=NULL, int priority=rcPrioNone, TTicks t0=NEVER, TTicks t1=NEVER, TTicks repeat=NEVER, TTicks hysteresis=NEVER)
 Add or replace a request (direct value and parameters).
 
void SetRequest (const char *valString, const char *reqGid=NULL, int priority=rcPrioNone, TTicks t0=NEVER, TTicks t1=NEVER, TTicks repeat=NEVER, TTicks hysteresis=NEVER)
 Add or replace a request (direct value and parameters).
 
void SetRequest (TTicks valTime, const char *reqGid=NULL, int priority=rcPrioNone, TTicks t0=NEVER, TTicks t1=NEVER, TTicks repeat=NEVER, TTicks hysteresis=NEVER)
 Add or replace a request (direct value and parameters).
 
void SetRequestFromStr (const char *reqDef)
 Set request by textual definition. See CRcRequest::SetFromStr() and the Home2L Book for more information on the syntax of request definitions.
 
void SetTrigger (const char *reqGid, int priority=rcPrioNone, TTicks t0=NEVER, TTicks repeat=NEVER)
 Set a trigger request (no value needs to be given).
 
void SetTriggerFromStr (const char *reqDef)
 Set trigger request by textual definition.
 
void DelRequest (const char *reqGid=NULL, TTicks t1=NEVER)
 Delete a request. More...
 
bool GetRequestSet (CRcRequestSet *ret, bool allowNet=true)
 Query all pending requests. More...
 
CRcRequestGetRequest (const char *reqGid, bool allowNet=true)
 Query a request by its request GID. More...
 

(App) Emulate classical "read" and "write" operations ...

The use of the following methods is not recommended. However, their implementations may be illustrative examples on how to work with subscriptions or requests.

void ReadValueState (CRcValueState *retValueState, TTicks maxTime=-1)
 Perform a blocking read to obtain an up-to-date value from the driver. Internally, a temporary subscription is generated and the CRcSubscriber methods are used to implement this reading.
 
void WriteValue (CRcValueState value, int priority=rcPrioNone, const char *reqGid="write")
 Write a value by issueing or updating a request with the given global id. The implementation of this method can be used as a tutorial on working with requests.
 
void UnWrite (const char *reqGid="write")
 

(Drv) User data for the driver ...

void SetUserData (void *_data)
 Set user-specified data for this resource.
 
void * UserData ()
 Retrieve user-specified data.
 

(Drv) Reporting values from the real device ...

To be called by a driver to report a change in the real device.

Note: The methods 'Report...' and 'DriveValue' serve as serialization points on the data paths Driver -> Subscribers and Subscribers -> Driver, respectively. The internal methods filter out duplicates reported one immediately after the other. Neither a driver nor a subscriber have to worry about duplicates.

void ReportValueState (const CRcValueState *_valueState)
 Report value and state; if different from previous value/state, notify all subscribers. If '_valueState->Type () == rctNone', the new state is reported with the old value.
 
void ReportValue (bool _value, ERcState _state=rcsValid)
 
void ReportValue (int _value, ERcState _state=rcsValid)
 
void ReportValue (float _value, ERcState _state=rcsValid)
 
void ReportValue (const char *_value, ERcState _state=rcsValid)
 
void ReportValue (TTicks _value, ERcState _state=rcsValid)
 
void ReportTrigger ()
 For triggers, this method must be called.
 
void ReportState (ERcState _state)
 Report state change only, value remains unmodified.
 
void ReportBusy ()
 Report a busy state (without changing the value).
 
void ReportUnknown ()
 Report an unknown state.
 

(Drv) Misc. Helpers ...

void RedriveValue (bool force=true)
 Drive the currently requested value again. More...
 

(Meta) For info & directory services ...

const char * GetInfo (CString *ret, int verbosity=1, bool allowNet=true)
 Get textual information on this resource. More...
 
void PrintInfo (FILE *f=stdout, int verbosity=1, bool allowNet=true)
 
int LockLocalSubscribers ()
 Return number of all active local subscribers for a resource and lock this object. During the locked state, other operations are also locked out, so the caller should use this carefully and unlock as soon as possible. On error, a warning is emitted, but all successfully read subscribers are returned.
 
CRcSubscriberGetLocalSubscriber (int n)
 
void UnlockLocalSubscribers ()
 
int LockLocalRequests ()
 Return number of active requests for a local resource and lock this object. During the locked state, other operations are also locked out, so the caller should use this carefully and unlock as soon as possible. On error, a warning is emitted, but all successfully read requests are returned.
 
CRcRequestGetLocalRequest (int n)
 
void UnlockLocalRequests ()
 

(Meta/App) Properties for internal or special use (semi-static and dynamic) ...

Unless specified otherwise, the data returned by the following methods is almost static ("semi-static") in the sense that it may change if and only if the object is (re-)registered or unregistered.

class CRcHost * Host ()
 
class CRcDriverDriver ()
 
unsigned RegSeq ()
 The 'regSeq' number is incremented each time the resource is registered or unregistered. Reading it before and after a critical section allows a caller to check whether semi-static data may have changed during the critical section and eventually withdraw and repeat the action.
 
bool IsRegistered ()
 
void WaitForRegistration ()
 Wait until registered or a network timeout occured.
 
bool HasSubscribers ()
 Return whether this resource is currently subscribed (dynamic, not semi-static).
 
bool HasRequests ()
 Return whether this resource has requests (dynamic, not semi-static).
 

Member Function Documentation

◆ Get()

static CResource * CResource::Get ( const char *  uri,
bool  allowWait = false 
)
static

Look up a resource by its URI and return a reference to it.

The returned pointer is always valid (!= NULL) unless the URI is syntactically incorrect and will neither now nor in the future refer to a valid resource. Hence, the pointer can be used for identity comparisons.

If 'allowWait' is 'false', the function returns immediately. If 'allowWait' is 'true', the function may wait/block for some time, increasing the chance that the resource is known afterwards.

If the URI is not absolute, it is relative to "/alias".

If the URI is syntactically incorrect, a warning is emitted and 'NULL' is returned. It is allowed to pass 'uri == NULL', in which case NULL will be returned without any warning.

◆ GarbageCollection()

static void CResource::GarbageCollection ( )
static

Remove all unregistered resources.

The calling process must not hold (and later use) any references to 'CResource' objects if this function is used.

Usually, this function is not needed. It is only required with very long uptimes which for some reason cannnot be restarted easily. Resources that get unregistered (e.g. because their server terminates) are not deleted from memory to keep eventual references to them valid. If such a resource is never re-registered again, e.g. because a server is removed from the net permanently or its naming scheme is changed, the unregistered resources still require (little) memory. If the number of unregistered resources exceeds "rc.maxOrphaned", the process is terminated.

◆ GetValue()

ERcState CResource::GetValue ( bool *  retBool,
TTicks retTimeStamp = NULL 
)

Get a value of type "Bool" or a type based on it.

Type mismatches inside a type class are silently tolerated. The returned state must be checked. If the state is 'rcsUnknown', the type does not match or if 'this == NULL', a value of 'rcsUnknown' is returned and '*ret...' is left unchanged. No runtime errors will be thrown.

◆ Subscribe()

CResource * CResource::Subscribe ( CRcSubscriber subscr)
inline

Subscribe to this resource. The caller remains owner of 'subscr'.

     If the present value of 'this' is known, an initial notification with the current value
     is sent to the subscriber.
     'this' is returned to allow short constructs like "rc = RcGetResource (...)->Subscribe (subscr)". 

Definition at line 1061 of file resources.H.

◆ SetRequest() [1/2]

void CResource::SetRequest ( CRcRequest _request)
inline

Add or replace a request (generic version).

Parameters
_requestmust by a dynamically allocated object, which is handed over and must no longer be used by the caller afterwards. If the no known value is given (state rcsUnknown), an already existing request with the same ID is deleted.

Definition at line 1084 of file resources.H.

◆ SetRequest() [2/2]

void CResource::SetRequest ( CRcValueState value,
const char *  reqGid = NULL,
int  priority = rcPrioNone,
TTicks  t0 = NEVER,
TTicks  t1 = NEVER,
TTicks  repeat = NEVER,
TTicks  hysteresis = NEVER 
)

Add or replace a request (generic value, direct parameters). The request attributes are explaind in the Home2L Book.

Parameters
reqGididentifies the request; it is legal to pass NULL, in which case the instance name is used.
valuespecifies the requested value (only type and value are used).
priorityis the request priority attribute.
t0is the activation (start) time attribute (optional).
t1is the expiration (stop) time attribute (optional).
repeatis the repetition interval attribute (optional).
hysteresisis the hysteresis attribute (optional).

If the no known value is given (state rcsUnknown), an already existing request with the same ID is deleted.

◆ DelRequest()

void CResource::DelRequest ( const char *  reqGid = NULL,
TTicks  t1 = NEVER 
)

Delete a request.

Parameters
reqGidis the global request identifierr (GID) and identifies the request. If set to 'NULL', the instance name is used.
t1is the time at which the request is to be deleted (optional).

◆ GetRequestSet()

bool CResource::GetRequestSet ( CRcRequestSet ret,
bool  allowNet = true 
)

Query all pending requests.

Parameters
retpoints to the set of returned request IDs.
allowNetdetermines whether network communication is allowed. If 'true', the call may block for unpredictable time (usually at most the time given by 'rc.netTimeout'). If 'false', the call never blocks, but will surely fail for remote resources.
Returns
true on success or false on error.

◆ GetRequest()

CRcRequest * CResource::GetRequest ( const char *  reqGid,
bool  allowNet = true 
)

Query a request by its request GID.

Parameters
reqGidis the request ID.
allowNetspecifies wether network access (and eventual blocking/waiting) is allowed.
Returns
a dynamic object with the queried request or NULL if the resource cannot be queried (e.g. because it is unreachable, non-existing, or if it is not local and 'allowNet' is not set). The returned object must be deleted using 'delete'.

If the resource cannot be queried, e.g. because it is unreachable or non-existing, NULL is returned.

If the resource can be queried successfully, but no such request exists, 'ret->Value()' will have a state of rcsUnknown.

If an incompatible request has been set, CRcRequest::IsCompatible() will return 'false' on the returned object.

Note: This method uses GetRequestSet() internally. If multiple requests are to be queried, it is more efficient to call GetRequestSet() once instead.

◆ Register()

static CResource * CResource::Register ( CRcDriver _rcDriver,
const char *  _lid,
ERcType  _type,
bool  _writable,
void *  _data = NULL 
)
inlinestatic

Register a new local resource for a driver.

Parameters
_rcDriveris the driver for the resource.
_lidis the local resource ID (LID).
_typeis the resource type.
_writabledecides whether the resource is writable.
_datais an optional user data reference (see CResource::SetUserData() ).
Returns
reference to the resource. On error, 'NULL' is returned and a warning emitted.

Note: For the automatic documentation system, invocations of these methods may be documented as follows:

  • If a default value is to be set, the SetDefault() call must follow in the next line.
  • The next line must be a comment of the form: / * [RC:<driver>] <brief description>
  • If a long description is supplied, the next line must be: " *" ... then the description follows in lines starting with "*".
  • The comment block must end with a line starting with "* /" (end of comment - ignore the space here).
  • To explicitly exclude the resource from documentation, place a line with "/ * [RC:-] * /" (end/start of comment - ignore the spaces here) below or behind the call.

Details on the documentation system can be found in the Home2L Book.

Definition at line 1184 of file resources.H.

◆ Unregister()

void CResource::Unregister ( )

Unregister a resource.

Unused 'CResource' objects are never deleted from heap, but only marked as unregistered and its state set to 'rcsUnknown', if they are no longer used.

◆ RedriveValue()

void CResource::RedriveValue ( bool  force = true)
inline

Drive the currently requested value again.

     This re-evaluates the currently pending requests and calls CRcDriver::DriveValue() again.
     This is useful if the driver was unable to properly handle the last call to DriveValue()
     or for some other reason needs to catch up with the currently driven value.

     If 'force == false', the driver's DriveValue() is only called if the value to drive is
     actually different from the current value.

     This method must not be called from inside CRcDriver::DriveValue(). 

Definition at line 1264 of file resources.H.

◆ GetInfo()

const char * CResource::GetInfo ( CString ret,
int  verbosity = 1,
bool  allowNet = true 
)

Get textual information on this resource.

Parameters
retpoints to a string object filled with the textual information.
verbosityis the verbosity level: 0 = single line, 1 = list pending requests and subscriptions.
allowNetdefines whether network access is allowed. By default ('true'), the method is network transparent, and for remote resources, its host is contacted. If set to 'false', no network operation is performed and the locally available information is shown (may also be used for for diagnostic purposes).
Returns
pointer to the returned string.

The documentation for this class was generated from the following file: