error "readingsUpdate() missed to call readingsBeginUpdate first"

Begonnen von roelb, 02 September 2019, 13:33:38

Vorheriges Thema - Nächstes Thema

roelb

Hey folks,

I ran into an issue that I can't seem to figure out. My setup is as follows:

I have a KNX device "GEN_EXTRACTION_FAN" that represents an extraction fan with 4 levels - off (0), low (1), mid (2) and high (3).

The underlying device actually works with three relays. One turns the fan on or off. The other two are the medium and high speed relays. For each of these three relays, I have two KNX group objects defined. One that switches the relay and one status object that represents the current relay state. So far, so good.

In FHEM, I want to have a single object that represents the logical fan. So I've defined the fan with 6 group objects, two for each relay. As I also want to be able to see the current logical state (off, low, mid or high) I've added a userReading that returns either value based on the current state of the relays. That all works. This would be the following setup:

define GEN_EXTRACTION_FAN KNX 1/4/0:dpt1.001:low:set:nosuffix 1/4/1:dpt1.001:low-status:get:nosuffix 1/4/2:dpt1.001:mid:set:nosuffix 1/4/3:dpt1.001:mid-status:get:nosuffix 1/4/4:dpt1.001:high:set:nosuffix 1/4/5:dpt1.001:high-status:get:nosuffix
attr GEN_EXTRACTION_FAN userReadings level-get {\
        return "high" if ReadingsVal("GEN_EXTRACTION_FAN",'high-status','0') eq "on";; \
        return "mid" if ReadingsVal("GEN_EXTRACTION_FAN",'mid-status','0') eq "on";; \
        return "low" if ReadingsVal("GEN_EXTRACTION_FAN",'low-status','0') eq "on";; \
        return "off";; }


Things go wrong in the next step. As I also want to be able to easiliy set the logical state of the fan, without caring about the actual relays, I've added a 7th group object. This uses a dummy KNX group address as this seems to be the only way to add a custom reading to a KNX object in FHEM:


define GEN_EXTRACTION_FAN KNX 1/4/0:dpt1.001:low:set:nosuffix 1/4/1:dpt1.001:low-status:get:nosuffix 1/4/2:dpt1.001:mid:set:nosuffix 1/4/3:dpt1.001:mid-status:get:nosuffix 1/4/4:dpt1.001:high:set:nosuffix 1/4/5:dpt1.001:high-status:get:nosuffix 9/9/9:dpt5:level:set:nosuffix


I then use the eventMap and stateCmd attributes to do something useful when a value is written to this group address.

attr GEN_EXTRACTION_FAN eventMap {\
        usr=>{ '^level low$'=>'level 1',\
                '^level mid$'=>'level 2',\
                '^level high$'=>'level 3',\
                '^level off$'=>'level 0'}}
attr GEN_EXTRACTION_FAN stateCmd {\
    if ($gadName=~m/level/i) {\
        $state==0 && fhem("set GEN_EXTRACTION_FAN high off;;set GEN_EXTRACTION_FAN mid off;;set GEN_EXTRACTION_FAN low off");; \
        $state==1 && fhem("set GEN_EXTRACTION_FAN high off;;set GEN_EXTRACTION_FAN mid off;;set GEN_EXTRACTION_FAN low on");; \
        $state==2 && fhem("set GEN_EXTRACTION_FAN mid on;;set GEN_EXTRACTION_FAN high off;;set GEN_EXTRACTION_FAN low on");; \
        $state==3 && fhem("set GEN_EXTRACTION_FAN high on;;set GEN_EXTRACTION_FAN mid off;;set GEN_EXTRACTION_FAN low on");; \
    }\
}


This does what I expect it to do. Running "SET GEN_EXTRACTION_FAN level high" (or off/low/mid) works as expected and sets all the seperate relays. All states are updated in FHEM. However, each time I run this command, I get three error messages in my log:


2019.09.02 13:30:03 1: readingsUpdate(GEN_EXTRACTION_FAN,state,) missed to call readingsBeginUpdate first.
2019.09.02 13:30:03 1: stacktrace:
2019.09.02 13:30:03 1:     main::readingsBulkUpdate            called by ./FHEM/10_KNX.pm (1005)
2019.09.02 13:30:03 1:     main::KNX_Set                       called by /data/fhem/fhem.pl (3592)
2019.09.02 13:30:03 1:     main::CallFn                        called by /data/fhem/fhem.pl (1808)
2019.09.02 13:30:03 1:     main::DoSet                         called by /data/fhem/fhem.pl (1840)
2019.09.02 13:30:03 1:     main::CommandSet                    called by ./FHEM/98_cmdalias.pm (99)
2019.09.02 13:30:03 1:     main::CommandCmdAlias               called by /data/fhem/fhem.pl (1214)
2019.09.02 13:30:03 1:     main::AnalyzeCommand                called by /data/fhem/fhem.pl (1062)
2019.09.02 13:30:03 1:     main::AnalyzeCommandChain           called by ./FHEM/98_telnet.pm (242)
2019.09.02 13:30:03 1:     main::telnet_Read                   called by /data/fhem/fhem.pl (3597)
2019.09.02 13:30:03 1:     main::CallFn                        called by /data/fhem/fhem.pl (726)
2019.09.02 13:30:03 1: readingsUpdate(GEN_EXTRACTION_FAN,last-sender,fhem) missed to call readingsBeginUpdate first.
2019.09.02 13:30:03 1: stacktrace:
2019.09.02 13:30:03 1:     main::readingsBulkUpdate            called by ./FHEM/10_KNX.pm (1006)
2019.09.02 13:30:03 1:     main::KNX_Set                       called by /data/fhem/fhem.pl (3592)
2019.09.02 13:30:03 1:     main::CallFn                        called by /data/fhem/fhem.pl (1808)
2019.09.02 13:30:03 1:     main::DoSet                         called by /data/fhem/fhem.pl (1840)
2019.09.02 13:30:03 1:     main::CommandSet                    called by ./FHEM/98_cmdalias.pm (99)
2019.09.02 13:30:03 1:     main::CommandCmdAlias               called by /data/fhem/fhem.pl (1214)
2019.09.02 13:30:03 1:     main::AnalyzeCommand                called by /data/fhem/fhem.pl (1062)
2019.09.02 13:30:03 1:     main::AnalyzeCommandChain           called by ./FHEM/98_telnet.pm (242)
2019.09.02 13:30:03 1:     main::telnet_Read                   called by /data/fhem/fhem.pl (3597)
2019.09.02 13:30:03 1:     main::CallFn                        called by /data/fhem/fhem.pl (726)
2019.09.02 13:30:03 1: readingsUpdate(GEN_EXTRACTION_FAN,level-get,high) missed to call readingsBeginUpdate first.
2019.09.02 13:30:03 1: stacktrace:
2019.09.02 13:30:03 1:     main::readingsBulkUpdate            called by /data/fhem/fhem.pl (4553)
2019.09.02 13:30:03 1:     main::readingsEndUpdate             called by ./FHEM/10_KNX.pm (1007)
2019.09.02 13:30:03 1:     main::KNX_Set                       called by /data/fhem/fhem.pl (3592)
2019.09.02 13:30:03 1:     main::CallFn                        called by /data/fhem/fhem.pl (1808)
2019.09.02 13:30:03 1:     main::DoSet                         called by /data/fhem/fhem.pl (1840)
2019.09.02 13:30:03 1:     main::CommandSet                    called by ./FHEM/98_cmdalias.pm (99)
2019.09.02 13:30:03 1:     main::CommandCmdAlias               called by /data/fhem/fhem.pl (1214)
2019.09.02 13:30:03 1:     main::AnalyzeCommand                called by /data/fhem/fhem.pl (1062)
2019.09.02 13:30:03 1:     main::AnalyzeCommandChain           called by ./FHEM/98_telnet.pm (242)
2019.09.02 13:30:03 1:     main::telnet_Read                   called by /data/fhem/fhem.pl (3597)
2019.09.02 13:30:03 1:     main::CallFn                        called by /data/fhem/fhem.pl (726)


Is there another way to accomplish what I am doing here without these error messages each time the command is run?

rudolfkoenig

It looks to me that stateCmd in the KNX module was _not_ intended for changing the device, but computing a state value, more or less the same like the globally available stateFormat.

I propose using a notify instead.

roelb

Thnx. I solved it by replacing the stateCmd with four notify definitions as per your suggestion.

Too bad the stateCmd route throws these errors. I liked the elegant solution where all logic is contained within the same object.