]> git.basschouten.com Git - openhab-addons.git/blob
1f4f2bba7df453c00e888af87af215276e55ac2b
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.souliss.internal.handler;
14
15 import java.text.SimpleDateFormat;
16 import java.util.Date;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.binding.souliss.internal.SoulissBindingConstants;
21 import org.openhab.binding.souliss.internal.SoulissProtocolConstants;
22 import org.openhab.binding.souliss.internal.config.GatewayConfig;
23 import org.openhab.binding.souliss.internal.protocol.CommonCommands;
24 import org.openhab.core.library.types.DateTimeType;
25 import org.openhab.core.library.types.DecimalType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.OpenClosedType;
28 import org.openhab.core.thing.Thing;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.thing.binding.BaseThingHandler;
32
33 /**
34  * This class implements the base Souliss Typical All other Typicals derive from
35  * this class
36  *
37  * ...from wiki of Dario De Maio
38  * In Souliss the logics that drive your lights, curtains, LED, and
39  * others are pre-configured into so called Typicals. A Typical is a
40  * logic with a predefined set of inputs and outputs and a know
41  * behavior, are used to standardize the user interface and have a
42  * configuration-less behavior.
43  *
44  * @author Tonino Fazio - Initial contribution
45  * @author Luca Calcaterra - Refactor for OH3
46  */
47
48 @NonNullByDefault
49 public abstract class SoulissGenericHandler extends BaseThingHandler implements TypicalCommonMethods {
50
51     private int iSlot;
52     private int iNode;
53
54     private final CommonCommands commonCommands = new CommonCommands();
55
56     // 0 means that Secure Send is disabled
57     boolean bSecureSend = false;
58     // true means that expected value is setpoint (only for T31, T19 and T6x)
59     boolean bExpectedValueSameAsSet = false;
60
61     protected SoulissGenericHandler(Thing thing) {
62         super(thing);
63     }
64
65     /**
66      * @return the iSlot
67      */
68     public int getSlot() {
69         return iSlot;
70     }
71
72     @Override
73     public void initialize() {
74         try {
75             var cfg = thing.getConfiguration();
76             var props = cfg.getProperties();
77
78             var pNode = props.get("node");
79             var pSlot = props.get("slot");
80
81             if ((pNode != null) && (pSlot != null)) {
82                 iNode = Integer.parseInt(pNode.toString());
83                 iSlot = Integer.parseInt(pSlot.toString());
84                 updateProperty(SoulissBindingConstants.PROPERTY_NODE, Integer.toString(iNode));
85                 updateProperty(SoulissBindingConstants.PROPERTY_SLOT, Integer.toString(iSlot));
86                 updateProperty(SoulissBindingConstants.PROPERTY_UNIQUEID,
87                         "N" + Integer.toString(iNode) + "S" + Integer.toString(iSlot));
88             }
89         } catch (Exception e) {
90             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
91                     "Error getting node/slot from souliss typical (thing config)");
92         }
93     }
94
95     /**
96      * @param SoulissNode
97      *            the SoulissNodeID to get
98      */
99     public int getNode() {
100         return iNode;
101     }
102
103     protected synchronized void commandReadNodeTypsStates() {
104         var gwConfig = getGatewayConfig();
105         if (gwConfig != null) {
106             commonCommands.sendTypicalRequestFrame(gwConfig, this.getNode(), 1);
107         }
108     }
109
110     /**
111      * Send a command as hexadecimal, e.g.: SOULISS_T1N_ON_CMD = 0x02; short
112      * SOULISS_T1N_OFF_CMD = 0x04;
113      *
114      * @param command
115      */
116     public void commandSEND(byte command) {
117         var gwConfig = getGatewayConfig();
118         if (gwConfig != null) {
119             commonCommands.sendFORCEFrame(gwConfig, this.getNode(), this.getSlot(), command);
120         }
121     }
122
123     public void commandSendRgb(byte command, byte r, byte g, byte b) {
124         var gwConfig = getGatewayConfig();
125         if (gwConfig != null) {
126             commonCommands.sendFORCEFrame(gwConfig, command, r, g, b);
127         }
128     }
129
130     public void commandSEND(byte command, byte b1, byte b2) {
131         var gwConfig = getGatewayConfig();
132         if (gwConfig != null) {
133             commonCommands.sendFORCEFrameT31SetPoint(gwConfig, this.getNode(), this.getSlot(), command, b1, b2);
134         }
135     }
136
137     public void commandSEND(byte b1, byte b2) {
138         var gwConfig = getGatewayConfig();
139         if (gwConfig != null) {
140             commonCommands.sendFORCEFrameT61SetPoint(gwConfig, this.getNode(), this.getSlot(), b1, b2);
141         }
142     }
143
144     /**
145      * Create a time stamp as "yyyy-MM-dd'T'HH:mm:ssz"
146      *
147      * @return String timestamp
148      */
149     private static String getTimestamp() {
150         // Pattern : yyyy-MM-dd'T'HH:mm:ssz
151         var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz");
152         var n = new Date();
153         return sdf.format(n.getTime());
154     }
155
156     @Override
157     public void thingUpdated(Thing thing) {
158         updateThing(thing);
159     }
160
161     public @Nullable GatewayConfig getGatewayConfig() {
162         var bridge = getBridge();
163         if (bridge != null) {
164             SoulissGatewayHandler bridgeHandler = (SoulissGatewayHandler) bridge.getHandler();
165             if (bridgeHandler != null) {
166                 return bridgeHandler.getGwConfig();
167             }
168         }
169         return null;
170     }
171
172     public @Nullable String getLabel() {
173         return getThing().getLabel();
174     }
175
176     public void setHealthy(byte shHealthy) {
177         this.updateState(SoulissBindingConstants.HEALTHY_CHANNEL, new DecimalType(shHealthy & 0xFF));
178         this.updateStatus(ThingStatus.ONLINE);
179     }
180
181     public void setLastStatusStored() {
182         this.updateState(SoulissBindingConstants.LASTSTATUSSTORED_CHANNEL, DateTimeType.valueOf(getTimestamp()));
183     }
184
185     protected @Nullable OnOffType getOhStateOnOffFromSoulissVal(byte sVal) {
186         if (sVal == SoulissProtocolConstants.SOULISS_T1N_ON_COIL) {
187             return OnOffType.ON;
188         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_OFF_COIL) {
189             return OnOffType.OFF;
190         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_ON_FEEDBACK) {
191             return OnOffType.ON;
192         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_OFF_FEEDBACK) {
193             return OnOffType.OFF;
194         } else if (sVal == SoulissProtocolConstants.SOULISS_T4N_NOT_ARMED) {
195             return OnOffType.OFF;
196         } else if (sVal == SoulissProtocolConstants.SOULISS_T4N_ARMED) {
197             return OnOffType.ON;
198         }
199
200         return null;
201     }
202
203     protected @Nullable OpenClosedType getOhStateOpenCloseFromSoulissVal(byte sVal) {
204         if (sVal == SoulissProtocolConstants.SOULISS_T1N_ON_COIL) {
205             return OpenClosedType.CLOSED;
206         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_OFF_COIL) {
207             return OpenClosedType.OPEN;
208         }
209         return null;
210     }
211 }