|
@ -2,17 +2,16 @@
|
|||
|
||||
<ul class="nav">
|
||||
<li><a href="{{docu}}/index.html">Overview</a></li>
|
||||
<li><a href="{{docu}}/concepts-esh/items.html">Concepts</a>
|
||||
<li><a href="{{docu}}/concepts/items.html">Concepts</a>
|
||||
<ul>
|
||||
<li><a href="{{docu}}/concepts-esh/items.html">Items</a></li>
|
||||
<li><a href="{{docu}}/concepts-esh/things.html">Things</a></li>
|
||||
<li><a href="{{docu}}/concepts-esh/discovery.html">Inbox & Discovery</a></li>
|
||||
<li><a href="{{docu}}/concepts-esh/events.html">Events</a></li>
|
||||
<li><a href="{{docu}}/concepts/items.html">Items</a></li>
|
||||
<li><a href="{{docu}}/concepts/things.html">Things</a></li>
|
||||
<li><a href="{{docu}}/concepts/discovery.html">Inbox & Discovery</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="{{docu}}/features/addons.html">Add-ons</a>
|
||||
<ul>
|
||||
<li><a href="{{docu}}/features/bindings/hue/readme.html">Bindings</a>
|
||||
<li><a href="{{docu}}/features/bindings/digitalstrom/readme.html">Bindings</a>
|
||||
<ul>
|
||||
<li><a href="{{docu}}/features/bindings/digitalstrom/readme.html">digitalSTROM</a></li>
|
||||
<li><a href="{{docu}}/features/bindings/hue/readme.html">Philips Hue</a></li>
|
||||
|
@ -23,10 +22,10 @@
|
|||
<li><a href="{{docu}}/features/bindings/yahooweather/readme.html">Yahoo Weather</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="{{docu}}/features/ui/icons.html">User Interfaces</a>
|
||||
<li><a href="{{docu}}/features/uis.html">User Interfaces</a>
|
||||
<ul>
|
||||
<li><a href="{{docu}}/features/ui/icons.html">Icon Support</a></li>
|
||||
<li><a href="{{docu}}/features/ui/paperui.html">Paper UI</a></li>
|
||||
<li><a href="{{docu}}/features/ui/basic/readme.html">Basic UI</a></li>
|
||||
<li><a href="{{docu}}/features/iconsets/classic/readme.html">Classic Iconset</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
layout: documentation
|
||||
---
|
||||
|
||||
{% include base.html %}
|
||||
|
||||
# Thing Discovery and Inbox
|
||||
|
||||
Many technologies and systems can be automatically discovered on the network or browsed through some API. It therefore makes a lot of sense to use these features for a smart home solution.
|
||||
|
||||
In Eclipse SmartHome bindings can therefore implement _Discovery Services_ for things. As a solution might not want to make everything that is found on the network immediately available to the user and his applications, all _Discovery Results_ are regarded as suggestions that are first put into an _inbox_.
|
||||
|
||||
## Glossary
|
||||
|
||||
- _Discovery_: Search for available things in the smart home environment.
|
||||
- _Discovery Result_: Result of a _Discovery_ stored in the _Inbox_.
|
||||
- _Discovery Service_: Implements a service to discover things, typically based on a specialized protocol (e.g. UPnP).
|
||||
- _Inbox_: List of all discovered things, constantly updated by all running discoveries.
|
||||
|
||||
## Inbox
|
||||
|
||||
The inbox represents a list of all discovered things (`DiscoveryResult`) from all known discovery services. Bindings can register new discovery services to discover new thing types (e.g. the Hue binding registers a new discovery service to search for Hue lights). Technically the inbox is an OSGi service which manages the discovery results. Notification about new things added to or things removed from the inbox will be sent as events.
|
||||
|
||||
### Discovery Result
|
||||
|
||||
A discovery result represents a discovered thing of a specific thing type, that could be instantiated as things in Eclipse SmartHome. The result usually contains properties that identify the discovered things further like IP address or a serial number. Each discovery result also has a timestamp when it was added to or updated in the inbox and it may also contain a time to live, indicating the time after which it will be automatically removed from the inbox.
|
||||
|
||||
The following table gives an overview about the main parts of a `DiscoveryResult`:
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `thingUID` | The `thingUID` is the unique identifier of the specific discovered thing (e.g. a device's serial number). It *must not* be constructed out of properties, that can change (e.g. IP addresses). A typical `thingUID` could look like this: `hue:bridge:001788141f1a`
|
||||
| `thingTypeUID` | Contrary to the `thingUID` is the `thingTypeUID` that specifies the type the discovered thing belongs to. It could be constructed from e.g. a product number. A typical `thingTypeUID` could be the following: `hue:bridge`.
|
||||
| `bridgeUID` | If the discovered thing belongs to a bridge, the `bridgeUID` contains the UID of that bridge.
|
||||
| `properties` | The `properties` of a `DiscoveryResult` contain the configuration for the newly created thing.
|
||||
|
||||
Discovery results can either be ignored or approved, where in the latter case a thing is created for them and they become available in the application. The configuration of that created thing contains the values from the `properties`of the approved `DiscoveryResult`. If an entry is ignored, it will be hidden in the inbox without creating a thing for it.
|
||||
|
||||
### Active Scan vs. Background Discovery
|
||||
|
||||
There are different ways how a thing can be discovered:
|
||||
|
||||
- In protocols like UPnP or Bonjour/mDNS devices send announcements on the network that can be listened to. In Eclipse SmartHome we refer to such mechanisms as "background discovery", i.e. passive mechanisms where events come in and can be processed. Things can be therefore found any time and put into the inbox.
|
||||
|
||||
- There might be an API, which can be accessed to actively query all available things. In Eclipse SmartHome, this is called an "active scan" and thus configuration UIs must provide a way to trigger such a scan for a certain thing type. In general, it is not recommended to do any active discovery by the binding in the background as it can negatively impact the system performance. The only exception is that a scan can be triggered once at startup and if a bridge has been added, so that its attached things are directly discovered.
|
||||
|
||||
## Available Discovery Services
|
||||
|
||||
Eclipse SmartHome already comes with some discovery services. These are:
|
||||
|
||||
- `UPnPDiscoveryService`: This discovery service discovers all IP devices using the UPnP protocol. The bindings must implement a `UpnpDiscoveryParticipant` to support this discovery service. The [UPnP discovery service documentation](../development/bindings/discovery-services.html#upnp-discovery) explains in detail, how to do that.
|
||||
- `MDNSDiscoveryService`: All devices supporting the mDNS protocol are discovered by this service.
|
||||
|
||||
Bindings implement more discovery services, e.g. the search for Hue lights in the Hue binding or the search for the local weather in the Yahoo weather binding.
|
||||
|
||||
The [Implement Discovery Service](../development/bindings/discovery-services.html) chapter describes how to implement DiscoveryServices in a binding.
|
|
@ -0,0 +1,96 @@
|
|||
---
|
||||
layout: documentation
|
||||
---
|
||||
|
||||
{% include base.html %}
|
||||
|
||||
# Event Type Definition
|
||||
|
||||
Eclipse SmartHome provides the possibility to easily implement new event types and event factories.
|
||||
|
||||
## Define new Event Type
|
||||
|
||||
Events can be added by implementing the `Event` interface or the `AbstractEvent` class which offers a default implementation. Both classes are located in the Eclipse SmartHome core bundle.
|
||||
|
||||
The following Java snippet shows a new event type extending the class `AbstractEvent`.
|
||||
|
||||
```java
|
||||
public class SunriseEvent extends AbstractEvent {
|
||||
|
||||
public final static String TYPE = SunriseEvent.class.getSimpleName();
|
||||
|
||||
private final SunriseDTO sunriseDTO;
|
||||
|
||||
SunriseEvent(String topic, String payload, SunriseDTO sunriseDTO) {
|
||||
super(topic, payload, null);
|
||||
this.sunriseDTO = sunriseDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
public SunriseDTO getSunriseDTO() {
|
||||
return sunriseDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Sunrise at '" + getSunriseDTO.getTime() + "'.";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The listing below summarizes some coding guidelines as illustrated in the example above:
|
||||
|
||||
- Events should only be created by event factories. Constructors do not have any access specifier in order to make the class package private.
|
||||
- The serialization of the payload into a data transfer object (e.g. `SunriseDTO`) should be part of the event factory and will be assigned to a class member via the constructor.
|
||||
- A public member `TYPE` represents the event type as string representation and is usually the name of the class.
|
||||
- The `toString()` method should deliver a meaningful string since it is used for event logging.
|
||||
- The source of an event can be null if not required.
|
||||
|
||||
For more information about implementing an event, please refer to the Java documentation.
|
||||
|
||||
## Define new Event Factory
|
||||
Event factories can be added by implementing the `EventFactory` interface or the `AbstractEventFactory` class. The `AbstractEventFactory` provides some useful utility for parameter validation and payload serialization & deserialization with JSON. The classes are located in the Eclipse SmartHome core bundle.
|
||||
|
||||
```java
|
||||
public class SunEventFactory extends AbstractEventFactory {
|
||||
|
||||
private static final String SUNRISE_EVENT_TOPIC = "smarthome/sun/{time}/sunrise";
|
||||
|
||||
public SunEventFactory() {
|
||||
super(Sets.newHashSet(SunriseEvent.TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Event createEventByType(String eventType, String topic, String payload, String source) throws Exception {
|
||||
Event event = null;
|
||||
if (eventType.equals(SunriseEvent.TYPE)) {
|
||||
createSunriseEvent(topic, payload);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
private createSunriseEvent(String topic, String payload) {
|
||||
SunriseDTO sunriseDTO = deserializePayload(payload, SunriseDTO.class);
|
||||
return new SunriseEvent(topic, payload, sunriseDTO);
|
||||
}
|
||||
|
||||
public static SunriseEvent createSunriseEvent(Sunrise sunrise) {
|
||||
String topic = buildTopic(SUNRISE_EVENT_TOPIC, sunrise.getTime());
|
||||
SunriseDTO sunriseDTO = map(sunrise);
|
||||
String payload = serializePayload(sunriseDTO);
|
||||
return new SunriseEvent(topic, payload, sunriseDTO);
|
||||
}
|
||||
}
|
||||
```
|
||||
The listing below summarizes some guidelines as illustrated in the example above:
|
||||
|
||||
- Provide the supported event types (`SunriseEvent.TYPE`) via an `AbstractEventFactory` constructor call. The supported event types will be returned by the `AbstractEventFactory.getSupportedEventTypes()` method.
|
||||
- The event factory defines the topic (`SUNRISE_EVENT_TOPIC`) of the supported event types. Please ensure that the topic format follows the topic structure of the Eclipse SmartHome core events, similar to a REST URI (`{namespace}/{entityType}/{entity}/{sub-entity-1}/.../{sub-entity-n}/{action}`). The namespace must be `smarthome`.
|
||||
- Implement the method `createEventByType(String eventType, String topic, String payload, String source)` to create a new event based on the topic and the payload, determined by the event type. This method will be called by the framework in order to dispatch received events to the corresponding event subscribers. If the payload is serialized with JSON, the method `deserializePayload(String payload, Class<T> classOfPayload)`can be used to deserialize the payload into a data transfer object.
|
||||
- Provide a static method to create event instances based on a domain object (Item, Thing, or in the example above `Sunrise`). This method can be used by components in order to create events based on domain objects which should be sent by the EventPublisher. If the data transfer object should be serialized into a JSON payload, the method `serializePayload(Object payloadObject)` can be used.
|
||||
|
||||
For more information about implementing an event factory, please refer to the Java documentation.
|
|
@ -0,0 +1,200 @@
|
|||
---
|
||||
layout: documentation
|
||||
---
|
||||
|
||||
{% include base.html %}
|
||||
|
||||
# Events
|
||||
|
||||
The Eclipse SmartHome framework provides an event bus for inter-component communication. The communication is based on events which can be sent and received through the event bus in an asynchronous way. Examples of Eclipse SmartHome event types are _ItemCommandEvent_, _ItemStateEvent_, _ItemAddedEvent_, _ThingStatusInfoEvent_, etc.
|
||||
|
||||
This section gives a short overview about the event API and illustrates how to receive such events. Furthermore, the sending of events and the implementation of new event types will be described.
|
||||
|
||||
A code snippet about receiving events can be found in chapter "Receive Events". In particular, receiving _ItemStateEvents_ and _ItemCommandEvents_ is described in chapter "Receive ItemStateEvents and ItemCommandEvents".
|
||||
|
||||
## API Introduction
|
||||
|
||||
### The Interfaces
|
||||
|
||||

|
||||
|
||||
The `EventPublisher` posts `Event`s through the Eclipse SmartHome event bus in an asynchronous way. The `EventSubscriber` defines the callback interface to receive events of specific types to which the event subscriber is subscribed. The EventPublisher and the EventSubscribers are registered as OSGi services. An event subscriber can provide an `EventFilter` in order to filter events based on the topic or the content. If there is no filter all subscribed event types are received. The event itself will be subclassed for each event type, which exists in the System (e.g. ItemCommandEvent, ItemUpdatedEvent, ThingStatusInfoEvent).
|
||||
|
||||
### The Core Events
|
||||
This section lists the core events provided by Eclipse SmartHome which can be divided into the categories _Item Events_, _Thing Events_ and _Inbox Events_.
|
||||
|
||||
An event consists of a `topic`, a `type`, a `payload` and a `source`. The payload can be serialized with any String representation and is determined by its concrete event type implementation (e.g. ItemCommandEvent, ItemUpdatedEvent). The payloads of the Eclipse SmartHome core events are serialized with JSON. Each event implementation provides the payload as high level methods as well, usually presented by a data transfer object (DTO).
|
||||
|
||||
A topic clearly defines the target of the event and its structure is similar to a REST URI, except the last part, the action. The topics of Eclipse SmartHome events are divided into the following four parts: `{namespace}/{entityType}/{entity}/{action}`, e.g. `smarthome/items/{itemName}/command`.
|
||||
|
||||
The type of an event is represented by a string, usually the name of the concrete event implementation class, e.g. ItemCommandEvent, ItemUpdatedEvent. This string type presentation is used by event subscribers for event subscription (see chapter "Receive Events") and by the framework for the creation of concrete event instances.
|
||||
|
||||
The event source is optional and represents the name of the source identifying the sender.
|
||||
|
||||
#### Item Events
|
||||
|
||||
| Event |Description |Topic |
|
||||
|-----------------------|-------------------------------------------------|----------------------------------------|
|
||||
| ItemAddedEvent |An item has been added to the item registry. |smarthome/items/{itemName}/added |
|
||||
| ItemRemovedEvent |An item has been removed from the item registry. |smarthome/items/{itemName}/removed |
|
||||
| ItemUpdatedEvent |An item has been updated in the item registry. |smarthome/items/{itemName}/updated |
|
||||
| ItemCommandEvent |A command is sent to an item via a channel. |smarthome/items/{itemName}/command |
|
||||
| ItemStateEvent |The state of an item is updated. |smarthome/items/{itemName}/state |
|
||||
| ItemStateChangedEvent |The state of an item has changed. |smarthome/items/{itemName}/statechanged |
|
||||
|
||||
**Note:** The ItemStateEvent is always sent if the state of an item is updated, even if the state did not change. ItemStateChangedEvent is sent only if the state of an item was really changed. It contains the old and the new state of the item.
|
||||
|
||||
#### Thing Events
|
||||
|
||||
| Event |Description |Topic |
|
||||
|-----------------------|-------------------------------------------------|-----------------------------------|
|
||||
| ThingAddedEvent |A thing has been added to the thing registry. |smarthome/things/{thingUID}/added |
|
||||
| ThingRemovedEvent |A thing has been removed from the thing registry.|smarthome/things/{thingUID}/removed|
|
||||
| ThingUpdatedEvent |A thing has been updated in the thing registry. |smarthome/things/{thingUID}/updated|
|
||||
| ThingStatusInfoEvent |The status of a thing is updated. |smarthome/things/{thingUID}/status |
|
||||
| ThingStatusInfoChangedEvent |The status of a thing changed. |smarthome/things/{thingUID}/statuschanged |
|
||||
|
||||
**Note:** The ThingStatusInfoEvent is always sent if the status info of a thing is updated, even if the status did not change. ThingStatusInfoChangedEvent is sent only if the status of a thing was really changed. It contains the old and the new status of the thing.
|
||||
|
||||
#### Inbox Events
|
||||
|
||||
| Event |Description |Topic |
|
||||
|-----------------------|---------------------------------------------------|-----------------------------------|
|
||||
| InboxAddedEvent |A discovery result has been added to the inbox. |smarthome/inbox/{thingUID}/added |
|
||||
| InboxRemovedEvent |A discovery result has been removed from the inbox. |smarthome/inbox/{thingUID}/removed |
|
||||
| InboxUpdateEvent |A discovery result has been updated in the inbox. |smarthome/inbox/{thingUID}/updated |
|
||||
|
||||
#### Link Events
|
||||
|
||||
| Event |Description |Topic |
|
||||
|-----------------------------|---------------------------------------------------------|------------------------------------------------|
|
||||
| ItemChannelLinkAddedEvent |An item channel link has been added to the registry. |smarthome/links/{itemName}-{channelUID}/added |
|
||||
| ItemChannelLinkRemovedEvent |An item channel link has been removed from the registry. |smarthome/links/{itemName}-{channelUID}/removed |
|
||||
| ItemThingLinkAddedEvent |An item thing link has been added to the registry. |smarthome/links/{itemName}-{thingUID}/added |
|
||||
| ItemThingLinkRemovedEvent |An item thing link has been removed from the registry. |smarthome/links/{itemName}-{thingUID}/removed |
|
||||
|
||||
## Receive Events
|
||||
|
||||
This section describes how to receive Eclipse SmartHome events in Java. If you want to receive events "outside" Eclipse SmartHome, e.g. with JavaScript, please refer to the [Server Sent Events section](../features/rest.html).
|
||||
|
||||
An event subscriber defines the callback interface for receiving events from the Eclipse SmartHome event bus. The following Java snippet shows how to receive `ItemStateEvent`s and `ItemCommandEvent`s from the event bus. Therefore, the `EventSubscriber` interface must be implemented.
|
||||
|
||||
```java
|
||||
public class SomeItemEventSubscriber implements EventSubscriber {
|
||||
private final Set<String> subscribedEventTypes = ImmutableSet.of(ItemStateEvent.TYPE, ItemCommandEvent.TYPE);
|
||||
private final EventFilter eventFiter = new TopicEventFilter("smarthome/items/ItemX/.*");
|
||||
|
||||
@Override
|
||||
public Set<String> getSubscribedEventTypes() {
|
||||
return subscribedEventTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventFilter getEventFilter() {
|
||||
return eventFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Event event) {
|
||||
String topic = event.getTopic();
|
||||
String type = event.getType();
|
||||
String payload = event.getPayload();
|
||||
if (event instanceof ItemCommandEvent) {
|
||||
ItemCommandEvent itemCommandEvent = (ItemCommandEvent) event;
|
||||
String itemName = itemCommandEvent.getItemName();
|
||||
Command command = itemCommandEvent.getItemCommand();
|
||||
// ...
|
||||
} else if (event instanceof ItemStateEvent) {
|
||||
ItemStateEvent itemStateEvent = (ItemStateEvent) event;
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
The `SomeItemEventSubscriber` is subscribed to the event types `ItemStateEvent` and `ItemCommandEvent`, provided by the method `getSubscribedEventTypes()`. A string representation of an event type can be found by a public member `TYPE` which usually presents the name of the class. To subscribe to all available event types, use the public member `ALL_EVENT_TYPES` of the event subscriber interface.
|
||||
|
||||
The event subscriber provides a `TopicEventFilter` which is a default Eclipse SmartHome `EventFilter` implementation that ensures filtering of events based on a topic. The argument of the filter is a [Java regular expression](http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html). The filter method `EventFilter.apply()` will be called for each event on the event bus to which the event subscriber is subscribed (in the example above ItemStateEvent and ItemCommandEvent). If the filter applies (in the given example for all item events with the item name "ItemX"), the event will be received by the `EventSubscriber.receive()` method. Received events can be cast to the event implementation class for further processing.
|
||||
|
||||
Each event subscriber must be registered via OSGi Declarative Services (DS) under the `org.eclipse.smarthome.event.EventSubscriber` interface.
|
||||
|
||||
```xml
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="SomeItemEventSubscriber">
|
||||
<implementation class="org.eclipse.smarthome.core.items.events.SomeItemEventSubscriber"/>
|
||||
<service>
|
||||
<provide interface="org.eclipse.smarthome.core.events.EventSubscriber"/>
|
||||
</service>
|
||||
</scr:component>
|
||||
```
|
||||
|
||||
The listing below summarizes some best practices in order to implement event subscribers:
|
||||
|
||||
- To subscribe to only one event type Eclipse SmartHome provides the `org.eclipse.smarthome.core.events.AbstractTypedEventSubscriber` implementation. To receive an already cast event the `receiveTypedEvent(T)` method must be implemented. To provide an event filter the method `getEventFilter()` can be overridden.
|
||||
- Eclipse SmartHome provides an `AbstractItemEventSubscriber` class in order to receive ItemStateEvents and ItemCommandEvents (more information can be obtained in the next chapter).
|
||||
- To filter events based on a topic the `org.eclipse.smarthome.core.events.TopicEventFilter` implementation from the Eclipse SmartHome core bundle can be used. The filtering is based on [Java regular expression](http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html).
|
||||
- The subscribed event types and the filter should be stored as class members (see example above) due to performance reasons.
|
||||
- If the subscribed event types are sufficient in order to receive all interested events, do not return any filter (in that case the method getFilter() returns null) due to performance reasons.
|
||||
- Avoid the creation of too many event subscribers. Similar event types can be received in one event subscriber.
|
||||
- Handle exceptions in event subscriber implementation and throw only serious exceptions. Thrown exceptions will be handled in the framework by logging an error message with the cause.
|
||||
- The receive method should terminate quickly, since it blocks other event subscribers. Create a thread for long running operations.
|
||||
|
||||
|
||||
### Receive ItemStateEvents and ItemCommandEvents
|
||||
Due to the fact that receiving ItemStateEvents and ItemCommandEvents is a common use case, Eclipse SmartHome provides an abstract event subscriber implementation via the core bundle. The class `org.eclipse.smarthome.core.items.events.AbstractItemEventSubscriber` provides two methods `receiveUpdate(ItemStateEvent)` and `receiveCommand(ItemCommandEvent)` which can be implemented in order to receive and handle such events.
|
||||
|
||||
```java
|
||||
public class SomeItemEventSubscriber extends AbstractItemEventSubscriber {
|
||||
private final EventFilter eventFiter = new TopicEventFilter("smarthome/items/ItemX/.*");
|
||||
|
||||
@Override
|
||||
public EventFilter getEventFilter() {
|
||||
return eventFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receiveCommand(ItemCommandEvent commandEvent) {
|
||||
// do something
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void receiveUpdate(ItemStateEvent stateEvent) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Send Events
|
||||
|
||||
Usually the core events are only sent by the Eclipse SmartHome framework. However, it is possible to sent events explicitly, e.g. ItemCommandEvents and ItemStateEvents. The Java snippet below illustrates how to send events via the EventPublisher. The Eclipse SmartHome core events can only be created via the corresponding event factory.
|
||||
|
||||
```java
|
||||
public class SomeComponentWantsToPost {
|
||||
private EventPublisher eventPublisher;
|
||||
|
||||
public void postSomething() {
|
||||
ItemCommandEvent itemCommandEvent = ItemEventFactory.createCommandEvent("ItemX", OnOffType.ON);
|
||||
eventPublisher.post(itemCommandEvent);
|
||||
}
|
||||
|
||||
protected void setEventPublisher(EventPublisher eventPublisher) {
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
protected void unsetEventPublisher(EventPublisher eventPublisher) {
|
||||
this.eventPublisher = null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The EventPublisher will be injected via OSGi Declarative Services.
|
||||
|
||||
```xml
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="SomeComponentWantsToPost">
|
||||
<!-- ... -->
|
||||
<reference bind="setEventPublisher" cardinality="1..1" interface="org.eclipse.smarthome.core.events.EventPublisher"
|
||||
name="EventPublisher" policy="static" unbind="unsetEventPublisher"/>
|
||||
</scr:component>
|
||||
```
|
||||
|
||||
## Define new Event Types
|
||||
|
||||
It is possible to create and provide new event types. For a detailed description please refer to the [Event Type Definition section](./event-type-definition.html).
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
layout: documentation
|
||||
---
|
||||
|
||||
{% include base.html %}
|
||||
|
||||
# About Eclipse SmartHome
|
||||
|
||||
## Background
|
||||
Since the emergence of broadband internet connections, smartphones and tablets the smart home market shows a remarkable upsurge. This has led to a very fragmented market, which makes it difficult for customers to "bet on the right horse". In fact, there is not one system, protocol or standard that could possibly fulfill all potential requirements. There is hence a need for platforms that allow the integration of different systems, protocols or standards and that provide a uniform way of user interaction and higher level services.
|
||||
|
||||
## How does Eclipse SmartHome help?
|
||||
|
||||
The goals of the Eclipse SmartHome project can be summarized as:
|
||||
|
||||
* Provide a flexible framework for smart home and ambient assisted living (AAL) solutions. This framework focuses on the use cases of this domain, e.g. on easy automation and visualization aspects.
|
||||
* Specify extension points for integration possibilities and higher-level services. Extending and thus customizing the solution must be as simple as possible and this requires concise and dedicated interfaces.
|
||||
* Provide implementations of extensions for relevant systems, protocols or standards. Many of them can be useful to many smart home solutions, so this project will provide a set of extensions that can be included if desired. They can also be in the shape of a general Java library or an OSGi bundle, so that these implementations can be used independently of the rest of the project as well.
|
||||
* Provide a development environment and tools to foster implementations of extensions. The right tooling can support the emergence of further extensions and thus stimulate future contributions to the project.
|
||||
* Create a packaging and demo setups. Although the focus is on the framework, it needs to be shown how to package a real solution from it, which can be used as a starting point and for demo purposes.
|
||||
Description
|
||||
* The Eclipse SmartHome project is a framework that allows building smart home solutions that have a strong focus on heterogeneous environments, i.e. solutions that deal with the integration of different protocols or standards. Its purpose is to provide a uniform access to devices and information and to facilitate different kinds of interactions with them. This framework consists out of a set of OSGi bundles that can be deployed on an OSGi runtime and which defines OSGi services as extension points.
|
||||
|
||||
The stack is meant to be usable on any kind of system that can run an OSGi stack - be it a multi-core server, a residential gateway or a Raspberry Pi.
|
||||
|
||||
The project focuses on services and APIs for the following topics:
|
||||
|
||||
1. _Data Handling_: This includes a basic but extensible type system for smart home data and commands that provides a common ground for an abstracted data and device access as well as event mechanisms to send this information around. It is the most important topic for integrating with other systems, which is done through so called bindings, which are a special type of extension.
|
||||
1. _Rule Engines_: A flexible rule engine that allows changing rules during runtime and which defines extension types that allow breaking down rules into smaller pieces like triggers, actions, logic modules and templates.
|
||||
1. _Declarative User Interfaces_: A framework with extensions for describing user interface content in a declarative way. This includes widgets, icons, charts etc.
|
||||
1. _Persistence Management_: Infrastructure that allows automatic data processing based on a simple and unified configuration. Persistence services are pluggable extensions, which can be anything from a log writer to an IoT cloud service.
|
||||
|
||||
Besides the runtime framework and implementation, the Eclipse SmartHome project also provides different kinds of tools and samples:
|
||||
|
||||
* Eclipse editors for editing configuration models and rules. These provide full IDE support, such as content assist and syntax validation.
|
||||
* Maven archetypes to easily create skeletons for extensions
|
||||
* Demo packaging with other Eclipse IoT projects
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
layout: documentation
|
||||
---
|
||||
|
||||
{% include base.html %}
|
||||
|
||||
# Items
|
||||
|
||||
Eclipse SmartHome has a strict separation between the physical world (the "things", see below) and the application, which is built around the notion of "items" (also called the virtual layer).
|
||||
|
||||
Items represent functionality that is used by the application (mainly user interfaces or automation logic). Items have a state and are used through events.
|
||||
|
||||
The following item types are currently available (alphabetical order):
|
||||
|
||||
<table>
|
||||
<tr><td><b>Itemname</b></td><td><b>Description</b></td><td><b>Command Types</b></td></tr>
|
||||
<tr><td>Color</td><td>Color information (RGB)</td><td>OnOff, IncreaseDecrease, Percent, HSB</td></tr>
|
||||
<tr><td>Contact</td><td>Item storing status of e.g. door/window contacts</td><td>OpenClose</td></tr>
|
||||
<tr><td>DateTime</td><td>Stores date and time</td><td></td></tr>
|
||||
<tr><td>Dimmer</td><td>Item carrying a percentage value for dimmers</td><td>OnOff, IncreaseDecrease, Percent</td></tr>
|
||||
<tr><td>Group</td><td>Item to nest other items / collect them in groups</td><td>-</td></tr>
|
||||
<tr><td>Number</td><td>Stores values in number format</td><td>Decimal</td></tr>
|
||||
<tr><td>Player</td><td>Allows to control players (e.g. audio players)</td><td>PlayPause, NextPrevious, RewindFastforward</td></tr>
|
||||
<tr><td>Rollershutter</td><td>Typically used for blinds</td><td>UpDown, StopMove, Percent</td></tr>
|
||||
<tr><td>String</td><td>Stores texts</td><td>String</td></tr>
|
||||
<tr><td>Switch</td><td>Typically used for lights (on/off)</td><td>OnOff</td></tr>
|
||||
</table>
|
||||
|
||||
Group Items can derive their own state depending on their member items.
|
||||
|
||||
- AVG displays the average of the item states in the group.
|
||||
- OR displays an OR of the group, typically used to display whether any item in a group has been set.
|
||||
- other aggregations: AND, SUM, MIN, MAX, NAND, NOR
|
|
@ -0,0 +1,91 @@
|
|||
---
|
||||
layout: documentation
|
||||
---
|
||||
|
||||
# Things
|
||||
|
||||
Things are the entities that can physically be added to a system and which can potentially provide many functionalities in one. It is important to note that things do not have to be devices, but they can also represent a web service or any other manageable source of information and functionality.
|
||||
From a user perspective, they are relevant for the setup and configuration process, but not for the operation.
|
||||
|
||||
Things can have configuration properties, which can be optional or mandatory. Such properties can be basic information like an IP address, an access token for a web service or a device specific configuration that alters its behavior.
|
||||
|
||||
Things provide "channels", which represent the different functions they provide. Channels are linked to items, where such links are the glue between the virtual and the physical layer. Once such a link is established, a thing reacts on events sent for an item that is linked to one of its channels. Likewise, it actively sends out events for items linked to its channels.
|
||||
|
||||
A special type of thing is a "bridge". Bridges are things that need to be added to the system in order to gain access to other things. A typical example of a bridge is an IP gateway for some non-IP based home automation system.
|
||||
|
||||
As many things can be automatically discovered, there are special mechanisms available that deal with the handling of [automatically discovered things](discovery.html).
|
||||
|
||||
|
||||
## Thing Status
|
||||
|
||||
Each thing has a status object, which helps to identify possible problems with the device or service. The following table provides an overview of the different statuses:
|
||||
|
||||
| Status | Description |
|
||||
|---------------|-------------|
|
||||
| UNINITIALIZED | This is the initial status of a thing, when it is added or the framework is being started. This status is also assigned, if the initializing process failed or the binding is not available. Commands, which are sent to channels will not be processed.
|
||||
| INITIALIZING | This state is assigned while the binding initializes the thing. It depends on the binding how long the initializing process takes. Commands, which are sent to channels will not be processed.
|
||||
| ONLINE | The device/service represented by a thing is assumed to be working correctly and can process commands.
|
||||
| OFFLINE | The device/service represented by a thing is assumed to be not working correctly and may not process commands. But the framework is allowed to send commands, because some radio-based devices may go back to ONLINE, if a command is sent to them.
|
||||
| REMOVING | The device/service represented by a thing should be removed, but the binding did not confirm the deletion yet. Some bindings need to communicate with the device to unpair it from the system. Thing is probably not working and commands can not be processed.
|
||||
| REMOVED | This status indicates, that the device/service represented by a thing was removed from the external system. Usually this status is an intermediate status, because the thing is removed from the database after this status is assigned.
|
||||
|
||||
The statuses UNINITIALIZED, INITIALIZING and REMOVING are set by the framework, where as the statuses ONLINE, OFFLINE and REMOVED is assigned from a binding.
|
||||
|
||||
### Status Transitions
|
||||
|
||||
The following diagram shows the allowed status transitions:
|
||||
|
||||

|
||||
|
||||
The initial state of a thing is UNINITIALIZED. From UNINITIALIZED the thing goes into INITIALIZING. If the initialization fails, the thing goes back to UNINITIALIZED. If the initialization succeeds, the binding sets the status of the thing to ONLINE or OFFLINE, which both means, that the thing is INITIALIZED. From one of this states the thing can go back into UNINITIALIZED, REMOVING or REMOVED. The statuses REMOVING and REMOVED can also be reached from any other state.
|
||||
|
||||
## Status Details
|
||||
|
||||
A status is detailed further with a status detail object. The following table lists the different status details for each status:
|
||||
|
||||
<table>
|
||||
<tr valign="top"><td rowspan="5">UNINITIALIZED</td><td>NONE</td><td>No further status details available.</td></tr>
|
||||
<tr valign="top"> <td>HANDLER_MISSING_ERROR</td><td>The handler cannot be initialized, because the responsible binding is not available or started.</td></tr>
|
||||
<tr valign="top"> <td>HANDLER_REGISTERING_ERROR</td><td>The handler failed in the service registration phase.</td></tr>
|
||||
<tr valign="top"> <td>HANDLER_CONFIGURATION_PENDING</td><td>The handler is registered but can not be initialized caused by missing configuration parameters.</td></tr>
|
||||
<tr valign="top"> <td>HANDLER_INITIALIZING_ERROR</td><td>The handler failed in the initialization phase.</td></tr>
|
||||
<tr valign="top"><td>INITIALIZING</td> <td>NONE</td><td>No further status details available.</td></tr>
|
||||
<tr valign="top"><td rowspan="2">ONLINE</td> <td>NONE</td><td>No further status details available.</td></tr>
|
||||
<tr valign="top"> <td>CONFIGURATION_PENDING</td><td>The thing is waiting to transfer configuration information to a device. Some bindings need to communicate with the device to make sure the configuration is accepted.</td></tr>
|
||||
<tr valign="top"><td rowspan="6">OFFLINE</td> <td>NONE</td><td>No further status details available.</td></tr>
|
||||
<tr valign="top"> <td>COMMUNICATION_ERROR</td><td>Error in communication with the device. This may also be only a temporary error.</td></tr>
|
||||
<tr valign="top"> <td>CONFIGURATION_ERROR</td><td>An issue with the configuration of a thing prevents the communication with the represented device or service. This issue might be solved by reconfiguring the thing.</td></tr>
|
||||
<tr valign="top"> <td>BRIDGE_OFFLINE</td><td>Assuming the thing to be offline because the corresponding bridge is offline.</td></tr>
|
||||
<tr valign="top"> <td>FIRMWARE_UPDATING</td><td>The thing is currently operating a firmware update.</td></tr>
|
||||
<tr valign="top"> <td>DUTY_CYCLE</td><td>The thing is currently in DUTY_CYCLE state, which means it is blocked for further usage.</td></tr>
|
||||
<tr valign="top"><td>REMOVING</td> <td>NONE</td><td>No further status details available.</td></tr>
|
||||
<tr valign="top"><td>REMOVED</td> <td>NONE</td><td>No further status details available.</td></tr>
|
||||
</table>
|
||||
|
||||
### Status Description
|
||||
|
||||
To provide additional information about the current status a description is used. The status description is to be specified by the binding. This description can be used for debugging purposes and should not be presented to the user, as it might contain unreadable technical information (e.g. an HTTP status code, or any other protocol specific information, which helps to identify the current problem).
|
||||
|
||||
### Thing Status API
|
||||
|
||||
The Thing interface defines a method `getStatusInfo()` to retrieve the current status of the thing. The following code shows how to print the status of each thing into the console:
|
||||
|
||||
```java
|
||||
Collection<Thing> things = thingRegistry.getAll();
|
||||
for (Thing thing : things) {
|
||||
ThingStatusInfo statusInfo = thing.getStatusInfo();
|
||||
switch (statusInfo.getStatus()) {
|
||||
case ONLINE:
|
||||
System.out.println("Thing is online");
|
||||
break;
|
||||
case OFFLINE:
|
||||
System.out.println("Thing is offline");
|
||||
break;
|
||||
default:
|
||||
System.out.println("Thing is in state " + statusInfo.getStatus());
|
||||
break;
|
||||
}
|
||||
System.out.println("Thing status detail: " + statusInfo.getStatusDetail());
|
||||
System.out.println("Thing status description: " + statusInfo.getDescription());
|
||||
}
|
||||
```
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 537 B After Width: | Height: | Size: 537 B |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 979 B After Width: | Height: | Size: 979 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
Before Width: | Height: | Size: 761 B After Width: | Height: | Size: 761 B |
Before Width: | Height: | Size: 314 B After Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 894 B After Width: | Height: | Size: 894 B |
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
Before Width: | Height: | Size: 877 B After Width: | Height: | Size: 877 B |
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 314 B After Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
Before Width: | Height: | Size: 761 B After Width: | Height: | Size: 761 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 659 B After Width: | Height: | Size: 659 B |
Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 194 B |
Before Width: | Height: | Size: 837 B After Width: | Height: | Size: 837 B |
Before Width: | Height: | Size: 169 B After Width: | Height: | Size: 169 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 199 B After Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 837 B After Width: | Height: | Size: 837 B |
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 891 B After Width: | Height: | Size: 891 B |
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 944 B After Width: | Height: | Size: 944 B |
Before Width: | Height: | Size: 208 B After Width: | Height: | Size: 208 B |
Before Width: | Height: | Size: 995 B After Width: | Height: | Size: 995 B |
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 207 B |
Before Width: | Height: | Size: 995 B After Width: | Height: | Size: 995 B |
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 207 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 188 B After Width: | Height: | Size: 188 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 207 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 968 B After Width: | Height: | Size: 968 B |
Before Width: | Height: | Size: 573 B After Width: | Height: | Size: 573 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1021 B After Width: | Height: | Size: 1021 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 995 B After Width: | Height: | Size: 995 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 998 B After Width: | Height: | Size: 998 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 873 B After Width: | Height: | Size: 873 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 181 B After Width: | Height: | Size: 181 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |