##############################################################################
#
# 72_TA_CMI_JSON.pm
#
# This file is part of Fhem.
#
# Fhem is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Fhem is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fhem. If not, see .
#
##############################################################################
#
# TA_CMI_JSON (c) Martin Gutenbrunner / https://github.com/delmar43/FHEM
#
# This module queries the CMI JSON API and allows to map values to readings.
# Supported devices are UVR1611, UVR16x2, RSM610, CAN-I/O45, CAN-EZ2, CAN-MTx2,
# and CAN-BC2 by Technische Alternative https://www.ta.co.at/
#
# Information in the Wiki: https://wiki.fhem.de/wiki/TA_CMI_UVR16x2_UVR1611
#
# Discussed in FHEM Forum:
# * https://forum.fhem.de/index.php/topic,92740.0.html (official)
# * https://forum.fhem.de/index.php/topic,41439.0.html (previous discussions)
# * https://forum.fhem.de/index.php/topic,13534.45.html (previous discussions)
#
# $Id$
#
##############################################################################
package main;
use strict;
use warnings;
sub TA_CMI_JSON_Initialize {
my ($hash) = @_;
$hash->{SetFn} = "TA_CMI_JSON::Set";
$hash->{GetFn} = "TA_CMI_JSON::Get";
$hash->{DefFn} = "TA_CMI_JSON::Define";
$hash->{UndefFn} = "TA_CMI_JSON::Undef";
$hash->{NotifyFn} = "TA_CMI_JSON::Notify";
# $hash->{FW_detailFn} = "TA_CMI_JSON::DetailFn";
# $hash->{FW_directNotify} = "TA_CMI_JSON::DirectNotify";
$hash->{AttrList} = "username password outputStatesInterval interval readingNamesInputs:textField-long ".
"readingNamesOutputs:textField-long readingNamesDL-Bus:textField-long ".
"readingNamesLoggingAnalog:textField-long readingNamesLoggingDigital:textField-long ".
"includePrettyReadings:0,1 includeUnitReadings:0,1 prettyOutputStates:0,1 setList:textField-long ".
$readingFnAttributes;
Log3 '', 3, "TA_CMI_JSON - Initialize done ...";
}
package TA_CMI_JSON;
use strict;
use warnings;
use HttpUtils;
use GPUtils qw(:all);
my %deviceNames = (
'80' => 'UVR1611',
'87' => 'UVR16x2',
'88' => 'RSM610',
'89' => 'CAN-I/O45',
'8B' => 'CAN-EZ2',
'8C' => 'CAN-MTx2',
'8D' => 'CAN-BC2',
'8E' => 'UVR65',
'8F' => 'CAN-EZ3',
'91' => 'UVR610',
'92' => 'UVR67',
'A3' => 'BL_NET'
);
my %versions = (
1 => '1.25.2 2016-12-12',
2 => '1.26.1 2017-02-24',
3 => '1.28.0 2017-11-09',
4 => '1.34.2 2019-04-04',
5 => '1.35.1 2019-07-02',
6 => '1.38.1 2021-02-04'
);
my %units = (
0 => '', 1 => '°C', 2 => 'W/m²', 3 => 'l/h', 4 => 'Sek', 5 => 'Min', 6 => 'l/Imp',
7 => 'K', 8 => '%', 10 => 'kW', 11 => 'kWh', 12 => 'MWh', 13 => 'V', 14 => 'mA',
15 => 'Std', 16 => 'Tage', 17 => 'Imp', 18 => 'kΩ', 19 => 'l', 20 => 'km/h',
21 => 'Hz', 22 => 'l/min', 23 => 'bar', 24 => '', 25 => 'km', 26 => 'm', 27 => 'mm',
28 => 'm³', 35 => 'l/d', 36 => 'm/s', 37 => 'm³/min', 38 => 'm³/h', 39 => 'm³/d',
40 => 'mm/min', 41 => 'mm/h', 42 => 'mm/d', 43 => 'Aus/Ein', 44 => 'Nein/Ja',
46 => '°C', 50 => '€', 51 => '$', 52 => 'g/m³', 53 => '', 54 => '°', 56 => '°',
57 => 'Sek', 58 => '', 59 => '%', 60 => 'Uhr', 63 => 'A', 65 => 'mbar', 66 => 'Pa',
67 => 'ppm'
);
my %rasStates = (
0 => 'Time/auto',
1 => 'Standard',
2 => 'Setback',
3 => 'Standby/frost pr.'
);
my %outputStates = (
0 => 'n/a',
1 => 'Auto-Off',
3 => 'Auto-On',
5 => 'Manual-Off',
7 => 'Manual-On'
);
my %fixwertTypes = (
'fixwertAnalog' => 'D1',
'fixwertDigital' => '11',
'fixwertImpuls' => '1f'
);
## Import der FHEM Funktionen
BEGIN {
GP_Import(qw(
readingsSingleUpdate
readingsBulkUpdate
readingsBulkUpdateIfChanged
readingsBeginUpdate
readingsEndUpdate
readingsDelete
Log3
HttpUtils_Close
HttpUtils_NonblockingGet
RemoveInternalTimer
InternalTimer
makeReadingName
AttrVal
json2nameValue
gettimeofday
))
};
sub Define($$) {
my ( $hash, $def ) = @_;
my @a = split( "[ \t][ \t]*", $def );
my $name = $a[0];
my $module = $a[1];
my $cmiUrl = $a[2];
my $nodeId = $a[3];
my $queryParams = $a[4];
if(@a != 4 && @a != 5) {
my $msg = "TA_CMI_JSON ($name) - Wrong syntax: define TA_CMI_JSON CMI-URL CAN-Node-ID ";
Log3 $name, 0, $msg;
return $msg;
}
$hash->{NAME} = $name;
$hash->{CMIURL} = $cmiUrl;
$hash->{NODEID} = $nodeId;
$hash->{QUERYPARAM} = $queryParams;
my $hexNodeId = sprintf('%1x',$nodeId);
$hexNodeId = "0$hexNodeId" unless length($hexNodeId) == 2;
$hash->{NODEID_HEX} = $hexNodeId;
Log3 $name, 3, "TA_CMI_JSON ($name) - Define ... module=$module, CMI-URL=$cmiUrl, nodeId=$nodeId";
readingsSingleUpdate($hash, 'state', 'defined', 1);
SetupIntervals($hash) if ($main::init_done);
return undef;
}
sub Notify($$) {
my ($own_hash, $dev_hash) = @_;
my $ownName = $own_hash->{NAME}; # own name / hash
return "" if(main::IsDisabled($ownName)); # Return without any further action if the module is disabled
my $devName = $dev_hash->{NAME}; # Device that created the events
my $events = main::deviceEvents($dev_hash, 1);
if($devName eq "global" && grep(m/^INITIALIZED|REREADCFG$/, @{$events})) {
SetupIntervals($own_hash);
}
}
sub SetupIntervals($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $queryParams = $hash->{QUERYPARAM};
if ( defined $queryParams ) {
$hash->{INTERVAL} = AttrVal( $name, "interval", "60" );
Log3 $name, 3, "TA_CMI_JSON ($name) - queryParam interval: ".$hash->{INTERVAL};
Log3 $name, 3, "TA_CMI_JSON ($name) - queryParams=$queryParams";
}
#make initial call in any case, even if queryParams not defined. because that brings us model and number of outputs
GetStatus( $hash );
my $outputStatesInterval = AttrVal( $name, 'outputStatesInterval', undef);
if ( defined $outputStatesInterval ) {
Log3 $name, 3, "TA_CMI_JSON ($name) - Define::outputStatesInterval: $outputStatesInterval";
RequestOutputStates ( $hash );
}
}
sub GetStatus($) {
my ( $hash ) = @_;
my $name = $hash->{NAME};
PerformHttpRequest($hash);
}
sub Undef($$) {
my ($hash, $arg) = @_;
my $name = $hash->{NAME};
HttpUtils_Close($hash);
RemoveInternalTimer($hash);
return undef;
}
sub PerformHttpRequest($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $queryParam = $hash->{QUERYPARAM};
$queryParam = '' unless defined $queryParam;
my $url = "http://$hash->{CMIURL}/INCLUDE/api.cgi?jsonnode=$hash->{NODEID}&jsonparam=$queryParam"."&_=".gettimeofday();
my $username = AttrVal($name, 'username', 'admin');
my $password = AttrVal($name, 'password', 'admin');
my $param = {
url => "$url",
timeout => 5,
hash => $hash,
method => "GET",
header => "User-Agent: FHEM\r\nAccept: application/json",
user => $username,
pwd => $password,
callback => \&ParseHttpResponse
};
Log3 $name, 4, "TA_CMI_JSON ($name) - PerformHttpRequest $url";
HttpUtils_NonblockingGet($param);
}
sub ParseHttpResponse($$$) {
my ($param, $err, $data) = @_;
my $hash = $param->{hash};
my $name = $hash->{NAME};
my $return;
if($err ne "") {
Log3 $name, 0, "TA_CMI_JSON ($name) - error while requesting ".$param->{url}." - $err";
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, 'state', 'ERROR', 1);
readingsBulkUpdate($hash, 'error', $err, 1);
readingsEndUpdate($hash, 1);
} elsif($data ne "") {
my $keyValues = json2nameValue($data);
my $j2nvErr = $keyValues->{json2nameValueErrorText};
if (defined $j2nvErr) {
Log3 $name, 1, "TA_CMI_JSON ($name) - JSON problem: $j2nvErr. Skipping. Can be ignored if not occurring too often.";
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, 'state', 'ERROR', 0);
readingsBulkUpdate($hash, 'error', $j2nvErr, 0);
readingsEndUpdate($hash, 1);
return undef;
}
my $canDevice = extractDeviceName($keyValues->{Header_Device});
$hash->{CAN_DEVICE} = $canDevice;
$hash->{model} = $canDevice;
$hash->{CMI_API_VERSION} = extractVersion($keyValues->{Header_Version});
readingsDelete($hash, "error");
readingsDelete($hash, "state");
readingsBeginUpdate($hash);
readingsBulkUpdateIfChanged($hash, 'state', $keyValues->{Status}, 1);
if ( $keyValues->{Status} eq 'OK' ) {
my $queryParams = $hash->{QUERYPARAM};
$queryParams = '' unless defined $queryParams;
extractReadings($hash, $keyValues, 'Inputs', 'Inputs') if ($queryParams =~ /I/);
extractReadings($hash, $keyValues, 'Outputs', 'Outputs') if ($queryParams =~ /O/);
if ($queryParams =~ /D/) {
if ($canDevice eq 'UVR16x2' or $canDevice eq 'RSM610' ) {
extractReadings($hash, $keyValues, 'DL-Bus', 'DL-Bus');
} else {
Log3 $name, 1, "TA_CMI_JSON ($name) - Reading DL-Bus input is not supported on $canDevice";
}
}
if ($queryParams =~ /La/) {
if ($canDevice eq 'UVR16x2') {
extractReadings($hash, $keyValues, 'LoggingAnalog', 'Logging_Analog');
} else {
Log3 $name, 1, "TA_CMI_JSON ($name) - Reading Logging Analog data is not supported on $canDevice";
}
}
if ($queryParams =~ /Ld/) {
if ($canDevice eq 'UVR16x2') {
extractReadings($hash, $keyValues, 'LoggingDigital', 'Logging_Digital');
} else {
Log3 $name, 1, "TA_CMI_JSON ($name) - Reading Logging Digital data is not supported on $canDevice";
}
}
}
readingsEndUpdate($hash, 1);
# Log3 $name, 3, "TA_CMI_JSON ($name) - Device: $keyValues->{Header_Device}";
}
if ( defined $hash->{QUERYPARAM} ) {
my $functionName = "TA_CMI_JSON::GetStatus";
RemoveInternalTimer($hash, $functionName);
InternalTimer( gettimeofday() + $hash->{INTERVAL}, $functionName, $hash, 0 );
}
return undef;
}
sub extractDeviceName($) {
my ($input) = @_;
return (defined($deviceNames{$input}) ? $deviceNames{$input} : 'unknown: ' . $input);
}
sub extractVersion($) {
my ($input) = @_;
return (defined($versions{$input}) ? $versions{$input} : 'unknown: ' . $input);
}
sub extractReadings($$$$) {
my ( $hash, $keyValues, $id, $dataKey ) = @_;
my $name = $hash->{NAME};
my $readingNames = AttrVal($name, "readingNames$id", '');
Log3 $name, 5, 'readingNames'.$id.": $readingNames";
my @readingsArray = split(/ /, $readingNames); #1:T.Kollektor 5:T.Vorlauf
my $inclUnitReadings = AttrVal( $name, "includeUnitReadings", 0 );
my $inclPrettyReadings = AttrVal( $name, "includePrettyReadings", 0 );
for my $i (0 .. (@readingsArray-1)) {
my ( $idx, $readingName ) = split(/\:/, $readingsArray[$i]);
$readingName = makeReadingName($readingName);
my $jsonKey = 'Data_'.$dataKey.'_'.$idx.'_Value_Value';
my $readingValue = $keyValues->{$jsonKey};
Log3 $name, 5, "TA_CMI_JSON ($name) - readingName: $readingName, key: $jsonKey, value: $readingValue";
readingsBulkUpdateIfChanged($hash, $readingName, $readingValue, 1);
$jsonKey = 'Data_'.$dataKey.'_'.$idx.'_Value_RAS';
my $readingRas = $keyValues->{$jsonKey};
if (defined($readingRas)) {
readingsBulkUpdateIfChanged($hash, $readingName . '_RAS', $readingRas, 1);
if ($inclPrettyReadings) {
my $ras = (defined($rasStates{$readingRas}) ? $rasStates{$readingRas} : undef);
readingsBulkUpdateIfChanged($hash, $readingName . '_RAS_Pretty', $ras, 1) if ($ras);
}
}
my $unit;
if ($inclUnitReadings || $inclPrettyReadings) {
$jsonKey = 'Data_'.$dataKey.'_'.$idx.'_Value_Unit';
my $readingUnit = $keyValues->{$jsonKey};
$unit = (defined($units{$readingUnit}) ? $units{$readingUnit} : 'unknown: ' . $readingUnit);
Log3 $name, 5, "TA_CMI_JSON ($name) - readingName: $readingName . '_Unit', key: $jsonKey, value: $readingUnit, unit: $unit";
readingsBulkUpdateIfChanged($hash, $readingName . '_Unit', $unit, 1) if ($inclUnitReadings);
}
if ($inclPrettyReadings) {
readingsBulkUpdateIfChanged($hash, $readingName . '_Pretty', $readingValue . ' ' . $unit, 1);
}
}
return undef;
}
sub Set {
my ( $hash, $name, $opt, @arg) = @_;
Log3 $name, 5, "TA_CMI_JSON ($name) - Set: $name $opt ".join(' ', @arg);
my ($sets, $cmdList) = getCmdHash(AttrVal($name, 'setList', ''));
if ($opt eq 'fixwertAnalog' || $opt eq 'fixwertDigital' || $opt eq 'fixwertImpuls') {
my $index = $arg[0];
my $value = $arg[1];
my $type = $fixwertTypes{$opt};
FixwertChangeRequest($hash, $index, $value, $type);
return undef;
} else {
my $command = $sets->{$opt};
if (defined $command) {
# Log3 $name, 5, "TA_CMI_JSON ($name) - command: $command";
my ($cmd, $index, $value) = split(' ', $command);
# Log3 $name, 5, "TA_CMI_JSON ($name) - cmd: $cmd";
# Log3 $name, 5, "TA_CMI_JSON ($name) - index: $index";
# Log3 $name, 5, "TA_CMI_JSON ($name) - value: $value";
# Log3 $name, 5, "TA_CMI_JSON ($name) - arg: ".join(' ', @arg);
unshift @arg, $value if (defined $value);
unshift @arg, $index if (defined $index);
# Log3 $name, 5, "TA_CMI_JSON ($name) - arg2: ".join(' ', @arg);
return Set($hash, $name, $cmd, @arg);
}
}
return "Unknown argument $opt, choose one of fixwertAnalog fixwertDigital fixwertImpuls $cmdList";
}
# credits for this method go to MQTT2_DEVICE
sub getCmdHash($)
{
my ($list) = @_;
my (%h, @cmd);
map {
my ($k,$v) = split(" ",$_,2);
push @cmd, $k;
$k =~ s/:.*//; # potential arguments
$h{$k} = $v;
}
grep /./,
split("\n", $list);
return (\%h, join(" ",@cmd));
}
sub FixwertChangeRequest($$$$) {
my ($hash, $index, $value, $type) = @_;
my $name = $hash->{NAME};
my $nodeId = $hash->{NODEID};
my $cmiIp = $hash->{CMIURL};
my $hexNodeId = $hash->{NODEID_HEX};
$index--; #1 on the Web UI is index 0. 2 is 1, etc.
my $hexIndex = sprintf('%1x',$index);
$hexIndex = "0$hexIndex" unless length($hexIndex) == 2;
my $referrer = "Referer: http://$cmiIp/menupagex.cgi?nodex2=".$hexNodeId."005800";
my $url = "http://$cmiIp/INCLUDE/change.cgi?changeadrx2=".$hexNodeId."00".$hexIndex."4414".$type."01&changetox2=".$value."&_=".gettimeofday();
my $username = AttrVal($name, 'username', 'admin');
my $password = AttrVal($name, 'password', 'admin');
my $param = {
url => "$url",
timeout => 5,
hash => $hash,
method => "GET",
header => $referrer,
user => $username,
pwd => $password,
callback => \&FixwertChangeRequest_Callback
};
Log3 $name, 4, "TA_CMI_JSON ($name) - FixwertChangeRequest $url";
HttpUtils_NonblockingGet($param);
}
sub FixwertChangeRequest_Callback {
my ($param, $err, $data) = @_;
my $hash = $param->{hash};
my $name = $hash->{NAME};
if($err ne "") {
Log3 $name, 0, "TA_CMI_JSON ($name) - error while calling ".$param->{url}." - $err";
} elsif($data ne "") {
Log3 $name, 5, "TA_CMI_JSON ($name) - FixwertChangeRequest_Callback: $data";
}
return undef;
}
sub Get($$$$) {
my ( $hash, $name, $opt, $args ) = @_;
if ("update" eq $opt) {
PerformHttpRequest($hash);
return undef;
}
if ("readOutputStates" eq $opt) {
RequestOutputStates($hash); #unless $hash->{CAN_DEVICE} ne 'UVR1611';
return undef;
}
# Log3 $name, 3, "ZoneMinder ($name) - Get done ...";
return "Unknown argument $opt, choose one of update readOutputStates";
}
sub RequestOutputStates($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $nodeId = $hash->{NODEID};
my $hexNodeId = $hash->{NODEID_HEX};
my $url = "http://$hash->{CMIURL}/INCLUDE/agx2.cgi?nodex2=$hexNodeId"."&_=".gettimeofday();
my $username = AttrVal($name, 'username', 'admin');
my $password = AttrVal($name, 'password', 'admin');
my $param = {
url => "$url",
timeout => 5,
hash => $hash,
method => "GET",
header => "User-Agent: FHEM\r\nAccept: application/json",
user => $username,
pwd => $password,
callback => \&ParseOutputStateResponse
};
Log3 $name, 4, "TA_CMI_JSON ($name) - RequestOutputStates $url";
HttpUtils_NonblockingGet($param);
}
sub ParseOutputStateResponse($$$) {
my ($param, $err, $data) = @_;
my $hash = $param->{hash};
my $name = $hash->{NAME};
my $return;
if($err ne "") {
Log3 $name, 0, "TA_CMI_JSON ($name) - error while requesting output data ".$param->{url}." - $err";
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, 'state', 'ERROR', 0);
readingsBulkUpdate($hash, 'error', $err, 0);
readingsEndUpdate($hash, 1);
} elsif($data ne "") {
readingsDelete($hash, "error");
readingsDelete($hash, "state");
my @values = split(';', $data);
my $nrValues = @values -2;
my $prettyOutputStates = AttrVal( $name, "prettyOutputStates", '0' );
my $readingNames = AttrVal($name, "readingNamesOutputs", undef);
if ( ! defined $readingNames ) {
Log3 $name, 1, "TA_CMI_JSON ($name) - Unable to assign output states, please set attribute readingNamesOutputs";
return undef;
}
my @readingsArray = split(/ /, $readingNames); #1:T.Kollektor 5:T.Vorlauf
readingsBeginUpdate($hash);
foreach (@readingsArray) {
my ( $readingNameIndex, $readingName ) = split(/\:/, $_);
my $i = $readingNameIndex+1;
$readingName = makeReadingName($readingName);
my $readingValue = $values[$i];
readingsBulkUpdateIfChanged($hash, $readingName.'_State', $readingValue, 1);
if ($prettyOutputStates eq '1') {
my $prettyValue = (defined($outputStates{$readingValue}) ? $outputStates{$readingValue} : '?:'.$readingValue);
readingsBulkUpdateIfChanged($hash, $readingName.'_State_Pretty', $prettyValue, 1);
}
Log3 $name, 5, "TA_CMI_JSON ($name) - readingName: $readingName, readingNameIndex: $readingNameIndex, valueIndex: $i, value: $readingValue";
}
readingsEndUpdate($hash, 1);
Log3 $name, 5, "TA_CMI_JSON ($name) - Output Data $nrValues: $data";
}
my $outputStatesInterval = AttrVal($name, 'outputStatesInterval', undef);
if ( defined $outputStatesInterval ) {
Log3 $name, 5, "TA_CMI_JSON ($name) - outputStatesInterval $outputStatesInterval";
my $functionName = "TA_CMI_JSON::RequestOutputStates";
RemoveInternalTimer($hash, $functionName);
InternalTimer( gettimeofday() + $outputStatesInterval, $functionName, $hash, 0 );
}
return undef;
}
# Eval-Rückgabewert für erfolgreiches
# Laden des Moduls
1;
# Beginn der Commandref
=pod
=item [device]
=item summary Reads values from the Technische Alternative CMI device
=item summary_DE Werte vom CMI der Firma Technische Alternative auslesen.
=begin html
TA_CMI_JSON
Define
define <name> TA_CMI_JSON <IP> <CAN-Node-Id> <Query-Params>
Defines a device that receives values from the CMI at the given IP for the CAN-device with the given CAN-Node-Id.
Query-Param defines, which values you want to read. Allowed values are I,O,D.
Example:
defmod cmi TA_CMI_JSON 192.168.4.250 1 <I,O,D>
It's mandatory to define which values should be mapped to readings.
Only mapped values will not be written to readings. (see Attributes for details)
Set
fixwertAnalog
Set Fixwert to an analog value. Example:
set cmiNode fixwertAnalog <index> <value>
set cmiNode fixwertAnalog 3 64.0
will set Fixwert 3 to 64.0
fixwertDigital
Set Fixwert to a digital value. Also works for impulse values. Example:
set cmiNode fixwertDigital <index> <value>
set cmiNode fixwertDigital 2 1
will set Fixwert 2 to On/Yes.
fixwertImpuls
Trigger an impulse to Fixwert. Example:
set cmiNode fixwertImpuls <index> <value>
set cmiNode fixwertImpuls 3 1
will send an On-impulse to Fixwert 3.
Get
update
Triggers querying of values from the CMI. Please note that the request rate is limited to one query per minute.
readOutputStates
Reads Output states (eg Manual-On, Auto-Off) per defined output. Can be automated by setting outputStatesInterval
.
Attributes
readingNamesDL-Bus {index:reading-name}
This maps received values from the DL-Bus to readings. eg 1:Flowrate_Solar 2:T.Solar_Backflow
readingNamesInputs {index:reading-name}
This maps received values from the Inputs to readings. eg 1:Flowrate_Solar 2:T.Solar_Backflow
readingNamesOutputs {index:reading-name}
This maps received values from the Outputs to readings. eg 1:Flowrate_Solar 2:T.Solar_Backflow
readingNamesLoggingAnalog {index:reading-name}
This maps received values from Analog Logging to readings. zB eg 1:Flowrate_Solar 2:T.Solar_Backflow
readingNamesLoggingDigital {index:reading-name}
This maps received values from Digital Logging to readings. zB eg 1:Flowrate_Solar 2:T.Solar_Backflow
includeUnitReadings [0:1]
Adds another reading per value, which just contains the according unit of that reading.
includePrettyReadings [0:1]
Adds another reading per value, which contains value plus unit of that reading.
interval
Query interval in seconds. Minimum query interval is 60 seconds.
outputStatesInterval
Request interval in seconds for getting output states.
prettyOutputStates [0:1]
If set, generates a reading _State_Pretty for output states (eg Auto-On, Manual-Off)
-
setList
Used to define Set shortcuts for fixwertAnalog, Digital, and Impuls. eg Light_on:noArg fixwertImpuls 3 1
The second parameter (for the value) can be left out and directly read from the input field. eg Water_Temperature fixwertAnalog 7
can be used like set cmiNode Water_Temperature 55.0
.
username
Username for querying the JSON-API. Needs to be either admin or user privilege.
password
Password for querying the JSON-API.
Readings
Readings will appear according to the mappings defined in Attributes.
=end html
=begin html_DE
TA_CMI_JSON
Weitere Informationen zu diesem Modul im FHEM-Wiki.
Define
define <name> TA_CMI_JSON <IP> <CAN-Node-Id> <Query-Params>
Liest Werte vom CMI mit der angegebenen IP für das CAN-Gerät mit der angegebenen Node-Id.
Query-Param definiert, welche Werte ausgelesen werden sollen. Erlaubt sind I,O,D.
Beispiel:
defmod cmi TA_CMI_JSON 192.168.4.250 1 <I,O,D>
Daneben muss auch noch das mapping angegeben werden, welche Werte in welches Reading geschrieben werden sollen.
Nur gemappte Werte werden in Readings geschrieben. (siehe Attributes)
Set
fixwertAnalog
Setzt einen Fixwert auf einen analogen Wert. Beispiel:
set cmiNode fixwertAnalog <index> <value>
set cmiNode fixwertAnalog 3 64.0
setzt Fixwert 3 auf 64.0
fixwertDigital
Setzt einen Fixwert auf einen digitalen Wert. Funktioniert auch für Impulse. Beispiel:
set cmiNode fixwertDigital <index> <value>
set cmiNode fixwertDigital 2 1
setzt Fixwert 2 auf Ein/Ja
fixwertImpuls
Sendet einen Impuls an den Fixwert. Beispiel:
set cmiNode fixwertImpuls <index> <value>
set cmiNode fixwertImpuls 3 1
sendet einen Ein-Impuls nach Fixwert 3.
Get
update
Hiermit kann sofort eine Abfrage der API ausgeführt werden. Das Limit von einer Anfrage pro Minute besteht trotzdem.
readOutputStates
Liest Ausgangs-Stati, zB Auto-Ein, Hand-Aus. Kann mittels outputStatesInterval
automatisch ausgeführt werden. Das Zeitlimit von 60 Sekunden trifft hier nicht zu.
Attributes
readingNamesDL-Bus {index:reading-name}
Hiermit werden erhaltene Werte vom DL-Bus einem Reading zugewiesen. zB 1:Durchfluss_Solar 2:T.Solar_RL
readingNamesInput {index:reading-name}
Hiermit werden erhaltene Werte der Eingänge einem Reading zugewiesen. zB 1:Durchfluss_Solar 2:T.Solar_RL
readingNamesDL-Bus {index:reading-name}
Hiermit werden erhaltene Werte der Ausgänge einem Reading zugewiesen. zB 1:Durchfluss_Solar 2:T.Solar_RL
readingNamesLoggingAnalog {index:reading-name}
Hiermit werden erhaltene Werte vom Analog Logging einem Reading zugewiesen. zB 1:Durchfluss_Solar 2:T.Solar_RL
readingNamesLoggingDigital {index:reading-name}
Hiermit werden erhaltene Werte vom Digital Logging einem Reading zugewiesen. zB 1:Durchfluss_Solar 2:T.Solar_RL
includeUnitReadings [0:1]
Definiert, ob zu jedem Reading ein zusätzliches Reading _Name geschrieben werden soll, welches die Einheit enthält.
includePrettyReadings [0:1]
Definiert, ob zu jedem Reading zusätzlich ein Reading, welches Wert und Einheit enthält, geschrieben werden soll.
interval
Abfrage-Intervall in Sekunden. Muss mindestens 60 sein.
outputStatesInterval
Abfrage-Intervall für Ausgangs-Stati in Sekunden.
prettyOutputStates [0:1]
Definiert, ob zu einem Ausgangs-Status ein zusätzliches Reading _State_Pretty geschrieben werden soll (liefert zB Auto-On, Manual-Off)
-
setList
Dienst zum Anlegen direkter Set Befehle für fixwertAnalog, Digital, und Impuls. zB Licht_ein:noArg fixwertImpuls 3 1
Wird der zweite Parameter (der Wert) weggelassen, kann dieser direkt aus dem Textfeld übernommen werden. zB Wasser_Temperatur fixwertAnalog 7
könnte dann mit set cmiNode Wasser_Temperatur 55.0
verwendet werden.
username
Username zur Abfrage der JSON-API. Muss die Berechtigungsstufe admin oder user haben.
password
Passwort zur Abfrage der JSON-API.
Readings
Readings werden entsprechend der Definition in den Attributen angelegt.
=end html_DE
# Ende der Commandref
=cut