39_STELLMOTOR - ventilsteuerung mit R/L-Motor und relais, zB.Heizungsmischer 3.0

Begonnen von epsrw1, 24 Mai 2014, 15:52:17

Vorheriges Thema - Nächstes Thema

cwagner

Hallo Florian,

dem mit der Perl-Version will ich noch mal nachgehen - das will ich aber in Ruhe vorbereiten. Ich benutze 5.12 und hatte angenommen, dass dies nötigenfalls mit FHEM aktualisiert wird.

Ein Start mit SysCMD funktioniert nicht - mit FHEMDev startet er. Dann wechsele ich die DEV.

Deine angepasste Variante funktioniert danach genau einmal: Es gibt nach der ersten Motorbewegung dann aber dann doch eine Fehlermeldung:
Unknown argument , choose one of <PiFace|Gpio|FhemDev|OtherOutType>

Dann ist erst einmal Feierabend.

Herzliche Grüße

Christian
PI 2B+/3B+ Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

epsrw1

ZitatAber, da Du mich jetzt auf meinen Irrweg hingewiesen hast, habe ich es noch einmal mit FhemDev versucht und hoffe die Syntax richtig nachvollzogen habe:
Internals:
   CFGFN
   DEF        FhemDev
   NAME       Stellmotor2
   NOTIFYDEV  global
   NR         920
   NTFY_ORDER 50-Stellmotor2
   STATE      20
   TYPE       STELLMOTOR
   Readings:
     2014-06-11 23:11:44   DoResetAtStop   1402521104.42784
     2014-06-11 23:11:13   OutType         FhemDev
     2014-06-11 23:11:44   command_queue   0
     2014-06-11 23:13:55   lastStart       1402521235.6357
     2014-06-11 23:13:55   locked          1
     2014-06-11 23:13:55   position        20
     2014-06-11 23:13:55   queue_lastdiff  0
     2014-06-11 23:13:55   state           20
     2014-06-11 23:13:55   stopTime        1402521237.46366
Attributes:
   STMcalibrateDirection L
   STMfhemDevRL Switch_Heizkeller output B
   STMfhemDevSTART Switch_Heizkeller output C
   STMinvertOut 0
   STMmapOffCmd OFF
   STMmapOnCmd ON
   STMmaxDriveSeconds 95
   STMmaxTics 100
   STMpollInterval 0.1
   STMresetOtherDeviceAtCalibrate 0
   STMrlType  einzel
   STMsysCmdRL Switch_Heizkeller output B
   STMsysCmdSTART Switch_Heizkeller output C
   STMtimeTolerance 0.01

Ich sende set Stellmotor2 70 ausgehend von 1: Erwartungsgemäß: B on   C off    nach knapp 66 Sekunden sollte B off und  C off stehen.
Tatsächlich sehe ich aber weiterhin B on , das wird immer wiederholt
und sehe im Log weiterhin:
2014.06.11 23:28:18 3: STELLMOTOR Stellmotor2 Set Target:71.8212885605661 Cmd:1.82128856056615 RL:R
2014.06.11 23:28:22 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522100.83032 now:1402522102.61282 queue_lastdiff:1.87631456475509
2014.06.11 23:28:23 3: STELLMOTOR Stellmotor2 Set Target:71.8763145647551 Cmd:1.87631456475509 RL:R
2014.06.11 23:28:27 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522105.1107 now:1402522106.83404 queue_lastdiff:1.81404038479454
2014.06.11 23:28:27 3: STELLMOTOR Stellmotor2 Set Target:71.8140403847945 Cmd:1.81404038479454 RL:R

Ich habe hohe Systemlast.
Ich sende set Stellmotor2 1 und ich sehe B off  und C on   - nach rund 66 Sekunden sollte B off und C off stehen.
Tatsächlich springt aber B auf on und C auf off.
Das wird wieder regelmäßig wiederholt.
2014.06.11 23:30:26 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522224.14926 now:1402522225.88432 queue_lastdiff:1.82638695365504
2014.06.11 23:30:26 3: STELLMOTOR Stellmotor2 Set Target:2.82638695365504 Cmd:-67.1736130463449 RL:L
2014.06.11 23:31:32 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522290.46205 now:1402522292.21283 queue_lastdiff:1.84292793273926
2014.06.11 23:31:32 3: STELLMOTOR Stellmotor2 Set Target:2.84292793273926 Cmd:1.84292793273926 RL:R
2014.06.11 23:31:36 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522294.67761 now:1402522296.41339 queue_lastdiff:1.8271373447619
2014.06.11 23:31:36 3: STELLMOTOR Stellmotor2 Set Target:2.8271373447619 Cmd:1.8271373447619 RL:R
2014.06.11 23:31:40 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522298.86658 now:1402522300.61928 queue_lastdiff:1.84494696165386
2014.06.11 23:31:41 3: STELLMOTOR Stellmotor2 Set Target:2.84494696165386 Cmd:1.84494696165386 RL:R

Ich hoffe, Dir hiermit helfen zu können...
Danke, dass Du Dein Modul so engagiert fortschreibst.
Ich habe keine Ahnung, aber davon wenigstens ganz viel

epsrw1

Zitatdie schaltzustände sind alle richtig obwohl das ergebnis verwirrend aussieht. in der tat hat Dein motor das Schwingen angefangen, da die queue_lastdiff jeweils über 1 war wurde ständig neue moves begonnen.
abhilfe: neues attr STMlastDiffMax (default 1), versuch es mit wert 2 das sollte reichen.
hint: get Stellmotor2 attrHelp STMlastDiffMax :)

Ich habe hohe Systemlast.
Ich sende set Stellmotor2 1 und ich sehe B off  und C on   - nach rund 66 Sekunden sollte B off und C off stehen.
Tatsächlich springt aber B auf on und C auf off.
Das wird wieder regelmäßig wiederholt.
2014.06.11 23:30:26 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522224.14926 now:1402522225.88432 queue_lastdiff:1.82638695365504
2014.06.11 23:30:26 3: STELLMOTOR Stellmotor2 Set Target:2.82638695365504 Cmd:-67.1736130463449 RL:L
2014.06.11 23:31:32 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402522290.46205 now:1402522292.21283 queue_lastdiff:1.84292793273926
2014.06.11 23:31:32 3: STELLMOTOR Stellmotor2 Set Target:2.84292793273926 Cmd:1.84292793273926 RL:R


man sieht hier im log output daß der motor erwartungsgemäß nach einiger zeit stoppt, und dann sofort einen neuen drive startet. der wert queue_lastdiff ist regelmäßig über 1. je nach reaktionszeit des systems muß das attr. STMlastDiffMax entsprechend erhöht werden, hier würde ich es mit 2 versuchen.

die funktion ist dazu gedacht, einzelne "ausrutscher" in der stopzeit abzufangen und sofort zu korrigieren, zB falls fhem mal hängt un der motor 10sek zu weit gefahren ist, wird nicht die diff abgespeichert bis zum nächsten drive sondern der extremwert sofort korrigiert.

und hier das update mit dem neuen attr:
# $Id: 98_STELLMOTOR.pm 2016 2014-06-13 12:41:00Z Florian Duesterwald $
####################################################################################################
#
# 98_STELLMOTOR.pm
#
#   drive a valve to percent value, based on motor drive time
#
# This file is free contribution and not part of fhem.
# refer to mail a t duesterwald d.o.t info if necessary
# thanks to cwagner for testing and a great documentation of the module:
#
# http://www.fhemwiki.de/wiki/Mischersteuerung
#
# for Gpio and for PiFace type you need to have wiringPi installed first
# at default location: /usr/local/bin/gpio
#
# 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 <http://www.gnu.org/licenses/>.
#
####################################################################################################

#my($cwagner)=1;

package main;
use strict;
use warnings;
use Time::HiRes qw(gettimeofday);

sub STELLMOTOR_Define($$);
sub STELLMOTOR_Undefine($$);
sub STELLMOTOR_Set($@);
sub STELLMOTOR_Get($@);
sub STELLMOTOR_Notify(@);
sub STELLMOTOR_Attr(@);
sub STELLMOTOR_Calibrate($@);
#}

sub STELLMOTOR_commandSend($@){
#params: stop or start: R or L drive
my ($hash, @args) = @_;
my $name = $hash->{NAME};
my $command = $args[0]; #command= R | L | S
#desired states for start and stop cmds, apply invert to this
#state  R  L  STOP
#portRL  1  1  0 #früher:startport
#portST  1  0  0 #früher:rlport
my %portRL = ( "R" => 1,
"L" => 0,
"S" => 0 );
my %portST = ( "R" => 1,
"L" => 1,
"S" => 0 );

#wechsel / einzel ? return desired state for both ports at R/L
my $STMrlType = AttrVal($name, "STMrlType", "einzel");
if($STMrlType eq "einzel"){
#change portRL val at R move if attr STMrlType is present (to get zero if type = einzel)
$portST{"R"}=0;
}elsif($STMrlType ne "wechsel"){
Log3($name, 3, "STELLMOTOR $name attr STMrlType has unknown value:".$STMrlType);
return;
}
#invert 1 and zero, maybe needed for funny hardware conditions
#some funny devices may need other stuff than 0|1 to switch off|on
my $STMinvertOutVals = AttrVal($name, "STMinvertOut", 0);
my $STMmapOffCmd = AttrVal($name, "STMmapOffCmd", 0);
my $STMmapOnCmd = AttrVal($name, "STMmapOnCmd", 0);
foreach("R","L","S"){
if($STMinvertOutVals ne "0"){
$portRL{$_}=($portRL{$_}?0:1); #first do the invert
$portST{$_}=($portST{$_}?0:1); #first do the invert
}
if($STMmapOffCmd ne "0"){
$portRL{$_}=($portRL{$_}?$portRL{$_}:$STMmapOffCmd); #do the mapping for 0
$portST{$_}=($portST{$_}?$portST{$_}:$STMmapOffCmd); #do the mapping for 0
}
if($STMmapOnCmd ne "0"){
$portRL{$_}=($portRL{$_}?$STMmapOnCmd:$portRL{$_}); #do the mapping for 0
$portST{$_}=($portST{$_}?$STMmapOnCmd:$portST{$_}); #do the mapping for 0
}
}

#2014-06-13 debug
if(defined($cwagner)){
foreach("R","L","S"){
Log3($name, 3, "STELLMOTOR $name cwagner1 data for ".$_."=>rl=".$portRL{$_}.",st=".$portST{$_});
}
}
#2014-06-13 debug

#actual state of the cmd hash data example:
#state  R  L  STOP
#portRL  on on off #früher:startport
#portST  on off off #früher:rlport
#check dev type and exec the commands
my($cmd,$execRL,$execSTART);
#define <name> STELLMOTOR <PiFace|Gpio|SysCmd|FhemDev>
my $OutType = ReadingsVal($name, "OutType", "dummy");
if(($OutType eq "PiFace") or ($OutType eq "Gpio")){
#pif and gpio eigentlich sinnlos, bleiben trotzdem erhalten für DAU und für abwärts-kompatibilität
#cmd type Gpio / #cmd type PiFace
$cmd = "/usr/local/bin/gpio";
my $outPinBase = 0; #gpio pins without recalc
if($OutType eq "PiFace"){
$outPinBase = 200; #recalc +200 for the pins
$cmd .=" -p"; #use -p option for gpio
}
my($startport)=AttrVal($name, "STMgpioPortRL", 5);
my($rlport)=AttrVal($name, "STMgpioPortSTART", 4);
$execRL = $cmd." write ".($outPinBase+$rlport)." ".$portRL{$command};
$execRL = `$execRL`;
$execSTART = $cmd." write ".($outPinBase+$startport)." ".$portST{$command};
$execSTART = `$execSTART`;
}elsif($OutType eq "SysCmd"){
my $STMsysCmdRL = AttrVal($name, "STMsysCmdRL", 0);
my $STMsysCmdSTART = AttrVal($name, "STMsysCmdSTART", 0);
$execRL = $STMsysCmdRL." ".$portRL{$command};
$execRL = `$execRL`;
$execSTART = $STMsysCmdSTART." ".$portST{$command};
$execSTART = `$execSTART`;
}elsif($OutType eq "FhemDev"){
my $STMfhemDevRL = AttrVal($name, "STMfhemDevRL", "Stellmotor2rl");
CommandSet(undef,$STMfhemDevRL." ".$portRL{$command});
my $STMfhemDevSTART = AttrVal($name, "STMfhemDevSTART", "Stellmotor2start");
CommandSet(undef,$STMfhemDevSTART." ".$portST{$command});
#2014-06-13 debug
if(defined($cwagner)){
Log3($name, 3, "STELLMOTOR $name cwagner2 command: set ".$STMfhemDevRL." ".$portRL{$command});
Log3($name, 3, "STELLMOTOR $name cwagner2 command: set ".$STMfhemDevSTART." ".$portST{$command});
}
#2014-06-13 debug
}elsif($OutType eq "dummy"){
Log3($name, 3, "STELLMOTOR $name testing with device type:".$OutType);
return;
}else{  #$OutType eq "dummy" or unknown value
Log3($name, 3, "STELLMOTOR $name unknown device type:".$OutType);
return;
}
return;
}

sub STELLMOTOR_Initialize($){
my ($hash) = @_;
$hash->{DefFn} = "STELLMOTOR_Define";
$hash->{UndefFn} = "STELLMOTOR_Undefine";
$hash->{SetFn} = "STELLMOTOR_Set";
$hash->{GetFn} = "STELLMOTOR_Get";
$hash->{NotifyFn} = "STELLMOTOR_Notify";
$hash->{AttrFn} = "STELLMOTOR_Attr";
my($attrlist);
foreach(_stmAttribs("keys","")){
$attrlist.=" ".$_;
if(_stmAttribs("listval",$_) ne "all"){
if(_stmAttribs("listval",$_)=~/:/){
$attrlist.=":";
my($min,$max)=split(/:/,_stmAttribs("listval",$_));
while($min<$max){
$attrlist.=$min.",";
$min++;
}
$attrlist.=$max;
}elsif(_stmAttribs("listval",$_)=~/,/){
$attrlist.=":"._stmAttribs("listval",$_);
}
#" disable:0,1 STMmaxTics:10,12,100,1000 STMmaxDriveSeconds " .
}
}
$hash->{AttrList} = $readingFnAttributes.$attrlist;
}
sub STELLMOTOR_Define($$){
my ($hash, $def) = @_;
my @args = split("[ \t]+", $def);
my $menge = int(@args);
if (int(@args) < 2) {
return "Define: to less arguments. Usage:\n" .
#   "define <name> STELLMOTOR <PiFace|Gpio|FhemDev|OtherOutType> <RL-Out-Port> <Start-Out-Port>";
  "define <name> STELLMOTOR <PiFace|Gpio|SysCmd|dummy|FhemDev>";
}
my $name = $args[0];
readingsSingleUpdate($hash, "OutType", $args[2], 1);
$hash->{NOTIFYDEV} = "global";
if(($args[2] ne "PiFace") and ($args[2] ne "Gpio") and ($args[2] ne "SysCmd") and ($args[2] ne "FhemDev") and ($args[2] ne "dummy")){
return "Define: Err87 unsupported Output Device ".$args[2].". Usage:\n" .
"define <name> STELLMOTOR <PiFace|Gpio|SysCmd|FhemDev>";
}
Log3($name, 3, "STELLMOTOR $name active, type=".$args[2]);
readingsSingleUpdate($hash, "state", "initialized",1);
my $position = ReadingsVal($name,"position", "0");
readingsSingleUpdate($hash, "state", $position,1);
#set attr based on device type
foreach(_stmAttribs("keys","")){
if(AttrVal($name,$_,"missing") ne "missing"){
#nothing, only set non-present attr
}elsif(_stmAttribs("area",$_) eq "global"){
CommandAttr(undef,$name." ".$_." "._stmAttribs("default",$_));
}elsif($args[2] eq _stmAttribs("area",$_)){
CommandAttr(undef,$name." ".$_." "._stmAttribs("default",$_));
}
}
InternalTimer(gettimeofday() + 120, "STELLMOTOR_GetUpdate", $hash, 0);
return;
}
sub STELLMOTOR_Undefine($$){
  my($hash, $name) = @_;
  RemoveInternalTimer($hash);
  return;
}
sub STELLMOTOR_Set($@) {
my ($hash, @args) = @_;
my $name = $hash->{NAME};
my $OutType = ReadingsVal($name,'OutType', "PiFace");
my $moveTarget = $args[1];
if($moveTarget eq "calibrate"){STELLMOTOR_Calibrate($hash);return;}
my $STMmaxDriveSeconds = AttrVal($name, "STMmaxDriveSeconds", 107);
my $STMmaxTics = AttrVal($name, "STMmaxTics", 100);
if($moveTarget eq "reset"){
readingsBeginUpdate($hash);
foreach(("locked","queue_lastdiff","command_queue")){
readingsBulkUpdate($hash, $_ , 0);
}
foreach(("state","position")){
readingsBulkUpdate($hash, $_ , 1);
}
readingsEndUpdate($hash, 1);
return;
}elsif(($moveTarget eq "?") or ($moveTarget < 1) or ($moveTarget > ($STMmaxTics+1))){
if($moveTarget eq "0"){$moveTarget.=" (min.value is 1) ";}
my $usage = "Unknown argument $moveTarget, choose one of calibrate:noArg reset:noArg ";
foreach(1,2,8,9,10,16,20,30,40,50,60,70,80,90,100){ $usage .= " ".$_.":noArg "; }
return $usage;
}
if (IsDisabled($name)) {
readingsSingleUpdate($hash, "command_queue", $moveTarget, 0); #save requested value to queue and return
Log3 $name, 3, "STELLMOTOR $name device is disabled - set:".$moveTarget." only in queue."; 
return;
}
my $locked = ReadingsVal($name,'locked',0);
if ($locked eq 1) {
if(gettimeofday() - ( ReadingsVal($name,'lastStart',0) + $STMmaxDriveSeconds + 10 ) < 0){
#check time since last cmd, if < MaxDrvSecs, queue command and return
readingsSingleUpdate($hash, "command_queue", $moveTarget, 0); #save requested value to queue and return
return;
}
}
# if(($OutType ne "PiFace") and ($OutType ne "Gpio") and ($OutType ne "FhemDev") and ($OutType ne "OtherOutType")){
if(($OutType ne "PiFace") and ($OutType ne "Gpio") and ($OutType ne "SysCmd") and ($OutType ne "FhemDev")){
return "Unknown argument ".$OutType.", choose one of <PiFace|Gpio|FhemDev|SysCmd>";
}
my $actual_state = ReadingsVal($name,'position',1); #Use default 1 to omit error on first use
readingsSingleUpdate($hash,'position',$moveTarget,1); #update position reading
$moveTarget = $moveTarget + ReadingsVal($name,'queue_lastdiff',0); #add last time diff or old value below 1 Tic
readingsSingleUpdate($hash, "queue_lastdiff", 0, 1);
my $moveCmdTime = $moveTarget-$actual_state;
my $STMtimeTolerance = AttrVal($name, "STMtimeTolerance", 0.01);
if( ((abs($moveCmdTime) - $STMtimeTolerance) <= 1 )){
readingsSingleUpdate($hash, "queue_lastdiff", $moveCmdTime, 1);
return;
}
my $directionRL = "L";
if($moveCmdTime>0){ $directionRL = "R"; }
Log3($name, 3, "STELLMOTOR $name Set Target:".int($moveTarget)." Cmd:".$moveCmdTime." RL:".$directionRL);
$moveCmdTime=abs($moveCmdTime); #be shure to have positive moveCmdTime value
readingsSingleUpdate($hash, "locked", 1, 1); #lock module for other commands
readingsSingleUpdate($hash, "lastStart", gettimeofday(), 1); #set the actual drive starttime
$moveCmdTime=$moveCmdTime*$STMmaxDriveSeconds/$STMmaxTics;  #now we have the time in seconds the motor must run
readingsSingleUpdate($hash, "stopTime", (gettimeofday()+$moveCmdTime), 1); #set the end time of the move
STELLMOTOR_commandSend($hash,$directionRL);
return;
}
sub STELLMOTOR_Stop($@){
my ($hash,$option) = @_;
my $name = $hash->{NAME};
my $OutType = ReadingsVal($name,'OutType', "PiFace");
if(($OutType ne "PiFace") and ($OutType ne "Gpio") and ($OutType ne "FhemDev") and ($OutType ne "SysCmd")){
return "Unknown argument ".$OutType.", choose one of <PiFace|Gpio|FhemDev|SysCmd>";
}
STELLMOTOR_commandSend($hash,"S");
my $now = gettimeofday();
my $stopTime = ReadingsVal($name,"stopTime",$now);
my $STMmaxDriveSeconds = AttrVal($name, "STMmaxDriveSeconds", 107);
my $STMmaxTics = AttrVal($name, "STMmaxTics", 100);

my $lastGuiState = ReadingsVal($name,'state', 1);
if(!($lastGuiState=~/^\d+$/)){
Log3($name, 3, "STELLMOTOR $name Stop Problem: lastGuiState:$lastGuiState please report this error L.".__LINE__);
$lastGuiState=1;
}
my $queue_lastdiff = ($stopTime-$now)*$STMmaxTics/$STMmaxDriveSeconds*(
(ReadingsVal($name,'position', 1)> $lastGuiState
)?1:-1);
readingsSingleUpdate($hash, "queue_lastdiff", $queue_lastdiff, 1); #store time diff for next cmd
readingsSingleUpdate($hash, "locked", 0, 1); #unlock device
readingsSingleUpdate($hash, "stopTime", 0, 1); #reset stoptime to zero
my $position = ReadingsVal($name,'position', "StopError");
readingsSingleUpdate($hash,'state',int($position),1); #update position reading
if(ReadingsVal($name,'DoResetAtStop', "afterCalibrate") eq "afterCalibrate"){
readingsSingleUpdate($hash, "DoResetAtStop", gettimeofday(), 1); #set actual time = last calibrate
if(AttrVal($name,"STMresetOtherDeviceAtCalibrate",0)){
CommandSet(undef, AttrVal($name,"STMresetOtherDeviceAtCalibrate",0)." reset");
Log3($name, 3, "STELLMOTOR $name STMresetOtherDeviceAtCalibrate:".AttrVal($name,"STMresetOtherDeviceAtCalibrate",0));
}
STELLMOTOR_Set($hash,$name,"reset");
}
Log3($name, 3, "STELLMOTOR $name Stop Timing Call: stopTime:$stopTime now:$now queue_lastdiff:$queue_lastdiff");
}
sub STELLMOTOR_GetUpdate($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $STMtimeTolerance = AttrVal($name, "STMtimeTolerance", 0.01);
my $stopTime = ReadingsVal($name,"stopTime", 0);
my $now = gettimeofday();
if(($stopTime ne 0) and (($stopTime-$now)<$STMtimeTolerance)){
STELLMOTOR_Stop($hash);
}
my $command_queue = ReadingsVal($name,"command_queue", 0);
my $queue_lastdiff = ReadingsVal($name,"queue_lastdiff", 0);
my $locked = ReadingsVal($name,"locked", 0);
my $STMlastDiffMax = AttrVal($name, "STMlastDiffMax", 1);
my $position = ReadingsVal($name,"position", 1);
if($command_queue>0 and $locked==0){
readingsSingleUpdate($hash, "command_queue", 0, 1); #remove old value from queue start the drive
STELLMOTOR_Set($hash,$name,$command_queue);
}elsif(abs($queue_lastdiff)>$STMlastDiffMax){ #start new drive if last diff > 1sec (attr: STMlastDiffMax)
STELLMOTOR_Set($hash,$name,$position);
}
my $STMpollInterval = AttrVal($name, "STMpollInterval", 0.1);
if ($STMpollInterval ne "off") {
InternalTimer(gettimeofday() + ($STMpollInterval), "STELLMOTOR_GetUpdate", $hash, 0);
# STELLMOTOR_Get($hash,"position");
}
#fetch missing pos.value in state after reboot
my $lastGuiState = ReadingsVal($name,'state', 1);
if(!($lastGuiState=~/^\d+$/)){
Log3($name, 3, "STELLMOTOR $name Stop Problem: lastGuiState:$lastGuiState please report this error L.".__LINE__);
my $position = ReadingsVal($name,'position', "1");
readingsSingleUpdate($hash,'state',$position,1); #update position reading
$lastGuiState=1;
}
#end debug
return;
}
sub STELLMOTOR_Get($@){
my ($hash, @a) = @_;
my $name = $hash->{NAME};
my $get = $a[1];
my @stmgets = (keys(%{$hash->{READINGS}}));
$get="?" if(!_in_array($get,(@stmgets,"attrHelp","readingsHelp","stmWwiki")));
my $usage = "Unknown argument $get, choose one of";
foreach(@stmgets){
$usage.=" ".$_.":noArg";
}
$usage.=" attrHelp:";
my($first)=0;
foreach(_stmAttribs("keys","")){
if($first){
$usage.=$_;
$first=0;
}else{
$usage.=",".$_;
}
}
$usage.=" readingsHelp:";
foreach(_stmRdings("keys","")){
$usage.=$_.",";
}
$usage.=" stmWwiki:get,set,readings,attr";
#check what has been requested?
if($get eq "attrHelp"){return _stmAttribs("help",$a[2]);}
if($get eq "readingsHelp"){return _stmRdings("help",$a[2]);}
if($get eq "stmWwiki"){
my $bereich = $a[2];
#bereich "get" "set" "readings" "attr"
my $wret;
if($bereich eq "get"){
$wret=STELLMOTOR_Get($hash,$name,"?");
$wret=~s/Unknown argument \?, choose one of//g;
$wret=~s/\s+/\n* /g;
$wret=~s/:noArg//g;
$wret=~s/:/: /g;
return "extracted usage of get command:\n\n".$wret
}elsif($bereich eq "set"){
$wret=STELLMOTOR_Set($hash,$name,"?");
$wret=~s/Unknown argument \?, choose one of//g;
$wret=~s/\s+/\n* /g;
$wret=~s/:noArg//g;
$wret=~s/:/: /g;
return "extracted usage of set command:\n\n".$wret;
}elsif($bereich eq "readings"){
$wret="\n== Readings ==\nAlle Readings sind auch in fhem durch das kommando get readingsHelp <varname> erklärt, für's \"".
"schnelle nachschauen zwischendurch\".\n\n{| class=\"wikitable sortable\"\n|-\n! Reading !! (Typ) Default !! Beschreibung\n|-\n";
foreach(_stmRdings("keys","")){
$wret.="| ". $_."|| ("._stmRdings("type",$_).") "._stmRdings("default",$_)." || "._stmRdings("description",$_)."\n|-\n";
}
$wret.="\n|}\n\n";
}elsif($bereich eq "attr"){
$wret="\n== Attributes ==\nAlle Attributes sind auch in fhem durch das kommando get attrHelp <varname> erklärt, für's \"".
"schnelle nachschauen zwischendurch\".\n\n{| class=\"wikitable sortable\"\n|-\n! Attribute !! (Typ) Default !! Beschreibung\n|-\n";
foreach(_stmAttribs("keys","")){
$wret.="| ". $_."|| ("._stmAttribs("type",$_).") "._stmAttribs("default",$_)." || "._stmAttribs("description",$_)."\n|-\n";
}
$wret.="\n|}\n\n";
}else{
return "get Error in Line ".__LINE__;
}
return $wret;
}
return $usage if $get eq "?";
my $ret = $get.": ".ReadingsVal($name,$get, "Unknown");
return $ret;
}
sub STELLMOTOR_Notify(@) {
  my ($hash, $dev) = @_;
  my $name = $hash->{NAME};
  if ($dev->{NAME} eq "global" && grep (m/^INITIALIZED$/,@{$dev->{CHANGED}})){
    Log3($name, 3, "STELLMOTOR $name initialized");
    STELLMOTOR_GetUpdate($hash);   
  }
  return;
}
sub STELLMOTOR_Attr(@) {
my ($cmd, $name, $attrName, $attrVal) = @_;
my $hash = $defs{$name};
#validate special attr STMpollInterval
if ($attrName eq "STMpollInterval") {
if (!defined $attrVal) {
RemoveInternalTimer($hash);   
Log3($name, 3, "STELLMOTOR $name attr [$attrName] deleted");
CommandDeleteAttr(undef, "$name STMpollInterval");
} elsif ($attrVal eq "off" || ( $attrVal >= 0.01 and $attrVal <= 600 ) ) {
Log3($name, 3, "STELLMOTOR $name attribute-value [$attrName] = $attrVal changed");
STELLMOTOR_GetUpdate($hash);
} else {
RemoveInternalTimer($hash);
Log3($name, 3, "STELLMOTOR $name attribute-value [$attrName] = $attrVal wrong, use seconds >0.01 as float (max 600)");
}
#fetch all remaining attribs and just check if data type matches
} elsif (_in_array($attrName,_stmAttribs("keys"," "))) {
if (!defined $attrVal){
CommandDeleteAttr(undef, "$name $attrName");
} elsif (_stmvalidateAttr($attrName, $attrVal) ) {
Log3($name, 3, "STELLMOTOR $name attribute-value [$attrName] = $attrVal changed");
} else {
CommandDeleteAttr(undef, "$name attrName");
}
}
return;
}
sub STELLMOTOR_Calibrate($@){
#drive to left (or right if attr) for maximum time and call "set reset"
my ($hash,$option) = @_;
my $name = $hash->{NAME};
my $STMmaxDriveSeconds = AttrVal($name, "STMmaxDriveSeconds", 107);
my $STMmaxTics = ReadingsVal($name,'STMmaxTics', "100");
my $OutType = ReadingsVal($name,'OutType', "PiFace");
if(($OutType ne "PiFace") and ($OutType ne "Gpio") and ($OutType ne "FhemDev") and ($OutType ne "SysCmd") and ($OutType ne "dummy")){
return "Unknown argument ".$OutType.", choose one of <PiFace|Gpio|FhemDev|SysCmd>";
}

my $STMcalibrateDirection = AttrVal($name, "STMcalibrateDirection", "L");
my $moveTime = 1 + $STMmaxTics; #1 tic more than 100 to be shure to be at pos.1
Log3($name, 3, "STELLMOTOR $name Calibrate Started, RL:".$STMcalibrateDirection);
readingsSingleUpdate($hash, "locked", 1, 1); #lock module for other commands
readingsSingleUpdate($hash, "lastStart", gettimeofday(), 1); #set the actual drive starttime
$moveTime=$moveTime*$STMmaxDriveSeconds/$STMmaxTics;  #now we have the time in seconds the motor must run
readingsSingleUpdate($hash, "stopTime", (gettimeofday()+$moveTime), 1); #set the end time of the move
readingsSingleUpdate($hash, "DoResetAtStop", "afterCalibrate", 1); #set the end time of the move
STELLMOTOR_commandSend($hash,AttrVal($name,"STMcalibrateDirection","L"));
return;
}

sub _in_array($@){
my ($search_for,@arr) = @_;
foreach(@arr){
return 1 if $_ eq $search_for;
}
return 0;
}
sub _stmvalidateAttr($@){
#usage: _stmvalidateAttr($attrName, $attrVal)
my($attrName, $attrVal)=@_;
#validate special attr and refuse
if(($attrName eq "STMmaxTics") and ($attrVal<1)){
return 0;
}elsif(($attrName eq "STMrlType") and (($attrVal ne "wechsel") and ($attrVal ne "einzel"))){
return 0;
}
my $attrType = _stmAttribs("type",$attrName);
if($attrType eq "int"){
return 1 if $attrVal=~/^[-+]?\d+$/;
}elsif($attrType eq "float"){
return 1 if $attrVal=~/^[-+]?\d+\.?\d*$/;
}elsif($attrType eq "string"){
return 1 if length($attrVal);
}else{
return 0;
}
}
sub _stmRdings($@){
#usage: _stmRdings("help","stmVarName")
# "keys" || "default" || "type" || "help"  ,<keyname>
my($type,$reqKey)=@_;
my %rdings = (
"OutType"=>[("PiFace","string","in der device definition festgelegter OutType","global","PiFace,Gpio,SysCmd,dummy,FhemDev")],
"state"=>[("active","string","aktuelle position oder fehlermeldung","global","active,error,initialized,0..100")],
"command_queue"=>[("0","int","befehl in der warteschleife","global","0..100")],
"position"=>[("1","int","aktuelle desired position","global","0..100")],
"queue_lastdiff"=>[("0","float","letzte zeitdifferenz","global","float")],
"locked"=>[("0","int","1 während motor gerade läuft","global","0,1")],
"lastStart"=>[("0","float","zeitstempel letzter start des motors","global","float")],
"stopTime"=>[("0","float","zeitstempel nächster stop des motors","global","float")],
"DoResetAtStop"=>[("afterCalibrate","string","temporärwert nur während kalibrierungsphase","global","'',afterCalibrate")]
);
if($type eq "keys"){
return keys(%rdings);
}elsif($type eq "default"){
return $rdings{$reqKey}[0];
}elsif($type eq "type"){
return $rdings{$reqKey}[1];
}elsif($type eq "description"){
return $rdings{$reqKey}[2];
}elsif($type eq "area"){
return $rdings{$reqKey}[3];
}elsif($type eq "listval"){
return $rdings{$reqKey}[4];
}elsif($type eq "help"){
return "readingsHelp for ".$reqKey.":\n default:".$rdings{$reqKey}[0]." type:".$rdings{$reqKey}[1]." listval:".$rdings{$reqKey}[4]
." \ndescription:".$rdings{$reqKey}[2];
}else{
return "_ rdings?";
}
}
sub _stmAttribs($@){
#usage: _stmAttribs("type","stmVarName")
# "keys" || "default" || "type" || "help"  ,<keyname>
my($type,$reqKey)=@_;
my %attribs = (
"STMrlType"=>[("einzel","string","je nach schaltplan, wechsel=start+RL-relais, einzel=R-relais+L-relais","global","wechsel,einzel")],
"STMinvertOut"=>[("0","int","setzen für devices die 0 für start und 1 für stop erwarten","global","0,1")],
"STMmapOffCmd"=>[("0","string","string der im device-command anstatt '0' verwendet wird für stop","global","all")],
"STMmapOnCmd"=>[("0","string","string der im device-command anstatt '1' verwendet wird für start","global","all")],
"STMgpioPortRL"=>[("5","int","piface port oder gpio port für RL oder R relais (bei RL ist 1=R)","PiFaceGpio","0:31")],
"STMgpioPortSTART"=>[("4","int","piface port oder gpio port für START (oder L relais bei 'einzel')","PiFaceGpio","0:31")],
"STMsysCmdRL"=>[("0","string","freies command das für RL an die shell übergeben wird","SysCmd","all")],
"STMsysCmdSTART"=>[("0","string","freies command das für START an die shell übergeben wird","SysCmd","all")],
"STMfhemDevRL"=>[("RelaisRL","string","fhem device name für RL (oder R) aktor","FhemDev","all")],
"STMfhemDevSTART"=>[("RelaisSTART","string","fhem device name für START (oder L) aktor","FhemDev","all")],
"STMmaxDriveSeconds"=>[("107","int","gestoppte Zeit in Sekunden, die der Motor für die Fahrt von 0 bis 100 Prozent braucht","global","all")],
"STMmaxTics"=>[("100","int","Mischerstellung - bei Prozentangaben (PID20) 100, bei Winkelangaben anzupassen","global","1:100")],
"STMtimeTolerance"=>[("0.01","float","stop-time differenzen kleiner als dieser wert werden ignoriert","global","0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.1")],
"STMresetOtherDeviceAtCalibrate"=>[("0","string","zusätzliches fhem device das am ende der kalibrierung 'set ** reset' gesendet bekommt","global","all")],
"STMpollInterval"=>[("0.1","float","Zeitintervall nach dem FHEM prüft, ob die interne Stoppzeit erreicht wurde. Hier sollte möglichst kleiner Wert aein, nur erhöhen falls FHEM zu langsam läuft","global","all")],
"STMcalibrateDirection"=>[("L","string","auf R wird die kalibrierung nach rechts gefahren, default=links","global","L,R")],
"STMlastDiffMax"=>[("1","int","ist die stoppzeit weiter als dieser wert vom Soll entfernt, wird sofort neuer drive gestartet","global","1:5")]
);
if($type eq "keys"){
return keys(%attribs);
}elsif($type eq "default"){
return $attribs{$reqKey}[0];
}elsif($type eq "type"){
return $attribs{$reqKey}[1];
}elsif($type eq "description"){
return $attribs{$reqKey}[2];
}elsif($type eq "area"){
return $attribs{$reqKey}[3];
}elsif($type eq "listval"){
return $attribs{$reqKey}[4];
}elsif($type eq "help"){
return "attrHelp for ".$reqKey.":\n default:".$attribs{$reqKey}[0]." type:".$attribs{$reqKey}[1]." area:".$attribs{$reqKey}[3]
." \nlistval:".$attribs{$reqKey}[4]
." \ndescription:".$attribs{$reqKey}[2];
}else{
return "_ attribs?";
}
}

1;

=pod
=begin html

<a name="STELLMOTOR"></a>
<h3>STELLMOTOR</h3>
<ul>
  The STELLMOTOR module manages the control of a 4-way (or 3-way) heating system valve with a simple Right/Left
  Motor drive. Any other motor driven device may be used, too. The two Relays for Right/Left and Motor-Start can
  be attached to <a href=http://www.raspberrypi.org/>Raspberry Pi</a> extension board <a href=http://www.PiFace.org.uk/products/PiFace_digital/>PiFace Digital</a> or
  to GPIO pins directly.
  <br>
  Other supported device types are: SysCmd (any command that will be passed to shell) and FhemDev (any existing actor device in fhem)
  <br>
  The actual position is stored in the reading "position" and displayed in the STATE. It is a int value between
  1 and "STMmaxTics" which defaults to 100. This value is supposed to be percentage of valve opening.<br>
  it is calculated from time the motor has been driven right/left and the attr setting "STMmaxDriveSeconds" which
  defaults to 107 seconds time the motor needs from extreme position to the opposite one.<br>
  STELLMOTOR is tested with the Raspbian OS.<br><br>
 
  <b>Preparatory Work</b><br>
  The use of STELLMOTOR module requires some preparatory work.
  <ul>
    <br>
    <li>Module needs tools from <a href=http://wiringpi.com>Wiring Pi</a>. Install it with<br>
      <code>git clone git://git.drogon.net/wiringPi<br>
        cd wiringPi<br>
        ./build</code><br>
    </li>
    <li>Please refer to PiFace Digital Documentation.
    </li>
    <li>Other device types than PiFace and Gpio doesn't need this preparatory work.
    </li>
  </ul>
  <br>

  <a name="STELLMOTORdefine"></a>
  <b>Define</b>
    <ul><br>
       <code>define &lt;name&gt; STELLMOTOR &lt;PiFace|Gpio|SysCmd|FhemDev&gt; </code><br>
    </ul><br>

<a name="STELLMOTORset"></a>
<b>Set</b><br/>
<ul>
<br/>
<code>set &lt;name&gt; &lt;value&gt;</code>
<br/><br/>
<ul>
<li>set desired valve position to be driven too<br/><br/>
Examples:<br/>
set &lt;name&gt; 1 =&gt; drive to 1%<br/>
set &lt;name&gt; 26 =&gt; drive to 26%<br/>
set &lt;name&gt; 100 =&gt; drive to 100%<br/>
</li>
<br/>
</ul>

<br/>
<code>set &lt;name&gt; reset</code>
<br/>
<code>set &lt;name&gt; calibrate</code>: turn left maximum drive time and reset device readings
<br/><br/>
</ul>
<br>

<a name="STELLMOTORget"></a>
<b>Get</b><br/>
<ul>
<br/>
<code>get &lt;name&gt; </code>
<br/><br/>
<ul>
<li>get actual position<br/><br/>
Example:<br/>
get &lt;name&gt; =&gt; get actual position<br/>
</li>
</ul>
</ul>
<br>

<a name="STELLMOTORattr"></a>
<b>Attributes</b><br/><br/>
<ul>
  <li><a name="#STELLMOTOR_STMrlType">STMrlType</a> wechsel | einzel<br>
  je nach elektrischem anschluß des motors einstellen, default ist "wechsel", d.h. RL-Out-Port schaltet um
  zwischen R und L Lauf, und Start-Out-Port wird für jede motorbewegung eingeschaltet.<br>
  bei "einzel" wird Start-Out-Port für linkslauf einzeln geschaltet, und RL-Out-Port für rechtslauf einzeln geschaltet.<br>
  <b>ACHTUNG:</b> falsche Einstellung kann zu Kurzschluß am Motor führen, bitte Einstellung genau überdenken oder mit dummy testen!!
  </li>
<li>
------------------------------
</li>
  <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>
<br>

<b>Generated Readings/Events:</b>
<br/><br/>
<ul>
<li>position: 1..100% (or other STMmaxTics than 100), value is set at begin of drive request</li>
<li>state: active|error|&lt;position&gt; (position value is set at the stop of motor drive)</li>
<li>lastStart: HiRes-Time</li>
<li>locked: 0|1</li>
<li>queue_lastdiff<br>
  based on fhem load or other blocking commands, the stop command will be executed near the calculated
  stop time, but never exactly at it. the STELLMOTOR module caches the difference at stopping the drive
  and adds it at the next drive start to its time calculation in otrder to have accurate position value.
</li>
<li>rlport: pin no.</li>
<li>startport: pin no.</li>
<li>stopTime: zero or sceduled time to stop a drive</li>
<li>command_queue: &lt;position&gt;<br>
incoming new desired setting while motor drives the last command (or is disabled) is cached here for
later execution.
</li>
<li>OutType: from device def PiFace|Gpio|OtherDeviceType</li>
<li>DoResetAtStop: last time Calibrate finished</li>
<br>
</ul>

</ul>

=end html
=cut

Ich habe keine Ahnung, aber davon wenigstens ganz viel

epsrw1

ZitatHi Florian,

so, dass sieht nun gut aus - es funktioniert, mit diesen beiden Einstellungen komme ich aus dem Schwingen raus:
Code: [Auswählen]

   STMlastDiffMax 5
   STMpollInterval 1
   STMrlType  einzel
   STMtimeTolerance .5


Es fällt auf, dass nach Erreichen der gewünschten Position nach einer mehr oder weniger kurzen Zeitspanne dann im Sekundentakt die Readings
Code: [Auswählen]

2014-06-12 22:35:42   position        10
     2014-06-12 22:35:42   queue_lastdiff  1.38111817209344

aktualisiert werden. Auf meinem leistungsschwachen System (Fritzbox 7390) führt das zur erwähnten Systembelastung.

Wenn die bestellte Position erreicht wurde, dann müsste doch, wenigsten nach einigen Schwingungen auch auf einem langsamen System eigentlich Schluss sein? Da nun minutenlang die lastdiff immer denselben Wert, frage ich mich, ob das richtig ist. Oder wird da das Reading nicht aktualisiert? Gehe ich hin und lösche das Reading (deleteReading) ist der nächste genannte Wert 0 und dann bleibt wie erwartet Ruhe.

Die Prozessorauslastung ist dann wie gewohnt.

STMtimeTolerance ist zu hoch eingestellt, die zulässigen werte sind 0.01 bis 0.1

was das erneute "schwingen" betrifft, da hab ich im code gepfuscht gehabt und was übersehen bei der großen umstellung. update anbei

# $Id: 98_STELLMOTOR.pm 2016 2014-06-13 00:44:00Z Florian Duesterwald $

Ich habe keine Ahnung, aber davon wenigstens ganz viel

cwagner

Jupp, jetzt macht es Spaß! Das Nachkalibrieren auf meinem langsamen System (4 Websessions auf und Logging hochgedreht) ist jetzt im Griff. Das Programm arbeitet und meldet erwartungsgemäß. Aber: Der Mischer läuft aus dem Ruder, weil in dieser Version keine Befehle nach links abgesetzt werden. Verbose habe ich auf 5 gestellt (macht aber keinen Unterscheid gegenüber 3 oder 0):

2014.06.13 07:00:06 3: STELLMOTOR Stellmotor2 Calibrate Started, RL:L
2014.06.13 07:01:44 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402635702.576 now:1402635704.17563 queue_lastdiff:1.68382945813631
2014.06.13 07:05:41 3: STELLMOTOR Stellmotor2 Set Target:10 Cmd:9 RL:R
2014.06.13 07:05:52 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402635950.43969 now:1402635952.26415 queue_lastdiff:-1.92048624942177
2014.06.13 07:06:05 3: STELLMOTOR Stellmotor2 Set Target:18.0795137505782 Cmd:8.07951375057823 RL:R
2014.06.13 07:06:15 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402635972.94576 now:1402635975.27727 queue_lastdiff:-2.45421560187089
2014.06.13 07:06:24 3: STELLMOTOR Stellmotor2 Set Target:27.5457843981291 Cmd:7.54578439812911 RL:R
2014.06.13 07:06:34 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402635991.40859 now:1402635993.9193 queue_lastdiff:-2.64285564422607
2014.06.13 07:07:12 3: STELLMOTOR Stellmotor2 Set Target:17.3571443557739 Cmd:-12.6428556442261 RL:L
2014.06.13 07:07:27 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402636044.71343 now:1402636046.55544 queue_lastdiff:1.93895691319516
2014.06.13 07:07:39 3: STELLMOTOR Stellmotor2 Set Target:11.9389569131952 Cmd:-8.06104308680484 RL:L
2014.06.13 07:07:49 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402636067.2805 now:1402636069.04417 queue_lastdiff:1.85648842861778
2014.06.13 07:07:49 3: STELLMOTOR Stellmotor2 Set Target:2.85648842861778 Cmd:-7.14351157138222 RL:L
2014.06.13 07:08:01 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402636076.8356 now:1402636080.78347 queue_lastdiff:4.15565264852423
2014.06.13 07:08:01 3: STELLMOTOR Stellmotor2 Set Target:5.15565264852423 Cmd:4.15565264852423 RL:R
2014.06.13 07:08:07 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402636085.70973 now:1402636087.42325 queue_lastdiff:1.80370732357627
2014.06.13 07:09:36 3: STELLMOTOR Stellmotor2 Set Target:11.8037073235763 Cmd:10.8037073235763 RL:R
2014.06.13 07:09:49 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402636186.67224 now:1402636189.00454 queue_lastdiff:-2.45505483526933
2014.06.13 07:12:17 3: STELLMOTOR Stellmotor2 Set Target:17.5449451647307 Cmd:7.54494516473067 RL:R
2014.06.13 07:12:27 3: STELLMOTOR Stellmotor2 Stop Timing Call: stopTime:1402636344.92379 now:1402636347.43512 queue_lastdiff:-2.64350840919896


Tatsächlich sind ausgesendet worden (achten auf Mischer_weniger=B und Mischer_mehr=C):
2014-06-13_07:05:42 Switch_Heizkeller Brenner: OFF Mischer_weniger: ON Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:05:51 Switch_Heizkeller Brenner: OFF Mischer_weniger: OFF Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:06:06 Switch_Heizkeller Brenner: OFF Mischer_weniger: ON Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:06:14 Switch_Heizkeller Brenner: OFF Mischer_weniger: OFF Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:06:25 Switch_Heizkeller Brenner: OFF Mischer_weniger: ON Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:06:32 Switch_Heizkeller Brenner: OFF Mischer_weniger: OFF Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:08:02 Switch_Heizkeller Brenner: OFF Mischer_weniger: ON Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:08:06 Switch_Heizkeller Brenner: OFF Mischer_weniger: OFF Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:09:37 Switch_Heizkeller Brenner: OFF Mischer_weniger: ON Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:09:48 Switch_Heizkeller Brenner: OFF Mischer_weniger: OFF Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:12:18 Switch_Heizkeller Brenner: OFF Mischer_weniger: ON Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF
2014-06-13_07:12:26 Switch_Heizkeller Brenner: OFF Mischer_weniger: OFF Mischer_mehr: OFF Waschkueche: ON EWT: ON F: OFF G: OFF H: OFF


Das Listing des Device:
Internals:
   CFGFN      ./FHEM/test.cfg
   DEF        FhemDev
   NAME       Stellmotor2
   NOTIFYDEV  global
   NR         752
   NTFY_ORDER 50-Stellmotor2
   STATE      80
   TYPE       STELLMOTOR
   Readings:
     2014-06-13 07:01:44   DoResetAtStop   1402635704.65127
     2014-06-13 07:30:38   OutType         FhemDev
     2014-06-13 07:01:44   command_queue   0
     2014-06-13 07:41:51   lastStart       1402638111.91855
     2014-06-13 07:42:15   locked          0
     2014-06-13 07:41:51   position        80
     2014-06-13 07:42:15   queue_lastdiff  -2.46475796950491
     2014-06-13 07:42:16   state           80
     2014-06-13 07:42:15   stopTime        0
Attributes:
   STMcalibrateDirection L
   STMfhemDevRL Switch_Heizkeller output B
   STMfhemDevSTART Switch_Heizkeller output C
   STMinvertOut 0
   STMlastDiffMax 3
   STMmapOffCmd OFF
   STMmapOnCmd ON
   STMmaxDriveSeconds 95
   STMmaxTics 100
   STMpollInterval 1
   STMresetOtherDeviceAtCalibrate 0
   STMrlType  einzel
   STMtimeTolerance 0.1
   room       _house



Noch eine Beobachtung: command_queue bleibt auf 0, auch wenn ich in eine laufende Fahrt hinein eine weitere "beauftrage". Zum Beispiel ausgehend von 10 set Stellmotor2 30 und sofort set Stellmotor2 70, dann sprint Position sofort auf 70 und es wird nun 70 angefahren. Tatsächlich werden die Befehle aber sauber gequeued abgearbeitet.

Grüße
Christian
PI 2B+/3B+ Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

epsrw1

ZitatNoch eine Beobachtung: command_queue bleibt auf 0, auch wenn ich in eine laufende Fahrt hinein eine weitere "beauftrage". Zum Beispiel ausgehend von 10 set Stellmotor2 30 und sofort set Stellmotor2 70, dann sprint Position sofort auf 70 und es wird nun 70 angefahren. Tatsächlich werden die Befehle aber sauber gequeued abgearbeitet.
die queue triggert kein event um die systemlast nicht zu vergeuden, und wird daher nur bei manuellem update (zB F5 key) angezeigt.

aus Deinen logfiles sehe ich folgendes:
a) entweder das log hat nicht richtig reagiert und ist unvollständig
b) Dein switch hat nicht reagiert und die kommandos nicht ausgeführt.
c) irgendwo beim mapping zwischen "output C" und "Mischer_mehr" innerhalb Deiner config wird der wert verschluckt (warum heißt eig. device anders als logeintrag?)

in der angehängten bilddatei habe ich es zusammensortiert und farbig markiert nach R + L. zu den L commands (Cmd ist negativzahl) gibt es keine schaltevents.

hier eine version zum debuggen (schreibt jede schaltaktion explizit ins log:
(zum nicht mehr debuggen einfach die zeile 32: "my($cwagner)=1;" löschen)

# $Id: 98_STELLMOTOR.pm 2018 2014-06-14 09:37:00Z Florian Duesterwald $

Ich habe keine Ahnung, aber davon wenigstens ganz viel

cwagner

Hallo Florian,

wie üblich geht es in Praxis heute Abend weiter - danke für die Debug-Fassung (das hatte ich mit verbose=5 versucht auszuloten). Da werde ich der Sache hoffentlich auf die Spur kommen.

ein "set Switch_Heizkeller output C ON" von der Konsole oder aus anderen Programm funktioniert. Deshalb habe ich das Problem nicht an dieser Stelle gesucht, aber das können wir ja mit der Debug-Zeile checken.

Warum heißt es im Device "C" ocder "B": Das OW_SWITCH-Modul erlaubt den Ports (A, B, C,.... H) Namen zu geben und man kann dann sowohl über den sprechenden Namen wie über den stumpfen Port adressieren.
Damit wird natürlich FHEM für den gemeinen Anwender leichter les- und verstehbar.

Um sicher zu gehen, dass durch diese Alias-Namen keine Komplikationen entstehen, teste ich grundsätzlich mit den Portnamen. Die sind mir da ja geläufig, in einem halben Jahr weiß ich natürlich nicht mehr, dass Port B "Mischer_weniger" benannt ist.
set Switch_Heizkeller output Mischer_mehr ON" ist also identisch mit set Switch_Heizkeller output C

Herzliche Grüße

Christian
PI 2B+/3B+ Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB

epsrw1

update:
# $Id: 98_STELLMOTOR.pm 2018 2014-06-14 09:37:00Z Florian Duesterwald $

Ich habe keine Ahnung, aber davon wenigstens ganz viel

ph1959de

Bitte, bitte, bitte - nimm das Modul wieder in den ersten Beitrag. Warum? Das ist jetzt hier (vorübergehend) der letzte Beitrag ... und der enthält nicht die aktuelle Version des Moduls.

Danke, Peter
Aktives Mitglied des FHEM e.V. | Moderator im Forenbereich "Wiki"

epsrw1

ph1959de, habe das bislang anders gehandhabt, da der erste beitrag wesentlich unpraktischer (für mich) ist. die problematik mit dem aktuellsten ist mir klar, daher war debug im vorletzten noch nciht gelöscht, und im letzten (mit debug code aber abgeschaltetem debug) für die "allgemeinheit" gedacht.
was soll's, es ist umgestellt, wäre ja nicht sinnvoll althergebrachte gewohnheit mit update im ersten beitrag durcheinanderzubringen nur weil es für einen einzelnen "praktischer" wäre. und nun wartet mein grill auf mich :)
LG, florian
Ich habe keine Ahnung, aber davon wenigstens ganz viel

epsrw1

Ich habe keine Ahnung, aber davon wenigstens ganz viel

epsrw1

update:

# $Id: 39_STELLMOTOR.pm 2021 2014-06-20 18:00:00Z Florian Duesterwald $
Ich habe keine Ahnung, aber davon wenigstens ganz viel

epsrw1

update:

# $Id: 39_STELLMOTOR.pm 2022 2014-06-21 11:54:00Z Florian Duesterwald $


+attr STMdebugToLog3
-Log level angepaßt
Ich habe keine Ahnung, aber davon wenigstens ganz viel

epsrw1

update:

# $Id: 39_STELLMOTOR.pm 2022 2014-06-29 14:04:00Z Florian Duesterwald $


(minor changes)
Ich habe keine Ahnung, aber davon wenigstens ganz viel

epsrw1

update:

# $Id: 39_STELLMOTOR.pm 2023 2014-07-01 22:34:00Z Florian Duesterwald $
Ich habe keine Ahnung, aber davon wenigstens ganz viel