The event itself will be subclassed for each event type, which exists in the System (e.g. `ItemCommandEvent`, `ItemUpdatedEvent`, `ThingStatusInfoEvent`).
The payload can be serialized with any String representation and is determined by its concrete event type implementation (e.g. `ItemCommandEvent`, `ItemUpdatedEvent`).
The topics of openHAB events are divided into the following four parts: `{namespace}/{entityType}/{entity}/{action}`, e.g. `openhab/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.
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 openHAB `EventFilter` implementation that ensures filtering of events based on a topic.
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.
- openHAB provides an `AbstractItemEventSubscriber` class in order to receive `ItemStateEvents` and `ItemCommandEvents` (more information can be obtained in the next chapter).
- 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.
Due to the fact that receiving `ItemStateEvents` and `ItemCommandEvents` is a common use case, openHAB provides an abstract event subscriber implementation via the core bundle.
The class `org.openhab.core.items.events.AbstractItemEventSubscriber` provides two methods `receiveUpdate(ItemStateEvent)` and `receiveCommand(ItemCommandEvent)` which can be implemented in order to receive and handle such events.
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 extending the `AbstractEventFactory` class.
The `AbstractEventFactory` provides some useful utility for parameter validation and payload serialization & deserialization with JSON.
The classes are located in the openHAB core bundle.
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 openHAB core events, similar to a REST URI (`{namespace}/{entityType}/{entity}/{sub-entity-1}/.../{sub-entity-n}/{action}`).
- 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.