mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 03:06:37 +00:00
21_OWLCD.pm: Version 7.0 mit Anpassungen für OWX Next Generation
21_OWMULTI.pm: Version 7.0 mit Anpassungen für OWX Next Generation 21_OWSWITCH.pm: Version 7.0 mit Anpassungen für OWX Next Generation git-svn-id: https://svn.fhem.de/fhem/trunk@14824 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a3b98833ff
commit
7df0751160
File diff suppressed because it is too large
Load Diff
@ -7,48 +7,7 @@
|
|||||||
# Prof. Dr. Peter A. Henning
|
# Prof. Dr. Peter A. Henning
|
||||||
# Norbert Truchsess
|
# Norbert Truchsess
|
||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
|
||||||
########################################################################################
|
|
||||||
#
|
|
||||||
# define <name> OWMULTI [<model>] <ROM_ID> [interval] or OWMULTI <FAM_ID>.<ROM_ID> [interval]
|
|
||||||
#
|
|
||||||
# where <name> may be replaced by any name string
|
|
||||||
#
|
|
||||||
# <model> is a 1-Wire device type. If omitted, we assume this to be an
|
|
||||||
# DS2438
|
|
||||||
# <FAM_ID> is a 1-Wire family id, currently allowed value is 26
|
|
||||||
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
|
|
||||||
# without Family ID, e.g. A2D90D000800
|
|
||||||
# [interval] is an optional query interval in seconds
|
|
||||||
#
|
|
||||||
# get <name> id => OW_FAMILY.ROM_ID.CRC
|
|
||||||
# get <name> present => 1 if device present, 0 if not
|
|
||||||
# get <name> interval => query interval
|
|
||||||
# get <name> reading => measurement value obtained from VFunction
|
|
||||||
# get <name> temperature => temperature measurement
|
|
||||||
# get <name> VDD => supply voltage measurement
|
|
||||||
# get <name> raw => raw measurement voltages
|
|
||||||
# get <name> version => OWX version number
|
|
||||||
#
|
|
||||||
# set <name> interval => set period for measurement
|
|
||||||
#
|
|
||||||
# Additional attributes are defined in fhem.cfg
|
|
||||||
# Note: attributes "tempXXXX" are read during every update operation.
|
|
||||||
#
|
|
||||||
# attr <name> tempOffset <float> = temperature offset in degree Celsius added to the raw temperature reading
|
|
||||||
# attr <name> tempUnit <string> = unit of measurement, e.g. Celsius/Kelvin/Fahrenheit, default is Celsius
|
|
||||||
# attr <name> VName <string>[|<string>] = name for the voltage channel [|short name used in state reading]
|
|
||||||
# attr <name> VUnit <string> = unit of measurement for the voltage channel (default V, none for empty)
|
|
||||||
# attr <name> Vfunction <string> = arbitrary functional expression involving the values VDD, V, W, T
|
|
||||||
# VDD is replaced by the measured supply voltage in Volt,
|
|
||||||
# V by the measured external voltage channel
|
|
||||||
# W by the measured external sense channel
|
|
||||||
# T by the measured and corrected temperature in its unit
|
|
||||||
# attr <name> WName <string>[|<string>] = name for the sense channel [|short name used in state reading]
|
|
||||||
# attr <name> WUnit <string>[|<string>] = unit of measurement for the sense channel (default 1/16384 V, none for empty)
|
|
||||||
# attr <name> Wfunction <string> = arbitrary functional expression involving the values VDD, V, W, T
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
@ -73,7 +32,7 @@ package main;
|
|||||||
use vars qw{%attr %defs %modules $readingFnAttributes $init_done};
|
use vars qw{%attr %defs %modules $readingFnAttributes $init_done};
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
#add FHEM/lib to @INC if it's not allready included. Should rather be in fhem.pl than here though...
|
#add FHEM/lib to @INC if it's not already included. Should rather be in fhem.pl than here though...
|
||||||
BEGIN {
|
BEGIN {
|
||||||
if (!grep(/FHEM\/lib$/,@INC)) {
|
if (!grep(/FHEM\/lib$/,@INC)) {
|
||||||
foreach my $inc (grep(/FHEM$/,@INC)) {
|
foreach my $inc (grep(/FHEM$/,@INC)) {
|
||||||
@ -87,14 +46,12 @@ no warnings 'deprecated';
|
|||||||
|
|
||||||
sub Log($$);
|
sub Log($$);
|
||||||
|
|
||||||
my $owx_version="6.1";
|
my $owx_version="7.0";
|
||||||
#-- flexible channel name
|
#-- flexible channel name
|
||||||
my ($owg_channel,$owg_schannel);
|
my ($owg_channel,$owg_schannel);
|
||||||
|
|
||||||
my %gets = (
|
my %gets = (
|
||||||
"id" => "",
|
"id" => "",
|
||||||
"present" => "",
|
|
||||||
"interval" => "",
|
|
||||||
"reading" => "",
|
"reading" => "",
|
||||||
"temperature" => "",
|
"temperature" => "",
|
||||||
"VDD" => "",
|
"VDD" => "",
|
||||||
@ -174,9 +131,9 @@ sub OWMULTI_Attr(@) {
|
|||||||
#-- interval modified at runtime
|
#-- interval modified at runtime
|
||||||
$key eq "interval" and do {
|
$key eq "interval" and do {
|
||||||
#-- check value
|
#-- check value
|
||||||
return "OWMULTI: Set with short interval, must be > 1" if(int($value) < 1);
|
return "OWMULTI: set $name interval must be >= 0" if(int($value) < 0);
|
||||||
#-- update timer
|
#-- update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = int($value);
|
||||||
if ($init_done) {
|
if ($init_done) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0);
|
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0);
|
||||||
@ -261,7 +218,6 @@ sub OWMULTI_Define ($$) {
|
|||||||
return "OWMULTI: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value";
|
return "OWMULTI: $a[0] ID $a[2] invalid, specify a 12 or 2.12 digit value";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#-- determine CRC Code - only if this is a direct interface
|
#-- determine CRC Code - only if this is a direct interface
|
||||||
$crc = sprintf("%02x",OWX_CRC($fam.".".$id."00"));
|
$crc = sprintf("%02x",OWX_CRC($fam.".".$id."00"));
|
||||||
|
|
||||||
@ -269,6 +225,7 @@ sub OWMULTI_Define ($$) {
|
|||||||
$hash->{OW_ID} = $id;
|
$hash->{OW_ID} = $id;
|
||||||
$hash->{OW_FAMILY} = $fam;
|
$hash->{OW_FAMILY} = $fam;
|
||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
|
$hash->{ERRCOUNT} = 0;
|
||||||
$hash->{ROM_ID} = "$fam.$id.$crc";
|
$hash->{ROM_ID} = "$fam.$id.$crc";
|
||||||
$hash->{INTERVAL} = $interval;
|
$hash->{INTERVAL} = $interval;
|
||||||
|
|
||||||
@ -530,33 +487,6 @@ sub OWMULTI_Get($@) {
|
|||||||
#-- Get other values according to interface type
|
#-- Get other values according to interface type
|
||||||
my $interface= $hash->{IODev}->{TYPE};
|
my $interface= $hash->{IODev}->{TYPE};
|
||||||
|
|
||||||
#-- get present
|
|
||||||
if($a[1] eq "present" ) {
|
|
||||||
#-- OWX interface
|
|
||||||
if( $interface =~ /^OWX/ ){
|
|
||||||
#-- asynchronous mode
|
|
||||||
if( $hash->{ASYNC} ){
|
|
||||||
eval {
|
|
||||||
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
|
|
||||||
};
|
|
||||||
return GP_Catch($@) if $@;
|
|
||||||
return "$name.present => ".ReadingsVal($name,"present","unknown");
|
|
||||||
} else {
|
|
||||||
$value = OWX_Verify($master,$hash->{ROM_ID});
|
|
||||||
}
|
|
||||||
$hash->{PRESENT} = $value;
|
|
||||||
return "$name.present => $value";
|
|
||||||
} else {
|
|
||||||
return "OWMULTI: Verification not yet implemented for interface $interface";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- get interval
|
|
||||||
if($reading eq "interval") {
|
|
||||||
$value = $hash->{INTERVAL};
|
|
||||||
return "$name.interval => $value";
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- get version
|
#-- get version
|
||||||
if( $a[1] eq "version") {
|
if( $a[1] eq "version") {
|
||||||
return "$name.version => $owx_version";
|
return "$name.version => $owx_version";
|
||||||
@ -572,7 +502,7 @@ sub OWMULTI_Get($@) {
|
|||||||
$ret = OWX_ASYNC_RunToCompletion($hash,OWXMULTI_PT_GetValues($hash));
|
$ret = OWX_ASYNC_RunToCompletion($hash,OWXMULTI_PT_GetValues($hash));
|
||||||
};
|
};
|
||||||
$ret = GP_Catch($@) if $@;
|
$ret = GP_Catch($@) if $@;
|
||||||
#-- OWFS interface not yet implemented
|
#-- OWFS interface
|
||||||
}elsif( $interface eq "OWServer" ){
|
}elsif( $interface eq "OWServer" ){
|
||||||
$ret = OWFSMULTI_GetValues($hash);
|
$ret = OWFSMULTI_GetValues($hash);
|
||||||
#-- Unknown interface
|
#-- Unknown interface
|
||||||
@ -582,7 +512,8 @@ sub OWMULTI_Get($@) {
|
|||||||
|
|
||||||
#-- process result
|
#-- process result
|
||||||
if( $master->{ASYNCHRONOUS} ){
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
return "OWSMULTI: $name getting readings, please wait for completion";
|
#return "OWSMULTI: $name getting readings, please wait for completion";
|
||||||
|
return undef;
|
||||||
}else{
|
}else{
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
return "OWMULTI: Could not get values from device $name, reason $ret";
|
return "OWMULTI: Could not get values from device $name, reason $ret";
|
||||||
@ -628,20 +559,17 @@ sub OWMULTI_GetValues($) {
|
|||||||
OWMULTI_InitializeDevice($hash)
|
OWMULTI_InitializeDevice($hash)
|
||||||
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
|
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
|
||||||
|
|
||||||
#-- restart timer for updates
|
RemoveInternalTimer($hash);
|
||||||
RemoveInternalTimer($hash);
|
#-- auto-update for device disabled;
|
||||||
|
return undef
|
||||||
|
if( $hash->{INTERVAL} == 0 );
|
||||||
|
#-- restart timer for updates
|
||||||
InternalTimer(time()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0);
|
InternalTimer(time()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0);
|
||||||
|
|
||||||
|
|
||||||
#-- Get values according to interface type
|
#-- Get values according to interface type
|
||||||
my $interface= $hash->{IODev}->{TYPE};
|
my $interface= $hash->{IODev}->{TYPE};
|
||||||
if( $interface eq "OWX" ){
|
if( $interface eq "OWX" ){
|
||||||
#-- max 3 tries
|
$ret = OWXMULTI_GetValues($hash);
|
||||||
for(my $try=0; $try<3; $try++){
|
|
||||||
$ret = OWXMULTI_GetValues($hash);
|
|
||||||
#ASYNC: Need to wait for some result
|
|
||||||
return if( !defined($ret) );
|
|
||||||
}
|
|
||||||
}elsif( $interface eq "OWX_ASYNC" ){
|
}elsif( $interface eq "OWX_ASYNC" ){
|
||||||
eval {
|
eval {
|
||||||
OWX_ASYNC_Schedule( $hash, OWXMULTI_PT_GetValues($hash) );
|
OWX_ASYNC_Schedule( $hash, OWXMULTI_PT_GetValues($hash) );
|
||||||
@ -715,10 +643,10 @@ sub OWMULTI_Set($@) {
|
|||||||
#-- set new timer interval
|
#-- set new timer interval
|
||||||
if($key eq "interval") {
|
if($key eq "interval") {
|
||||||
# check value
|
# check value
|
||||||
return "OWMULTI: Set with short interval, must be > 1"
|
return "OWMULTI: set $name interval must be >= 0"
|
||||||
if(int($value) < 1);
|
if(int($value) < 0);
|
||||||
# update timer
|
# update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = int($value);
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0);
|
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWMULTI_GetValues", $hash, 0);
|
||||||
return undef;
|
return undef;
|
||||||
@ -875,31 +803,33 @@ sub OWXMULTI_BinValues($$$$$$$) {
|
|||||||
#-- hash of the busmaster
|
#-- hash of the busmaster
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my @data=[];
|
my $error = 0;
|
||||||
|
my @data = [];
|
||||||
my ($value,$lsb,$msb,$sign);
|
my ($value,$lsb,$msb,$sign);
|
||||||
my $msg;
|
my $msg;
|
||||||
OWX_WDBG($name,"OWXMULTI_BinValues called for device $name in context $context with ",$res)
|
|
||||||
if( $main::owx_debug>2 );
|
OWX_WDBGL($name,4,"OWXMULTI_BinValues: called for device $name in context $context with data ",$res);
|
||||||
|
|
||||||
#-- always check for success, unused are reset, numread
|
#-- always check for success, unused are reset, numread
|
||||||
return unless ($context =~ /^ds2438.getv[ad]d$/);
|
return unless ($context =~ /^ds2438.getv[ad]d$/);
|
||||||
|
|
||||||
#Log 1,"OWXMULTI_BinValues context = $context";
|
#-- we have to get rid of the first 11 bytes
|
||||||
|
if( length($res) == 20 ){
|
||||||
#-- process results
|
$res=substr($res,11);
|
||||||
@data=split(//,$res);
|
|
||||||
#-- not useful here, because data may be filled up with ff
|
|
||||||
#if (@data != 9) {
|
|
||||||
# $msg="$name returns invalid data length, ".int(@data)." instead of 9 bytes";
|
|
||||||
if ((ord($data[0]) & 112)!=0) {
|
|
||||||
$msg="$name: conversion not complete or data invalid";
|
|
||||||
}elsif (OWX_CRC8(substr($res,0,8),$data[8])==0) {
|
|
||||||
$msg="$name returns invalid CRC";
|
|
||||||
}else{
|
|
||||||
$msg="No error";
|
|
||||||
}
|
}
|
||||||
OWX_WDBG($name,"OWXMULTI_BinValues: ".$msg,"")
|
@data=split(//,$res);
|
||||||
if( $main::owx_debug>2 );
|
|
||||||
|
#-- process results
|
||||||
|
if ((ord($data[0]) & 112)!=0) {
|
||||||
|
$msg = "$name: conversion not complete or data invalid in context $context ";
|
||||||
|
$error = 1;
|
||||||
|
}elsif (OWX_CRC8(substr($res,0,8),$data[8]) eq "\0x00") {
|
||||||
|
$msg = "$name: invalid CRC ";
|
||||||
|
$error = 1;
|
||||||
|
}else{
|
||||||
|
$msg = "$name: no error, ";
|
||||||
|
}
|
||||||
|
OWX_WDBGL($name,5-4*$error,"OWXMULTI_BinValues: ".$msg,$res);
|
||||||
|
|
||||||
#-- this must be different for the different device types
|
#-- this must be different for the different device types
|
||||||
# family = 26 => DS2438
|
# family = 26 => DS2438
|
||||||
@ -955,9 +885,14 @@ sub OWXMULTI_BinValues($$$$$$$) {
|
|||||||
$hash->{owg_val}->[3] = ($msb*256.+ $lsb)/4096;
|
$hash->{owg_val}->[3] = ($msb*256.+ $lsb)/4096;
|
||||||
|
|
||||||
#-- and now from raw to formatted values
|
#-- and now from raw to formatted values
|
||||||
$hash->{PRESENT} = 1;
|
if( $error ){
|
||||||
my $value = OWMULTI_FormatValues($hash);
|
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1;
|
||||||
};
|
|
||||||
|
}else{
|
||||||
|
$hash->{PRESENT} = 1;
|
||||||
|
OWMULTI_FormatValues($hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,75 +1023,75 @@ sub OWXMULTI_GetValues($) {
|
|||||||
#-- switch the device to current measurement off, VDD only
|
#-- switch the device to current measurement off, VDD only
|
||||||
#-- issue the match ROM command \x55 and the write scratchpad command
|
#-- issue the match ROM command \x55 and the write scratchpad command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
#OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x08", 0, 0, 0, undef, 0);
|
#OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x08", 0, 0, 0, undef, undef);
|
||||||
#-- switch the device to current measurement on, VDD only
|
#-- switch the device to current measurement on, VDD only
|
||||||
#-- issue the match ROM command \x55 and the write scratchpad command
|
#-- issue the match ROM command \x55 and the write scratchpad command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x09", 0, 2, 0, undef, 0.01);
|
OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x09", 0, 2, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- copy scratchpad to register
|
#-- copy scratchpad to register
|
||||||
#-- issue the match ROM command \x55 and the copy scratchpad command
|
#-- issue the match ROM command \x55 and the copy scratchpad command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "copy SP", 0, $owx_dev, "\x48\x00", 0, 1, 0, undef, 0.01);
|
OWX_Qomplex($master, $hash, "copy SP", 0, $owx_dev, "\x48\x00", 0, 1, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- initiate temperature conversion
|
#-- initiate temperature conversion
|
||||||
#-- conversion needs some 12 ms !
|
#-- conversion needs some 12 ms !
|
||||||
#-- issue the match ROM command \x55 and the start conversion command
|
#-- issue the match ROM command \x55 and the start conversion command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "T conversion", 0, $owx_dev, "\x44", 0, 0, 0, undef, 0.02);
|
OWX_Qomplex($master, $hash, "T conversion", 0, $owx_dev, "\x44", 0, 0, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- initiate voltage conversion
|
#-- initiate voltage conversion
|
||||||
#-- conversion needs some 6 ms !
|
#-- conversion needs some 6 ms !
|
||||||
#-- issue the match ROM command \x55 and the start conversion command
|
#-- issue the match ROM command \x55 and the start conversion command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "V conversion", 0, $owx_dev, "\xB4", 0, 0, 0, undef, 0.01);
|
OWX_Qomplex($master, $hash, "V conversion", 0, $owx_dev, "\xB4", 0, 0, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- from memory to scratchpad
|
#-- from memory to scratchpad
|
||||||
#-- copy needs some 12 ms !
|
#-- copy needs some 12 ms !
|
||||||
#-- issue the match ROM command \x55 and the recall memory command
|
#-- issue the match ROM command \x55 and the recall memory command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "recall", 0, $owx_dev, "\xB8\x00", 0, 2, 0, undef, 0.02);
|
OWX_Qomplex($master, $hash, "recall", 0, $owx_dev, "\xB8\x00", 0, 2, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- NOW ask the specific device
|
#-- NOW ask the specific device
|
||||||
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
||||||
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
# 1 provides additional reset after last operation
|
# 1 provides additional reset after last operation
|
||||||
OWX_Qomplex($master, $hash, "ds2438.getvdd", 1, $owx_dev, "\xBE\x00\x08", 0, 9, 11, \&OWXMULTI_BinValues, 0.01);
|
OWX_Qomplex($master, $hash, "ds2438.getvdd", 1, $owx_dev, "\xBE\x00", 0, 20, 0, \&OWXMULTI_BinValues, 0.015);
|
||||||
|
|
||||||
#-- switch the device to current measurement off, V external only
|
#-- switch the device to current measurement off, V external only
|
||||||
#-- issue the match ROM command \x55 and the write scratchpad command
|
#-- issue the match ROM command \x55 and the write scratchpad command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
#OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x00", 0, 0, 0, undef, 0);
|
#OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x00", 0, 0, 0, undef, undef);
|
||||||
#-- switch the device to current measurement on, V external only
|
#-- switch the device to current measurement on, V external only
|
||||||
#-- issue the match ROM command \x55 and the write scratchpad command
|
#-- issue the match ROM command \x55 and the write scratchpad command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x01", 0, 1, 0, undef, 0.01);
|
OWX_Qomplex($master, $hash, "write SP", 0, $owx_dev, "\x4E\x00\x01", 0, 1, 0, undef, 0.015);
|
||||||
|
|
||||||
|
|
||||||
#-- copy scratchpad to register
|
#-- copy scratchpad to register
|
||||||
#-- issue the match ROM command \x55 and the copy scratchpad command
|
#-- issue the match ROM command \x55 and the copy scratchpad command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "copy SP", 0, $owx_dev, "\x48\x00", 0, 1, 0, undef, 0.01);
|
OWX_Qomplex($master, $hash, "copy SP", 0, $owx_dev, "\x48\x00", 0, 1, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- initiate voltage conversion
|
#-- initiate voltage conversion
|
||||||
#-- conversion needs some 6 ms !
|
#-- conversion needs some 6 ms !
|
||||||
#-- issue the match ROM command \x55 and the start conversion command
|
#-- issue the match ROM command \x55 and the start conversion command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "V conversion", 0, $owx_dev, "\xB4", 0, 0, 0, undef, 0.01);
|
OWX_Qomplex($master, $hash, "V conversion", 0, $owx_dev, "\xB4", 0, 0, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- from memory to scratchpad
|
#-- from memory to scratchpad
|
||||||
#-- copy needs some 12 ms !
|
#-- copy needs some 12 ms !
|
||||||
#-- issue the match ROM command \x55 and the recall memory command
|
#-- issue the match ROM command \x55 and the recall memory command
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "recall", 0, $owx_dev, "\xB8\x00", 0, 1, 0, undef, 0.02);
|
OWX_Qomplex($master, $hash, "recall", 0, $owx_dev, "\xB8\x00", 0, 1, 0, undef, 0.015);
|
||||||
|
|
||||||
#-- NOW ask the specific device
|
#-- NOW ask the specific device
|
||||||
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
#-- issue the match ROM command \x55 and the read scratchpad command \xBE
|
||||||
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
#-- reading 9 + 2 + 9 data bytes = 20 bytes
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
# 1 provides additional reset after last operation
|
# 1 provides additional reset after last operation
|
||||||
OWX_Qomplex($master, $hash, "ds2438.getvad", 1, $owx_dev, "\xBE\x00", 0, 9, 11, \&OWXMULTI_BinValues, 0.01);
|
OWX_Qomplex($master, $hash, "ds2438.getvad", 1, $owx_dev, "\xBE\x00", 0, 20, 0, \&OWXMULTI_BinValues, 0.015);
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -1444,14 +1379,14 @@ sub OWXMULTI_PT_SetValues($@) {
|
|||||||
code </li>
|
code </li>
|
||||||
<li>
|
<li>
|
||||||
<code><interval></code>
|
<code><interval></code>
|
||||||
<br />Measurement interval in seconds. The default is 300 seconds. </li>
|
<br />Measurement interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update. </li>
|
||||||
</ul>
|
</ul>
|
||||||
<a name="OWMULTIset"></a>
|
<a name="OWMULTIset"></a>
|
||||||
<h4>Set</h4>
|
<h4>Set</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a name="owmulti_interval">
|
<li><a name="owmulti_interval">
|
||||||
<code>set <name> interval <int></code></a><br /> Measurement
|
<code>set <name> interval <int></code></a><br /> Measurement
|
||||||
interval in seconds. The default is 300 seconds. </li>
|
interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update. </li>
|
||||||
</ul>
|
</ul>
|
||||||
<a name="OWMULTIget"></a>
|
<a name="OWMULTIget"></a>
|
||||||
<h4>Get</h4>
|
<h4>Get</h4>
|
||||||
@ -1459,13 +1394,6 @@ sub OWXMULTI_PT_SetValues($@) {
|
|||||||
<li><a name="owmulti_id">
|
<li><a name="owmulti_id">
|
||||||
<code>get <name> id</code></a>
|
<code>get <name> id</code></a>
|
||||||
<br /> Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC </li>
|
<br /> Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC </li>
|
||||||
<li><a name="owmulti_present">
|
|
||||||
<code>get <name> present</code>
|
|
||||||
</a>
|
|
||||||
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
|
|
||||||
<li><a name="owmulti_interval2">
|
|
||||||
<code>get <name> interval</code></a><br />Returns measurement interval in
|
|
||||||
seconds. </li>
|
|
||||||
<li><a name="owmulti_reading">
|
<li><a name="owmulti_reading">
|
||||||
<code>get <name> reading</code></a><br />Obtain all three measurement values. </li>
|
<code>get <name> reading</code></a><br />Obtain all three measurement values. </li>
|
||||||
<li><a name="owmulti_temperature">
|
<li><a name="owmulti_temperature">
|
||||||
@ -1477,7 +1405,9 @@ sub OWXMULTI_PT_SetValues($@) {
|
|||||||
</ul>
|
</ul>
|
||||||
<a name="OWMULTIattr"></a>
|
<a name="OWMULTIattr"></a>
|
||||||
<h4>Attributes</h4>
|
<h4>Attributes</h4>
|
||||||
<ul>
|
<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 name="owmulti_vname"><code>attr <name> VName
|
<li><a name="owmulti_vname"><code>attr <name> VName
|
||||||
<string>[|<string>]</code></a>
|
<string>[|<string>]</code></a>
|
||||||
<br />name for the voltage channel [|short name used in state reading]. </li>
|
<br />name for the voltage channel [|short name used in state reading]. </li>
|
||||||
|
@ -11,46 +11,6 @@
|
|||||||
#
|
#
|
||||||
########################################################################################
|
########################################################################################
|
||||||
#
|
#
|
||||||
# define <name> OWSWITCH [<model>] <ROM_ID> [interval] or OWSWITCH <fam>.<ROM_ID> [interval]
|
|
||||||
#
|
|
||||||
# where <name> may be replaced by any name string
|
|
||||||
#
|
|
||||||
# <model> is a 1-Wire device type. If omitted, we assume this to be an
|
|
||||||
# DS2413. Allowed values are DS2413, DS2406, DS2408
|
|
||||||
# <fam> is a 1-Wire family id, currently allowed values are 12, 29, 3A
|
|
||||||
# <ROM_ID> is a 12 character (6 byte) 1-Wire ROM ID
|
|
||||||
# without Family ID, e.g. A2D90D000800
|
|
||||||
# [interval] is an optional query interval in seconds
|
|
||||||
#
|
|
||||||
# get <name> id => FAM_ID.ROM_ID.CRC
|
|
||||||
# get <name> present => 1 if device present, 0 if not
|
|
||||||
# get <name> interval => query interval
|
|
||||||
# get <name> input <channel-name> => state for channel (name A, B or defined channel name)
|
|
||||||
# note: this value reflects the measured value, not necessarily the one set as
|
|
||||||
# output state, because the output transistors are open collector switches. A measured
|
|
||||||
# state of 1 = OFF therefore corresponds to an output state of 1 = OFF, but a measured
|
|
||||||
# state of 0 = ON can also be due to an external shortening of the output.
|
|
||||||
# get <name> gpio => values for channels
|
|
||||||
# get <name> version => OWX version number
|
|
||||||
#
|
|
||||||
# set <name> interval => set period for measurement
|
|
||||||
# set <name> output <channel-name> on|off|on-for-timer <int>|on-for-timer <int>
|
|
||||||
# => set value for channel (name A, B or defined channel name)
|
|
||||||
# note: 1 = OFF, 0 = ON in normal usage. See also the note above
|
|
||||||
# ON-for-timer/OFF-for-timer will set the desired value only for <int> seconds
|
|
||||||
# and then will return to the opposite value.
|
|
||||||
# set <name> gpio value => set values for channels (3 = both OFF, 1 = B ON 2 = A ON 0 = both ON)
|
|
||||||
# set <name> init yes => re-initialize device
|
|
||||||
#
|
|
||||||
# Additional attributes are defined in fhem.cfg, in some cases per channel, where <channel>=A,B
|
|
||||||
# Note: attributes are read only during initialization procedure - later changes are not used.
|
|
||||||
#
|
|
||||||
# attr <name> stateS <string> = character string denoting external shortening condition, default is X
|
|
||||||
# attr <name> <channel>Name <string>|<string> = name for the channel [|short name used in state reading]
|
|
||||||
# attr <name> <channel>Unit <string>|<string> = values to display in state variable for on|off condition
|
|
||||||
#
|
|
||||||
########################################################################################
|
|
||||||
#
|
|
||||||
# This programm is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
@ -87,15 +47,13 @@ no warnings 'deprecated';
|
|||||||
|
|
||||||
sub Log($$);
|
sub Log($$);
|
||||||
|
|
||||||
my $owx_version="6.11";
|
my $owx_version="7.0";
|
||||||
#-- fixed raw channel name, flexible channel name
|
#-- fixed raw channel name, flexible channel name
|
||||||
my @owg_fixed = ("A","B","C","D","E","F","G","H");
|
my @owg_fixed = ("A","B","C","D","E","F","G","H");
|
||||||
my @owg_channel = ("A","B","C","D","E","F","G","H");
|
my @owg_channel = ("A","B","C","D","E","F","G","H");
|
||||||
|
|
||||||
my %gets = (
|
my %gets = (
|
||||||
"id" => "",
|
"id" => "",
|
||||||
"present" => "",
|
|
||||||
"interval" => "",
|
|
||||||
"input" => "",
|
"input" => "",
|
||||||
"gpio" => "",
|
"gpio" => "",
|
||||||
"version" => ""
|
"version" => ""
|
||||||
@ -251,6 +209,7 @@ sub OWSWITCH_Define ($$) {
|
|||||||
$hash->{OW_ID} = $id;
|
$hash->{OW_ID} = $id;
|
||||||
$hash->{OW_FAMILY} = $fam;
|
$hash->{OW_FAMILY} = $fam;
|
||||||
$hash->{PRESENT} = 0;
|
$hash->{PRESENT} = 0;
|
||||||
|
$hash->{ERRCOUNT} = 0;
|
||||||
$hash->{INTERVAL} = $interval;
|
$hash->{INTERVAL} = $interval;
|
||||||
|
|
||||||
#-- Couple to I/O device
|
#-- Couple to I/O device
|
||||||
@ -326,9 +285,9 @@ sub OWSWITCH_Attr(@) {
|
|||||||
#-- interval modified at runtime
|
#-- interval modified at runtime
|
||||||
$key eq "interval" and do {
|
$key eq "interval" and do {
|
||||||
#-- check value
|
#-- check value
|
||||||
return "OWSWITCH: Set with short interval, must be > 1" if(int($value) < 1);
|
return "OWSWITCH: set $name interval must be >= 0" if(int($value) < 0);
|
||||||
#-- update timer
|
#-- update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = int($value);
|
||||||
if ($init_done) {
|
if ($init_done) {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
|
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
|
||||||
@ -490,28 +449,6 @@ sub OWSWITCH_Get($@) {
|
|||||||
|
|
||||||
#-- hash of the busmaster
|
#-- hash of the busmaster
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
|
|
||||||
#-- get present
|
|
||||||
if($a[1] eq "present") {
|
|
||||||
#-- asynchronous mode
|
|
||||||
if( $hash->{ASYNC} ){
|
|
||||||
eval {
|
|
||||||
OWX_ASYNC_RunToCompletion($hash,OWX_ASYNC_PT_Verify($hash));
|
|
||||||
};
|
|
||||||
return GP_Catch($@) if $@;
|
|
||||||
return "$name.present => ".ReadingsVal($name,"present","unknown");
|
|
||||||
} else {
|
|
||||||
$value = OWX_Verify($master,$hash->{ROM_ID});
|
|
||||||
}
|
|
||||||
$hash->{PRESENT} = $value;
|
|
||||||
return "$name.present => $value";
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- get interval
|
|
||||||
if($a[1] eq "interval") {
|
|
||||||
$value = $hash->{INTERVAL};
|
|
||||||
return "$name.interval => $value";
|
|
||||||
}
|
|
||||||
|
|
||||||
#-- get version
|
#-- get version
|
||||||
if( $a[1] eq "version") {
|
if( $a[1] eq "version") {
|
||||||
@ -547,15 +484,16 @@ sub OWSWITCH_Get($@) {
|
|||||||
};
|
};
|
||||||
$ret = GP_Catch($@) if $@;
|
$ret = GP_Catch($@) if $@;
|
||||||
#-- OWFS interface
|
#-- OWFS interface
|
||||||
}elsif( $interface eq "OWFS" ){
|
}elsif( $interface eq "OWServer" ){
|
||||||
$ret = OWFSSWITCH_GetState($hash);
|
$ret = OWFSSWITCH_GetState($hash);
|
||||||
#-- Unknown interface
|
#-- Unknown interface
|
||||||
}else{
|
}else{
|
||||||
return "OWSWITCH: Get with wrong IODev type $interface";
|
return "OWSWITCH: Get with wrong IODev type $interface";
|
||||||
}
|
}
|
||||||
#-- process result
|
#-- process result
|
||||||
if( ($master->{ASYNCHRONOUS}) && ($interface ne "OWFS") ){
|
if( ($master->{ASYNCHRONOUS}) && ($interface ne "OWServer") ){
|
||||||
return "OWSWITCH: $name getting input, please wait for completion";
|
#return "OWSWITCH: $name getting input, please wait for completion";
|
||||||
|
return undef;
|
||||||
}else{
|
}else{
|
||||||
return $name.".".$a[2]." => ".$hash->{READINGS}{$owg_channel[$fnd]}{VAL};
|
return $name.".".$a[2]." => ".$hash->{READINGS}{$owg_channel[$fnd]}{VAL};
|
||||||
}
|
}
|
||||||
@ -579,7 +517,8 @@ sub OWSWITCH_Get($@) {
|
|||||||
}
|
}
|
||||||
#-- process results
|
#-- process results
|
||||||
if( $master->{ASYNCHRONOUS} ){
|
if( $master->{ASYNCHRONOUS} ){
|
||||||
return "OWSWITCH: $name getting gpio, please wait for completion";
|
#return "OWSWITCH: $name getting gpio, please wait for completion";
|
||||||
|
return undef;
|
||||||
}else{
|
}else{
|
||||||
if( defined($ret) ){
|
if( defined($ret) ){
|
||||||
return "OWSWITCH: Could not get values from device $name, reason $ret";
|
return "OWSWITCH: Could not get values from device $name, reason $ret";
|
||||||
@ -609,8 +548,11 @@ sub OWSWITCH_GetValues($) {
|
|||||||
OWSWITCH_InitializeDevice($hash)
|
OWSWITCH_InitializeDevice($hash)
|
||||||
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
|
if( $hash->{READINGS}{"state"}{VAL} eq "defined");
|
||||||
|
|
||||||
#-- restart timer for updates
|
RemoveInternalTimer($hash);
|
||||||
RemoveInternalTimer($hash);
|
#-- auto-update for device disabled;
|
||||||
|
return undef
|
||||||
|
if( $hash->{INTERVAL} == 0 );
|
||||||
|
#-- restart timer for updates
|
||||||
InternalTimer(time()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
|
InternalTimer(time()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
|
||||||
|
|
||||||
#-- Get readings according to interface type
|
#-- Get readings according to interface type
|
||||||
@ -714,10 +656,10 @@ sub OWSWITCH_Set($@) {
|
|||||||
#-- set new timer interval
|
#-- set new timer interval
|
||||||
if($key eq "interval") {
|
if($key eq "interval") {
|
||||||
# check value
|
# check value
|
||||||
return "OWSWITCH: Set with short interval, must be > 1"
|
return "OWSWITCH: set $name interval must be >= 0"
|
||||||
if(int($value) < 1);
|
if(int($value) < 0);
|
||||||
# update timer
|
# update timer
|
||||||
$hash->{INTERVAL} = $value;
|
$hash->{INTERVAL} = int($value);
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
|
InternalTimer(gettimeofday()+$hash->{INTERVAL}, "OWSWITCH_GetValues", $hash, 0);
|
||||||
return undef;
|
return undef;
|
||||||
@ -1025,7 +967,8 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
#-- hash of the busmaster
|
#-- hash of the busmaster
|
||||||
my $master = $hash->{IODev};
|
my $master = $hash->{IODev};
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my @data=[];
|
my $error = 0;
|
||||||
|
my @data = [];
|
||||||
my $value;
|
my $value;
|
||||||
my $msg;
|
my $msg;
|
||||||
my $cmd;
|
my $cmd;
|
||||||
@ -1033,8 +976,7 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
my $outfnd;
|
my $outfnd;
|
||||||
my $outval;
|
my $outval;
|
||||||
|
|
||||||
OWX_WDBG($name,"OWXSWITCH_BinValues called for device $name in context $context with data ",$res)
|
OWX_WDBGL($name,4,"OWXSWITCH_BinValues: called for device $name in context $context with data ",$res);
|
||||||
if( $main::owx_debug>2 );
|
|
||||||
|
|
||||||
#-- note: value 1 corresponds to OFF, 0 to ON normally
|
#-- note: value 1 corresponds to OFF, 0 to ON normally
|
||||||
# val = input value, vax = output value
|
# val = input value, vax = output value
|
||||||
@ -1048,13 +990,21 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
#-- initial get operation
|
#-- initial get operation
|
||||||
#-- family = 12 => DS2406 -------------------------------------------------------
|
#-- family = 12 => DS2406 -------------------------------------------------------
|
||||||
if( $chip eq "ds2406" ) {
|
if( $chip eq "ds2406" ) {
|
||||||
|
#-- we have to get rid of the first 12 bytes
|
||||||
|
if( length($res) == 16 ){
|
||||||
|
$res=substr($res,12);
|
||||||
|
}
|
||||||
@data=split(//,$res);
|
@data=split(//,$res);
|
||||||
|
$crcpart = $crcpart.substr($res,0,2);
|
||||||
|
|
||||||
if (@data != 4){
|
if (@data != 4){
|
||||||
$msg="Error - $name returns invalid data length, ".int(@data)." instead of 4 bytes, ";
|
$error = 1;
|
||||||
}elsif(OWX_CRC16($crcpart.substr($res,0,2),$data[2],$data[3]) == 0){
|
$msg = "$name: invalid data length in $context, ".int(@data)." instead of 4 bytes, ";
|
||||||
$msg="Error - state could not be set for device $name, invalid CRC, ";
|
}elsif(OWX_CRC16($crcpart,$data[2],$data[3]) == 0){
|
||||||
|
$error = 1;
|
||||||
|
$msg = "$name: invalid CRC in getstate, ";
|
||||||
}else{
|
}else{
|
||||||
$msg="No error, ";
|
$msg = "$name: no error, ";
|
||||||
$value=ord($data[0]);
|
$value=ord($data[0]);
|
||||||
$hash->{owg_val}->[0] = ($value>>2) & 1;
|
$hash->{owg_val}->[0] = ($value>>2) & 1;
|
||||||
$hash->{owg_vax}->[0] = $value & 1;
|
$hash->{owg_vax}->[0] = $value & 1;
|
||||||
@ -1064,15 +1014,24 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
}
|
}
|
||||||
#-- family = 29 => DS2408 -------------------------------------------------------
|
#-- family = 29 => DS2408 -------------------------------------------------------
|
||||||
}elsif( $chip eq "ds2408" ) {
|
}elsif( $chip eq "ds2408" ) {
|
||||||
|
#-- we have to get rid of the first 12 bytes
|
||||||
|
if( length($res) == 22 ){
|
||||||
|
$res=substr($res,12);
|
||||||
|
}
|
||||||
@data=split(//,$res);
|
@data=split(//,$res);
|
||||||
if (@data != 10){
|
$crcpart = $crcpart.substr($res,0,8);
|
||||||
$msg="Error - $name returns invalid data length, ".int(@data)." instead of 10 bytes, ";
|
|
||||||
|
if (@data < 10){
|
||||||
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data length in $context, ".int(@data)." instead of >=10 bytes, ";
|
||||||
}elsif(ord($data[6])!=255){
|
}elsif(ord($data[6])!=255){
|
||||||
$msg="Error - $name returns invalid data, ";
|
$error = 1;
|
||||||
}elsif(OWX_CRC16($crcpart.substr($res,0,8),$data[8],$data[9]) == 0){
|
$msg = "$name: invalid data in getstate, ";
|
||||||
$msg="Error - state could not be set for device $name, invalid CRC, ";
|
}elsif(OWX_CRC16($crcpart,$data[8],$data[9]) == 0){
|
||||||
|
$error = 1;
|
||||||
|
$msg = "$name: invalid CRC in getstate, ";
|
||||||
}else{
|
}else{
|
||||||
$msg="No error, ";
|
$msg = "$name: no error, ";
|
||||||
for(my $i=0;$i<8;$i++){
|
for(my $i=0;$i<8;$i++){
|
||||||
$hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1;
|
$hash->{owg_val}->[$i] = (ord($data[0])>>$i) & 1;
|
||||||
$hash->{owg_vax}->[$i] = (ord($data[1])>>$i) & 1;
|
$hash->{owg_vax}->[$i] = (ord($data[1])>>$i) & 1;
|
||||||
@ -1080,27 +1039,33 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
}
|
}
|
||||||
#-- family = 3A => DS2413 -------------------------------------------------------
|
#-- family = 3A => DS2413 -------------------------------------------------------
|
||||||
}elsif( $chip eq "ds2413" ){
|
}elsif( $chip eq "ds2413" ){
|
||||||
|
#-- we have to get rid of the first 10 bytes
|
||||||
|
if( length($res) == 12 ){
|
||||||
|
$res=substr($res,10);
|
||||||
|
}
|
||||||
@data=split(//,$res);
|
@data=split(//,$res);
|
||||||
|
|
||||||
if (@data != 2){
|
if (@data != 2){
|
||||||
$msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data length in $context, ".int(@data)." instead of 2 bytes, ";
|
||||||
}elsif((15- (ord($data[0])>>4)) != (ord($data[0]) & 15)){
|
}elsif((15- (ord($data[0])>>4)) != (ord($data[0]) & 15)){
|
||||||
$msg="Error - $name returns invalid data, ";
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data in getstate, ";
|
||||||
}else{
|
}else{
|
||||||
$msg="No error, ";
|
$msg ="$name: no error, ";
|
||||||
$hash->{owg_val}->[0] = ord($data[0]) & 1;
|
$hash->{owg_val}->[0] = ord($data[0]) & 1;
|
||||||
$hash->{owg_vax}->[0] = (ord($data[0])>>1) & 1;
|
$hash->{owg_vax}->[0] = (ord($data[0])>>1) & 1;
|
||||||
$hash->{owg_val}->[1] = (ord($data[0])>>2) & 1;
|
$hash->{owg_val}->[1] = (ord($data[0])>>2) & 1;
|
||||||
$hash->{owg_vax}->[1] = (ord($data[0])>>3) & 1;
|
$hash->{owg_vax}->[1] = (ord($data[0])>>3) & 1;
|
||||||
}
|
}
|
||||||
#--
|
|
||||||
}else{
|
|
||||||
die "OWSWITCH: $name has unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues getstate\n";
|
|
||||||
};
|
};
|
||||||
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
|
main::OWX_WDBGL($name,5-4*$error,"OWXSWITCH_BinValues $context: ".$msg,$res);
|
||||||
if( $main::owx_debug>2 );
|
|
||||||
|
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1
|
||||||
|
if( $error );
|
||||||
|
|
||||||
#-- Formatting only after final get
|
#-- Formatting only after final get
|
||||||
if( $outfnd eq "final"){
|
if( defined($outfnd) && ($outfnd eq "final") && !$error ){
|
||||||
$hash->{PRESENT} = 1;
|
$hash->{PRESENT} = 1;
|
||||||
$value = OWSWITCH_FormatValues($hash);
|
$value = OWSWITCH_FormatValues($hash);
|
||||||
return undef;
|
return undef;
|
||||||
@ -1128,13 +1093,20 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
$value = $2;
|
$value = $2;
|
||||||
#-- family = 12 => DS2406 -------------------------------------------------------
|
#-- family = 12 => DS2406 -------------------------------------------------------
|
||||||
if( $chip eq "ds2406" ) {
|
if( $chip eq "ds2406" ) {
|
||||||
|
#-- we have to get rid of the first 13 bytes
|
||||||
|
if( length($res) == 15 ){
|
||||||
|
$res=substr($res,13);
|
||||||
|
}
|
||||||
@data=split(//,$res);
|
@data=split(//,$res);
|
||||||
|
|
||||||
if (@data != 2){
|
if (@data != 2){
|
||||||
$msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data length in setstate, ".int(@data)." instead of 2 bytes, ";
|
||||||
}elsif(OWX_CRC16($crcpart,$data[0],$data[1]) == 0){
|
}elsif(OWX_CRC16($crcpart,$data[0],$data[1]) == 0){
|
||||||
$msg="Error - state could not be set for device $name, invalid CRC, ";
|
$error = 1;
|
||||||
|
$msg = "$name: invalid CRC in setstate, ";
|
||||||
}else{
|
}else{
|
||||||
$msg="No error, ";
|
$msg = "$name: no error, ";
|
||||||
$hash->{owg_val}->[0] = ($value>>2) & 1;
|
$hash->{owg_val}->[0] = ($value>>2) & 1;
|
||||||
$hash->{owg_vax}->[0] = $value & 1;
|
$hash->{owg_vax}->[0] = $value & 1;
|
||||||
$hash->{owg_val}->[1] = ($value>>3) & 1;
|
$hash->{owg_val}->[1] = ($value>>3) & 1;
|
||||||
@ -1142,12 +1114,20 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
}
|
}
|
||||||
#-- family = 29 => DS2408 -------------------------------------------------------
|
#-- family = 29 => DS2408 -------------------------------------------------------
|
||||||
}elsif( $chip eq "ds2408" ) {
|
}elsif( $chip eq "ds2408" ) {
|
||||||
if (length($res)!=1){
|
#-- we have to get rid of the first 12 bytes
|
||||||
$msg="Error - $name returns invalid data length, ".length($res)." instead of 1 bytes, ";
|
if( length($res) == 13 ){
|
||||||
}elsif($res ne "\xAA"){
|
$res=substr($res,12);
|
||||||
$msg="Error - state could not be set for device $name, ";
|
}
|
||||||
|
@data=split(//,$res);
|
||||||
|
|
||||||
|
if (@data !=1 ){
|
||||||
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data length in setstate, ".int(@data)." instead of 1 bytes, ";
|
||||||
|
}elsif($data[0] ne "\xAA"){
|
||||||
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data in setstate, ";
|
||||||
}else{
|
}else{
|
||||||
$msg="No error, ";
|
$msg = "$name: no error, ";
|
||||||
for(my $i=0;$i<8;$i++){
|
for(my $i=0;$i<8;$i++){
|
||||||
$outval = ($value >>$i) & 1;
|
$outval = ($value >>$i) & 1;
|
||||||
$hash->{owg_vax}->[$i] = $outval;
|
$hash->{owg_vax}->[$i] = $outval;
|
||||||
@ -1157,13 +1137,20 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
}
|
}
|
||||||
#-- family = 3A => DS2413 -------------------------------------------------------
|
#-- family = 3A => DS2413 -------------------------------------------------------
|
||||||
}elsif( $chip eq "ds2413" ){
|
}elsif( $chip eq "ds2413" ){
|
||||||
|
#-- we have to get rid of the first 12 bytes
|
||||||
|
if( length($res) == 14 ){
|
||||||
|
$res=substr($res,12);
|
||||||
|
}
|
||||||
@data=split(//,$res);
|
@data=split(//,$res);
|
||||||
|
|
||||||
if (@data != 2){
|
if (@data != 2){
|
||||||
$msg="Error - $name returns invalid data length, ".int(@data)." instead of 2 bytes, ";
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data length in setstate, ".int(@data)." instead of 2 bytes, ";
|
||||||
}elsif( $data[0] ne "\xAA"){
|
}elsif( $data[0] ne "\xAA"){
|
||||||
$msg="Error - state could not be set for device $name, ";
|
$error = 1;
|
||||||
|
$msg = "$name: invalid data in setstate, ";
|
||||||
}else{
|
}else{
|
||||||
$msg="No error, ";
|
$msg = "$name: no error, ";
|
||||||
$outval = (ord($data[1])>>1) & 1;
|
$outval = (ord($data[1])>>1) & 1;
|
||||||
$hash->{owg_vax}->[0] = $outval;
|
$hash->{owg_vax}->[0] = $outval;
|
||||||
$hash->{owg_val}->[0] = 0
|
$hash->{owg_val}->[0] = 0
|
||||||
@ -1174,15 +1161,12 @@ sub OWXSWITCH_BinValues($$$$$$$) {
|
|||||||
if( $outval ==0);
|
if( $outval ==0);
|
||||||
}
|
}
|
||||||
#--
|
#--
|
||||||
}else{
|
}
|
||||||
die "OWSWITCH: $name has unknown device family $hash->{OW_FAMILY} in OWXSWITCH_BinValues setstate\n";
|
OWX_WDBGL($name,5-4*$error,"OWXSWITCH_BinValues $context: ".$msg,$res);
|
||||||
};
|
$hash->{ERRCOUNT}=$hash->{ERRCOUNT}+1
|
||||||
OWX_WDBG($name,"OWXSWITCH_BinValues: ".$msg,$res)
|
if( $error );
|
||||||
if( $main::owx_debug>2 );
|
|
||||||
#-- and finally after setstate follows another getstate
|
#-- and finally after setstate follows another getstate
|
||||||
OWXSWITCH_GetModState($hash,"final",undef);
|
OWXSWITCH_GetModState($hash,"final",undef);
|
||||||
}else{
|
|
||||||
die "OWSWITCH: unknown context $context in OWXSWITCH_BinValues";
|
|
||||||
}
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -1219,15 +1203,15 @@ sub OWXSWITCH_GetModState($$$) {
|
|||||||
if( !defined($outfnd) ){
|
if( !defined($outfnd) ){
|
||||||
$context = "getstate";
|
$context = "getstate";
|
||||||
#-- take your time
|
#-- take your time
|
||||||
$proc = 0;
|
$proc = 1;
|
||||||
}elsif( $outfnd eq "final"){
|
}elsif( $outfnd eq "final"){
|
||||||
$context = "getstate.final";
|
$context = "getstate.final";
|
||||||
#-- faster !
|
#-- faster !
|
||||||
$proc = 16;
|
$proc = 1;
|
||||||
}else{
|
}else{
|
||||||
$context = "modstate.$outfnd.$outval";
|
$context = "modstate.$outfnd.$outval";
|
||||||
#-- faster !
|
#-- faster !
|
||||||
$proc = 16;
|
$proc = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- family = 12 => DS2406
|
#-- family = 12 => DS2406
|
||||||
@ -1246,14 +1230,13 @@ sub OWXSWITCH_GetModState($$$) {
|
|||||||
return "OWSWITCH: $name has returned invalid data"
|
return "OWSWITCH: $name has returned invalid data"
|
||||||
if( length($res)!=16);
|
if( length($res)!=16);
|
||||||
#OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
eval {
|
return OWXSWITCH_BinValues($hash,"ds2406.$context",undef,$owx_dev,$select,4,substr($res,12));
|
||||||
OWXSWITCH_BinValues($hash,"ds2406.$context",undef,$owx_dev,$select,4,substr($res,12));
|
|
||||||
};
|
|
||||||
return $@ ? $@ : undef;
|
|
||||||
#-- NEW OWX interface
|
#-- NEW OWX interface
|
||||||
}else{
|
}else{
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "ds2406.$context", $proc, $owx_dev, $select, $select, 4, 12, \&OWXSWITCH_BinValues, 0);
|
#OWX_Qomplex($master, $hash, "ds2406.$context", $proc, $owx_dev, $select, $select, 4, 12, \&OWXSWITCH_BinValues, 0.05);
|
||||||
|
OWX_Qomplex($master, $hash, "ds2406.$context", $proc, $owx_dev, $select, $select, 16, 0, \&OWXSWITCH_BinValues, 0.05);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
#-- family = 29 => DS2408
|
#-- family = 29 => DS2408
|
||||||
@ -1272,14 +1255,13 @@ sub OWXSWITCH_GetModState($$$) {
|
|||||||
return "OWSWITCH: $name has returned invalid data"
|
return "OWSWITCH: $name has returned invalid data"
|
||||||
if( length($res)!=22);
|
if( length($res)!=22);
|
||||||
#OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
eval {
|
return OWXSWITCH_BinValues($hash,"ds2408.$context",0,$owx_dev,$select,4,substr($res,12));
|
||||||
OWXSWITCH_BinValues($hash,"ds2408.$context",0,$owx_dev,$select,4,substr($res,12));
|
|
||||||
};
|
|
||||||
return $@ ? $@ : undef;
|
|
||||||
#-- NEW OWX interface
|
#-- NEW OWX interface
|
||||||
}else{
|
}else{
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "ds2408.$context", $proc, $owx_dev, $select, $select,10, 12, \&OWXSWITCH_BinValues, 0);
|
#OWX_Qomplex($master, $hash, "ds2408.$context", $proc, $owx_dev, $select, $select,12, 12, \&OWXSWITCH_BinValues, 0.05);
|
||||||
|
OWX_Qomplex($master, $hash, "ds2408.$context", $proc, $owx_dev, $select, $select, 22, 0, \&OWXSWITCH_BinValues, 0.05);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
#-- family = 3A => DS2413
|
#-- family = 3A => DS2413
|
||||||
@ -1297,14 +1279,13 @@ sub OWXSWITCH_GetModState($$$) {
|
|||||||
return "OWSWITCH: $name has returned invalid data"
|
return "OWSWITCH: $name has returned invalid data"
|
||||||
if( length($res)!=12);
|
if( length($res)!=12);
|
||||||
#OWX_Reset($master);
|
#OWX_Reset($master);
|
||||||
eval {
|
return OWXSWITCH_BinValues($hash,"ds2413.$context",0,$owx_dev,substr($res,9,1),2,substr($res,10));
|
||||||
OWXSWITCH_BinValues($hash,"ds2413.$context",0,$owx_dev,substr($res,9,1),2,substr($res,10));
|
|
||||||
};
|
|
||||||
return $@ ? $@ : undef;
|
|
||||||
#-- NEW OWX interface
|
#-- NEW OWX interface
|
||||||
}else{
|
}else{
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
OWX_Qomplex($master, $hash, "ds2413.$context", $proc, $owx_dev, "\xF5", "\xF5", 2, 10, \&OWXSWITCH_BinValues, 0);
|
#OWX_Qomplex($master, $hash, "ds2413.$context", $proc, $owx_dev, "\xF5", "\xF5", 2, 10, \&OWXSWITCH_BinValues, 0.05);
|
||||||
|
OWX_Qomplex($master, $hash, "ds2413.$context", $proc, $owx_dev, "\xF5", "\xF5", 12, 0, \&OWXSWITCH_BinValues, 0.05);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1353,10 +1334,10 @@ sub OWXSWITCH_SetState($$) {
|
|||||||
return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",0,$owx_dev,$select,2,substr($res,13));
|
return OWXSWITCH_BinValues($hash,"ds2406.setstate.$value",0,$owx_dev,$select,2,substr($res,13));
|
||||||
#-- NEW OWX interface
|
#-- NEW OWX interface
|
||||||
}else{
|
}else{
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
# 16 pushes this to the top of the queue
|
# 16 pushes this to the top of the queue
|
||||||
#OWX_Qomplex($master, $hash, "ds2406.setstate.$value", 0, $owx_dev, $select, 0, 2, 13, \&OWXSWITCH_BinValues, 0.01);
|
#OWX_Qomplex($master, $hash, "ds2406.setstate.$value", 1, $owx_dev, $select, $select, 2, 13, \&OWXSWITCH_BinValues, undef);
|
||||||
OWX_Qomplex($master, $hash, "ds2406.setstate.$value", 0, $owx_dev, $select, 0, 2, 2, \&OWXSWITCH_BinValues, 0.01);
|
OWX_Qomplex($master, $hash, "ds2406.setstate.$value", 1, $owx_dev, $select, $select, 15, 0, \&OWXSWITCH_BinValues, undef);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
#-- family = 29 => DS2408
|
#-- family = 29 => DS2408
|
||||||
@ -1378,7 +1359,8 @@ sub OWXSWITCH_SetState($$) {
|
|||||||
}else{
|
}else{
|
||||||
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
#### master slave context proc owx_dev data crcpart numread startread callback delay
|
||||||
# 16 pushes this to the top of the queue
|
# 16 pushes this to the top of the queue
|
||||||
OWX_Qomplex($master, $hash, "ds2408.setstate.$value", 16, $owx_dev, $select, 0, 1, 12, \&OWXSWITCH_BinValues, 0);
|
#OWX_Qomplex($master, $hash, "ds2408.setstate.$value", 1, $owx_dev, $select, 0, 1, 12, \&OWXSWITCH_BinValues, undef);
|
||||||
|
OWX_Qomplex($master, $hash, "ds2408.setstate.$value", 1, $owx_dev, $select, 0, 13, 0, \&OWXSWITCH_BinValues, undef);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
#-- family = 3A => DS2413
|
#-- family = 3A => DS2413
|
||||||
@ -1390,7 +1372,7 @@ sub OWXSWITCH_SetState($$) {
|
|||||||
#-- OLD OWX interface
|
#-- OLD OWX interface
|
||||||
if( !$master->{ASYNCHRONOUS} ){
|
if( !$master->{ASYNCHRONOUS} ){
|
||||||
OWX_Reset($master);
|
OWX_Reset($master);
|
||||||
$res=OWX_Complex($master,$owx_dev,$select,1);
|
$res=OWX_Complex($master,$owx_dev,$select,2);
|
||||||
if( $res eq 0 ){
|
if( $res eq 0 ){
|
||||||
return "device $owx_dev not accessible in writing";
|
return "device $owx_dev not accessible in writing";
|
||||||
}
|
}
|
||||||
@ -1400,7 +1382,8 @@ sub OWXSWITCH_SetState($$) {
|
|||||||
}else{
|
}else{
|
||||||
#### master slave context proc owx_dev data cmd numread startread callback delay
|
#### master slave context proc owx_dev data cmd numread startread callback delay
|
||||||
# 16 pushes this to the top of the queue
|
# 16 pushes this to the top of the queue
|
||||||
OWX_Qomplex($master, $hash, "ds2413.setstate", 16, $owx_dev, $select, 0, 2, 12, \&OWXSWITCH_BinValues, 0);
|
#OWX_Qomplex($master, $hash, "ds2413.setstate", 1, $owx_dev, $select, 0, 2, 12, \&OWXSWITCH_BinValues, undef);
|
||||||
|
OWX_Qomplex($master, $hash, "ds2413.setstate", 1, $owx_dev, $select, 0, 14, 0, \&OWXSWITCH_BinValues, undef);
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1693,14 +1676,14 @@ sub OWXSWITCH_PT_SetOutput($$$) {
|
|||||||
code </li>
|
code </li>
|
||||||
<li>
|
<li>
|
||||||
<code><interval></code>
|
<code><interval></code>
|
||||||
<br />Measurement interval in seconds. The default is 300 seconds. </li>
|
<br />Measurement interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update. </li>
|
||||||
</ul>
|
</ul>
|
||||||
<a name="OWSWITCHset"></a>
|
<a name="OWSWITCHset"></a>
|
||||||
<h4>Set</h4>
|
<h4>Set</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a name="owswitch_interval">
|
<li><a name="owswitch_interval">
|
||||||
<code>set <name> interval <int></code></a><br /> Measurement
|
<code>set <name> interval <int></code></a><br /> Measurement
|
||||||
interval in seconds. The default is 300 seconds. </li>
|
interval in seconds. The default is 300 seconds, a value of 0 disables the automatic update. </li>
|
||||||
<li><a name="owswitch_output">
|
<li><a name="owswitch_output">
|
||||||
<code>set <name> output <channel-name> on | off | on-for-timer <time> | off-for-timer <time></code>
|
<code>set <name> output <channel-name> on | off | on-for-timer <time> | off-for-timer <time></code>
|
||||||
</a><br />Set
|
</a><br />Set
|
||||||
@ -1721,13 +1704,6 @@ sub OWXSWITCH_PT_SetOutput($$$) {
|
|||||||
<li><a name="owswitch_id">
|
<li><a name="owswitch_id">
|
||||||
<code>get <name> id</code></a>
|
<code>get <name> id</code></a>
|
||||||
<br /> Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC </li>
|
<br /> Returns the full 1-Wire device id OW_FAMILY.ROM_ID.CRC </li>
|
||||||
<li><a name="owswitch_present">
|
|
||||||
<code>get <name> present</code>
|
|
||||||
</a>
|
|
||||||
<br /> Returns 1 if this 1-Wire device is present, otherwise 0. </li>
|
|
||||||
<li><a name="owswitch_interval2">
|
|
||||||
<code>get <name> interval</code></a><br />Measurement interval in
|
|
||||||
seconds. </li>
|
|
||||||
<li><a name="owswitch_input">
|
<li><a name="owswitch_input">
|
||||||
<code>get <name> input <channel-name></code></a><br /> state for
|
<code>get <name> input <channel-name></code></a><br /> state for
|
||||||
channel (A,B, ... or defined channel name) This value reflects the measured value,
|
channel (A,B, ... or defined channel name) This value reflects the measured value,
|
||||||
@ -1738,8 +1714,12 @@ sub OWXSWITCH_PT_SetOutput($$$) {
|
|||||||
<li><a name="owswitch_gpio">
|
<li><a name="owswitch_gpio">
|
||||||
<code>get <name> gpio</code></a><br />Obtain state of all channels</li>
|
<code>get <name> gpio</code></a><br />Obtain state of all channels</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a name="OWSWITCHattr"></a>
|
<a name="OWSWITCHattr"></a>
|
||||||
<h4>Attributes</h4> For each of the following attributes, the channel identification A,B,...
|
<h4>Attributes</h4>
|
||||||
|
<ul><li><a name="owswitch_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>
|
||||||
|
</ul>For each of the following attributes, the channel identification A,B,...
|
||||||
may be used. <ul>
|
may be used. <ul>
|
||||||
<li><a name="owswitch_states"><code><name> stateS <string></code></a>
|
<li><a name="owswitch_states"><code><name> stateS <string></code></a>
|
||||||
<br/> character string denoting external shortening condition (default is X, set to "none" for empty).</li>
|
<br/> character string denoting external shortening condition (default is X, set to "none" for empty).</li>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user