]> git.basschouten.com Git - openhab-addons.git/blob
9e757e3218faac3d034985dcfe832f71bd88a208
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.enocean.internal.eep;
14
15 import static org.openhab.binding.enocean.internal.messages.ESP3Packet.*;
16
17 import java.lang.reflect.InvocationTargetException;
18
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;
33
34 /**
35  *
36  * @author Daniel Weber - Initial contribution
37  */
38 public class EEPFactory {
39
40     private static final Logger logger = LoggerFactory.getLogger(EEPFactory.class);
41
42     public static EEP createEEP(EEPType eepType) {
43         try {
44             Class<? extends EEP> cl = eepType.getEEPClass();
45             if (cl == null) {
46                 throw new IllegalArgumentException("Message " + eepType + " not implemented");
47             }
48             return cl.newInstance();
49         } catch (IllegalAccessException | InstantiationException e) {
50             throw new IllegalArgumentException(e);
51         }
52     }
53
54     public static EEP buildEEP(EEPType eepType, ERP1Message packet) {
55         try {
56             Class<? extends EEP> cl = eepType.getEEPClass();
57             if (cl == null) {
58                 throw new IllegalArgumentException("Message " + eepType + " not implemented");
59             }
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());
67
68             throw new IllegalArgumentException(e);
69         }
70     }
71
72     public static EEP buildEEPFromTeachInERP1(ERP1Message msg) {
73         if (!msg.getIsTeachIn() && !(msg.getRORG() == RORG.RPS)) {
74             return null;
75         }
76
77         switch (msg.getRORG()) {
78             case RPS:
79                 try {
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
82                         return result;
83                     }
84                 } catch (Exception e) {
85                 }
86
87                 try {
88                     EEP result = new F6_02_01(msg);
89                     if (result.isValid()) { // check if highest bit is not set
90                         return result;
91                     }
92                 } catch (Exception e) {
93                 }
94
95                 try {
96                     EEP result = new F6_10_00(msg);
97                     if (result.isValid()) {
98                         return result;
99                     }
100                 } catch (Exception e) {
101                 }
102                 try {
103                     EEP result = new F6_10_00_EltakoFPE(msg);
104                     if (result.isValid()) { // check if data == 0x10 or 0x00
105                         return result;
106                     }
107                 } catch (Exception e) {
108                 }
109                 try {
110                     EEP result = new F6_10_01(msg);
111                     if (result.isValid()) {
112                         return result;
113                     }
114                 } catch (Exception e) {
115                 }
116
117                 return null;
118             case _1BS:
119                 return new D5_00_01(msg);
120             case _4BS: {
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");
124                     return null;
125                 }
126
127                 byte db_3 = msg.getPayload()[1];
128                 byte db_2 = msg.getPayload()[2];
129                 byte db_1 = msg.getPayload()[3];
130
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);
134
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 }));
139
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;
144                 }
145
146                 return buildEEP(eepType, msg);
147             }
148             case UTE: {
149                 byte[] payload = msg.getPayload();
150
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
154                         - 1];
155
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);
161
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;
170                     } else {
171                         return null;
172                     }
173                 }
174
175                 return buildEEP(eepType, msg);
176             }
177             case Unknown:
178             case VLD:
179             case MSC:
180             case SIG:
181                 return null;
182         }
183
184         return null;
185     }
186
187     public static EEP buildResponseEEPFromTeachInERP1(ERP1Message msg, byte[] senderId) {
188         switch (msg.getRORG()) {
189             case UTE:
190                 EEP result = new UTEResponse(msg);
191                 result.setSenderId(senderId);
192
193                 return result;
194             case _4BS:
195                 result = new _4BSTeachInVariation3Response(msg);
196                 result.setSenderId(senderId);
197
198                 return result;
199             default:
200                 return null;
201         }
202     }
203 }