solarpowerlog trunk
Developer: Basic Concepts

This section describes some basics concepts used in deveoping the software.

IInverterBase: Interface for Inverters

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:

  • Comms
    • Generate the concrete connection object (IConnect derived) The type of connection is extracted automatically from the configuration. On Datafilters, a default "Dummy" Connection will be created, if the specific configuratoin entries are missing.
  • Capabilites
    • Generating the required CCapabilites (see #Inverters/Capabilites.h)
    • Infrastructure around Capabilites: Adding, Iterator, Finding an concrete Capability...

Target for a WorkScheduler

  • Inverters should use solarpowerlog's Work Scheduler for execution planning. To be able to receive ICommands they are derived from ICommandTarget.
    • By using the default Scheduler (see Registry), concurrency is avoided, so there is no need for locking methods for common accessed datas.

Connection: Connecting to the word.

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)

inverter_comm.png
Connection Services

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:

Todo:
implement some kind of generic timeout handling, like schedule timeout, cancel timeout.)
See also:
IInverterBase::connection

How Capabilites transport datas

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).

FilterSequence.png
Capabilitiy passed through two filters (simplified)

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.

(

Todo:
More details are planned to appear on the IDataFilter description.)

The image below shows all the classes involved in the dataflow from the Inverter to the DataFilter:

dataflow_classes.png
Classes needed to let the data flow

This image shows how a typical update of a Capbility, and how the Data-Filter receives the information.

dataflow_sequence.png
Dataflow Sequence Diagram

Code-Snippets around Capabilites.

Unconditionally Register a new Capability (e.g in the constructor)

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 ";
 }

"Work Scheduler"

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.

Todo:
that Workscheduler-Page is not yet written,