|
solarpowerlog trunk
|
This section describes some basics concepts used in deveoping the software.
IIinverterBase is the interface which should be used for all inverters. It is also the base class for all DataFilters, (IDataFilter), as they also need most of the infracstructure for their duties.
It is ought to be derived, and the concrete implemenation implements the data aquisition.
To help avoiding doublicated code, the base class have contains already some code for the following funcions:
As stated before, the base class creates the communication object. To determine which connectiion type is to be used, it will use the factory IConnectionFactory. This factory looks in the configuration-path -- supplied by the bootstrap code -- for the entry "commtype" and create the associated comms object.
BTW: The connection classes will also retrieve their configuration from the config file automatically.
The comms object will not automatically connect. This should be done later while running the initializtion commmand (see workqueue below)
The image above shows the services currently exists for the comm classes.
Currently, the connection classed are mixed synchron and asynchronous. But this will change, the connection class should use asynchronous methods to avoid blocking the main task while waiting for completion.
This also implies, that the inverters have to implement some kind of time-out handling by itself. (Well its on the TODO list:
As described here, Capabilies store abstraced measurement values as well as some meta-datas controlling the Capabilites itself.
Simplified, the values are generated at the inverter's object and passed down to Datafilters (or loggers).
The data is passed along the Filters using the Observer Design pattern inheritated by the capability: Upon updating it, the Inverter calls the Notify function and the DataFilter gets notified.
As illustrated, Datafilters can also be chained. With this abitrary data manipulations can be achieved: The datafilter can calculate additional data sets (example: Efficiency out of Pin and Pout), or do some other arithmetics on them (mean value...)
Datafilters can also be parallel to e.g enable parallel serving of data to different logging systems: One would log to disk, the other servin a web page.
By the way, the Inverter manages a list of capablities in the map (IInverterBase::CapabilityMap). (The map is organized in pairs of <string,CCapability*> containing the description of the Capability and a pointer to the Capability.) However, there is an API to access the Capability in IInverteBase and an enhanced one in IDataFilter.
(
The image below shows all the classes involved in the dataflow from the Inverter to the DataFilter:
This image shows how a typical update of a Capbility, and how the Data-Filter receives the information.
Unconditionally Register a new Capability (e.g in the constructor)
c = new CCapability(CAPA_CAPAS_UPDATED, CAPA_CAPAS_UPDATED_TYPE, this); AddCapability(CAPA_CAPAS_UPDATED, c); *
Update a Capability's Value, create if not existance. Check for type
CCapability *cap = GetConcreteCapability(CAPA_INVERTER_TEMPERATURE_NAME); if (!cap) { string s; IValue *v; CCapability *c; s = CAPA_INVERTER_TEMPERATURE_NAME; v = IValue::Factory(CAPA_INVERTER_TEMPERATURE_TYPE); ((CValue<float>*) v)->Set(f); c = new CCapability(s, v, this); AddCapability(s, c); cap = GetConcreteCapability(CAPA_CAPAS_UPDATED); cap->Notify(); } // Capa already in the list. Check if we need to update it. else if (cap->getValue()->GetType() == CAPA_INVERTER_TEMPERATURE_TYPE) { CValue<float> *val = (CValue<float>*) cap->getValue(); if (val -> Get() != f) { val->Set(f); cap->Notify(); } } else { cerr << "BUG: " << CAPA_INVERTER_TEMPERATURE_NAME* << " not a float "; }
IInverterbase is derived from ICOmmandTarget. This class can reiceive commands from CWorkSchedule objects. One CWorkSchedule object can be received by the Registry, which is open for all objects to use. (This Scheduler is operated by solarpowerlogs internals, so no extra code is required to have an operating schedule.)
For Details, for example, how to use a CWorkSchedule and how to schedule some Work in a specific amount of time, please see the WorkScheduler overview Page.