2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.enocean.internal.eep;
15 import static org.openhab.binding.enocean.internal.messages.ESP3Packet.*;
17 import java.lang.reflect.InvocationTargetException;
19 import org.openhab.binding.enocean.internal.eep.Base.UTEResponse;
20 import org.openhab.binding.enocean.internal.eep.Base._4BSMessage;
21 import org.openhab.binding.enocean.internal.eep.Base._4BSTeachInVariation3Response;
22 import org.openhab.binding.enocean.internal.eep.D5_00.D5_00_01;
23 import org.openhab.binding.enocean.internal.eep.F6_01.F6_01_01;
24 import org.openhab.binding.enocean.internal.eep.F6_02.F6_02_01;
25 import org.openhab.binding.enocean.internal.eep.F6_10.F6_10_00;
26 import org.openhab.binding.enocean.internal.eep.F6_10.F6_10_00_EltakoFPE;
27 import org.openhab.binding.enocean.internal.eep.F6_10.F6_10_01;
28 import org.openhab.binding.enocean.internal.messages.ERP1Message;
29 import org.openhab.binding.enocean.internal.messages.ERP1Message.RORG;
30 import org.openhab.core.util.HexUtils;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
36 * @author Daniel Weber - Initial contribution
38 public class EEPFactory {
40 private static final Logger logger = LoggerFactory.getLogger(EEPFactory.class);
42 public static EEP createEEP(EEPType eepType) {
44 Class<? extends EEP> cl = eepType.getEEPClass();
46 throw new IllegalArgumentException("Message " + eepType + " not implemented");
48 return cl.newInstance();
49 } catch (IllegalAccessException | InstantiationException e) {
50 throw new IllegalArgumentException(e);
54 public static EEP buildEEP(EEPType eepType, ERP1Message packet) {
56 Class<? extends EEP> cl = eepType.getEEPClass();
58 throw new IllegalArgumentException("Message " + eepType + " not implemented");
60 return cl.getConstructor(ERP1Message.class).newInstance(packet);
61 } catch (IllegalAccessException | InstantiationException | IllegalArgumentException | InvocationTargetException
62 | NoSuchMethodException | SecurityException e) {
63 logger.error("Cannot instantiate EEP {}-{}-{}: {}",
64 HexUtils.bytesToHex(new byte[] { eepType.getRORG().getValue() }),
65 HexUtils.bytesToHex(new byte[] { (byte) eepType.getFunc() }),
66 HexUtils.bytesToHex(new byte[] { (byte) eepType.getType() }), e.getMessage());
68 throw new IllegalArgumentException(e);
72 public static EEP buildEEPFromTeachInERP1(ERP1Message msg) {
73 if (!msg.getIsTeachIn() && !(msg.getRORG() == RORG.RPS)) {
77 switch (msg.getRORG()) {
80 EEP result = new F6_01_01(msg);
81 if (result.isValid()) { // check if t21 is set, nu not set, and data == 0x10 or 0x00
84 } catch (Exception e) {
88 EEP result = new F6_02_01(msg);
89 if (result.isValid()) { // check if highest bit is not set
92 } catch (Exception e) {
96 EEP result = new F6_10_00(msg);
97 if (result.isValid()) {
100 } catch (Exception e) {
103 EEP result = new F6_10_00_EltakoFPE(msg);
104 if (result.isValid()) { // check if data == 0x10 or 0x00
107 } catch (Exception e) {
110 EEP result = new F6_10_01(msg);
111 if (result.isValid()) {
114 } catch (Exception e) {
119 return new D5_00_01(msg);
121 int db_0 = msg.getPayload()[4];
122 if ((db_0 & _4BSMessage.LRN_Type_Mask) == 0) { // Variation 1
123 logger.info("Received 4BS Teach In variation 1 without EEP");
127 byte db_3 = msg.getPayload()[1];
128 byte db_2 = msg.getPayload()[2];
129 byte db_1 = msg.getPayload()[3];
131 int func = (db_3 & 0xFF) >>> 2;
132 int type = ((db_3 & 0b11) << 5) + ((db_2 & 0xFF) >>> 3);
133 int manufId = ((db_2 & 0b111) << 8) + (db_1 & 0xff);
135 logger.info("Received 4BS Teach In with EEP A5-{}-{} and manufacturerID {}",
136 HexUtils.bytesToHex(new byte[] { (byte) func }),
137 HexUtils.bytesToHex(new byte[] { (byte) type }),
138 HexUtils.bytesToHex(new byte[] { (byte) manufId }));
140 EEPType eepType = EEPType.getType(RORG._4BS, func, type, manufId);
141 if (eepType == null) {
142 logger.debug("Received unsupported EEP teach in, fallback to generic thing");
143 eepType = EEPType.Generic4BS;
146 return buildEEP(eepType, msg);
149 byte[] payload = msg.getPayload();
151 byte rorg = payload[payload.length - 1 - ESP3_STATUS_LENGTH - ESP3_SENDERID_LENGTH];
152 byte func = payload[payload.length - 1 - ESP3_STATUS_LENGTH - ESP3_SENDERID_LENGTH - ESP3_RORG_LENGTH];
153 byte type = payload[payload.length - 1 - ESP3_STATUS_LENGTH - ESP3_SENDERID_LENGTH - ESP3_RORG_LENGTH
156 byte manufIdMSB = payload[payload.length - 1 - ESP3_STATUS_LENGTH - ESP3_SENDERID_LENGTH
157 - ESP3_RORG_LENGTH - 2];
158 byte manufIdLSB = payload[payload.length - 1 - ESP3_STATUS_LENGTH - ESP3_SENDERID_LENGTH
159 - ESP3_RORG_LENGTH - 3];
160 int manufId = ((manufIdMSB & 0b111) << 8) + (manufIdLSB & 0xff);
162 EEPType eepType = EEPType.getType(RORG.getRORG(rorg), func, type, manufId);
163 if (eepType == null) {
164 logger.info("Received unsupported EEP teach in, fallback to generic thing");
165 RORG r = RORG.getRORG(rorg);
166 if (r == RORG._4BS) {
167 eepType = EEPType.Generic4BS;
168 } else if (r == RORG.VLD) {
169 eepType = EEPType.GenericVLD;
175 return buildEEP(eepType, msg);
187 public static EEP buildResponseEEPFromTeachInERP1(ERP1Message msg, byte[] senderId) {
188 switch (msg.getRORG()) {
190 EEP result = new UTEResponse(msg);
191 result.setSenderId(senderId);
195 result = new _4BSTeachInVariation3Response(msg);
196 result.setSenderId(senderId);