[teleinfo] Add support for Standard tic mode (#11375)
* Add a ticMode parameter to serial controller Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Improve checksum verification Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add parameter to deactivate checksum verification Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add standard field labels Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add things and channels for standard tic mode Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add standard tic mode timestamp Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Fix typo Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add some required null annotation Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add parser for relais states Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add relais channels and refactor standard mode channels Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add @NonNullByDefault on enum Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Update documentation Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Fix formula in documentation Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Fix code issues Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Move channel type description in same file than channel group type description Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add pattern specification to dateTime channel type Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add missing channelGroup id in channel UID Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Add trace log Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Fix group labels Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Make labels uppercase Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Make options lowercase Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh> * Simplify group label Signed-off-by: Olivier Marceau <hollysaiqs@marceau.ovh>
This commit is contained in:
parent
f8a6522100
commit
5d52435dea
|
@ -12,6 +12,10 @@ These values can be used to
|
|||
|
||||
## Supported Things
|
||||
|
||||
### Historical TIC mode
|
||||
|
||||
Historical TIC mode is the only mode of all telemeters before Linky models and the default mode for Linky telemeters.
|
||||
|
||||
The Teleinfo binding provides support for both single-phase and three-phase connection, ICC evolution and the following pricing modes:
|
||||
|
||||
- HCHP mode
|
||||
|
@ -34,6 +38,19 @@ The Teleinfo binding provides support for both single-phase and three-phase conn
|
|||
| cbetm_hc_electricitymeter | three-phase | HCHP | |
|
||||
| cbetm_tempo_electricitymeter | three-phase | Tempo | |
|
||||
|
||||
### Standard TIC mode
|
||||
|
||||
Linky telemeters add a new `Standard` mode with more detailed information but still provide information on the legacy format under the `Historical` denomination.
|
||||
|
||||
Standard mode doesn't depend on the pricing options, but it adds some useful information for electricity producers.
|
||||
|
||||
| Thing type | Connection | Producer mode |
|
||||
|--------------------------------------------|--------------|--------------|
|
||||
| lsmm_electricitymeter | single-phase | |
|
||||
| lsmm_prod_electricitymeter | single-phase | [x] |
|
||||
| lstm_electricitymeter | three-phase | |
|
||||
| lstm_prod_electricitymeter | three-phase | [x] |
|
||||
|
||||
## Discovery
|
||||
|
||||
Before the binding can be used, a serial controller must be added. This needs to be done manually. Select __Teleinfo Serial Controller__ and enter the serial port.
|
||||
|
@ -49,30 +66,33 @@ Once the serial controller added, electricity meters will automatically appear a
|
|||
|----------------------|--------------|---------------------------------------|---------------------------------|
|
||||
| `serialcontroller` | `serialport` | Path to the serial controller | /dev/ttyXXXX, rfc2217://ip:port |
|
||||
| `*_electricitymeter` | `adco` | Electricity meter identifier | 12 digits number |
|
||||
| | `ticMode` | TIC mode | `STANDARD`, `HISTORICAL` (default) |
|
||||
|
||||
## Channels
|
||||
|
||||
### Historical TIC mode
|
||||
|
||||
Channel availability depends on the electricity connection (single or three-phase) and on the pricing mode (Base, HCHP, EJP or Tempo).
|
||||
|
||||
| Channel | Type | Description | Phase | Mode |
|
||||
| Channel | Type | Description | Connection | Mode |
|
||||
|----------|---------------------------|----------------------------------------------------------|--------|-------|
|
||||
| isousc | `Number:ElectricCurrent` | Subscribed electric current | All | All |
|
||||
| ptec | `String` | Current pricing period | All | All |
|
||||
| imax | `Number:ElectricCurrent` | Maximum consumed electric current | Single | All |
|
||||
| imax1 | `Number:ElectricCurrent` | Maximum consumed electric current on phase 1 | Three | All |
|
||||
| imax2 | `Number:ElectricCurrent` | Maximum consumed electric current on phase 2 | Three | All |
|
||||
| imax3 | `Number:ElectricCurrent` | Maximum consumed electric current on phase 3 | Three | All |
|
||||
| adps | `Number:ElectricCurrent` | Excess electric current warning | Single | All |
|
||||
| adir1 | `Number:ElectricCurrent` | Excess electric current on phase 1 warning | Three | All |
|
||||
| adir2 | `Number:ElectricCurrent` | Excess electric current on phase 2 warning | Three | All |
|
||||
| adir3 | `Number:ElectricCurrent` | Excess electric current on phase 3 warning | Three | All |
|
||||
| iinst | `Number:ElectricCurrent` | Instantaneous electric current | Single | All |
|
||||
| iinst1 | `Number:ElectricCurrent` | Instantaneous electric current on phase 1 | Three | All |
|
||||
| iinst2 | `Number:ElectricCurrent` | Instantaneous electric current on phase 2 | Three | All |
|
||||
| iinst3 | `Number:ElectricCurrent` | Instantaneous electric current on phase 3 | Three | All |
|
||||
| ppot | `String` | Electrical potential presence | Three | All |
|
||||
| pmax | `Number:Energy` | Maximum consumed electric power on all phases | Three | All |
|
||||
| papp | `Number:Power` | Instantaneous apparent power | Three, single (ICC evolution only) | All |
|
||||
| imax | `Number:ElectricCurrent` | Maximum consumed electric current | Single-phase | All |
|
||||
| imax1 | `Number:ElectricCurrent` | Maximum consumed electric current on phase 1 | Three-phase | All |
|
||||
| imax2 | `Number:ElectricCurrent` | Maximum consumed electric current on phase 2 | Three-phase | All |
|
||||
| imax3 | `Number:ElectricCurrent` | Maximum consumed electric current on phase 3 | Three-phase | All |
|
||||
| adps | `Number:ElectricCurrent` | Excess electric current warning | Single-phase | All |
|
||||
| adir1 | `Number:ElectricCurrent` | Excess electric current on phase 1 warning | Three-phase | All |
|
||||
| adir2 | `Number:ElectricCurrent` | Excess electric current on phase 2 warning | Three-phase | All |
|
||||
| adir3 | `Number:ElectricCurrent` | Excess electric current on phase 3 warning | Three-phase | All |
|
||||
| iinst | `Number:ElectricCurrent` | Instantaneous electric current | Single-phase | All |
|
||||
| iinst1 | `Number:ElectricCurrent` | Instantaneous electric current on phase 1 | Three-phase | All |
|
||||
| iinst2 | `Number:ElectricCurrent` | Instantaneous electric current on phase 2 | Three-phase | All |
|
||||
| iinst3 | `Number:ElectricCurrent` | Instantaneous electric current on phase 3 | Three-phase | All |
|
||||
| ppot | `String` | Electrical potential presence | Three-phase | All |
|
||||
| pmax | `Number:Energy` | Maximum consumed electric power on all phases | Three-phase | All |
|
||||
| papp | `Number:Power` | Instantaneous apparent power | Three-phase, single-phase (ICC evolution only) | All |
|
||||
| hhphc | `String` | Pricing schedule group | All | HCHP |
|
||||
| hchc | `Number:Energy` | Total consumed energy at low rate pricing | All | HCHP |
|
||||
| hchp | `Number:Energy` | Total consumed energy at high rate pricing | All | HCHP |
|
||||
|
@ -88,8 +108,64 @@ Channel availability depends on the electricity connection (single or three-phas
|
|||
| pejp | `Number:Duration` | Prior notice to EJP start | All | EJP |
|
||||
| demain | `String` | Following day color | All | Tempo |
|
||||
|
||||
### Standard TIC mode
|
||||
|
||||
| Channel | Type | Description | Connection | Mode |
|
||||
|----------|---------------------------|----------------------------------------------------------|--------|-------|
|
||||
| ngtf | `String` | Provider schedule name | All | All |
|
||||
| ltarf | `String` | Current pricing label | All | All |
|
||||
| east | `Number:Energy` | Total active energy withdrawn | All | All |
|
||||
| easf*XX* | `Number:Energy` | Active energy withdrawn from provider on index <img src="https://render.githubusercontent.com/render/math?math=XX \in \{01,\dots,10\}"/> | All | All |
|
||||
| easd*XX* | `Number:Energy` | Active energy withdrawn from distributor on index <img src="https://render.githubusercontent.com/render/math?math=XX \in \{01,\dots,04\}"/> | All | All |
|
||||
| irms*X* | `Number:ElectricCurrent` | RMS Current on phase *X* | All for <img src="https://render.githubusercontent.com/render/math?math=X=1"/>, Three-phase for <img src="https://render.githubusercontent.com/render/math?math=X\in \{2,3\}"/> | All |
|
||||
| urms*X* | `Number:Potential` | RMS Voltage on phase *X* | All for <img src="https://render.githubusercontent.com/render/math?math=X=1"/>, Three-phase for <img src="https://render.githubusercontent.com/render/math?math=X\in \{2,3\}"/> | All |
|
||||
| pref | `Number:Power` | Reference apparent power | All | All |
|
||||
| pcoup | `Number:Power` | Apparent power rupture capacity | All | All |
|
||||
| sinsts | `Number:Power` | Instantaneous withdrawn apparent power | Single-phase | All |
|
||||
| smaxsn | `Number:Power` | Maximum withdrawn apparent power of the day | Single-phase | All |
|
||||
| smaxsnMinus1 | `Number:Power` | Maximum withdrawn apparent power of the previous day | Single-phase | All |
|
||||
| ccasn | `Number:Power` | Active charge point N | All | All |
|
||||
| ccasnMinus1 | `Number:Power` | Active charge point N-1 | All | All |
|
||||
| umoy*X* | `Number:Potential` | Mean Voltage on phase *X* | All for <img src="https://render.githubusercontent.com/render/math?math=X=1"/>, Three-phase for <img src="https://render.githubusercontent.com/render/math?math=X\in \{2,3\}"/> | All |
|
||||
| dpm*X* | `String` | Start of mobile peak period <img src="https://render.githubusercontent.com/render/math?math=X\in \{1,\dots,3\}"/> | All | All |
|
||||
| fpm*X* | `String` | End of mobile peak period <img src="https://render.githubusercontent.com/render/math?math=X\in \{1,\dots,3\}"/> | All | All |
|
||||
| msg1 | `String` | Short message | All | All |
|
||||
| msg2 | `String` | Very short message | All | All |
|
||||
| ntarf | `String` | Index of current pricing | All | All |
|
||||
| njourf | `String` | Number of current provider schedule | All | All |
|
||||
| njourfPlus1 | `String` | Number of next day provider schedule | All | All |
|
||||
| pjourfPlus1 | `String` | Profile of next day provider schedule | All | All |
|
||||
| ppointe | `String` | Profile of next rush day | All | All |
|
||||
| date | `DateTime` | Date and Time | All | All |
|
||||
| smaxsnDate | `DateTime` | Timestamp of SMAXSN value | All | All |
|
||||
| smaxsnMinus1Date | `DateTime` | Timestamp of SMAXSN-1 value | All | All |
|
||||
| ccasnDate | `DateTime` | Timestamp of CCASN value | All | All |
|
||||
| ccasnMinus1Date | `DateTime` | Timestamp of CCASN-1 value | All | All |
|
||||
| umoy*X*Date | `DateTime` | Timestamp of UMOY*X* value | All for <img src="https://render.githubusercontent.com/render/math?math=X=1"/>, Three-phase for <img src="https://render.githubusercontent.com/render/math?math=X\in \{2,3\}"/> | All |
|
||||
| dpm*X*Date | `DateTime` | Date of DPM*X* | All | All |
|
||||
| fpm*X*Date | `DateTime` | Date of FPM*X* | All | All |
|
||||
| relais*X* | `Switch` | relais status (<img src="https://render.githubusercontent.com/render/math?math=X\in {1,\dots,8}"/> ) | All | All |
|
||||
| sinsts*X* | `Number:Power` | Instantaneous withdrawn apparent power on phase *X* | Three-phase | All |
|
||||
| smaxsn*X* | `Number:Power` | Maximum withdrawn apparent power of the day on phase *X* | Three-phase | All |
|
||||
| smaxsn*X*Minus1 | `Number:Power` | Maximum withdrawn apparent power on the previous day on phase *X* | Three-phase | All |
|
||||
| smaxs*X*nDate | `DateTime` | Timestamp of SMAXSN*X* value | Three-phase | All |
|
||||
| smaxsn*X*Minus1Date | `DateTime` | Timestamp of SMAXSN*X*-1 value | Three-phase | All |
|
||||
| eait | `Number:Energy` | Total active energy withdrawn | All | All |
|
||||
| erq*X* | `Number:Energy` | Active energy withdrawn from provider on index <img src="https://render.githubusercontent.com/render/math?math=XX \in \{01,\dots,10\}"/> | All | All |
|
||||
| sinsti | `Number:Energy` | Active energy withdrawn from distributor on index <img src="https://render.githubusercontent.com/render/math?math=XX \in \{01,\dots,04\}"/> | All | All |
|
||||
| smaxin | `Number:Power` | Maximum injected apparent power of the day | All for <img src="https://render.githubusercontent.com/render/math?math=X=1"/>, Three-phase for <img src="https://render.githubusercontent.com/render/math?math=X\in \{2,3\}"/> | All |
|
||||
| smaxinMinus1 | `Number:Power` | Maximum injected apparent power of the previous day | All for <img src="https://render.githubusercontent.com/render/math?math=X=1"/>, Three-phase for <img src="https://render.githubusercontent.com/render/math?math=X\in \{2,3\}"/> | All |
|
||||
| ccain | `Number:Power` | Injected active charge point N | All | Producer |
|
||||
| ccainMinus1 | `Number:Power` | Injected active charge point N-1 | All | Producer |
|
||||
| smaxinDate | `DateTime` | Timestamp of SMAXIN value | All | Producer |
|
||||
| smaxinMinus1Date | `DateTime` | Timestamp of SMAXIN-1 value | All | Producer |
|
||||
| ccainDate | `DateTime` | Timestamp of CCAIN value | All | Producer |
|
||||
| ccainMinus1Date | `DateTime` | Timestamp of CCAIN-1 value | All | Producer |
|
||||
|
||||
## Full Example
|
||||
|
||||
### Historical TIC mode
|
||||
|
||||
The following `things` file declare a serial USB controller on `/dev/ttyUSB0` for a Single-phase Electricity meter with HC/HP option - CBEMM Evolution ICC and adco `031528042289` :
|
||||
|
||||
```
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
*/
|
||||
package org.openhab.binding.teleinfo.internal;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
|
@ -68,7 +70,6 @@ public class TeleinfoBindingConstants {
|
|||
public static final String CHANNEL_CBETM_IINST1 = "iinst1";
|
||||
public static final String CHANNEL_CBETM_IINST2 = "iinst2";
|
||||
public static final String CHANNEL_CBETM_IINST3 = "iinst3";
|
||||
public static final String CHANNEL_CBETM_FRAME_TYPE = "frameType";
|
||||
public static final String CHANNEL_CBETM_LONG_IMAX1 = "imax1";
|
||||
public static final String CHANNEL_CBETM_LONG_IMAX2 = "imax2";
|
||||
public static final String CHANNEL_CBETM_LONG_IMAX3 = "imax3";
|
||||
|
@ -77,6 +78,105 @@ public class TeleinfoBindingConstants {
|
|||
public static final String CHANNEL_CBETM_SHORT_ADIR1 = "adir1";
|
||||
public static final String CHANNEL_CBETM_SHORT_ADIR2 = "adir2";
|
||||
public static final String CHANNEL_CBETM_SHORT_ADIR3 = "adir3";
|
||||
// List of Linky standard mode channel ids
|
||||
public static final String CHANNEL_LSM_NGTF = "commonLSMGroup#ngtf";
|
||||
public static final String CHANNEL_LSM_LTARF = "commonLSMGroup#ltarf";
|
||||
public static final String CHANNEL_LSM_EAST = "commonLSMGroup#east";
|
||||
public static final String CHANNEL_LSM_EASF01 = "commonLSMGroup#easf01";
|
||||
public static final String CHANNEL_LSM_EASF02 = "commonLSMGroup#easf02";
|
||||
public static final String CHANNEL_LSM_EASF03 = "commonLSMGroup#easf03";
|
||||
public static final String CHANNEL_LSM_EASF04 = "commonLSMGroup#easf04";
|
||||
public static final String CHANNEL_LSM_EASF05 = "commonLSMGroup#easf05";
|
||||
public static final String CHANNEL_LSM_EASF06 = "commonLSMGroup#easf06";
|
||||
public static final String CHANNEL_LSM_EASF07 = "commonLSMGroup#easf07";
|
||||
public static final String CHANNEL_LSM_EASF08 = "commonLSMGroup#easf08";
|
||||
public static final String CHANNEL_LSM_EASF09 = "commonLSMGroup#easf09";
|
||||
public static final String CHANNEL_LSM_EASF10 = "commonLSMGroup#easf10";
|
||||
public static final String CHANNEL_LSM_EASD01 = "commonLSMGroup#easd01";
|
||||
public static final String CHANNEL_LSM_EASD02 = "commonLSMGroup#easd02";
|
||||
public static final String CHANNEL_LSM_EASD03 = "commonLSMGroup#easd03";
|
||||
public static final String CHANNEL_LSM_EASD04 = "commonLSMGroup#easd04";
|
||||
public static final String CHANNEL_LSM_IRMS1 = "commonLSMGroup#irms1";
|
||||
public static final String CHANNEL_LSM_URMS1 = "commonLSMGroup#urms1";
|
||||
public static final String CHANNEL_LSM_PREF = "commonLSMGroup#pref";
|
||||
public static final String CHANNEL_LSM_PCOUP = "commonLSMGroup#pcoup";
|
||||
public static final String CHANNEL_LSM_SINSTS = "commonLSMGroup#sinsts";
|
||||
public static final String CHANNEL_LSM_SMAXSN = "commonLSMGroup#smaxsn";
|
||||
public static final String CHANNEL_LSM_SMAXSN_MINUS_1 = "commonLSMGroup#smaxsnMinus1";
|
||||
public static final String CHANNEL_LSM_CCASN = "commonLSMGroup#ccasn";
|
||||
public static final String CHANNEL_LSM_CCASN_MINUS_1 = "commonLSMGroup#ccasnMinus1";
|
||||
public static final String CHANNEL_LSM_UMOY1 = "commonLSMGroup#umoy1";
|
||||
public static final String CHANNEL_LSM_STGE = "commonLSMGroup#stge";
|
||||
public static final String CHANNEL_LSM_DPM1 = "commonLSMGroup#dpm1";
|
||||
public static final String CHANNEL_LSM_FPM1 = "commonLSMGroup#fpm1";
|
||||
public static final String CHANNEL_LSM_DPM2 = "commonLSMGroup#dpm2";
|
||||
public static final String CHANNEL_LSM_FPM2 = "commonLSMGroup#fpm2";
|
||||
public static final String CHANNEL_LSM_DPM3 = "commonLSMGroup#dpm3";
|
||||
public static final String CHANNEL_LSM_FPM3 = "commonLSMGroup#fpm3";
|
||||
public static final String CHANNEL_LSM_MSG1 = "commonLSMGroup#msg1";
|
||||
public static final String CHANNEL_LSM_MSG2 = "commonLSMGroup#msg2";
|
||||
public static final String CHANNEL_LSM_PRM = "commonLSMGroup#prm";
|
||||
public static final String[] CHANNELS_LSM_RELAIS = IntStream.range(1, 9).mapToObj(i -> "commonLSMGroup#relais" + i)
|
||||
.toArray(String[]::new);
|
||||
public static final String CHANNEL_LSM_NTARF = "commonLSMGroup#ntarf";
|
||||
public static final String CHANNEL_LSM_NJOURF = "commonLSMGroup#njourf";
|
||||
public static final String CHANNEL_LSM_NJOURF_PLUS_1 = "commonLSMGroup#njourfPlus1";
|
||||
public static final String CHANNEL_LSM_PJOURF_PLUS_1 = "commonLSMGroup#pjourfPlus1";
|
||||
public static final String CHANNEL_LSM_PPOINTE = "commonLSMGroup#ppointe";
|
||||
|
||||
public static final String CHANNEL_LSM_IRMS2 = "threePhasedLSMGroup#irms2";
|
||||
public static final String CHANNEL_LSM_IRMS3 = "threePhasedLSMGroup#irms3";
|
||||
public static final String CHANNEL_LSM_URMS2 = "threePhasedLSMGroup#urms2";
|
||||
public static final String CHANNEL_LSM_URMS3 = "threePhasedLSMGroup#urms3";
|
||||
public static final String CHANNEL_LSM_SINSTS1 = "threePhasedLSMGroup#sinsts1";
|
||||
public static final String CHANNEL_LSM_SINSTS2 = "threePhasedLSMGroup#sinsts2";
|
||||
public static final String CHANNEL_LSM_SINSTS3 = "threePhasedLSMGroup#sinsts3";
|
||||
public static final String CHANNEL_LSM_SMAXSN1 = "threePhasedLSMGroup#smaxsn1";
|
||||
public static final String CHANNEL_LSM_SMAXSN2 = "threePhasedLSMGroup#smaxsn2";
|
||||
public static final String CHANNEL_LSM_SMAXSN3 = "threePhasedLSMGroup#smaxsn3";
|
||||
public static final String CHANNEL_LSM_SMAXSN1_MINUS_1 = "threePhasedLSMGroup#smaxsn1Minus1";
|
||||
public static final String CHANNEL_LSM_SMAXSN2_MINUS_1 = "threePhasedLSMGroup#smaxsn2Minus1";
|
||||
public static final String CHANNEL_LSM_SMAXSN3_MINUS_1 = "threePhasedLSMGroup#smaxsn3Minus1";
|
||||
public static final String CHANNEL_LSM_UMOY2 = "threePhasedLSMGroup#umoy2";
|
||||
public static final String CHANNEL_LSM_UMOY3 = "threePhasedLSMGroup#umoy3";
|
||||
|
||||
public static final String CHANNEL_LSM_EAIT = "producerLSMGroup#eait";
|
||||
public static final String CHANNEL_LSM_ERQ1 = "producerLSMGroup#erq1";
|
||||
public static final String CHANNEL_LSM_ERQ2 = "producerLSMGroup#erq2";
|
||||
public static final String CHANNEL_LSM_ERQ3 = "producerLSMGroup#erq3";
|
||||
public static final String CHANNEL_LSM_ERQ4 = "producerLSMGroup#erq4";
|
||||
public static final String CHANNEL_LSM_SINSTI = "producerLSMGroup#sinsti";
|
||||
public static final String CHANNEL_LSM_SMAXIN = "producerLSMGroup#smaxin";
|
||||
public static final String CHANNEL_LSM_SMAXIN_MINUS_1 = "producerLSMGroup#smaxinMinus1";
|
||||
public static final String CHANNEL_LSM_CCAIN = "producerLSMGroup#ccain";
|
||||
public static final String CHANNEL_LSM_CCAIN_MINUS_1 = "producerLSMGroup#ccainMinus1";
|
||||
|
||||
public static final String CHANNEL_LSM_DATE = "commonLSMGroup#date";
|
||||
public static final String CHANNEL_LSM_SMAXSN_DATE = "commonLSMGroup#smaxsnDate";
|
||||
public static final String CHANNEL_LSM_SMAXSN_MINUS_1_DATE = "commonLSMGroup#smaxsnMinus1Date";
|
||||
public static final String CHANNEL_LSM_CCASN_DATE = "commonLSMGroup#ccasnDate";
|
||||
public static final String CHANNEL_LSM_CCASN_MINUS_1_DATE = "commonLSMGroup#ccasnMinus1Date";
|
||||
public static final String CHANNEL_LSM_UMOY1_DATE = "commonLSMGroup#umoy1Date";
|
||||
public static final String CHANNEL_LSM_DPM1_DATE = "commonLSMGroup#dpm1Date";
|
||||
public static final String CHANNEL_LSM_FPM1_DATE = "commonLSMGroup#fpm1Date";
|
||||
public static final String CHANNEL_LSM_DPM2_DATE = "commonLSMGroup#dpm2Date";
|
||||
public static final String CHANNEL_LSM_FPM2_DATE = "commonLSMGroup#fpm2Date";
|
||||
public static final String CHANNEL_LSM_DPM3_DATE = "commonLSMGroup#dpm3Date";
|
||||
public static final String CHANNEL_LSM_FPM3_DATE = "commonLSMGroup#fpm3Date";
|
||||
|
||||
public static final String CHANNEL_LSM_SMAXIN_DATE = "producerLSMGroup#smaxinDate";
|
||||
public static final String CHANNEL_LSM_SMAXIN_MINUS_1_DATE = "producerLSMGroup#smaxinMinus1Date";
|
||||
public static final String CHANNEL_LSM_CCAIN_DATE = "producerLSMGroup#ccainDate";
|
||||
public static final String CHANNEL_LSM_CCAIN_MINUS_1_DATE = "producerLSMGroup#ccainMinus1Date";
|
||||
|
||||
public static final String CHANNEL_LSM_SMAXSN1_DATE = "threePhasedLSMGroup#smaxsn1Date";
|
||||
public static final String CHANNEL_LSM_SMAXSN2_DATE = "threePhasedLSMGroup#smaxsn2Date";
|
||||
public static final String CHANNEL_LSM_SMAXSN3_DATE = "threePhasedLSMGroup#smaxsn3Date";
|
||||
public static final String CHANNEL_LSM_SMAXSN1_MINUS_1_DATE = "threePhasedLSMGroup#smaxsn1Minus1Date";
|
||||
public static final String CHANNEL_LSM_SMAXSN2_MINUS_1_DATE = "threePhasedLSMGroup#smaxsn2Minus1Date";
|
||||
public static final String CHANNEL_LSM_SMAXSN3_MINUS_1_DATE = "threePhasedLSMGroup#smaxsn3Minus1Date";
|
||||
public static final String CHANNEL_LSM_UMOY2_DATE = "threePhasedLSMGroup#umoy2Date";
|
||||
public static final String CHANNEL_LSM_UMOY3_DATE = "threePhasedLSMGroup#umoy3Date";
|
||||
|
||||
public static final String NOT_A_CHANNEL = "";
|
||||
|
||||
|
@ -118,6 +218,18 @@ public class TeleinfoBindingConstants {
|
|||
public static final ThingTypeUID THING_TEMPO_CBETM_ELECTRICITY_METER_TYPE_UID = new ThingTypeUID(BINDING_ID,
|
||||
"cbetm_tempo_electricitymeter");
|
||||
|
||||
public static final ThingTypeUID THING_LSMT_PROD_ELECTRICITY_METER_TYPE_UID = new ThingTypeUID(BINDING_ID,
|
||||
"lsmt_prod_electricitymeter");
|
||||
|
||||
public static final ThingTypeUID THING_LSMM_PROD_ELECTRICITY_METER_TYPE_UID = new ThingTypeUID(BINDING_ID,
|
||||
"lsmm_prod_electricitymeter");
|
||||
|
||||
public static final ThingTypeUID THING_LSMT_ELECTRICITY_METER_TYPE_UID = new ThingTypeUID(BINDING_ID,
|
||||
"lsmt_electricitymeter");
|
||||
|
||||
public static final ThingTypeUID THING_LSMM_ELECTRICITY_METER_TYPE_UID = new ThingTypeUID(BINDING_ID,
|
||||
"lsmm_electricitymeter");
|
||||
|
||||
public static final String ERROR_OFFLINE_SERIAL_NOT_FOUND = "@text/teleinfo.thingstate.serial_notfound";
|
||||
public static final String ERROR_OFFLINE_SERIAL_INUSE = "@text/teleinfo.thingstate.serial_inuse";
|
||||
public static final String ERROR_OFFLINE_SERIAL_UNSUPPORTED = "@text/teleinfo.thingstate.serial_unsupported";
|
||||
|
|
|
@ -17,8 +17,6 @@ import static org.openhab.binding.teleinfo.internal.TeleinfoBindingConstants.*;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
@ -47,13 +45,15 @@ import org.slf4j.LoggerFactory;
|
|||
public class TeleinfoDiscoveryService extends AbstractDiscoveryService
|
||||
implements TeleinfoControllerHandlerListener, ThingHandlerService, DiscoveryService {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Stream.of(THING_HC_CBEMM_ELECTRICITY_METER_TYPE_UID,
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_HC_CBEMM_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_BASE_CBEMM_ELECTRICITY_METER_TYPE_UID, THING_TEMPO_CBEMM_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_EJP_CBEMM_ELECTRICITY_METER_TYPE_UID, THING_HC_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_BASE_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID, THING_TEMPO_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_EJP_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID, THING_HC_CBETM_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_BASE_CBETM_ELECTRICITY_METER_TYPE_UID, THING_TEMPO_CBETM_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_EJP_CBETM_ELECTRICITY_METER_TYPE_UID).collect(Collectors.toSet());
|
||||
THING_EJP_CBETM_ELECTRICITY_METER_TYPE_UID, THING_LSMT_PROD_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_LSMT_ELECTRICITY_METER_TYPE_UID, THING_LSMM_PROD_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_LSMM_ELECTRICITY_METER_TYPE_UID);
|
||||
|
||||
private static final int SCAN_DURATION_IN_S = 60;
|
||||
|
||||
|
@ -140,11 +140,12 @@ public class TeleinfoDiscoveryService extends AbstractDiscoveryService
|
|||
TeleinfoAbstractControllerHandler controllerHandlerRef = controllerHandler;
|
||||
if (controllerHandlerRef != null) {
|
||||
logger.debug("New eletricity meter detection from frame {}", frameSample);
|
||||
if (frameSample.get(Label.ADCO) == null) {
|
||||
throw new IllegalStateException("Missing ADCO key");
|
||||
if (frameSample.get(Label.ADCO) == null && frameSample.get(Label.ADSC) == null) {
|
||||
throw new IllegalStateException("Missing ADCO or ADSC key");
|
||||
}
|
||||
|
||||
String adco = frameSample.get(Label.ADCO);
|
||||
String adco = frameSample.get(Label.ADCO) != null ? frameSample.get(Label.ADCO)
|
||||
: frameSample.get(Label.ADSC);
|
||||
if (adco != null) {
|
||||
ThingUID thingUID = new ThingUID(getThingTypeUID(frameSample), adco,
|
||||
controllerHandlerRef.getThing().getUID().getId());
|
||||
|
@ -152,7 +153,7 @@ public class TeleinfoDiscoveryService extends AbstractDiscoveryService
|
|||
final Map<String, Object> properties = getThingProperties(adco);
|
||||
final String representationProperty = THING_ELECTRICITY_METER_PROPERTY_ADCO;
|
||||
DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withProperties(properties)
|
||||
.withLabel("Teleinfo ADCO " + adco).withThingType(getThingTypeUID(frameSample))
|
||||
.withLabel("Teleinfo ADCO/ADSC " + adco).withThingType(getThingTypeUID(frameSample))
|
||||
.withBridge(controllerHandlerRef.getThing().getUID())
|
||||
.withRepresentationProperty(representationProperty).build();
|
||||
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
*/
|
||||
package org.openhab.binding.teleinfo.internal.data;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Define the evolution option values
|
||||
*
|
||||
* @author Olivier MARCEAU - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Evolution {
|
||||
ICC,
|
||||
NONE
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.InvalidFrameException;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.Label;
|
||||
import org.openhab.binding.teleinfo.internal.serial.TeleinfoTicMode;
|
||||
|
||||
/**
|
||||
* The {@link Frame} class defines common attributes for any Teleinfo frames.
|
||||
|
@ -32,11 +33,16 @@ public class Frame implements Serializable {
|
|||
private static final long serialVersionUID = -1934715078822532494L;
|
||||
|
||||
private Map<Label, String> labelToValues = new EnumMap<>(Label.class);
|
||||
private Map<Label, String> labelToTimestamp = new EnumMap<>(Label.class);
|
||||
|
||||
public void put(Label label, String value) {
|
||||
labelToValues.put(label, value);
|
||||
}
|
||||
|
||||
public void putTimestamp(Label label, String timestamp) {
|
||||
labelToTimestamp.put(label, timestamp);
|
||||
}
|
||||
|
||||
public @Nullable String get(Label label) {
|
||||
return labelToValues.get(label);
|
||||
}
|
||||
|
@ -49,11 +55,33 @@ public class Frame implements Serializable {
|
|||
return null;
|
||||
}
|
||||
|
||||
public String getAsDateTime(Label label) {
|
||||
String timestamp = labelToTimestamp.get(label);
|
||||
if (timestamp == null) {
|
||||
return "";
|
||||
}
|
||||
return "20" + timestamp.substring(1, 3) + "-" + timestamp.substring(3, 5) + "-" + timestamp.substring(5, 7)
|
||||
+ "T" + timestamp.substring(7, 9) + ":" + timestamp.substring(9, 11) + ":"
|
||||
+ timestamp.substring(11, 13);
|
||||
}
|
||||
|
||||
public Frame() {
|
||||
// default constructor
|
||||
}
|
||||
|
||||
public FrameType getType() throws InvalidFrameException {
|
||||
TeleinfoTicMode ticMode = getTicMode();
|
||||
switch (ticMode) {
|
||||
case HISTORICAL:
|
||||
return getHistoricalType();
|
||||
case STANDARD:
|
||||
return getStandardType();
|
||||
default:
|
||||
throw new InvalidFrameException();
|
||||
}
|
||||
}
|
||||
|
||||
public FrameType getHistoricalType() throws InvalidFrameException {
|
||||
Phase phase = getPhase();
|
||||
Pricing pricing = getPricing();
|
||||
Evolution evolution = getEvolution();
|
||||
|
@ -152,14 +180,43 @@ public class Frame implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public TeleinfoTicMode getTicMode() throws InvalidFrameException {
|
||||
if (labelToValues.containsKey(Label.ADCO)) {
|
||||
return TeleinfoTicMode.HISTORICAL;
|
||||
} else if (labelToValues.containsKey(Label.ADSC)) {
|
||||
return TeleinfoTicMode.STANDARD;
|
||||
}
|
||||
throw new InvalidFrameException();
|
||||
}
|
||||
|
||||
public FrameType getStandardType() throws InvalidFrameException {
|
||||
boolean isProd = labelToValues.containsKey(Label.EAIT);
|
||||
boolean isThreePhase = labelToValues.containsKey(Label.IRMS2);
|
||||
if (isProd && isThreePhase) {
|
||||
return FrameType.LSMT_PROD;
|
||||
}
|
||||
if (isProd) {
|
||||
return FrameType.LSMM_PROD;
|
||||
}
|
||||
if (isThreePhase) {
|
||||
return FrameType.LSMT;
|
||||
}
|
||||
return FrameType.LSMM;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
labelToValues.clear();
|
||||
labelToTimestamp.clear();
|
||||
}
|
||||
|
||||
public Map<Label, String> getLabelToValues() {
|
||||
return labelToValues;
|
||||
}
|
||||
|
||||
public Map<Label, String> getLabelToTimestamp() {
|
||||
return labelToTimestamp;
|
||||
}
|
||||
|
||||
private char getProgrammeChar() {
|
||||
String optarif = labelToValues.get(Label.OPTARIF);
|
||||
if (optarif == null) {
|
||||
|
|
|
@ -14,6 +14,8 @@ package org.openhab.binding.teleinfo.internal.data;
|
|||
|
||||
import static org.openhab.binding.teleinfo.internal.TeleinfoBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
|
@ -22,6 +24,7 @@ import org.openhab.core.thing.ThingTypeUID;
|
|||
* @author Olivier MARCEAU - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum FrameType {
|
||||
CBETM_SHORT(null),
|
||||
CBETM_LONG_BASE(THING_BASE_CBETM_ELECTRICITY_METER_TYPE_UID),
|
||||
|
@ -36,15 +39,19 @@ public enum FrameType {
|
|||
CBEMM_ICC_EJP(THING_EJP_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID),
|
||||
CBEMM_ICC_TEMPO(THING_TEMPO_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID),
|
||||
CBEMM_ICC_HC(THING_HC_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID),
|
||||
LSMT_PROD(THING_LSMT_PROD_ELECTRICITY_METER_TYPE_UID),
|
||||
LSMM_PROD(THING_LSMM_PROD_ELECTRICITY_METER_TYPE_UID),
|
||||
LSMM(THING_LSMM_ELECTRICITY_METER_TYPE_UID),
|
||||
LSMT(THING_LSMT_ELECTRICITY_METER_TYPE_UID),
|
||||
UNKNOWN(null);
|
||||
|
||||
private ThingTypeUID thingTypeUid;
|
||||
private @Nullable ThingTypeUID thingTypeUid;
|
||||
|
||||
FrameType(ThingTypeUID thingTypeUid) {
|
||||
FrameType(@Nullable ThingTypeUID thingTypeUid) {
|
||||
this.thingTypeUid = thingTypeUid;
|
||||
}
|
||||
|
||||
public ThingTypeUID getThingTypeUid() {
|
||||
public @Nullable ThingTypeUID getThingTypeUid() {
|
||||
return thingTypeUid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
*/
|
||||
package org.openhab.binding.teleinfo.internal.data;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Define all the phase values
|
||||
*
|
||||
* @author Olivier MARCEAU - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Phase {
|
||||
ONE_PHASED,
|
||||
THREE_PHASED
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
*/
|
||||
package org.openhab.binding.teleinfo.internal.data;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Define all the pricing option values
|
||||
*
|
||||
* @author Olivier MARCEAU - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum Pricing {
|
||||
BASE,
|
||||
TEMPO,
|
||||
|
|
|
@ -21,10 +21,13 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||
import org.openhab.binding.teleinfo.internal.data.Frame;
|
||||
import org.openhab.binding.teleinfo.internal.data.Phase;
|
||||
import org.openhab.binding.teleinfo.internal.data.Pricing;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.FrameUtil;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.InvalidFrameException;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.Label;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.ValueType;
|
||||
import org.openhab.binding.teleinfo.internal.serial.TeleinfoTicMode;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
|
@ -130,7 +133,7 @@ public class TeleinfoElectricityMeterHandler extends BaseThingHandler implements
|
|||
@Override
|
||||
public void onFrameReceived(Frame frame) {
|
||||
String adco = configuration.getAdco();
|
||||
if (adco.equalsIgnoreCase(frame.get(Label.ADCO))) {
|
||||
if (adco.equalsIgnoreCase(frame.get(Label.ADCO)) || adco.equalsIgnoreCase(frame.get(Label.ADSC))) {
|
||||
updateStatesForChannels(frame);
|
||||
}
|
||||
}
|
||||
|
@ -139,39 +142,65 @@ public class TeleinfoElectricityMeterHandler extends BaseThingHandler implements
|
|||
for (Entry<Label, String> entry : frame.getLabelToValues().entrySet()) {
|
||||
Label label = entry.getKey();
|
||||
if (!label.getChannelName().equals(NOT_A_CHANNEL)) {
|
||||
logger.trace("Update channel {} to value {}", label.getChannelName(), entry.getValue());
|
||||
if (label == Label.PTEC) {
|
||||
updateState(label.getChannelName(), StringType.valueOf(entry.getValue().replace(".", "")));
|
||||
} else if (label.getType() == ValueType.STRING) {
|
||||
updateState(label.getChannelName(), StringType.valueOf(entry.getValue()));
|
||||
} else if (label.getType() == ValueType.INTEGER) {
|
||||
updateState(label.getChannelName(),
|
||||
QuantityType.valueOf(Integer.parseInt(entry.getValue()), label.getUnit()));
|
||||
updateState(label.getChannelName(), QuantityType
|
||||
.valueOf(label.getFactor() * Integer.parseInt(entry.getValue()), label.getUnit()));
|
||||
}
|
||||
}
|
||||
if (!label.getTimestampChannelName().equals(NOT_A_CHANNEL)) {
|
||||
String timestamp = frame.getAsDateTime(label);
|
||||
if (!timestamp.isEmpty()) {
|
||||
logger.trace("Update channel {} to value {}", label.getTimestampChannelName(), timestamp);
|
||||
updateState(label.getTimestampChannelName(), DateTimeType.valueOf(timestamp));
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (frame.getPricing() == Pricing.TEMPO) {
|
||||
updateState(CHANNEL_TEMPO_FRAME_PROGRAMME_CIRCUIT_1, StringType.valueOf(frame.getProgrammeCircuit1()));
|
||||
updateState(CHANNEL_TEMPO_FRAME_PROGRAMME_CIRCUIT_2, StringType.valueOf(frame.getProgrammeCircuit2()));
|
||||
}
|
||||
} catch (InvalidFrameException e) {
|
||||
logger.warn("Can not find pricing option.");
|
||||
}
|
||||
if (frame.getTicMode() == TeleinfoTicMode.HISTORICAL) {
|
||||
try {
|
||||
if (frame.getPricing() == Pricing.TEMPO) {
|
||||
updateState(CHANNEL_TEMPO_FRAME_PROGRAMME_CIRCUIT_1,
|
||||
StringType.valueOf(frame.getProgrammeCircuit1()));
|
||||
updateState(CHANNEL_TEMPO_FRAME_PROGRAMME_CIRCUIT_2,
|
||||
StringType.valueOf(frame.getProgrammeCircuit2()));
|
||||
}
|
||||
} catch (InvalidFrameException e) {
|
||||
logger.warn("Can not find pricing option.");
|
||||
}
|
||||
|
||||
try {
|
||||
Phase phase = frame.getPhase();
|
||||
if (phase == Phase.ONE_PHASED) {
|
||||
updateStateForMissingAlert(frame, Label.ADPS);
|
||||
} else if (phase == Phase.THREE_PHASED) {
|
||||
if (!wasLastFrameShort) {
|
||||
updateStateForMissingAlert(frame, Label.ADIR1);
|
||||
updateStateForMissingAlert(frame, Label.ADIR2);
|
||||
updateStateForMissingAlert(frame, Label.ADIR3);
|
||||
try {
|
||||
Phase phase = frame.getPhase();
|
||||
if (phase == Phase.ONE_PHASED) {
|
||||
updateStateForMissingAlert(frame, Label.ADPS);
|
||||
} else if (phase == Phase.THREE_PHASED) {
|
||||
if (!wasLastFrameShort) {
|
||||
updateStateForMissingAlert(frame, Label.ADIR1);
|
||||
updateStateForMissingAlert(frame, Label.ADIR2);
|
||||
updateStateForMissingAlert(frame, Label.ADIR3);
|
||||
}
|
||||
wasLastFrameShort = frame.isShortFrame();
|
||||
}
|
||||
} catch (InvalidFrameException e) {
|
||||
logger.warn("Can not find phase.");
|
||||
}
|
||||
} else {
|
||||
if (frame.getLabelToValues().containsKey(Label.RELAIS)) {
|
||||
String relaisString = frame.get(Label.RELAIS);
|
||||
if (relaisString != null) {
|
||||
boolean[] relaisStates = FrameUtil.parseRelaisStates(relaisString);
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
updateState(CHANNELS_LSM_RELAIS[i], OnOffType.from(relaisStates[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
wasLastFrameShort = frame.isShortFrame();
|
||||
}
|
||||
} catch (InvalidFrameException e) {
|
||||
logger.warn("Can not find phase.");
|
||||
logger.warn("Can not find TIC mode.");
|
||||
}
|
||||
|
||||
updateState(CHANNEL_LAST_UPDATE, new DateTimeType());
|
||||
|
|
|
@ -48,7 +48,9 @@ public class TeleinfoThingHandlerFactory extends BaseThingHandlerFactory {
|
|||
THING_HC_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID, THING_BASE_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_TEMPO_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID, THING_EJP_CBEMM_EVO_ICC_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_HC_CBETM_ELECTRICITY_METER_TYPE_UID, THING_BASE_CBETM_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_TEMPO_CBETM_ELECTRICITY_METER_TYPE_UID, THING_EJP_CBETM_ELECTRICITY_METER_TYPE_UID)
|
||||
THING_TEMPO_CBETM_ELECTRICITY_METER_TYPE_UID, THING_EJP_CBETM_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_LSMM_ELECTRICITY_METER_TYPE_UID, THING_LSMM_PROD_ELECTRICITY_METER_TYPE_UID,
|
||||
THING_LSMT_ELECTRICITY_METER_TYPE_UID, THING_LSMT_PROD_ELECTRICITY_METER_TYPE_UID)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
private final SerialPortManager serialPortManager;
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.openhab.binding.teleinfo.internal.data.Frame;
|
|||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.FrameUtil;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.InvalidFrameException;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.Label;
|
||||
import org.openhab.binding.teleinfo.internal.serial.TeleinfoTicMode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -43,19 +44,32 @@ public class TeleinfoInputStream extends InputStream {
|
|||
private BufferedReader bufferedReader;
|
||||
private @Nullable String groupLine;
|
||||
private boolean autoRepairInvalidADPSgroupLine;
|
||||
private final TeleinfoTicMode ticMode;
|
||||
private final boolean verifyChecksum;
|
||||
private final Frame frame = new Frame();
|
||||
|
||||
public TeleinfoInputStream(final InputStream teleinfoInputStream) {
|
||||
this(teleinfoInputStream, false);
|
||||
public TeleinfoInputStream(final InputStream teleinfoInputStream, TeleinfoTicMode ticMode) {
|
||||
this(teleinfoInputStream, false, ticMode, true);
|
||||
}
|
||||
|
||||
public TeleinfoInputStream(final @Nullable InputStream teleinfoInputStream,
|
||||
boolean autoRepairInvalidADPSgroupLine) {
|
||||
public TeleinfoInputStream(final InputStream teleinfoInputStream, boolean autoRepairInvalidADPSgroupLine,
|
||||
TeleinfoTicMode ticMode) {
|
||||
this(teleinfoInputStream, autoRepairInvalidADPSgroupLine, ticMode, true);
|
||||
}
|
||||
|
||||
public TeleinfoInputStream(final InputStream teleinfoInputStream, TeleinfoTicMode ticMode, boolean verifyChecksum) {
|
||||
this(teleinfoInputStream, false, ticMode, verifyChecksum);
|
||||
}
|
||||
|
||||
public TeleinfoInputStream(final @Nullable InputStream teleinfoInputStream, boolean autoRepairInvalidADPSgroupLine,
|
||||
TeleinfoTicMode ticMode, boolean verifyChecksum) {
|
||||
if (teleinfoInputStream == null) {
|
||||
throw new IllegalArgumentException("Teleinfo inputStream is null");
|
||||
}
|
||||
|
||||
this.autoRepairInvalidADPSgroupLine = autoRepairInvalidADPSgroupLine;
|
||||
this.ticMode = ticMode;
|
||||
this.verifyChecksum = verifyChecksum;
|
||||
this.bufferedReader = new BufferedReader(new InputStreamReader(teleinfoInputStream, StandardCharsets.US_ASCII));
|
||||
|
||||
groupLine = null;
|
||||
|
@ -96,29 +110,48 @@ public class TeleinfoInputStream extends InputStream {
|
|||
logger.trace("groupLine = {}", groupLine);
|
||||
String groupLineRef = groupLine;
|
||||
if (groupLineRef != null) {
|
||||
String[] groupLineTokens = groupLineRef.split("\\s");
|
||||
if (groupLineTokens.length != 2 && groupLineTokens.length != 3) {
|
||||
String[] groupLineTokens = groupLineRef.split(ticMode.getSeparator());
|
||||
if (ticMode == TeleinfoTicMode.HISTORICAL && groupLineTokens.length != 2 && groupLineTokens.length != 3
|
||||
|| ticMode == TeleinfoTicMode.STANDARD && groupLineTokens.length != 3
|
||||
&& groupLineTokens.length != 4) {
|
||||
final String error = String.format("The groupLine '%1$s' is incomplete", groupLineRef);
|
||||
throw new InvalidFrameException(error);
|
||||
}
|
||||
String labelStr = groupLineTokens[0];
|
||||
String valueString = groupLineTokens[1];
|
||||
String valueString;
|
||||
String timestampString = null;
|
||||
switch (ticMode) {
|
||||
default:
|
||||
valueString = groupLineTokens[1];
|
||||
break;
|
||||
case STANDARD:
|
||||
if (groupLineTokens.length == 3) {
|
||||
valueString = groupLineTokens[1];
|
||||
} else {
|
||||
timestampString = groupLineTokens[1];
|
||||
valueString = groupLineTokens[2];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// verify integrity (through checksum)
|
||||
char checksum = (groupLineTokens.length == 3 ? groupLineTokens[2].charAt(0) : ' ');
|
||||
char computedChecksum = FrameUtil.computeGroupLineChecksum(labelStr, valueString);
|
||||
if (computedChecksum != checksum) {
|
||||
logger.trace("computedChecksum = {}", computedChecksum);
|
||||
logger.trace("checksum = {}", checksum);
|
||||
final String error = String.format(
|
||||
"The groupLine '%s' is corrupted (integrity not checked). Actual checksum: '%s' / Expected checksum: '%s'",
|
||||
groupLineRef, checksum, computedChecksum);
|
||||
throw new InvalidFrameException(error);
|
||||
if (verifyChecksum) {
|
||||
char checksum = groupLineRef.charAt(groupLineRef.length() - 1);
|
||||
char computedChecksum = FrameUtil
|
||||
.computeGroupLineChecksum(groupLineRef.substring(0, groupLineRef.length() - 2), ticMode);
|
||||
if (computedChecksum != checksum) {
|
||||
logger.trace("computedChecksum = {}", computedChecksum);
|
||||
logger.trace("checksum = {}", checksum);
|
||||
final String error = String.format(
|
||||
"The groupLine '%s' is corrupted (integrity not checked). Actual checksum: '%s' / Expected checksum: '%s'",
|
||||
groupLineRef, checksum, computedChecksum);
|
||||
throw new InvalidFrameException(error);
|
||||
}
|
||||
}
|
||||
|
||||
Label label;
|
||||
try {
|
||||
label = Label.valueOf(labelStr);
|
||||
label = Label.getEnum(labelStr);
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (autoRepairInvalidADPSgroupLine && labelStr.startsWith(Label.ADPS.name())) {
|
||||
// in this hardware issue, label variable is composed by label name and value. E.g:
|
||||
|
@ -133,6 +166,9 @@ public class TeleinfoInputStream extends InputStream {
|
|||
}
|
||||
|
||||
frame.put(label, valueString);
|
||||
if (timestampString != null) {
|
||||
frame.putTimestamp(label, timestampString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +188,7 @@ public class TeleinfoInputStream extends InputStream {
|
|||
throw new UnsupportedOperationException("The 'read()' is not supported");
|
||||
}
|
||||
|
||||
private boolean isHeaderFrame(final @Nullable String line) {
|
||||
public static boolean isHeaderFrame(final @Nullable String line) {
|
||||
// A new teleinfo trame begin with '3' and '2' bytes (END OF TEXT et START OF TEXT)
|
||||
return (line != null && line.length() > 1 && line.codePointAt(0) == 3 && line.codePointAt(1) == 2);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.openhab.binding.teleinfo.internal.reader.io.serialport;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.teleinfo.internal.serial.TeleinfoTicMode;
|
||||
|
||||
/**
|
||||
* The {@link FrameUtil} class defines a utility class for {@link FrameCbetmLong}.
|
||||
|
@ -33,14 +34,31 @@ public class FrameUtil {
|
|||
* must not include in checksum computation.
|
||||
* @return the checksum of the given group line.
|
||||
*/
|
||||
public static char computeGroupLineChecksum(final String label, final String value) {
|
||||
final String groupLine = label + " " + value;
|
||||
public static char computeGroupLineChecksum(final String groupLine, TeleinfoTicMode ticMode) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < groupLine.length(); i++) {
|
||||
sum = sum + groupLine.codePointAt(i);
|
||||
sum += groupLine.codePointAt(i);
|
||||
}
|
||||
if (ticMode == TeleinfoTicMode.STANDARD) {
|
||||
sum += 0x09;
|
||||
}
|
||||
sum = (sum & 0x3F) + 0x20;
|
||||
|
||||
return (char) sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse relais states.
|
||||
*
|
||||
* @param relais integer string
|
||||
* @return State of each relais
|
||||
*/
|
||||
public static boolean[] parseRelaisStates(String relais) {
|
||||
boolean[] relaisState = new boolean[8];
|
||||
int value = Integer.parseInt(relais);
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
relaisState[i] = (value & 1) == 1;
|
||||
value >>= 1;
|
||||
}
|
||||
return relaisState;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,14 @@ import org.openhab.core.library.unit.Units;
|
|||
@NonNullByDefault
|
||||
public enum Label {
|
||||
|
||||
// Historical labels
|
||||
ADCO(ValueType.STRING, NOT_A_CHANNEL, Units.ONE),
|
||||
OPTARIF(ValueType.STRING, NOT_A_CHANNEL, Units.ONE),
|
||||
BASE(ValueType.INTEGER, CHANNEL_BASE_FRAME_BASE, Units.WATT_HOUR),
|
||||
HCHC(ValueType.INTEGER, CHANNEL_HC_FRAME_HCHC, Units.WATT_HOUR),
|
||||
HCHP(ValueType.INTEGER, CHANNEL_HC_FRAME_HCHP, Units.WATT_HOUR),
|
||||
EJPHN(ValueType.INTEGER, CHANNEL_EJP_FRAME_EJPHN, Units.WATT_HOUR),
|
||||
EJPHPM(ValueType.INTEGER, CHANNEL_EJP_FRAME_EJPHN, Units.WATT_HOUR),
|
||||
EJPHPM(ValueType.INTEGER, CHANNEL_EJP_FRAME_EJPHPM, Units.WATT_HOUR),
|
||||
PTEC(ValueType.STRING, CHANNEL_PTEC, Units.ONE),
|
||||
MOTDETAT(ValueType.STRING, CHANNEL_MOTDETAT, Units.AMPERE),
|
||||
ISOUSC(ValueType.INTEGER, CHANNEL_ISOUSC, Units.AMPERE),
|
||||
|
@ -60,16 +61,108 @@ public enum Label {
|
|||
BBRHCJR(ValueType.INTEGER, CHANNEL_TEMPO_FRAME_BBRHCJR, Units.WATT_HOUR),
|
||||
BBRHPJR(ValueType.INTEGER, CHANNEL_TEMPO_FRAME_BBRHPJR, Units.WATT_HOUR),
|
||||
PEJP(ValueType.INTEGER, CHANNEL_EJP_FRAME_PEJP, Units.MINUTE),
|
||||
DEMAIN(ValueType.STRING, CHANNEL_TEMPO_FRAME_DEMAIN, Units.ONE);
|
||||
DEMAIN(ValueType.STRING, CHANNEL_TEMPO_FRAME_DEMAIN, Units.ONE),
|
||||
|
||||
private ValueType type;
|
||||
private String channelName;
|
||||
private Unit<?> unit;
|
||||
// Standard TIC mode labels
|
||||
ADSC(ValueType.STRING, NOT_A_CHANNEL, Units.ONE),
|
||||
VTIC(ValueType.INTEGER, NOT_A_CHANNEL, Units.ONE),
|
||||
DATE(ValueType.STRING, NOT_A_CHANNEL, CHANNEL_LSM_DATE, Units.ONE),
|
||||
NGTF(ValueType.STRING, CHANNEL_LSM_NGTF, Units.ONE),
|
||||
LTARF(ValueType.STRING, CHANNEL_LSM_LTARF, Units.ONE),
|
||||
EAST(ValueType.INTEGER, CHANNEL_LSM_EAST, Units.WATT_HOUR),
|
||||
EASF01(ValueType.INTEGER, CHANNEL_LSM_EASF01, Units.WATT_HOUR),
|
||||
EASF02(ValueType.INTEGER, CHANNEL_LSM_EASF02, Units.WATT_HOUR),
|
||||
EASF03(ValueType.INTEGER, CHANNEL_LSM_EASF03, Units.WATT_HOUR),
|
||||
EASF04(ValueType.INTEGER, CHANNEL_LSM_EASF04, Units.WATT_HOUR),
|
||||
EASF05(ValueType.INTEGER, CHANNEL_LSM_EASF05, Units.WATT_HOUR),
|
||||
EASF06(ValueType.INTEGER, CHANNEL_LSM_EASF06, Units.WATT_HOUR),
|
||||
EASF07(ValueType.INTEGER, CHANNEL_LSM_EASF07, Units.WATT_HOUR),
|
||||
EASF08(ValueType.INTEGER, CHANNEL_LSM_EASF08, Units.WATT_HOUR),
|
||||
EASF09(ValueType.INTEGER, CHANNEL_LSM_EASF09, Units.WATT_HOUR),
|
||||
EASF10(ValueType.INTEGER, CHANNEL_LSM_EASF10, Units.WATT_HOUR),
|
||||
EASD01(ValueType.INTEGER, CHANNEL_LSM_EASD01, Units.WATT_HOUR),
|
||||
EASD02(ValueType.INTEGER, CHANNEL_LSM_EASD02, Units.WATT_HOUR),
|
||||
EASD03(ValueType.INTEGER, CHANNEL_LSM_EASD03, Units.WATT_HOUR),
|
||||
EASD04(ValueType.INTEGER, CHANNEL_LSM_EASD04, Units.WATT_HOUR),
|
||||
EAIT(ValueType.INTEGER, CHANNEL_LSM_EAIT, Units.WATT_HOUR),
|
||||
ERQ1(ValueType.INTEGER, CHANNEL_LSM_ERQ1, Units.VOLT_AMPERE_HOUR),
|
||||
ERQ2(ValueType.INTEGER, CHANNEL_LSM_ERQ2, Units.VOLT_AMPERE_HOUR),
|
||||
ERQ3(ValueType.INTEGER, CHANNEL_LSM_ERQ3, Units.VOLT_AMPERE_HOUR),
|
||||
ERQ4(ValueType.INTEGER, CHANNEL_LSM_ERQ4, Units.VOLT_AMPERE_HOUR),
|
||||
IRMS1(ValueType.INTEGER, CHANNEL_LSM_IRMS1, Units.AMPERE),
|
||||
IRMS2(ValueType.INTEGER, CHANNEL_LSM_IRMS2, Units.AMPERE),
|
||||
IRMS3(ValueType.INTEGER, CHANNEL_LSM_IRMS3, Units.AMPERE),
|
||||
URMS1(ValueType.INTEGER, CHANNEL_LSM_URMS1, Units.VOLT),
|
||||
URMS2(ValueType.INTEGER, CHANNEL_LSM_URMS2, Units.VOLT),
|
||||
URMS3(ValueType.INTEGER, CHANNEL_LSM_URMS3, Units.VOLT),
|
||||
PREF(ValueType.INTEGER, CHANNEL_LSM_PREF, Units.VOLT_AMPERE, 1000),
|
||||
PCOUP(ValueType.INTEGER, CHANNEL_LSM_PCOUP, Units.VOLT_AMPERE, 1000),
|
||||
SINSTS(ValueType.INTEGER, CHANNEL_LSM_SINSTS, Units.VOLT_AMPERE),
|
||||
SINSTS1(ValueType.INTEGER, CHANNEL_LSM_SINSTS1, Units.VOLT_AMPERE),
|
||||
SINSTS2(ValueType.INTEGER, CHANNEL_LSM_SINSTS2, Units.VOLT_AMPERE),
|
||||
SINSTS3(ValueType.INTEGER, CHANNEL_LSM_SINSTS3, Units.VOLT_AMPERE),
|
||||
SMAXSN(ValueType.INTEGER, CHANNEL_LSM_SMAXSN, CHANNEL_LSM_SMAXSN_DATE, Units.VOLT_AMPERE),
|
||||
SMAXSN1(ValueType.INTEGER, CHANNEL_LSM_SMAXSN1, CHANNEL_LSM_SMAXSN1_DATE, Units.VOLT_AMPERE),
|
||||
SMAXSN2(ValueType.INTEGER, CHANNEL_LSM_SMAXSN2, CHANNEL_LSM_SMAXSN2_DATE, Units.VOLT_AMPERE),
|
||||
SMAXSN3(ValueType.INTEGER, CHANNEL_LSM_SMAXSN3, CHANNEL_LSM_SMAXSN3_DATE, Units.VOLT_AMPERE),
|
||||
SMAXSN_MINUS_1(ValueType.INTEGER, CHANNEL_LSM_SMAXSN_MINUS_1, CHANNEL_LSM_SMAXSN_MINUS_1_DATE, Units.VOLT_AMPERE),
|
||||
SMAXSN1_MINUS_1(ValueType.INTEGER, CHANNEL_LSM_SMAXSN1_MINUS_1, CHANNEL_LSM_SMAXSN1_MINUS_1_DATE,
|
||||
Units.VOLT_AMPERE),
|
||||
SMAXSN2_MINUS_1(ValueType.INTEGER, CHANNEL_LSM_SMAXSN2_MINUS_1, CHANNEL_LSM_SMAXSN2_MINUS_1_DATE,
|
||||
Units.VOLT_AMPERE),
|
||||
SMAXSN3_MINUS_1(ValueType.INTEGER, CHANNEL_LSM_SMAXSN3_MINUS_1, CHANNEL_LSM_SMAXSN3_MINUS_1_DATE,
|
||||
Units.VOLT_AMPERE),
|
||||
SINSTI(ValueType.INTEGER, CHANNEL_LSM_SINSTI, Units.VOLT_AMPERE),
|
||||
SMAXIN(ValueType.INTEGER, CHANNEL_LSM_SMAXIN, CHANNEL_LSM_SMAXIN_DATE, Units.VOLT_AMPERE),
|
||||
SMAXIN_MINUS_1(ValueType.INTEGER, CHANNEL_LSM_SMAXIN_MINUS_1, CHANNEL_LSM_SMAXIN_MINUS_1_DATE, Units.VOLT_AMPERE),
|
||||
CCASN(ValueType.INTEGER, CHANNEL_LSM_CCASN, CHANNEL_LSM_CCASN_DATE, Units.WATT),
|
||||
CCASN_MINUS_1(ValueType.INTEGER, CHANNEL_LSM_CCASN_MINUS_1, CHANNEL_LSM_CCASN_MINUS_1_DATE, Units.WATT),
|
||||
CCAIN(ValueType.INTEGER, CHANNEL_LSM_CCAIN, CHANNEL_LSM_CCAIN_DATE, Units.WATT),
|
||||
CCAIN_MINUS_1(ValueType.INTEGER, CHANNEL_LSM_CCAIN_MINUS_1, CHANNEL_LSM_CCAIN_MINUS_1_DATE, Units.WATT),
|
||||
UMOY1(ValueType.INTEGER, CHANNEL_LSM_UMOY1, CHANNEL_LSM_UMOY1_DATE, Units.VOLT),
|
||||
UMOY2(ValueType.INTEGER, CHANNEL_LSM_UMOY2, CHANNEL_LSM_UMOY2_DATE, Units.VOLT),
|
||||
UMOY3(ValueType.INTEGER, CHANNEL_LSM_UMOY3, CHANNEL_LSM_UMOY3_DATE, Units.VOLT),
|
||||
STGE(ValueType.STRING, CHANNEL_LSM_STGE, Units.ONE),
|
||||
DPM1(ValueType.STRING, CHANNEL_LSM_DPM1, CHANNEL_LSM_DPM1_DATE, Units.ONE),
|
||||
FPM1(ValueType.STRING, CHANNEL_LSM_FPM1, CHANNEL_LSM_FPM1_DATE, Units.ONE),
|
||||
DPM2(ValueType.STRING, CHANNEL_LSM_DPM2, CHANNEL_LSM_DPM2_DATE, Units.ONE),
|
||||
FPM2(ValueType.STRING, CHANNEL_LSM_FPM2, CHANNEL_LSM_FPM2_DATE, Units.ONE),
|
||||
DPM3(ValueType.STRING, CHANNEL_LSM_DPM3, CHANNEL_LSM_DPM3_DATE, Units.ONE),
|
||||
FPM3(ValueType.STRING, CHANNEL_LSM_FPM3, CHANNEL_LSM_FPM3_DATE, Units.ONE),
|
||||
MSG1(ValueType.STRING, CHANNEL_LSM_MSG1, Units.ONE),
|
||||
MSG2(ValueType.STRING, CHANNEL_LSM_MSG2, Units.ONE),
|
||||
PRM(ValueType.STRING, CHANNEL_LSM_PRM, Units.ONE),
|
||||
RELAIS(ValueType.STRING, NOT_A_CHANNEL, Units.ONE),
|
||||
NTARF(ValueType.STRING, CHANNEL_LSM_NTARF, Units.ONE),
|
||||
NJOURF(ValueType.STRING, CHANNEL_LSM_NJOURF, Units.ONE),
|
||||
NJOURF_PLUS_1(ValueType.STRING, CHANNEL_LSM_NJOURF_PLUS_1, Units.ONE),
|
||||
PJOURF_PLUS_1(ValueType.STRING, CHANNEL_LSM_PJOURF_PLUS_1, Units.ONE),
|
||||
PPOINTE(ValueType.STRING, CHANNEL_LSM_PPOINTE, Units.ONE);
|
||||
|
||||
private final ValueType type;
|
||||
private final String channelName;
|
||||
private final String timestampChannelName;
|
||||
private final Unit<?> unit;
|
||||
private final int factor;
|
||||
|
||||
Label(ValueType type, String channelName, Unit<?> unit) {
|
||||
this(type, channelName, NOT_A_CHANNEL, unit, 1);
|
||||
}
|
||||
|
||||
Label(ValueType type, String channelName, String timestampChannelName, Unit<?> unit) {
|
||||
this(type, channelName, timestampChannelName, unit, 1);
|
||||
}
|
||||
|
||||
Label(ValueType type, String channelName, Unit<?> unit, int factor) {
|
||||
this(type, channelName, NOT_A_CHANNEL, unit, factor);
|
||||
}
|
||||
|
||||
Label(ValueType type, String channelName, String timestampChannelName, Unit<?> unit, int factor) {
|
||||
this.type = type;
|
||||
this.channelName = channelName;
|
||||
this.timestampChannelName = timestampChannelName;
|
||||
this.unit = unit;
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
public ValueType getType() {
|
||||
|
@ -80,7 +173,21 @@ public enum Label {
|
|||
return channelName;
|
||||
}
|
||||
|
||||
public String getTimestampChannelName() {
|
||||
return timestampChannelName;
|
||||
}
|
||||
|
||||
public Unit<?> getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public int getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
public static Label getEnum(String label) {
|
||||
String modifiedLabel = label.replace("-", "_MINUS_");
|
||||
modifiedLabel = modifiedLabel.replace("+", "_PLUS_");
|
||||
return valueOf(modifiedLabel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@
|
|||
*/
|
||||
package org.openhab.binding.teleinfo.internal.reader.io.serialport;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Defines all the type of values
|
||||
*
|
||||
* @author Olivier MARCEAU - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum ValueType {
|
||||
INTEGER,
|
||||
STRING
|
||||
|
|
|
@ -36,20 +36,24 @@ public class TeleinfoReceiveThread extends Thread {
|
|||
private SerialPort serialPort;
|
||||
private @Nullable TeleinfoReceiveThreadListener listener;
|
||||
private boolean autoRepairInvalidADPSgroupLine;
|
||||
private final TeleinfoTicMode ticMode;
|
||||
private final boolean verifyChecksum;
|
||||
|
||||
public TeleinfoReceiveThread(SerialPort serialPort, final TeleinfoSerialControllerHandler listener,
|
||||
boolean autoRepairInvalidADPSgroupLine) {
|
||||
boolean autoRepairInvalidADPSgroupLine, TeleinfoTicMode ticMode, boolean verifyChecksum) {
|
||||
super("OH-binding-TeleinfoReceiveThread-" + listener.getThing().getUID().getId());
|
||||
setDaemon(true);
|
||||
this.serialPort = serialPort;
|
||||
this.listener = listener;
|
||||
this.autoRepairInvalidADPSgroupLine = autoRepairInvalidADPSgroupLine;
|
||||
this.ticMode = ticMode;
|
||||
this.verifyChecksum = verifyChecksum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try (TeleinfoInputStream teleinfoStream = new TeleinfoInputStream(serialPort.getInputStream(),
|
||||
autoRepairInvalidADPSgroupLine)) {
|
||||
autoRepairInvalidADPSgroupLine, ticMode, verifyChecksum)) {
|
||||
while (!interrupted()) {
|
||||
TeleinfoReceiveThreadListener listener = this.listener;
|
||||
if (listener != null) {
|
||||
|
|
|
@ -23,5 +23,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||
public class TeleinfoSerialControllerConfiguration {
|
||||
|
||||
public String serialport = "";
|
||||
public String ticMode = "";
|
||||
public boolean verifyChecksum = true;
|
||||
public boolean autoRepairInvalidADPSgroupLine = true;
|
||||
}
|
||||
|
|
|
@ -148,7 +148,9 @@ public class TeleinfoSerialControllerHandler extends TeleinfoAbstractControllerH
|
|||
SerialPort commPort = portIdentifier.open("org.openhab.binding.teleinfo", 5000);
|
||||
serialPort = commPort;
|
||||
|
||||
commPort.setSerialPortParams(1200, SerialPort.DATABITS_7, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN);
|
||||
TeleinfoTicMode ticMode = TeleinfoTicMode.valueOf(config.ticMode);
|
||||
commPort.setSerialPortParams(ticMode.getBitrate(), SerialPort.DATABITS_7, SerialPort.STOPBITS_1,
|
||||
SerialPort.PARITY_EVEN);
|
||||
try {
|
||||
commPort.enableReceiveThreshold(1);
|
||||
} catch (UnsupportedCommOperationException e) {
|
||||
|
@ -161,7 +163,7 @@ public class TeleinfoSerialControllerHandler extends TeleinfoAbstractControllerH
|
|||
}
|
||||
logger.debug("Starting receive thread");
|
||||
TeleinfoReceiveThread receiveThread = new TeleinfoReceiveThread(commPort, this,
|
||||
config.autoRepairInvalidADPSgroupLine);
|
||||
config.autoRepairInvalidADPSgroupLine, ticMode, config.verifyChecksum);
|
||||
this.receiveThread = receiveThread;
|
||||
receiveThread.start();
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.teleinfo.internal.serial;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Define an enum for TIC mode of Linky telemeters
|
||||
*
|
||||
* @author Olivier MARCEAU - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum TeleinfoTicMode {
|
||||
HISTORICAL(1200, "\\s"),
|
||||
STANDARD(9600, "\\t");
|
||||
|
||||
private final int bitrate;
|
||||
private final String separator;
|
||||
|
||||
TeleinfoTicMode(int bitrate, String separator) {
|
||||
this.bitrate = bitrate;
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
public int getBitrate() {
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
public String getSeparator() {
|
||||
return separator;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<config-description uri="thing-type:teleinfo:adco">
|
||||
<parameter name="adco" type="text" required="true" pattern="^\w{12}$">
|
||||
<label>ADCO</label>
|
||||
<label>ADCO/ADSC</label>
|
||||
<description>Electricity meter identifier (format: 12 characters / e.g: '031528042289')</description>
|
||||
<limitToOptions>false</limitToOptions>
|
||||
</parameter>
|
||||
|
|
|
@ -0,0 +1,362 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="teleinfo"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<channel-group-type id="commonLSMGroupType">
|
||||
<label>Common</label>
|
||||
<description>Common channels for Linky telemeter in standard teleinformation mode</description>
|
||||
<category>Energy</category>
|
||||
<channels>
|
||||
|
||||
<channel id="ngtf" typeId="stringType">
|
||||
<label>NGTF</label>
|
||||
<description>Provider schedule name</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ltarf" typeId="stringType">
|
||||
<label>LTARF</label>
|
||||
<description>Current pricing label</description>
|
||||
</channel>
|
||||
|
||||
<channel id="east" typeId="energyType">
|
||||
<label>EAST</label>
|
||||
<description>Total active energy withdrawn</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf01" typeId="energyType">
|
||||
<label>EASF01</label>
|
||||
<description>Active energy withdrawn from provider on index 01</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf02" typeId="energyType">
|
||||
<label>EASF02</label>
|
||||
<description>Active energy withdrawn from provider on index 02</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf03" typeId="energyType">
|
||||
<label>EASF03</label>
|
||||
<description>Active energy withdrawn from provider on index 03</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf04" typeId="energyType">
|
||||
<label>EASF04</label>
|
||||
<description>Active energy withdrawn from provider on index 04</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf05" typeId="energyType">
|
||||
<label>EASF05</label>
|
||||
<description>Active energy withdrawn from provider on index 05</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf06" typeId="energyType">
|
||||
<label>EASF06</label>
|
||||
<description>Active energy withdrawn from provider on index 06</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf07" typeId="energyType">
|
||||
<label>EASF07</label>
|
||||
<description>Active energy withdrawn from provider on index 07</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf08" typeId="energyType">
|
||||
<label>EASF08</label>
|
||||
<description>Active energy withdrawn from provider on index 08</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf09" typeId="energyType">
|
||||
<label>EASF09</label>
|
||||
<description>Active energy withdrawn from provider on index 09</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easf10" typeId="energyType">
|
||||
<label>EASF10</label>
|
||||
<description>Active energy withdrawn from provider on index 10</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easd01" typeId="energyType">
|
||||
<label>EASD01</label>
|
||||
<description>Active energy withdrawn from distributor on index 01</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easd02" typeId="energyType">
|
||||
<label>EASD02</label>
|
||||
<description>Active energy withdrawn from distributor on index 02</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easd03" typeId="energyType">
|
||||
<label>EASD03</label>
|
||||
<description>Active energy withdrawn from distributor on index 03</description>
|
||||
</channel>
|
||||
|
||||
<channel id="easd04" typeId="energyType">
|
||||
<label>EASD04</label>
|
||||
<description>Active energy withdrawn from distributor on index 04</description>
|
||||
</channel>
|
||||
|
||||
<channel id="irms1" typeId="currentType">
|
||||
<label>IRMS1</label>
|
||||
<description>RMS Current on phase 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="urms1" typeId="potentialType">
|
||||
<label>URMS1</label>
|
||||
<description>RMS Voltage on phase 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="pref" typeId="powerType">
|
||||
<label>PREF</label>
|
||||
<description>Reference apparent power</description>
|
||||
</channel>
|
||||
|
||||
<channel id="pcoup" typeId="powerType">
|
||||
<label>PCOUP</label>
|
||||
<description>Apparent power rupture capacity</description>
|
||||
</channel>
|
||||
|
||||
<channel id="sinsts" typeId="powerType">
|
||||
<label>SINSTS</label>
|
||||
<description>Instantaneous withdrawn apparent power</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn" typeId="powerType">
|
||||
<label>SMAXSN</label>
|
||||
<description>Maximum withdrawn apparent power of the day</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsnMinus1" typeId="powerType">
|
||||
<label>SMAXSN-1</label>
|
||||
<description>Maximum withdrawn apparent power of the previous day</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccasn" typeId="powerType">
|
||||
<label>CCASN</label>
|
||||
<description>Active charge point N</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccasnMinus1" typeId="powerType">
|
||||
<label>CCASN-1</label>
|
||||
<description>Active charge point N-1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="umoy1" typeId="potentialType">
|
||||
<label>UMOY1</label>
|
||||
<description>Mean Voltage on phase 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="stge" typeId="stringType">
|
||||
<label>STGE</label>
|
||||
<description>Status registry</description>
|
||||
</channel>
|
||||
|
||||
<channel id="dpm1" typeId="stringType">
|
||||
<label>DPM1</label>
|
||||
<description>Start of mobile peak period 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="fpm1" typeId="stringType">
|
||||
<label>FPM1</label>
|
||||
<description>End of mobile peak period 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="dpm2" typeId="stringType">
|
||||
<label>DPM2</label>
|
||||
<description>Start of mobile peak period 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="fpm2" typeId="stringType">
|
||||
<label>FPM2</label>
|
||||
<description>End of mobile peak period 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="dpm3" typeId="stringType">
|
||||
<label>DPM3</label>
|
||||
<description>Start of mobile peak period 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="fpm3" typeId="stringType">
|
||||
<label>FPM3</label>
|
||||
<description>End of mobile peak period 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="msg1" typeId="stringType">
|
||||
<label>MSG1</label>
|
||||
<description>Short message</description>
|
||||
</channel>
|
||||
|
||||
<channel id="msg2" typeId="stringType">
|
||||
<label>MSG2</label>
|
||||
<description>Very short message</description>
|
||||
</channel>
|
||||
|
||||
<channel id="prm" typeId="stringType">
|
||||
<label>PRM</label>
|
||||
<description>PRM</description>
|
||||
</channel>
|
||||
|
||||
|
||||
<channel id="ntarf" typeId="stringType">
|
||||
<label>NTARF</label>
|
||||
<description>Index of current pricing</description>
|
||||
</channel>
|
||||
|
||||
<channel id="njourf" typeId="stringType">
|
||||
<label>NJOURF</label>
|
||||
<description>Number of current provider schedule</description>
|
||||
</channel>
|
||||
|
||||
<channel id="njourfPlus1" typeId="stringType">
|
||||
<label>NJOURF+1</label>
|
||||
<description>Number of next day provider schedule</description>
|
||||
</channel>
|
||||
|
||||
<channel id="pjourfPlus1" typeId="stringType">
|
||||
<label>PJOURF+1</label>
|
||||
<description>Profile of next day provider schedule</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ppointe" typeId="stringType">
|
||||
<label>PPOINTE</label>
|
||||
<description>Profile of next rush day</description>
|
||||
</channel>
|
||||
|
||||
<channel id="date" typeId="dateTimeType">
|
||||
<label>DATE</label>
|
||||
<description>Date and Time</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsnDate" typeId="dateTimeType">
|
||||
<label>SMAXSN TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsnMinus1Date" typeId="dateTimeType">
|
||||
<label>SMAXSN-1 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN-1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccasnDate" typeId="dateTimeType">
|
||||
<label>CCASN TIMESTAMP</label>
|
||||
<description>Timestamp of CCASN value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccasnMinus1Date" typeId="dateTimeType">
|
||||
<label>CCASN-1 TIMESTAMP</label>
|
||||
<description>Timestamp of CCASN-1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="umoy1Date" typeId="dateTimeType">
|
||||
<label>UMOY1 TIMESTAMP</label>
|
||||
<description>Timestamp of UMOY1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="dpm1Date" typeId="dateTimeType">
|
||||
<label>DPM1 TIMESTAMP</label>
|
||||
<description>Date of DPM1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="fpm1Date" typeId="dateTimeType">
|
||||
<label>FPM1 TIMESTAMP</label>
|
||||
<description>Date of FPM1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="dpm2Date" typeId="dateTimeType">
|
||||
<label>DPM2 TIMESTAMP</label>
|
||||
<description>Date of DPM2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="fpm2Date" typeId="dateTimeType">
|
||||
<label>FPM2 TIMESTAMP</label>
|
||||
<description>Date of FPM2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="dpm3Date" typeId="dateTimeType">
|
||||
<label>DPM3 TIMESTAMP</label>
|
||||
<description>Date of DPM3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="fpm3Date" typeId="dateTimeType">
|
||||
<label>FPM3 TIMESTAMP</label>
|
||||
<description>Date of FPM3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="relais1" typeId="switchType">
|
||||
<label>Relais 1</label>
|
||||
</channel>
|
||||
<channel id="relais2" typeId="switchType">
|
||||
<label>Relais 2</label>
|
||||
</channel>
|
||||
<channel id="relais3" typeId="switchType">
|
||||
<label>Relais 3</label>
|
||||
</channel>
|
||||
<channel id="relais4" typeId="switchType">
|
||||
<label>Relais 4</label>
|
||||
</channel>
|
||||
<channel id="relais5" typeId="switchType">
|
||||
<label>Relais 5</label>
|
||||
</channel>
|
||||
<channel id="relais6" typeId="switchType">
|
||||
<label>Relais 6</label>
|
||||
</channel>
|
||||
<channel id="relais7" typeId="switchType">
|
||||
<label>Relais 7</label>
|
||||
</channel>
|
||||
<channel id="relais8" typeId="switchType">
|
||||
<label>Relais 8</label>
|
||||
</channel>
|
||||
|
||||
</channels>
|
||||
|
||||
</channel-group-type>
|
||||
|
||||
<channel-type id="stringType">
|
||||
<item-type>String</item-type>
|
||||
<label>Teleinfo String Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%s" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="energyType">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Teleinfo Energy Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="currentType">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Teleinfo Current Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="potentialType">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>Teleinfo Potential Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="powerType">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Teleinfo Power Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="switchType">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Teleinfo Switch Type</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="dateTimeType">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Teleinfo DateTime Type</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS"/>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
|
@ -0,0 +1,133 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="teleinfo"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<channel-group-type id="producerLSMGroupType">
|
||||
<label>Producer</label>
|
||||
<description>Producer channels for Linky telemeter in standard teleinformation mode</description>
|
||||
<category>Energy</category>
|
||||
<channels>
|
||||
<channel id="eait" typeId="energyType">
|
||||
<label>EAIT</label>
|
||||
<description>Total active energy injected</description>
|
||||
</channel>
|
||||
|
||||
<channel id="erq1" typeId="energyType">
|
||||
<label>ERQ1</label>
|
||||
<description>Total reactive energy Q1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="erq2" typeId="energyType">
|
||||
<label>ERQ2</label>
|
||||
<description>Total reactive energy Q2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="erq3" typeId="energyType">
|
||||
<label>ERQ3</label>
|
||||
<description>Total reactive energy Q3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="erq4" typeId="energyType">
|
||||
<label>ERQ4</label>
|
||||
<description>Total reactive energy Q4</description>
|
||||
</channel>
|
||||
|
||||
<channel id="sinsti" typeId="powerType">
|
||||
<label>SINSTI</label>
|
||||
<description>Instantaneous injected apparent power</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxin" typeId="powerType">
|
||||
<label>SMAXIN</label>
|
||||
<description>Maximum injected apparent power of the day</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxinMinus1" typeId="powerType">
|
||||
<label>SMAXIN-1</label>
|
||||
<description>Maximum injected apparent power of the previous day</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccain" typeId="powerType">
|
||||
<label>CCAIN</label>
|
||||
<description>Injected active charge point N</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccainMinus1" typeId="powerType">
|
||||
<label>CCAIN-1</label>
|
||||
<description>Injected active charge point N-1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxinDate" typeId="dateTimeType">
|
||||
<label>SMAXIN TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXIN value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxinMinus1Date" typeId="dateTimeType">
|
||||
<label>SMAXIN-1 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXIN-1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccainDate" typeId="dateTimeType">
|
||||
<label>CCAIN TIMESTAMP</label>
|
||||
<description>Timestamp of CCAIN value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="ccainMinus1Date" typeId="dateTimeType">
|
||||
<label>CCAIN-1 TIMESTAMP</label>
|
||||
<description>Timestamp of CCAIN-1 value</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-type id="stringType">
|
||||
<item-type>String</item-type>
|
||||
<label>Teleinfo String Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%s" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="energyType">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Teleinfo Energy Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="currentType">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Teleinfo Current Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="potentialType">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>Teleinfo Potential Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="powerType">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Teleinfo Power Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="switchType">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Teleinfo Switch Type</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="dateTimeType">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Teleinfo DateTime Type</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS"/>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
|
@ -0,0 +1,179 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="teleinfo"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<channel-group-type id="threePhasedLSMGroupType">
|
||||
<label>Three-phase</label>
|
||||
<description>Three-phased channels for Linky telemeter in standard teleinformation mode</description>
|
||||
<category>Energy</category>
|
||||
<channels>
|
||||
|
||||
<channel id="irms2" typeId="currentType">
|
||||
<label>IRMS2</label>
|
||||
<description>RMS Current on phase 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="irms3" typeId="currentType">
|
||||
<label>IRMS3</label>
|
||||
<description>RMS Current on phase 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="urms2" typeId="potentialType">
|
||||
<label>URMS2</label>
|
||||
<description>RMS Voltage on phase 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="urms3" typeId="potentialType">
|
||||
<label>URMS3</label>
|
||||
<description>RMS Voltage on phase 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="sinsts1" typeId="powerType">
|
||||
<label>SINSTS1</label>
|
||||
<description>Instantaneous withdrawn apparent power on phase 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="sinsts2" typeId="powerType">
|
||||
<label>SINSTS2</label>
|
||||
<description>Instantaneous withdrawn apparent power on phase 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="sinsts3" typeId="powerType">
|
||||
<label>SINSTS3</label>
|
||||
<description>Instantaneous withdrawn apparent power on phase 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn1" typeId="powerType">
|
||||
<label>SMAXSN1</label>
|
||||
<description>Maximum withdrawn apparent power of the day on phase 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn2" typeId="powerType">
|
||||
<label>SMAXSN2</label>
|
||||
<description>Maximum withdrawn apparent power of the day on phase 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn3" typeId="powerType">
|
||||
<label>SMAXSN3</label>
|
||||
<description>Maximum withdrawn apparent power of the day on phase 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn1Minus1" typeId="powerType">
|
||||
<label>SMAXSN1-1</label>
|
||||
<description>Maximum withdrawn apparent power of the previous day on phase 1</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn2Minus1" typeId="powerType">
|
||||
<label>SMAXSN2-1</label>
|
||||
<description>Maximum withdrawn apparent power of the previous day on phase 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn3Minus1" typeId="powerType">
|
||||
<label>SMAXSN3-1</label>
|
||||
<description>Maximum withdrawn apparent power of the previous day on phase 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="umoy2" typeId="potentialType">
|
||||
<label>UMOY2</label>
|
||||
<description>Mean Voltage on phase 2</description>
|
||||
</channel>
|
||||
|
||||
<channel id="umoy3" typeId="potentialType">
|
||||
<label>UMOY3</label>
|
||||
<description>Mean Voltage on phase 3</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn1Date" typeId="dateTimeType">
|
||||
<label>SMAXSN1 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn2Date" typeId="dateTimeType">
|
||||
<label>SMAXSN2 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN2 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn3Date" typeId="dateTimeType">
|
||||
<label>SMAXSN3 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN3 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn1Minus1Date" typeId="dateTimeType">
|
||||
<label>SMAXSN1-1 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN1-1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn2Minus1Date" typeId="dateTimeType">
|
||||
<label>SMAXSN2-1 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN2-1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="smaxsn3Minus1Date" typeId="dateTimeType">
|
||||
<label>SMAXSN3-1 TIMESTAMP</label>
|
||||
<description>Timestamp of SMAXSN3-1 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="umoy2Date" typeId="dateTimeType">
|
||||
<label>UMOY2 TIMESTAMP</label>
|
||||
<description>Timestamp of UMOY2 value</description>
|
||||
</channel>
|
||||
|
||||
<channel id="umoy3Date" typeId="dateTimeType">
|
||||
<label>UMOY3 TIMESTAMP</label>
|
||||
<description>Timestamp of UMOY3 value</description>
|
||||
</channel>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-type id="stringType">
|
||||
<item-type>String</item-type>
|
||||
<label>Teleinfo String Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%s" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="energyType">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Teleinfo Energy Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="currentType">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Teleinfo Current Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="potentialType">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>Teleinfo Potential Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="powerType">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Teleinfo Power Type</label>
|
||||
<category>Energy</category>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="switchType">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Teleinfo Switch Type</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="dateTimeType">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Teleinfo DateTime Type</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS"/>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="teleinfo"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lsmm_electricitymeter" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="serialcontroller"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Linky Single-phase</label>
|
||||
<description>Single-phase Linky Electricity meter in standard mode</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="commonLSMGroup" typeId="commonLSMGroupType"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description-ref uri="thing-type:teleinfo:adco"/>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="teleinfo"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lsmm_prod_electricitymeter" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="serialcontroller"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Linky Single-phase Producer</label>
|
||||
<description>Single-phase producer Linky Electricity meter in standard mode</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="commonLSMGroup" typeId="commonLSMGroupType"/>
|
||||
<channel-group id="producerLSMGroup" typeId="producerLSMGroupType"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description-ref uri="thing-type:teleinfo:adco"/>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="teleinfo"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lsmt_electricitymeter" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="serialcontroller"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Linky Three-phase</label>
|
||||
<description>Three-phase Linky Electricity meter in standard mode</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="commonLSMGroup" typeId="commonLSMGroupType"/>
|
||||
<channel-group id="threePhasedLSMGroup" typeId="threePhasedLSMGroupType"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description-ref uri="thing-type:teleinfo:adco"/>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="teleinfo"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="lsmt_prod_electricitymeter" listed="false">
|
||||
<supported-bridge-type-refs>
|
||||
<bridge-type-ref id="serialcontroller"/>
|
||||
</supported-bridge-type-refs>
|
||||
|
||||
<label>Linky Three-phase Producer</label>
|
||||
<description>Three-phase producer Linky Electricity meter in standard mode</description>
|
||||
|
||||
<channel-groups>
|
||||
<channel-group id="commonLSMGroup" typeId="commonLSMGroupType"/>
|
||||
<channel-group id="producerLSMGroup" typeId="producerLSMGroupType"/>
|
||||
<channel-group id="threePhasedLSMGroup" typeId="threePhasedLSMGroupType"/>
|
||||
</channel-groups>
|
||||
|
||||
<config-description-ref uri="thing-type:teleinfo:adco"/>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</thing:thing-descriptions>
|
|
@ -19,6 +19,22 @@
|
|||
<description>Serial port of Teleinfo device (e.g.: /dev/ttyUSB0 on Linux, COM1 on Windows)</description>
|
||||
<limitToOptions>false</limitToOptions>
|
||||
</parameter>
|
||||
<parameter name="ticMode" type="text" required="true">
|
||||
<label>TIC mode</label>
|
||||
<description>TIC Mode of the telemeter (Standard TIC mode is only available on Linky telemeters)</description>
|
||||
<default>HISTORICAL</default>
|
||||
<options>
|
||||
<option value="HISTORICAL">Historical</option>
|
||||
<option value="STANDARD">Standard</option>
|
||||
</options>
|
||||
<limitToOptions>true</limitToOptions>
|
||||
</parameter>
|
||||
<parameter name="verifyChecksum" type="boolean" required="true">
|
||||
<label>Checksum Verification</label>
|
||||
<description>Activate checksum verification</description>
|
||||
<default>true</default>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
<parameter name="autoRepairInvalidADPSgroupLine" type="boolean" required="false">
|
||||
<label>Auto Repair Malformed ADPS Data</label>
|
||||
<description>Try to auto repair malformed ADPS data from hardware issues (e.g: "ADPS032" instead of "ADPS 032"
|
||||
|
|
|
@ -15,13 +15,17 @@ package org.openhab.binding.teleinfo.internal.reader.io;
|
|||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.time.Month;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.teleinfo.internal.TeleinfoBindingConstants;
|
||||
import org.openhab.binding.teleinfo.internal.data.Frame;
|
||||
import org.openhab.binding.teleinfo.internal.data.FrameType;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.serialport.Label;
|
||||
import org.openhab.binding.teleinfo.internal.serial.TeleinfoTicMode;
|
||||
import org.openhab.binding.teleinfo.util.TestUtils;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -33,7 +37,8 @@ public class TeleinfoInputStreamTest {
|
|||
@Test
|
||||
public void testReadNextFrameCbetmBase1() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("cbetm-base-option-1.raw")), false)) {
|
||||
new FileInputStream(TestUtils.getTestFile("cbetm-base-option-1.raw")), false,
|
||||
TeleinfoTicMode.HISTORICAL)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
|
||||
assertNotNull(frame);
|
||||
|
@ -57,7 +62,8 @@ public class TeleinfoInputStreamTest {
|
|||
@Test
|
||||
public void testReadNextFrameCbemmEvoIccHc1() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("cbemm-evo-icc-hc-option-1.raw")), false)) {
|
||||
new FileInputStream(TestUtils.getTestFile("cbemm-evo-icc-hc-option-1.raw")), false,
|
||||
TeleinfoTicMode.HISTORICAL)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
|
||||
assertNotNull(frame);
|
||||
|
@ -78,7 +84,8 @@ public class TeleinfoInputStreamTest {
|
|||
@Test
|
||||
public void testReadNextFrameCbetmEjp1() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("cbetm-ejp-option-1.raw")), false)) {
|
||||
new FileInputStream(TestUtils.getTestFile("cbetm-ejp-option-1.raw")), false,
|
||||
TeleinfoTicMode.HISTORICAL)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
|
||||
assertNotNull(frame);
|
||||
|
@ -104,7 +111,8 @@ public class TeleinfoInputStreamTest {
|
|||
@Test
|
||||
public void testReadNextFrameCbemmEvoIccTempo1() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("cbemm-evo-icc-tempo-option-1.raw")), false)) {
|
||||
new FileInputStream(TestUtils.getTestFile("cbemm-evo-icc-tempo-option-1.raw")), false,
|
||||
TeleinfoTicMode.HISTORICAL)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
|
||||
assertNotNull(frame);
|
||||
|
@ -133,7 +141,8 @@ public class TeleinfoInputStreamTest {
|
|||
@Test
|
||||
public void testReadNextFrameCbemmEvoIccBase1() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("cbemm-evo-icc-base-option-1.raw")), false)) {
|
||||
new FileInputStream(TestUtils.getTestFile("cbemm-evo-icc-base-option-1.raw")), false,
|
||||
TeleinfoTicMode.HISTORICAL)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
assertNotNull(frame);
|
||||
assertEquals(FrameType.CBEMM_ICC_BASE, frame.getType());
|
||||
|
@ -151,7 +160,8 @@ public class TeleinfoInputStreamTest {
|
|||
@Test
|
||||
public void testInvalidADPSgrouplineWithAutoRepairActivated() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("invalid-adps-groupline.raw")), true)) {
|
||||
new FileInputStream(TestUtils.getTestFile("invalid-adps-groupline.raw")), true,
|
||||
TeleinfoTicMode.HISTORICAL)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
|
||||
assertNotNull(frame);
|
||||
|
@ -159,4 +169,60 @@ public class TeleinfoInputStreamTest {
|
|||
assertEquals(37, frame.getAsInt(Label.ADPS));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadNextFrameLinkyTICModeStandardThreePhaseProd() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("linky-tic-mode-standard-three-phase-prod.raw")), false,
|
||||
TeleinfoTicMode.STANDARD, true)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
assertNotNull(frame);
|
||||
assertEquals(FrameType.LSMT_PROD, frame.getType());
|
||||
assertEquals("123456789012", frame.get(Label.ADSC));
|
||||
assertEquals("02", frame.get(Label.VTIC));
|
||||
assertEquals("", frame.get(Label.DATE));
|
||||
assertEquals(" TEMPO ", frame.get(Label.NGTF));
|
||||
assertEquals(" HP BLEU ", frame.get(Label.LTARF));
|
||||
assertEquals(11604109, frame.getAsInt(Label.EAST));
|
||||
assertEquals(2741488, frame.getAsInt(Label.EASF01));
|
||||
assertEquals(18, frame.getAsInt(Label.PCOUP));
|
||||
assertEquals("2021-04-14T08:26:25", frame.getAsDateTime(Label.DATE));
|
||||
DateTimeType dateTime = DateTimeType.valueOf(frame.getAsDateTime(Label.DATE));
|
||||
assertEquals(2021, dateTime.getZonedDateTime().getYear());
|
||||
assertEquals(Month.APRIL, dateTime.getZonedDateTime().getMonth());
|
||||
assertEquals(14, dateTime.getZonedDateTime().getDayOfMonth());
|
||||
assertEquals(8, dateTime.getZonedDateTime().getHour());
|
||||
assertEquals(26, dateTime.getZonedDateTime().getMinute());
|
||||
assertEquals(25, dateTime.getZonedDateTime().getSecond());
|
||||
|
||||
assertNotEquals(TeleinfoBindingConstants.NOT_A_CHANNEL, Label.CCASN.getTimestampChannelName());
|
||||
assertEquals("2021-04-14T08:00:00", frame.getAsDateTime(Label.CCASN));
|
||||
dateTime = DateTimeType.valueOf(frame.getAsDateTime(Label.CCASN));
|
||||
assertEquals(2021, dateTime.getZonedDateTime().getYear());
|
||||
assertEquals(Month.APRIL, dateTime.getZonedDateTime().getMonth());
|
||||
assertEquals(14, dateTime.getZonedDateTime().getDayOfMonth());
|
||||
assertEquals(8, dateTime.getZonedDateTime().getHour());
|
||||
assertEquals(0, dateTime.getZonedDateTime().getMinute());
|
||||
assertEquals(0, dateTime.getZonedDateTime().getSecond());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadNextFrameLinkyTICModeStandardSinglePhaseProd() throws Exception {
|
||||
try (TeleinfoInputStream in = new TeleinfoInputStream(
|
||||
new FileInputStream(TestUtils.getTestFile("linky-tic-mode-standard-single-phase-prod.raw")),
|
||||
TeleinfoTicMode.STANDARD, true)) {
|
||||
Frame frame = in.readNextFrame();
|
||||
assertNotNull(frame);
|
||||
assertEquals(FrameType.LSMM_PROD, frame.getType());
|
||||
assertEquals("123456789012", frame.get(Label.ADSC));
|
||||
assertEquals("02", frame.get(Label.VTIC));
|
||||
assertEquals("", frame.get(Label.DATE));
|
||||
assertEquals("PRODUCTEUR", frame.get(Label.NGTF));
|
||||
assertEquals("INDEX NON CONSO ", frame.get(Label.LTARF));
|
||||
assertEquals(0, frame.getAsInt(Label.EAST));
|
||||
assertEquals(0, frame.getAsInt(Label.EASF01));
|
||||
assertEquals(32781, frame.getAsInt(Label.EAIT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.teleinfo.internal.reader.io.serialport;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.teleinfo.internal.reader.io.TeleinfoInputStream;
|
||||
import org.openhab.binding.teleinfo.internal.serial.TeleinfoTicMode;
|
||||
import org.openhab.binding.teleinfo.util.TestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Olivier MARCEAU - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class FrameUtilTest {
|
||||
|
||||
@Test
|
||||
public void testComputeGroupLineChecksumThreePhaseProd() throws Exception {
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(TestUtils.getTestFile("linky-tic-mode-standard-three-phase-prod.raw"))));
|
||||
String groupLine;
|
||||
int i = 0;
|
||||
while ((groupLine = bufferedReader.readLine()) != null) {
|
||||
if (i >= 1 && !TeleinfoInputStream.isHeaderFrame(groupLine)) {
|
||||
char expected = groupLine.charAt(groupLine.length() - 1);
|
||||
char actual = FrameUtil.computeGroupLineChecksum(groupLine.substring(0, groupLine.length() - 2),
|
||||
TeleinfoTicMode.STANDARD);
|
||||
assertEquals(expected, actual, i + " " + groupLine + " " + (int) expected + " " + (int) actual);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeGroupLineChecksumSinglePhaseProd() throws Exception {
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
|
||||
new FileInputStream(TestUtils.getTestFile("linky-tic-mode-standard-single-phase-prod.raw"))));
|
||||
String groupLine;
|
||||
int i = 0;
|
||||
while ((groupLine = bufferedReader.readLine()) != null) {
|
||||
if (i >= 1 && !TeleinfoInputStream.isHeaderFrame(groupLine)) {
|
||||
char expected = groupLine.charAt(groupLine.length() - 1);
|
||||
char actual = FrameUtil.computeGroupLineChecksum(groupLine.substring(0, groupLine.length() - 2),
|
||||
TeleinfoTicMode.STANDARD);
|
||||
assertEquals(expected, actual, i + " " + groupLine + " " + (int) expected + " " + (int) actual);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComputeRelaisStates() {
|
||||
assertArrayEquals(new boolean[] { true, false, false, false, false, false, false, false },
|
||||
FrameUtil.parseRelaisStates("001"));
|
||||
assertArrayEquals(new boolean[] { false, false, true, true, false, false, false, true },
|
||||
FrameUtil.parseRelaisStates("140"));
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -14,6 +14,6 @@ IMAX3 027 ;
|
|||
PMAX 07990 ?
|
||||
PAPP 00540 *
|
||||
MOTDETAT 400000 F
|
||||
PPOT 00 #
|
||||
PPOT 00 #
|
||||
|
||||
ADCO XXXXXXXXXXXX 7
|
|
@ -15,6 +15,6 @@ IMAX3 044 :
|
|||
PMAX 17480 :
|
||||
PAPP 05800 .
|
||||
MOTDETAT 000000 B
|
||||
PPOT 00 #
|
||||
PPOT 00 #
|
||||
|
||||
ADCO XXXXXXXXXX G
|
|
@ -0,0 +1,70 @@
|
|||
EP*PREF 03 B
|
||||
PCOUP 03 \
|
||||
SINSTS 00000 F
|
||||
SMAXSN E180716063417 00021 9
|
||||
SMAXSN-1 E180715064903 00023 Y
|
||||
SINSTI 01258 L
|
||||
SMAXIN E180716103316 01423 /
|
||||
SMAXIN-1 E180715144229 01971 \
|
||||
CCASN E180716100000 00000 0
|
||||
CCASN-1 E180716090000 00000 V
|
||||
UMOY1 E180716103000 230 +
|
||||
STGE 002A0301 <
|
||||
MSG1 PAS DE MESSAGE <
|
||||
PRM 12345678901234 8
|
||||
RELAIS 000 B
|
||||
NTARF 01 N
|
||||
NJOURF 00 &
|
||||
NJOURF+1 00 B
|
||||
PJOURF+1 00008001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE 9
|
||||
|
||||
ADSC 123456789012 =
|
||||
VTIC 02 J
|
||||
DATE E180716103423 B
|
||||
NGTF PRODUCTEUR .
|
||||
LTARF INDEX NON CONSO 0
|
||||
EAST 000000000 O
|
||||
EASF01 000000000 "
|
||||
EASF02 000000000 #
|
||||
EASF03 000000000 $
|
||||
EASF04 000000000 %
|
||||
EASF05 000000000 &
|
||||
EASF06 000000000 '
|
||||
EASF07 000000000 (
|
||||
EASF08 000000000 )
|
||||
EASF09 000000000 *
|
||||
EASF10 000000000 "
|
||||
EASD01 000000000
|
||||
EASD02 000000000 !
|
||||
EASD03 000000000 "
|
||||
EASD04 000000000 #
|
||||
EAIT 000032781 Z
|
||||
ERQ1 000000000 ;
|
||||
ERQ2 000000890 M
|
||||
ERQ3 000002546 N
|
||||
ERQ4 000000000 >
|
||||
IRMS1 005 3
|
||||
URMS1 228 F
|
||||
PREF 03 B
|
||||
PCOUP 03 \
|
||||
SINSTS 00000 F
|
||||
SMAXSN E180716063417 00021 9
|
||||
SMAXSN-1 E180715064903 00023 Y
|
||||
SINSTI 01253 G
|
||||
SMAXIN E180716103316 01423 /
|
||||
SMAXIN-1 E180715144229 01971 \
|
||||
CCASN E180716100000 00000 0
|
||||
CCASN-1 E180716090000 00000 V
|
||||
UMOY1 E180716103000 230 +
|
||||
STGE 002A0301 <
|
||||
MSG1 PAS DE MESSAGE <
|
||||
PRM 12345678901234 8
|
||||
RELAIS 000 B
|
||||
NTARF 01 N
|
||||
NJOURF 00 &
|
||||
NJOURF+1 00 B
|
||||
PJOURF+1 00008001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE 9
|
||||
|
||||
ADSC 123456789012 =
|
||||
VTIC 02 J
|
||||
DATE E180716103424 C
|
|
@ -0,0 +1,171 @@
|
|||
774332 X
|
||||
IRMS1 001 /
|
||||
IRMS2 002 1
|
||||
IRMS3 001 1
|
||||
URMS1 234 C
|
||||
URMS2 240 A
|
||||
URMS3 242 D
|
||||
PREF 18 H
|
||||
PCOUP 18 "
|
||||
SINSTS 00046 P
|
||||
SINSTS1 00000 7
|
||||
SINSTS2 00531 A
|
||||
SINSTS3 00000 9
|
||||
SMAXSN E210414070239 02636 <
|
||||
SMAXSN1 E210414060632 00405 !
|
||||
SMAXSN2 E210414070239 02194 -
|
||||
SMAXSN3 E210414054725 00565 0
|
||||
SMAXSN-1 E210413195606 06560 _
|
||||
SMAXSN1-1 E210413111148 01084 A
|
||||
SMAXSN2-1 E210413195606 03275 Q
|
||||
SMAXSN3-1 E210413195814 02904 Q
|
||||
SINSTI 00000 <
|
||||
SMAXIN E210414000000 00000 L
|
||||
SMAXIN-1 E210413141848 03861 U
|
||||
CCASN E210414080000 00806 :
|
||||
CCASN-1 E210414073000 01152 U
|
||||
CCAIN E210414080000 00000 "
|
||||
CCAIN-1 E210414073000 00000 B
|
||||
UMOY1 E210414082000 230 &
|
||||
UMOY2 E210414082000 239 0
|
||||
UMOY3 E210414082000 243 ,
|
||||
STGE 013A0501 @
|
||||
MSG1 PAS DE MESSAGE <
|
||||
PRM 12345678901234 8
|
||||
RELAIS 000 B
|
||||
NTARF 02 O
|
||||
NJOURF 00 &
|
||||
NJOURF+1 00 B
|
||||
PJOURF+1 00004001 06004002 22004001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE .
|
||||
|
||||
ADSC 123456789012 =
|
||||
VTIC 02 J
|
||||
DATE E210414082625 A
|
||||
NGTF TEMPO F
|
||||
LTARF HP BLEU +
|
||||
EAST 011604109 %
|
||||
EASF01 002741488 D
|
||||
EASF02 005905500 ;
|
||||
EASF03 000624053 8
|
||||
EASF04 001070566 >
|
||||
EASF05 000524151 8
|
||||
EASF06 000738351 B
|
||||
EASF07 000000000 (
|
||||
EASF08 000000000 )
|
||||
EASF09 000000000 *
|
||||
EASF10 000000000 "
|
||||
EASD01 011604109 6
|
||||
EASD02 000000000 !
|
||||
EASD03 000000000 "
|
||||
EASD04 000000000 #
|
||||
EAIT 000671631 ]
|
||||
ERQ1 002970842 [
|
||||
ERQ2 000204084 N
|
||||
ERQ3 000084948 ^
|
||||
ERQ4 000774332 X
|
||||
IRMS1 001 /
|
||||
IRMS2 002 1
|
||||
IRMS3 001 1
|
||||
URMS1 234 C
|
||||
URMS2 240 A
|
||||
URMS3 242 D
|
||||
PREF 18 H
|
||||
PCOUP 18 "
|
||||
SINSTS 00013 J
|
||||
SINSTS1 00000 7
|
||||
SINSTS2 00568 K
|
||||
SINSTS3 00000 9
|
||||
SMAXSN E210414070239 02636 <
|
||||
SMAXSN1 E210414060632 00405 !
|
||||
SMAXSN2 E210414070239 02194 -
|
||||
SMAXSN3 E210414054725 00565 0
|
||||
SMAXSN-1 E210413195606 06560 _
|
||||
SMAXSN1-1 E210413111148 01084 A
|
||||
SMAXSN2-1 E210413195606 03275 Q
|
||||
SMAXSN3-1 E210413195814 02904 Q
|
||||
SINSTI 00000 <
|
||||
SMAXIN E210414000000 00000 L
|
||||
SMAXIN-1 E210413141848 03861 U
|
||||
CCASN E210414080000 00806 :
|
||||
CCASN-1 E210414073000 01152 U
|
||||
CCAIN E210414080000 00000 "
|
||||
CCAIN-1 E210414073000 00000 B
|
||||
UMOY1 E210414082000 230 &
|
||||
UMOY2 E210414082000 239 0
|
||||
UMOY3 E210414082000 243 ,
|
||||
STGE 013A0501 @
|
||||
MSG1 PAS DE MESSAGE <
|
||||
PRM 12345678901234 8
|
||||
RELAIS 000 B
|
||||
NTARF 02 O
|
||||
NJOURF 00 &
|
||||
NJOURF+1 00 B
|
||||
PJOURF+1 00004001 06004002 22004001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE .
|
||||
|
||||
ADSC 123456789012 =
|
||||
VTIC 02 J
|
||||
DATE E210414082627 C
|
||||
NGTF TEMPO F
|
||||
LTARF HP BLEU +
|
||||
EAST 011604109 %
|
||||
EASF01 002741488 D
|
||||
EASF02 005905500 ;
|
||||
EASF03 000624053 8
|
||||
EASF04 001070566 >
|
||||
EASF05 000524151 8
|
||||
EASF06 000738351 B
|
||||
EASF07 000000000 (
|
||||
EASF08 000000000 )
|
||||
EASF09 000000000 *
|
||||
EASF10 000000000 "
|
||||
EASD01 011604109 6
|
||||
EASD02 000000000 !
|
||||
EASD03 000000000 "
|
||||
EASD04 000000000 #
|
||||
EAIT 000671631 ]
|
||||
ERQ1 002970842 [
|
||||
ERQ2 000204084 N
|
||||
ERQ3 000084948 ^
|
||||
ERQ4 000774332 X
|
||||
IRMS1 001 /
|
||||
IRMS2 002 1
|
||||
IRMS3 001 1
|
||||
URMS1 234 C
|
||||
URMS2 240 A
|
||||
URMS3 242 D
|
||||
PREF 18 H
|
||||
PCOUP 18 "
|
||||
SINSTS 00018 O
|
||||
SINSTS1 00000 7
|
||||
SINSTS2 00565 H
|
||||
SINSTS3 00000 9
|
||||
SMAXSN E210414070239 02636 <
|
||||
SMAXSN1 E210414060632 00405 !
|
||||
SMAXSN2 E210414070239 02194 -
|
||||
SMAXSN3 E210414054725 00565 0
|
||||
SMAXSN-1 E210413195606 06560 _
|
||||
SMAXSN1-1 E210413111148 01084 A
|
||||
SMAXSN2-1 E210413195606 03275 Q
|
||||
SMAXSN3-1 E210413195814 02904 Q
|
||||
SINSTI 00000 <
|
||||
SMAXIN E210414000000 00000 L
|
||||
SMAXIN-1 E210413141848 03861 U
|
||||
CCASN E210414080000 00806 :
|
||||
CCASN-1 E210414073000 01152 U
|
||||
CCAIN E210414080000 00000 "
|
||||
CCAIN-1 E210414073000 00000 B
|
||||
UMOY1 E210414082000 230 &
|
||||
UMOY2 E210414082000 239 0
|
||||
UMOY3 E210414082000 243 ,
|
||||
STGE 013A0501 @
|
||||
MSG1 PAS DE MESSAGE <
|
||||
PRM 12345678901234 8
|
||||
RELAIS 000 B
|
||||
NTARF 02 O
|
||||
NJOURF 00 &
|
||||
NJOURF+1 00 B
|
||||
PJOURF+1 00004001 06004002 22004001 NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE NONUTILE .
|
||||
|
||||
ADSC 123456789012 =
|
||||
VTIC 02 J
|
||||
DATE E210414082629 E
|
Loading…
Reference in New Issue