Charging Station Configuration Add on - motown-io/motown GitHub Wiki

Responsibility

The charging station configuration add-on is responsible for configuring charging stations that haven't been configured yet.

Configuration flow

When a charging station, which has not been configured in Motown yet, sends a boot notification, the Motown core sends out a UnconfiguredChargingStationBootedEvent. The charging station configuration add-on listens for that event and looks in its local storage if it can find the configuration for the vendor and model mentioned in that event. The configuration consists of a set of evses, which itself consists of a set of connectors. If the configuration is found the configuration add-on sends out a ConfigureChargingStationCommand which contains the configuration information. If the configuration is not found no action is taken. The configuration add-on will respond the next time the charging station will send a boot notification to Motown.

Creating a configuration for a vendor and model can be done using the API.

Summary of the flow:

  • (unknown) charging station sends a boot notification to Motown
  • if the charging station is unknown or unconfigured Motown core sends out a UnconfiguredChargingStationBootedEvent
  • charging station configuration add-on listens for that event
  • the add-on checks its local storage if it knows the configuration for the vendor and model combination
  • if so: the add-on sends out a ConfigureChargingStationCommand
  • if not: the add-on takes no action and will pick up the next UnconfiguredChargingStationBootedEvent where the cycle repeats

Configuring the add-on

JPA

Make sure a JPA entity manager factory is running.

The JPA entities reside in package

  • io.motown.chargingstationconfiguration.viewmodel.persistence.entities.

The repositories reside in package

  • io.motown.chargingstationconfiguration.viewmodel.persistence.repositories.

As with all configuration samples, Spring is not required but it makes configuration a lot easier. A sample configuration of JPA in this add-on:

<!-- in-memory data source as a sample -->
<jdbc:embedded-database id="dataSource" type="HSQL">
    <jdbc:script location="classpath*:META-INF/hsqldb/schema.sql" />
    <!-- initialData.sql contains some dummy values to be able to use the charging station configuration add-on -->
    <jdbc:script location="classpath*:META-INF/hsqldb/initialData.sql" />
</jdbc:embedded-database>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="io.motown.chargingstationconfiguration.viewmodel.persistence"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="HSQL"/>
            <property name="generateDdl" value="true"/>
        </bean>
    </property>
</bean>

<!-- the repository beans can be used for setter injection on the domain service -->
<bean id="chargingStationTypeRepository" class="io.motown.chargingstationconfiguration.viewmodel.persistence.repositories.ChargingStationTypeRepository">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="manufacturerRepository" class="io.motown.chargingstationconfiguration.viewmodel.persistence.repositories.ManufacturerRepository">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

Domain service

The domain service contains the logic for accessing the repositories. The class is: io.motown.chargingstationconfiguration.viewmodel.domain.DomainService. The charging station type and manufacturer repository should be injected into the domain service.

Sample configuration:

<bean id="domainService" class="io.motown.chargingstationconfiguration.viewmodel.domain.DomainService">
    <!-- repositories mentioned in other sample -->
    <property name="chargingStationTypeRepository" ref="chargingStationTypeRepository" />
    <property name="manufacturerRepository" ref="manufacturerRepository" />
</bean>

Event listener

The add-on listens to UnconfiguredChargingStationBootedEvent. But it only does that if the event listener is active and configured. The event listener class is io.motown.chargingstationconfiguration.app.ConfigurationEventListener and requires access to a command gateway.

A sample configuration is:

<!-- make sure Axon picks up the EventHandler -->
<axon:annotation-config/>

<bean class="io.motown.chargingstationconfiguration.app.ConfigurationEventListener">
    <property name="commandGateway" ref="commandGateway" />
    <!-- domain service mentioned in other sample -->
    <property name="domainService" ref="domainService" />
    <!-- add-on id is a string value which is used to identify an add-on once multiple add-ons of the same type are running -->
    <property name="addOnId" value="1" />
</bean>

API

The add-on comes with a JSON REST API. The API can be used to list, create, update and delete configuration resources. The JSON REST API consists of 4 resources the provide access to the configuration items, they are located in package: io.motown.chargingstationconfiguration.viewmodel.restapi.

A more detailed description of the API can be found here.

Sample Spring configuration:

<bean class="io.motown.chargingstationconfiguration.viewmodel.restapi.ChargingStationTypeResource">
    <!-- domain service mentioned in other sample -->
    <property name="domainService" ref="domainService" />
</bean>

<bean class="io.motown.chargingstationconfiguration.viewmodel.restapi.ConnectorResource">
    <property name="domainService" ref="domainService" />
</bean>

<bean class="io.motown.chargingstationconfiguration.viewmodel.restapi.EvseResource">
    <property name="domainService" ref="domainService" />
</bean>

<bean class="io.motown.chargingstationconfiguration.viewmodel.restapi.ManufacturerResource">
    <property name="domainService" ref="domainService" />
</bean>

Sample web.xml configuration using Jersey:

<servlet>
    <servlet-name>JerseyConfigurationApiServlet</servlet-name>
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>io.motown.chargingstationconfiguration.viewmodel.restapi</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>JerseyConfigurationApiServlet</servlet-name>
    <url-pattern>/rest/config/*</url-pattern>
</servlet-mapping>
⚠️ **GitHub.com Fallback** ⚠️