mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
3631929b91
11_OWX_CCC: Neue Version, kleinere Fixes 11_OWX_FRM: Neue Version, kleinere Fixes 11_OWX_SER: Neue Version, kleinere Fixes 11_OWX_TCP: Neue Version, kleinere Fixes 21_OWAD.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes 21_OWCOUNT.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes 21_OWID.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes 21_OWLCD.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes 21_OWMULTI.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes 21_OWSWITCH.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes 21_OWTHERM.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes 21_OWVAR.pm: Neue Version, Support für OWX_ASYNC entfernt, kleinere Fixes git-svn-id: https://svn.fhem.de/fhem/trunk@23553 2b470e98-0d58-463d-a4d8-8e2adae1ed80
509 lines
15 KiB
Perl
509 lines
15 KiB
Perl
########################################################################################
|
|
#
|
|
# OWID.pm
|
|
#
|
|
# FHEM module to commmunicate with general 1-Wire ID-ROMS
|
|
#
|
|
# Prof. Dr. Peter A. Henning
|
|
#
|
|
# $Id$
|
|
#
|
|
########################################################################################
|
|
#
|
|
# This programm 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.
|
|
#
|
|
# The GNU General Public License can be found at
|
|
# http://www.gnu.org/copyleft/gpl.html.
|
|
# A copy is found in the textfile GPL.txt and important notices to the license
|
|
# from the author is found in LICENSE.txt distributed with these scripts.
|
|
#
|
|
# This script 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.
|
|
#
|
|
########################################################################################
|
|
package main;
|
|
|
|
use vars qw{%attr %defs %modules $readingFnAttributes $init_done};
|
|
use Time::HiRes qw(gettimeofday);
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
my $owx_version="7.23";
|
|
#-- declare variables
|
|
my %gets = (
|
|
"present" => ":noArg",
|
|
"id" => ":noArg",
|
|
"version" => ":noArg"
|
|
);
|
|
my %sets = (
|
|
"interval" => ""
|
|
);
|
|
my %updates = (
|
|
"present" => ""
|
|
);
|
|
|
|
########################################################################################
|
|
#
|
|
# The following subroutines are independent of the bus interface
|
|
#
|
|
# Prefix = OWID
|
|
#
|
|
########################################################################################
|
|
#
|
|
# OWID_Initialize
|
|
#
|
|
# Parameter hash = hash of device addressed
|
|
#
|
|
########################################################################################
|
|
|
|
sub OWID_Initialize ($) {
|
|
my ($hash) = @_;
|
|
|
|
$hash->{DefFn} = "OWID_Define";
|
|
$hash->{UndefFn} = "OWID_Undef";
|
|
$hash->{GetFn} = "OWID_Get";
|
|
$hash->{SetFn} = "OWID_Set";
|
|
$hash->{AttrFn} = "OWID_Attr";
|
|
$hash->{NotifyFn} = "OWID_Notify";
|
|
$hash->{InitFn} = "OWID_Init";
|
|
$hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model interval ".
|
|
$readingFnAttributes;
|
|
|
|
#--make sure OWX is loaded so OWX_CRC is available if running with OWServer
|
|
main::LoadModule("OWX");
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# OWID_Define - Implements DefFn function
|
|
#
|
|
# Parameter hash = hash of device addressed, def = definition string
|
|
#
|
|
#########################################################################################
|
|
|
|
sub OWID_Define ($$) {
|
|
my ($hash, $def) = @_;
|
|
|
|
#-- define <name> OWID <FAM_ID> <ROM_ID>
|
|
my @a = split("[ \t][ \t]*", $def);
|
|
|
|
my ($name,$interval,$model,$fam,$id,$crc,$ret);
|
|
|
|
#-- default
|
|
$name = $a[0];
|
|
$interval = 300;
|
|
$ret = "";
|
|
|
|
#-- check syntax
|
|
return "OWID: Wrong syntax, must be define <name> OWID [<model>] <id> [interval] or OWAD <fam>.<id> [interval]"
|
|
if(int(@a) < 2 || int(@a) > 5);
|
|
|
|
#-- different types of definition allowed
|
|
my $a2 = $a[2];
|
|
my $a3 = defined($a[3]) ? $a[3] : "";
|
|
#-- no model, 2+12 characters
|
|
if( $a2 =~ m/^[0-9|a-f|A-F]{2}\.[0-9|a-f|A-F]{12}$/ ) {
|
|
$fam = substr($a[2],0,2);
|
|
$id = substr($a[2],3);
|
|
if(int(@a)>=4) { $interval = $a[3]; }
|
|
if( $fam eq "01" ){
|
|
$model = "DS2401";
|
|
CommandAttr (undef,"$name model DS2401");
|
|
}elsif( $fam eq "09" ){
|
|
$model = "DS2502";
|
|
CommandAttr (undef,"$name model DS2502");
|
|
}else{
|
|
$model = "unknown";
|
|
CommandAttr (undef,"$name model unknown");
|
|
}
|
|
#-- model or family id, 12 characters
|
|
} elsif( $a3 =~ m/^[0-9|a-f|A-F]{12}$/ ) {
|
|
$id = $a[3];
|
|
if(int(@a)>=5) { $interval = $a[4]; }
|
|
#-- family id, 2 characters
|
|
if( $a2 =~ m/^[0-9|a-f|A-F]{2}$/ ) {
|
|
$fam = $a[2];
|
|
if( $fam eq "01" ){
|
|
$model = "DS2401";
|
|
CommandAttr (undef,"$name model DS2401");
|
|
}elsif( $fam eq "09" ){
|
|
$model = "DS2502";
|
|
CommandAttr (undef,"$name model DS2502");
|
|
}else{
|
|
$model = "unknown";
|
|
CommandAttr (undef,"$name model unknown");
|
|
}
|
|
}else{
|
|
$model = $a[2];
|
|
if( $model eq "DS2401" ){
|
|
$fam = "01";
|
|
CommandAttr (undef,"$name model DS2401");
|
|
}elsif( $model eq "DS2502" ){
|
|
$fam = "09";
|
|
CommandAttr (undef,"$name model DS2502");
|
|
}else{
|
|
return "OWID: Unknown 1-Wire device model $model";
|
|
}
|
|
}
|
|
} else {
|
|
return "OWID: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value";
|
|
}
|
|
|
|
#-- determine CRC Code
|
|
$crc = sprintf("%02X",OWX_CRC($fam.".".$id."00"));
|
|
|
|
#-- Define device internals
|
|
$hash->{ROM_ID} = "$fam.$id.$crc";
|
|
$hash->{OW_ID} = $id;
|
|
$hash->{OW_FAMILY} = $fam;
|
|
$hash->{PRESENT} = 0;
|
|
$hash->{INTERVAL} = $interval;
|
|
|
|
#-- Couple to I/O device
|
|
AssignIoPort($hash);
|
|
if( !defined($hash->{IODev}) or !defined($hash->{IODev}->{NAME}) ){
|
|
return "OWID: Warning, no 1-Wire I/O device found for $name.";
|
|
}
|
|
|
|
$modules{OWID}{defptr}{$id} = $hash;
|
|
#--
|
|
readingsSingleUpdate($hash,"state","Defined",1);
|
|
Log3 $name,1, "OWID: Device $name defined.";
|
|
|
|
$hash->{NOTIFYDEV} = "global";
|
|
|
|
return OWID_Init($hash);
|
|
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# OWID_Notify - Implements NotifyFn function
|
|
#
|
|
# Parameter hash = hash of device addressed, dev = device name
|
|
#
|
|
#########################################################################################
|
|
|
|
sub OWID_Notify ($$) {
|
|
my ($hash,$dev) = @_;
|
|
if( grep(m/^(INITIALIZED|REREADCFG)$/, @{$dev->{CHANGED}}) ) {
|
|
OWID_Init($hash);
|
|
} elsif( grep(m/^SAVE$/, @{$dev->{CHANGED}}) ) {
|
|
}
|
|
}
|
|
|
|
#########################################################################################
|
|
#
|
|
# OWID_Init - Implements InitFn function
|
|
#
|
|
# Parameter hash = hash of device addressed
|
|
#
|
|
#########################################################################################
|
|
|
|
sub OWID_Init ($) {
|
|
my ($hash)=@_;
|
|
#-- Start timer for updates
|
|
RemoveInternalTimer($hash);
|
|
InternalTimer(gettimeofday()+30, "OWID_GetValues", $hash, 0);
|
|
#--
|
|
readingsSingleUpdate($hash,"state","Initialized",1);
|
|
|
|
if (! (defined AttrVal($hash->{NAME},"stateFormat",undef))) {
|
|
$main::attr{$hash->{NAME}}{"stateFormat"} = "{ReadingsVal(\$name,\"present\",0) ? \"present\" : \"not present\"}";
|
|
}
|
|
|
|
return undef;
|
|
}
|
|
|
|
#######################################################################################
|
|
#
|
|
# OWID_Attr - Set one attribute value for device
|
|
#
|
|
# Parameter hash = hash of device addressed
|
|
# a = argument array
|
|
#
|
|
########################################################################################
|
|
|
|
sub OWID_Attr(@) {
|
|
my ($do,$name,$key,$value) = @_;
|
|
|
|
my $hash = $defs{$name};
|
|
my $ret;
|
|
|
|
if ( $do eq "set") {
|
|
ARGUMENT_HANDLER: {
|
|
#-- interval modified at runtime
|
|
$key eq "interval" and do {
|
|
#-- check value
|
|
return "OWID: set $name interval must be >= 0" if(int($value) < 0);
|
|
#-- update timer
|
|
$hash->{INTERVAL} = int($value);
|
|
if ($init_done) {
|
|
RemoveInternalTimer($hash);
|
|
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 0);
|
|
}
|
|
last;
|
|
};
|
|
$key eq "IODev" and do {
|
|
AssignIoPort($hash,$value);
|
|
if( defined($hash->{IODev}) ) {
|
|
$hash->{ASYNC} = $hash->{IODev}->{TYPE} eq "OWX_ASYNC" ? 1 : 0;
|
|
if ($init_done) {
|
|
OWID_Init($hash);
|
|
}
|
|
}
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
########################################################################################
|
|
#
|
|
# OWID_Get - Implements GetFn function
|
|
#
|
|
# Parameter hash = hash of device addressed, a = argument array
|
|
#
|
|
########################################################################################
|
|
|
|
sub OWID_Get($@) {
|
|
my ($hash, @a) = @_;
|
|
|
|
my $reading = $a[1];
|
|
my $name = $hash->{NAME};
|
|
my $model = $hash->{OW_MODEL};
|
|
my $value = undef;
|
|
my $ret = "";
|
|
my $offset;
|
|
my $factor;
|
|
|
|
#-- check syntax
|
|
return "OWID: Get argument is missing @a"
|
|
if(int(@a) != 2);
|
|
|
|
#-- check argument
|
|
my $msg = "OWID: Get with unknown argument $a[1], choose one of ";
|
|
$msg .= "$_$gets{$_} " foreach (keys%gets);
|
|
return $msg
|
|
if(!defined($gets{$a[1]}));
|
|
|
|
#-- get id
|
|
if($a[1] eq "id") {
|
|
$value = $hash->{ROM_ID};
|
|
return "$name.id => $value";
|
|
}
|
|
|
|
#-- get present
|
|
if($a[1] eq "present") {
|
|
#-- hash of the busmaster
|
|
my $master = $hash->{IODev};
|
|
my $interface = $master->{TYPE};
|
|
|
|
#-- OWX interface
|
|
if( $interface eq "OWX" ){
|
|
$value = OWX_Verify($master,$name,$hash->{ROM_ID},0);
|
|
#-- Unknown interface
|
|
} else {
|
|
return "OWID: Verification not yet implemented for interface $interface";
|
|
}
|
|
#-- process results
|
|
if( $master->{ASYNCHRONOUS} ){
|
|
return undef;
|
|
}else{
|
|
#-- generate an event only if presence has changed
|
|
if( $value == 0 ){
|
|
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
|
|
} else {
|
|
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
|
|
}
|
|
$hash->{PRESENT} = $value;
|
|
return "$name.present => $value";
|
|
}
|
|
}
|
|
|
|
#-- get version
|
|
if( $a[1] eq "version") {
|
|
return "$name.version => $owx_version";
|
|
}
|
|
}
|
|
|
|
########################################################################################
|
|
#
|
|
# OWID_GetValues - Updates the reading from one device
|
|
#
|
|
# Parameter hash = hash of device addressed
|
|
#
|
|
########################################################################################
|
|
|
|
sub OWID_GetValues($) {
|
|
my $hash = shift;
|
|
|
|
my $name = $hash->{NAME};
|
|
my $value = 0;
|
|
my $ret = "";
|
|
my $offset;
|
|
my $factor;
|
|
|
|
RemoveInternalTimer($hash);
|
|
#-- auto-update for device disabled;
|
|
return undef
|
|
if( $hash->{INTERVAL} == 0 );
|
|
#-- restart timer for updates
|
|
InternalTimer(time()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 0);
|
|
|
|
#-- hash of the busmaster
|
|
my $master = $hash->{IODev};
|
|
my $interface = $master->{TYPE};
|
|
|
|
$value = OWX_Verify($master,$name,$hash->{ROM_ID},0);
|
|
|
|
#-- process results
|
|
if( $master->{ASYNCHRONOUS} ){
|
|
return undef;
|
|
}else{
|
|
#-- generate an event only if presence has changed
|
|
if( $value == 0 ){
|
|
readingsSingleUpdate($hash,"present",0,$hash->{PRESENT});
|
|
} else {
|
|
readingsSingleUpdate($hash,"present",1,!$hash->{PRESENT});
|
|
}
|
|
$hash->{PRESENT} = $value;
|
|
return "$name.present => $value";
|
|
}
|
|
}
|
|
|
|
#######################################################################################
|
|
#
|
|
# OWID_Set - Set one value for device
|
|
#
|
|
# Parameter hash = hash of device addressed
|
|
# a = argument array
|
|
#
|
|
########################################################################################
|
|
|
|
sub OWID_Set($@) {
|
|
my ($hash, @a) = @_;
|
|
|
|
my $key = $a[1];
|
|
my $value = $a[2];
|
|
|
|
#-- for the selector: which values are possible
|
|
if (@a == 2){
|
|
my $newkeys = join(" ", keys %sets);
|
|
return $newkeys ;
|
|
}
|
|
|
|
#-- check syntax
|
|
return "OWID: Set needs at least one parameter"
|
|
if( int(@a)<3 );
|
|
#-- check argument
|
|
if( !defined($sets{$a[1]}) ){
|
|
return "OWID: Set with unknown argument $a[1]";
|
|
}
|
|
|
|
my $name = $hash->{NAME};
|
|
|
|
#-- set new timer interval
|
|
if($key eq "interval") {
|
|
# check value
|
|
return "OWID: Set $name interval must be >= 0"
|
|
if(int($value) < 0);
|
|
# update timer
|
|
$hash->{INTERVAL} = int($value);
|
|
RemoveInternalTimer($hash);
|
|
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWID_GetValues", $hash, 0);
|
|
return undef;
|
|
}
|
|
}
|
|
|
|
########################################################################################
|
|
#
|
|
# OWID_Undef - Implements UndefFn function
|
|
#
|
|
# Parameter hash = hash of device addressed
|
|
#
|
|
########################################################################################
|
|
|
|
sub OWID_Undef ($) {
|
|
my ($hash) = @_;
|
|
delete($modules{OWID}{defptr}{$hash->{OW_ID}});
|
|
RemoveInternalTimer($hash);
|
|
return undef;
|
|
}
|
|
|
|
1;
|
|
|
|
=pod
|
|
=item device
|
|
=item summary to control 1-Wire devices having only a serial number
|
|
=begin html
|
|
|
|
<a name="OWID"></a>
|
|
<h3>OWID</h3>
|
|
<ul>
|
|
<p>FHEM module for 1-Wire devices that know only their unique ROM ID<br />
|
|
<br />This 1-Wire module works with the OWX interface module or with the OWServer interface module
|
|
Please define an <a href="#OWX">OWX</a> device or <a href="#OWServer">OWServer</a> device first. <br /></p>
|
|
<br /><h4>Example</h4><br />
|
|
<p>
|
|
<code>define ROM1 OWX_ID OWCOUNT 09.CE780F000000 10</code>
|
|
<br />
|
|
</p><br />
|
|
<a name="OWIDdefine"></a>
|
|
<h4>Define</h4>
|
|
<p>
|
|
<code>define <name> OWID <fam> <id> [<interval>]</code> or <br/>
|
|
<code>define <name> OWID <fam>.<id> [<interval>]</code>
|
|
<br /><br /> Define a 1-Wire device.<br /><br />
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
<code><fam></code>
|
|
<br />2-character unique family id, see above
|
|
</li>
|
|
<li>
|
|
<code><id></code>
|
|
<br />12-character unique ROM id of the converter device without family id and CRC
|
|
code
|
|
</li>
|
|
<li>
|
|
<code><interval></code>
|
|
<br />Interval in seconds for checking the presence of the device. The default is 300 seconds. </li>
|
|
</ul>
|
|
<br />
|
|
<a name="OWIDset"></a>
|
|
<h4>Set</h4>
|
|
<ul>
|
|
<li><a name="owid_interval">
|
|
<code>set <name> interval <int></code></a><br />
|
|
Interval in seconds for checking the presence of the device. The default is 300 seconds. </li>
|
|
</ul>
|
|
<br />
|
|
<a name="OWIDget"></a>
|
|
<h4>Get</h4>
|
|
<ul>
|
|
<li><a name="owid_id">
|
|
<code>get <name> id</code></a>
|
|
<br /> Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC </li>
|
|
<li><a name="owid_present">
|
|
<code>get <name> present</code>
|
|
</a>
|
|
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
|
|
</ul>
|
|
<h4>Attributes</h4>
|
|
<ul><li><a name="owtherm_interval2">
|
|
<code>attr <name> interval <int></code></a><br /> Measurement
|
|
interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update.</li>
|
|
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
|
</ul>
|
|
</ul>
|
|
=end html
|
|
=cut
|