public class TheBroTransformationService implements TransformationService {
private final Logger logger = LoggerFactory.getLogger(TheBroTransformationService.class);
@Override
public @Nullable String transform(String config, String input) throws TransformationException {
}
}
```
Next you implement the `transform` method. You are given a user configuration and the input value.
In our case we do not use the `config` parameter.
Other services like the regex or map transformation are using this parameter for the regex ("`.*=(\\d*.\\d*).*`") or the map (`mapfile.map`) for example.
Our implementation is as simple as this:
```java
@Override
public @Nullable String transform(String config, String input) throws TransformationException {
return input + ",bro!";
}
```
# Developing a Profile
The communication between the framework and the Thing handlers can be influenced by "Profiles".
By their nature, profiles are correlated to links between Items and Channels (i.e. `ItemChannelLinks`),
just like transformations.
But in contrast to transformations, if one Channel is linked to several Items it also will have several profile instances.
Each instance handling the communication to exactly one of these Items.
Apart from that, they do not pass any commands or state updates to and from the Thing handler as by their nature trigger Channels are not capable of handling these.
This section explains how custom `Profile`s can be created.
First you want to create a new bundle for example via the skeleton.
## Profile Properties
A `Profile` is determined by its type, i.e. `StateProfileType` or `TriggerProfileType` and its `ProfileTypeUID`.
Both types are specified via interfaces `StateProfile` and `TriggerProfile`, respectively.
The `ProfileTypeUID` identifies one specific type of `Profile`.
Each `Profile` exists in a certain scope.
There are pre-defined `Profile`s that are defined in scope `ProfileTypeUID.SYSTEM_SCOPE`, which is "system".
Custom `Profiles` should be created in a different scope.
Thus a `ProfileTypeUID` can be created as follows: `new ProfileTypeUID("MyScope", "MyProfileName")`.
A `StateProfile` receives `Commands` and `StateUpdates` from the `ThingHandler` and from the `Item`.
It has to implement four methods that specify how the `Command`s or `StateUpdate`s should be handled.
A `TriggerProfile` makes it possible to link a `TriggerChannel` to an `Item`.
This `Profile` receives the `State` of the `Item` and the `Event` that has been triggered.
public class MyProfileTypeProvider implements ProfileTypeProvider {
@Override
public Collection<ProfileType> getProfileTypes(Locale locale) {
//return custom types
}
}
```
## ProfileFactory
The most important interface is the `ProfileFactory` which has to be implemented and announced as an OSGi service:
```java
@Component(service = { ProfileFactory.class })
public class MyProfileFactory implements ProfileFactory {
```
Such a factory is responsible for specific `ProfileTypeUID`s that should be returned by `Collection<ProfileTypeUID> getSupportedProfileTypeUIDs()`.
Further it is capable of creating these `Profile`s via `createProfile(ProfileTypeUID profileTypeUID, ProfileCallback callback, ProfileContext profileContext);`.
For convenience, the `ProfileFactory` and the `ProfileTypeProvider` can be put into one class and announce the two services:
If one device should "follow" the actions of another device, the FollowProfile can be used.
The term "follow" in this case means that any state that is sent to an `Item` will be forwarded from this `Item` to any linked channel with the FollowProfile.
The FollowProfile takes state updates on an `Item` and sends them as a command onto the channel.
In the direction from the ThingHandler towards the `Item`, the FollowProfile ignores state updates.
The `OffsetProfile` provides the possibility to adjust a value from a device before it arrives at the framework.
An offset can be specified via the parameter `offset` which has to be a `QuantityType` or `DecimalType`.
A positive offset is the amount of change from the device towards the framework, i.e. all values from the device are increased by this offset and values sent to the device are decreased by this offset.
A negative offset subtracts the offset from the value sent by the device to the framework and adds the offset to values sent from the framework to the device.
```java
Number <itemName> { channel="<bindingID>:<thing-typeID>:<thingName>:<channelName>"[profile="offset", offset="<value>"]}