]> git.basschouten.com Git - openhab-addons.git/blob
27d29f6e6d3b051c29cb8d8cfe0e118c6b306585
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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      * @return the SoulissNodeID
97      */
98     public int getNode() {
99         return iNode;
100     }
101
102     protected synchronized void commandReadNodeTypsStates() {
103         var gwConfig = getGatewayConfig();
104         if (gwConfig != null) {
105             commonCommands.sendTypicalRequestFrame(gwConfig, this.getNode(), 1);
106         }
107     }
108
109     /**
110      * Send a command as hexadecimal, e.g.: SOULISS_T1N_ON_CMD = 0x02; short
111      * SOULISS_T1N_OFF_CMD = 0x04;
112      *
113      * @param command
114      */
115     public void commandSEND(byte command) {
116         var gwConfig = getGatewayConfig();
117         if (gwConfig != null) {
118             commonCommands.sendFORCEFrame(gwConfig, this.getNode(), this.getSlot(), command);
119         }
120     }
121
122     public void commandSendRgb(byte command, byte r, byte g, byte b) {
123         var gwConfig = getGatewayConfig();
124         if (gwConfig != null) {
125             commonCommands.sendFORCEFrame(gwConfig, command, r, g, b);
126         }
127     }
128
129     public void commandSEND(byte command, byte b1, byte b2) {
130         var gwConfig = getGatewayConfig();
131         if (gwConfig != null) {
132             commonCommands.sendFORCEFrameT31SetPoint(gwConfig, this.getNode(), this.getSlot(), command, b1, b2);
133         }
134     }
135
136     public void commandSEND(byte b1, byte b2) {
137         var gwConfig = getGatewayConfig();
138         if (gwConfig != null) {
139             commonCommands.sendFORCEFrameT61SetPoint(gwConfig, this.getNode(), this.getSlot(), b1, b2);
140         }
141     }
142
143     /**
144      * Create a time stamp as "yyyy-MM-dd'T'HH:mm:ssz"
145      *
146      * @return String timestamp
147      */
148     private static String getTimestamp() {
149         // Pattern : yyyy-MM-dd'T'HH:mm:ssz
150         var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz");
151         var n = new Date();
152         return sdf.format(n.getTime());
153     }
154
155     @Override
156     public void thingUpdated(Thing thing) {
157         updateThing(thing);
158     }
159
160     public @Nullable GatewayConfig getGatewayConfig() {
161         var bridge = getBridge();
162         if (bridge != null) {
163             SoulissGatewayHandler bridgeHandler = (SoulissGatewayHandler) bridge.getHandler();
164             if (bridgeHandler != null) {
165                 return bridgeHandler.getGwConfig();
166             }
167         }
168         return null;
169     }
170
171     public @Nullable String getLabel() {
172         return getThing().getLabel();
173     }
174
175     public void setHealthy(byte shHealthy) {
176         this.updateState(SoulissBindingConstants.HEALTHY_CHANNEL, new DecimalType(shHealthy & 0xFF));
177         this.updateStatus(ThingStatus.ONLINE);
178     }
179
180     public void setLastStatusStored() {
181         this.updateState(SoulissBindingConstants.LASTSTATUSSTORED_CHANNEL, DateTimeType.valueOf(getTimestamp()));
182     }
183
184     protected @Nullable OnOffType getOhStateOnOffFromSoulissVal(byte sVal) {
185         if (sVal == SoulissProtocolConstants.SOULISS_T1N_ON_COIL) {
186             return OnOffType.ON;
187         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_OFF_COIL) {
188             return OnOffType.OFF;
189         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_ON_FEEDBACK) {
190             return OnOffType.ON;
191         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_OFF_FEEDBACK) {
192             return OnOffType.OFF;
193         } else if (sVal == SoulissProtocolConstants.SOULISS_T4N_NOT_ARMED) {
194             return OnOffType.OFF;
195         } else if (sVal == SoulissProtocolConstants.SOULISS_T4N_ARMED) {
196             return OnOffType.ON;
197         }
198
199         return null;
200     }
201
202     protected @Nullable OpenClosedType getOhStateOpenCloseFromSoulissVal(byte sVal) {
203         if (sVal == SoulissProtocolConstants.SOULISS_T1N_ON_COIL) {
204             return OpenClosedType.CLOSED;
205         } else if (sVal == SoulissProtocolConstants.SOULISS_T1N_OFF_COIL) {
206             return OpenClosedType.OPEN;
207         }
208         return null;
209     }
210 }