[somfytahoma] Fix getting history events (#18323)

Signed-off-by: Ondrej Pecta <opecta@gmail.com>
pull/18348/head
Ondrej Pecta 2025-03-01 22:35:13 +01:00 committed by GitHub
parent 72682766b3
commit b01d8225b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 177 additions and 56 deletions

View File

@ -49,7 +49,7 @@ Binding itself doesn't require specific configuration.
| JA-80/JA-100/JA-100F | lastEventTime | DateTime | the time of the last event | | JA-80/JA-100/JA-100F | lastEventTime | DateTime | the time of the last event |
| JA-80/JA-100/JA-100F | lastCheckTime | DateTime | the time of the last checking | | JA-80/JA-100/JA-100F | lastCheckTime | DateTime | the time of the last checking |
| JA-80/JA-100/JA-100F | alarm | N/A | the alarm trigger, might fire ALARM or TAMPER events | | JA-80/JA-100/JA-100F | alarm | N/A | the alarm trigger, might fire ALARM or TAMPER events |
| JA-100/JA-100F | lastEventSection | String | the section of the last event | | JA-80/JA-100/JA-100F | lastEventSection | String | the section of the last event |
| JA-100 | state_%nr% | String | the section %nr% status/control | | JA-100 | state_%nr% | String | the section %nr% status/control |
| JA-100 | pgm_%nr% | Switch | the PG switch %nr% status/control | | JA-100 | pgm_%nr% | Switch | the PG switch %nr% status/control |
| JA-100 | thermometer_%nr% | Number:Temperature | the thermometer %nr% value | | JA-100 | thermometer_%nr% | Number:Temperature | the thermometer %nr% value |

View File

@ -55,13 +55,16 @@ public class JablotronBindingConstants {
// Constants // Constants
public static final String JABLOTRON_API_URL = "https://api.jablonet.net/api/2.2/"; public static final String JABLOTRON_API_URL = "https://api.jablonet.net/api/2.2/";
public static final String AGENT = "net.jablonet/8.3.5.3331 (iPhone 14 Pro Max; iOS 17.4; )"; public static final String JABLOTRON_GQL_URL = "https://graph.jablotron.cloud/graphql";
public static final int TIMEOUT_SEC = 10; public static final String APP_VERSION = "8.6.1.3887";
public static final String AGENT = "net.jablonet/" + APP_VERSION;
public static final int TIMEOUT_SEC = 15;
public static final int TIMEOUT_LIMIT = 3;
public static final String SYSTEM = "openHAB"; public static final String SYSTEM = "openHAB";
public static final String VENDOR = "JABLOTRON:Jablotron"; public static final String VENDOR = "JABLOTRON:Jablotron";
public static final String CLIENT_VERSION = "MYJ-PUB-IOS-8.3.5.3331"; public static final String CLIENT_VERSION = "MYJ-PUB-IOS-" + APP_VERSION;
public static final String CLIENT_DEVICE = "Apple|iPhone 14 Pro Max|17.4";
public static final String APPLICATION_JSON = "application/json"; public static final String APPLICATION_JSON = "application/json";
public static final String MULTIPART_MIXED = "multipart/mixed;deferSpec=20220824";
public static final String WWW_FORM_URLENCODED = "application/x-www-form-urlencoded; charset=UTF-8"; public static final String WWW_FORM_URLENCODED = "application/x-www-form-urlencoded; charset=UTF-8";
public static final String AUTHENTICATION_CHALLENGE = "Authentication challenge without WWW-Authenticate header"; public static final String AUTHENTICATION_CHALLENGE = "Authentication challenge without WWW-Authenticate header";
public static final String PROPERTY_SERVICE_ID = "serviceId"; public static final String PROPERTY_SERVICE_ID = "serviceId";

View File

@ -17,7 +17,6 @@ import static org.openhab.binding.jablotron.JablotronBindingConstants.*;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -72,7 +71,7 @@ public abstract class JablotronAlarmHandler extends BaseThingHandler {
protected @Nullable ScheduledFuture<?> future = null; protected @Nullable ScheduledFuture<?> future = null;
protected @Nullable ExpiringCache<JablotronDataUpdateResponse> dataCache; protected @Nullable ExpiringCache<JablotronDataUpdateResponse> dataCache;
protected ExpiringCache<List<JablotronHistoryDataEvent>> eventCache; protected ExpiringCache<JablotronHistoryDataEvent> eventCache;
public JablotronAlarmHandler(Thing thing, String alarmName) { public JablotronAlarmHandler(Thing thing, String alarmName) {
super(thing); super(thing);
@ -186,20 +185,19 @@ public abstract class JablotronAlarmHandler extends BaseThingHandler {
logger.debug("Error during alarm status update: {}", dataUpdate.getErrorMessage()); logger.debug("Error during alarm status update: {}", dataUpdate.getErrorMessage());
} }
List<JablotronHistoryDataEvent> events = sendGetEventHistory(); JablotronHistoryDataEvent event = sendGetEventHistory();
if (events != null && !events.isEmpty()) { if (event != null) {
JablotronHistoryDataEvent event = events.get(0);
updateLastEvent(event); updateLastEvent(event);
} }
return true; return true;
} }
protected @Nullable List<JablotronHistoryDataEvent> sendGetEventHistory() { protected @Nullable JablotronHistoryDataEvent sendGetEventHistory() {
return sendGetEventHistory(alarmName); return sendGetEventHistory(alarmName);
} }
private @Nullable List<JablotronHistoryDataEvent> sendGetEventHistory(String alarm) { private @Nullable JablotronHistoryDataEvent sendGetEventHistory(String alarm) {
JablotronBridgeHandler handler = getBridgeHandler(); JablotronBridgeHandler handler = getBridgeHandler();
if (handler != null) { if (handler != null) {
return handler.sendGetEventHistory(getThing(), alarm); return handler.sendGetEventHistory(getThing(), alarm);
@ -208,7 +206,7 @@ public abstract class JablotronAlarmHandler extends BaseThingHandler {
} }
protected void updateLastEvent(JablotronHistoryDataEvent event) { protected void updateLastEvent(JablotronHistoryDataEvent event) {
updateState(CHANNEL_LAST_EVENT_TIME, new DateTimeType(getZonedDateTime(event.getDate()))); updateState(CHANNEL_LAST_EVENT_TIME, new DateTimeType(Instant.parse(event.getDate())));
updateState(CHANNEL_LAST_EVENT, new StringType(event.getEventText())); updateState(CHANNEL_LAST_EVENT, new StringType(event.getEventText()));
updateState(CHANNEL_LAST_EVENT_CLASS, new StringType(event.getIconType())); updateState(CHANNEL_LAST_EVENT_CLASS, new StringType(event.getIconType()));
updateState(CHANNEL_LAST_EVENT_INVOKER, new StringType(event.getInvokerName())); updateState(CHANNEL_LAST_EVENT_INVOKER, new StringType(event.getInvokerName()));
@ -220,12 +218,11 @@ public abstract class JablotronAlarmHandler extends BaseThingHandler {
} }
protected void updateEventChannel(String channel) { protected void updateEventChannel(String channel) {
List<JablotronHistoryDataEvent> events = eventCache.getValue(); JablotronHistoryDataEvent event = eventCache.getValue();
if (events != null && !events.isEmpty()) { if (event != null) {
JablotronHistoryDataEvent event = events.get(0);
switch (channel) { switch (channel) {
case CHANNEL_LAST_EVENT_TIME: case CHANNEL_LAST_EVENT_TIME:
updateState(CHANNEL_LAST_EVENT_TIME, new DateTimeType(getZonedDateTime(event.getDate()))); updateState(CHANNEL_LAST_EVENT_TIME, new DateTimeType(Instant.parse(event.getDate())));
break; break;
case CHANNEL_LAST_EVENT: case CHANNEL_LAST_EVENT:
updateState(CHANNEL_LAST_EVENT, new StringType(event.getEventText())); updateState(CHANNEL_LAST_EVENT, new StringType(event.getEventText()));
@ -243,11 +240,6 @@ public abstract class JablotronAlarmHandler extends BaseThingHandler {
} }
} }
public ZonedDateTime getZonedDateTime(String date) {
return ZonedDateTime.parse(date.substring(0, 22) + ":" + date.substring(22, 24),
DateTimeFormatter.ISO_DATE_TIME);
}
protected @Nullable JablotronControlResponse sendUserCode(String section, String key, String status, String code) { protected @Nullable JablotronControlResponse sendUserCode(String section, String key, String status, String code) {
JablotronBridgeHandler handler = getBridgeHandler(); JablotronBridgeHandler handler = getBridgeHandler();
if (handler != null) { if (handler != null) {

View File

@ -32,10 +32,10 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpMethod;
import org.openhab.binding.jablotron.internal.config.JablotronBridgeConfig; import org.openhab.binding.jablotron.internal.config.JablotronBridgeConfig;
import org.openhab.binding.jablotron.internal.discovery.JablotronDiscoveryService; import org.openhab.binding.jablotron.internal.discovery.JablotronDiscoveryService;
import org.openhab.binding.jablotron.internal.model.JablotronAccessTokenResponse;
import org.openhab.binding.jablotron.internal.model.JablotronControlResponse; import org.openhab.binding.jablotron.internal.model.JablotronControlResponse;
import org.openhab.binding.jablotron.internal.model.JablotronDataUpdateResponse; import org.openhab.binding.jablotron.internal.model.JablotronDataUpdateResponse;
import org.openhab.binding.jablotron.internal.model.JablotronDiscoveredService; import org.openhab.binding.jablotron.internal.model.JablotronDiscoveredService;
import org.openhab.binding.jablotron.internal.model.JablotronGetEventHistoryResponse;
import org.openhab.binding.jablotron.internal.model.JablotronGetServiceResponse; import org.openhab.binding.jablotron.internal.model.JablotronGetServiceResponse;
import org.openhab.binding.jablotron.internal.model.JablotronHistoryDataEvent; import org.openhab.binding.jablotron.internal.model.JablotronHistoryDataEvent;
import org.openhab.binding.jablotron.internal.model.JablotronLoginResponse; import org.openhab.binding.jablotron.internal.model.JablotronLoginResponse;
@ -54,6 +54,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
/** /**
@ -71,6 +74,8 @@ public class JablotronBridgeHandler extends BaseBridgeHandler {
final HttpClient httpClient; final HttpClient httpClient;
private String accessToken = "";
private @Nullable ScheduledFuture<?> future = null; private @Nullable ScheduledFuture<?> future = null;
/** /**
@ -169,14 +174,47 @@ public class JablotronBridgeHandler extends BaseBridgeHandler {
return sendMessage(url, urlParameters, classOfT, WWW_FORM_URLENCODED, true); return sendMessage(url, urlParameters, classOfT, WWW_FORM_URLENCODED, true);
} }
private @Nullable String sendGQLMessage(String url, String urlParameters) {
String line = "";
try {
logger.trace("Request: {} with data: {}", url, urlParameters);
ContentResponse resp = createGQLRequest(url)
.content(new StringContentProvider(urlParameters), APPLICATION_JSON).send();
line = resp.getContentAsString();
logger.trace("Response: {}", line);
return line;
} catch (TimeoutException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Timeout during calling url: " + url);
} catch (InterruptedException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Interrupt during calling url: " + url);
Thread.currentThread().interrupt();
} catch (JsonSyntaxException e) {
logger.debug("Invalid JSON received: {}", line);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Syntax error during calling url: " + url);
} catch (ExecutionException e) {
if (e.getMessage().contains(AUTHENTICATION_CHALLENGE)) {
relogin();
return null;
}
logger.debug("Error during calling url: {}", url, e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Error during calling url: " + url);
}
return null;
}
private @Nullable <T> T sendMessage(String url, String urlParameters, Class<T> classOfT, String encoding, private @Nullable <T> T sendMessage(String url, String urlParameters, Class<T> classOfT, String encoding,
boolean relogin) { boolean relogin) {
String line = ""; String line = "";
try { try {
logger.trace("Request: {} with data: {}", url, urlParameters);
ContentResponse resp = createRequest(url).content(new StringContentProvider(urlParameters), encoding) ContentResponse resp = createRequest(url).content(new StringContentProvider(urlParameters), encoding)
.send(); .send();
logger.trace("Request: {} with data: {}", url, urlParameters);
line = resp.getContentAsString(); line = resp.getContentAsString();
logger.trace("Response: {}", line); logger.trace("Response: {}", line);
return gson.fromJson(line, classOfT); return gson.fromJson(line, classOfT);
@ -212,13 +250,31 @@ public class JablotronBridgeHandler extends BaseBridgeHandler {
JablotronLoginResponse response = sendJsonMessage(url, urlParameters, JablotronLoginResponse.class, false); JablotronLoginResponse response = sendJsonMessage(url, urlParameters, JablotronLoginResponse.class, false);
if (response == null) { if (response == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Null login response");
return; return;
} }
if (response.getHttpCode() != 200) { if (response.getHttpCode() != 200) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Http error: " + response.getHttpCode()); "Login http error: " + response.getHttpCode());
return;
}
url = JABLOTRON_API_URL + "accessTokenGet.json";
urlParameters = "{ \"force-renew\": true }";
JablotronAccessTokenResponse token_response = sendJsonMessage(url, urlParameters,
JablotronAccessTokenResponse.class, false);
if (token_response == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Null get access token response");
return;
}
if (token_response.getHttpCode() != 200) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
"Get access token http error: " + response.getHttpCode());
} else { } else {
accessToken = token_response.getData().getAccessToken();
updateStatus(ThingStatus.ONLINE); updateStatus(ThingStatus.ONLINE);
} }
} }
@ -287,8 +343,7 @@ public class JablotronBridgeHandler extends BaseBridgeHandler {
return response; return response;
} }
protected @Nullable List<JablotronHistoryDataEvent> sendGetEventHistory(Thing th, String alarm) { protected @Nullable JablotronHistoryDataEvent sendGetEventHistory(Thing th, String alarm) {
String url = JABLOTRON_API_URL + alarm + "/eventHistoryGet.json";
JablotronAlarmHandler handler = (JablotronAlarmHandler) th.getHandler(); JablotronAlarmHandler handler = (JablotronAlarmHandler) th.getHandler();
if (handler == null) { if (handler == null) {
@ -296,18 +351,37 @@ public class JablotronBridgeHandler extends BaseBridgeHandler {
return null; return null;
} }
String urlParameters = "{\"limit\":1, \"service-id\":" + handler.thingConfig.getServiceId() + "}"; String urlParameters = "{\"operationName\":\"GetEvents\",\"query\":\"query GetEvents($cloudEntityIds: [CloudEntityID!]!, $pagination: Pagination, $lang: String!, $filter: EventsFilter, $eventIds: [ID!]!) { forEndUser { __typename events { __typename events(sources: $cloudEntityIds, pagination: $pagination, filter: $filter) { __typename edges { __typename node { __typename ...EventsFragment } } pageInfo { __typename hasNextPage endCursor startCursor } } batchEvents(sources: $cloudEntityIds, eventIds: $eventIds) { __typename ...EventsFragment } } } }\\nfragment EventsAttachementFragment on EventsAttachment { __typename files { __typename name mimeType downloadUrl } images { __typename name mimeType downloadUrl available widthPx heightPx } videos { __typename name mimeType downloadUrl duration } id type occurredAt }\\nfragment EventsEventFragment on EventsEvent { __typename id name { __typename translation(lang: $lang) } type occurredAt sources { __typename cloudEntityId } invokers { __typename ...EventsInvokerFragment } subjects { __typename ...EventsSubjectFragment } icon }\\nfragment EventsFragment on EventsEvent { __typename ...EventsEventFragment attachments { __typename ...EventsAttachementFragment } childEvents { __typename id name { __typename translation(lang: $lang) } type occurredAt sources { __typename cloudEntityId } invokers { __typename ...EventsInvokerFragment } subjects { __typename ...EventsSubjectFragment } icon attachments { __typename ...EventsAttachementFragment } } }\\nfragment EventsInvokerFragment on EventsInvoker { __typename cloudEntityId defaultName { __typename translation(lang: $lang) } name }\\nfragment EventsSubjectFragment on EventsSubject { __typename name cloudEntityId defaultName { __typename translation(lang: $lang) } }\",\"variables\":{\"cloudEntityIds\":[\"SERVICE_"
JablotronGetEventHistoryResponse response = sendJsonMessage(url, urlParameters, + alarm + ":" + handler.thingConfig.getServiceId() + "\"],\"eventIds\":[],\"lang\":\""
JablotronGetEventHistoryResponse.class); + bridgeConfig.getLang() + "\",\"pagination\":{\"first\":1}}}";
String response = sendGQLMessage(JABLOTRON_GQL_URL, urlParameters);
if (response == null) { if (response == null) {
logger.debug("Null response while getting event history");
return null; return null;
} }
if (200 != response.getHttpCode()) { return parseEventHistoryResponse(response);
logger.debug("Got error while getting history with http code: {}", response.getHttpCode()); }
}
return response.getData().getEvents(); private @Nullable JablotronHistoryDataEvent parseEventHistoryResponse(String response) {
JsonObject jsonObject = JsonParser.parseString(response).getAsJsonObject();
JsonArray edges = jsonObject.getAsJsonObject("data").getAsJsonObject("forEndUser").getAsJsonObject("events")
.getAsJsonObject("events").getAsJsonArray("edges");
JsonObject node = edges.get(0).getAsJsonObject().getAsJsonObject("node").getAsJsonObject();
JsonObject invoker = node.getAsJsonArray("invokers").get(0).getAsJsonObject();
JsonObject subject = node.getAsJsonArray("subjects").get(0).getAsJsonObject();
JablotronHistoryDataEvent event = new JablotronHistoryDataEvent();
event.setIconType(node.get("icon").getAsString());
event.setEventText(node.getAsJsonObject("name").get("translation").getAsString());
event.setDate(node.get("occurredAt").getAsString());
event.setSectionName(subject.getAsJsonObject("defaultName").get("translation").getAsString());
event.setInvokerName(invoker.getAsJsonObject("defaultName").get("translation").getAsString());
return event;
} }
protected @Nullable JablotronDataUpdateResponse sendGetStatusRequest(Thing th) { protected @Nullable JablotronDataUpdateResponse sendGetStatusRequest(Thing th) {
@ -399,8 +473,16 @@ public class JablotronBridgeHandler extends BaseBridgeHandler {
private Request createRequest(String url) { private Request createRequest(String url) {
return httpClient.newRequest(url).method(HttpMethod.POST).header(HttpHeader.ACCEPT, APPLICATION_JSON) return httpClient.newRequest(url).method(HttpMethod.POST).header(HttpHeader.ACCEPT, APPLICATION_JSON)
.header(HttpHeader.ACCEPT_LANGUAGE, bridgeConfig.getLang()).header(HttpHeader.ACCEPT_ENCODING, "*") .header(HttpHeader.ACCEPT_LANGUAGE, bridgeConfig.getLang()).header(HttpHeader.ACCEPT_ENCODING, "*")
.header("x-vendor-id", VENDOR).header("x-client-version", CLIENT_VERSION) .header("x-vendor-id", VENDOR).header("x-client-version", CLIENT_VERSION).agent(AGENT)
.header("x-client-device", CLIENT_DEVICE).agent(AGENT).timeout(TIMEOUT_SEC, TimeUnit.SECONDS); .timeout(TIMEOUT_SEC, TimeUnit.SECONDS);
}
private Request createGQLRequest(String url) {
return httpClient.newRequest(url).method(HttpMethod.POST).accept(MULTIPART_MIXED, APPLICATION_JSON)
.header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken)
.header(HttpHeader.ACCEPT_LANGUAGE, bridgeConfig.getLang())
.header(HttpHeader.ACCEPT_ENCODING, "gzip, deflate, br").agent(AGENT)
.timeout(TIMEOUT_SEC, TimeUnit.SECONDS);
} }
private void relogin() { private void relogin() {

View File

@ -198,9 +198,8 @@ public class JablotronJa100FHandler extends JablotronAlarmHandler {
} }
// update events // update events
List<JablotronHistoryDataEvent> events = sendGetEventHistory(); JablotronHistoryDataEvent event = sendGetEventHistory();
if (events != null && !events.isEmpty()) { if (event != null) {
JablotronHistoryDataEvent event = events.get(0);
updateLastEvent(event); updateLastEvent(event);
} }
return true; return true;

View File

@ -12,22 +12,28 @@
*/ */
package org.openhab.binding.jablotron.internal.model; package org.openhab.binding.jablotron.internal.model;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import com.google.gson.annotations.SerializedName;
/** /**
* The {@link JablotronHistoryData} class defines the data object for the * The {@link JablotronAccessTokenData} class defines the data object for access token
* getEventHistory response
* *
* @author Ondrej Pecta - Initial contribution * @author Ondrej Pecta - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
public class JablotronHistoryData { public class JablotronAccessTokenData {
List<JablotronHistoryDataEvent> events = new ArrayList<>(); @SerializedName("access-token")
private String accessToken = "";
public List<JablotronHistoryDataEvent> getEvents() { @SerializedName("access-token-expiration")
return events; private String accessTokenExpiration = "";
public String getAccessToken() {
return accessToken;
}
public String getAccessTokenExpiration() {
return accessTokenExpiration;
} }
} }

View File

@ -17,24 +17,22 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
/** /**
* The {@link JablotronGetEventHistoryResponse} class defines the response for the * The {@link JablotronAccessTokenResponse} class defines the get access token call
* getEventHistory operation * response
* *
* @author Ondrej Pecta - Initial contribution * @author Ondrej Pecta - Initial contribution
*/ */
@NonNullByDefault @NonNullByDefault
public class JablotronGetEventHistoryResponse { public class JablotronAccessTokenResponse {
@SerializedName("http-code") @SerializedName("http-code")
int httpCode = -1; private int httpCode = -1;
private JablotronAccessTokenData data = new JablotronAccessTokenData();
JablotronHistoryData data = new JablotronHistoryData();
public int getHttpCode() { public int getHttpCode() {
return httpCode; return httpCode;
} }
public JablotronHistoryData getData() { public JablotronAccessTokenData getData() {
return data; return data;
} }
} }

View File

@ -57,4 +57,24 @@ public class JablotronHistoryDataEvent {
public String getSectionName() { public String getSectionName() {
return sectionName; return sectionName;
} }
public void setIconType(String iconType) {
this.iconType = iconType;
}
public void setEventText(String eventText) {
this.eventText = eventText;
}
public void setInvokerName(String invokerName) {
this.invokerName = invokerName;
}
public void setSectionName(String sectionName) {
this.sectionName = sectionName;
}
public void setDate(String date) {
this.date = date;
}
} }

View File

@ -22,9 +22,15 @@
<channel id="lastEventClass" typeId="lastEventClass"/> <channel id="lastEventClass" typeId="lastEventClass"/>
<channel id="lastEventInvoker" typeId="lastEventInvoker"/> <channel id="lastEventInvoker" typeId="lastEventInvoker"/>
<channel id="lastEventTime" typeId="lastEventTime"/> <channel id="lastEventTime" typeId="lastEventTime"/>
<channel id="lastEventSection" typeId="lastEventSection"/>
<channel id="lastCheckTime" typeId="lastCheckTime"/> <channel id="lastCheckTime" typeId="lastCheckTime"/>
<channel id="alarm" typeId="alarm"/> <channel id="alarm" typeId="alarm"/>
</channels> </channels>
<properties>
<property name="thingTypeVersion">1</property>
</properties>
<config-description-ref uri="thing-type:jablotron:device"/> <config-description-ref uri="thing-type:jablotron:device"/>
</thing-type> </thing-type>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
<thing-type uid="jablotron:oasis">
<instruction-set targetVersion="1">
<add-channel id="lastEventSection">
<type>jablotron:lastEventSection</type>
<label>Alarm Last Event Section</label>
</add-channel>
</instruction-set>
</thing-type>
</update:update-descriptions>