letscontrolit / ESPEasy

Easy MultiSensor device based on ESP8266/ESP32
http://www.espeasy.com
Other
3.3k stars 2.22k forks source link

RDM6300 - read interval of rfid token #2982

Closed sa-wo closed 4 years ago

sa-wo commented 4 years ago

Hi, I have an issue with a RDm6300 rfid reader, I have already discussed this topic here https://www.letscontrolit.com/forum/viewtopic.php?f=4&t=7549&p=43527#p43527

My current setup is:

It seams that the reading interval of the rdm6300 is to high, even when I hold the tag in front of the reader is will recognize it several times, which will cause the relais turn off and on serveral times.

video1

We tried setting up different rules, nothing worked. This is my current rule:

on rfid_tag_water#Tag=3364040 do timerSet,1,2 Let,1,[water_pump#On] gpio,4,[VAR#1#!Z] endon

On Rules#Timer=1 do TaskValueSet,1,1,0 endon

It there a way to reduce the interval? THX sawo

device device_switch-relais

Budman1758 commented 4 years ago

Have you tried setting the interval to zero in the task settings? ^^

sa-wo commented 4 years ago

@Budman1758 thanks for your reply, but this device has changeable values in the task settings.

device

uzi18 commented 4 years ago

@sa-wo there is no such thing like interval in this plugin ... need to check if got something like this module or need logs from this module when rfid is in coil and far from coil

sa-wo commented 4 years ago

@uzi18 Hi this is the log, holding the token for 2 seconds on coil. No rules set.

83162: RFID : Tag: 3364040 83209: EVENT: rfid_tag_water#Tag=3364040 83227: RFID : Tag: 3364040 83291: RFID : Tag: 3364040 83335: EVENT: rfid_tag_water#Tag=3364040 83356: RFID : Tag: 3364040 83409: EVENT: rfid_tag_water#Tag=3364040 83421: RFID : Tag: 3364040 83485: RFID : Tag: 3364040 83510: EVENT: rfid_tag_water#Tag=3364040 83550: RFID : Tag: 3364040 83615: RFID : Tag: 3364040 83630: EVENT: rfid_tag_water#Tag=3364040 83679: RFID : Tag: 3364040 83756: EVENT: rfid_tag_water#Tag=3364040 83762: RFID : Tag: 3364040 83808: RFID : Tag: 3364040 83831: EVENT: rfid_tag_water#Tag=3364040 83878: RFID : Tag: 3364040 83916: EVENT: rfid_tag_water#Tag=3364040 83943: RFID : Tag: 3364040 84007: RFID : Tag: 3364040 84031: EVENT: rfid_tag_water#Tag=3364040 84072: RFID : Tag: 3364040 84137: RFID : Tag: 3364040 84180: EVENT: rfid_tag_water#Tag=3364040 84202: RFID : Tag: 3364040 84225: EVENT: rfid_tag_water#Tag=3364040 84266: RFID : Tag: 3364040 _84316: EVENT: rfid_tag_water#Tag=3364040 84416: EVENT: rfid_tag_water#Tag=3364040 84537: EVENT: rfid_tag_water#Tag=3364040 84609: EVENT: rfid_tag_water#Tag=3364040 84709: EVENT: rfid_tag_water#Tag=3364040 84809: EVENT: rfid_tag_water#Tag=3364040 84909: EVENT: rfid_tag_water#Tag=3364040 85027: EVENT: rfid_tagwater#Tag=3364040

The last 8 entries (84316 - 85027) appeared when I had already removed the token from coil.

Sawo

uzi18 commented 4 years ago

I need different log - directly from rfid module. You can try to get it by connect computer to usb on wemos d1 and use terminal app with settings 9600 8N1 (with hex display support - h-term/real term etc.) log same like before - 4s. with card and 4s. without card on coil.

sa-wo commented 4 years ago

@uzi18 I hope this is what you need, I user h-term.

output_2020-04-02_20-48-10.log output_2020-04-02_20-48-10_hex.log

Thx

uzi18 commented 4 years ago

@sa-wo ~what bin file did you flashed into esp?~ Will try to prepare build for you. ok it is in first post ;)

uzi18 commented 4 years ago

@TD-er do you have issues with envs?

[ESPEasy-mega_test]$ platformio run -v -e normal_ESP8266_1M
...
Error: VCS: Could not process command ['git', 'clone', '--recursive', '--depth', '1', '--branch', '2.6.3', 'https://github.com/esp8266/Arduino.git', '/home/users/linaja/.platformio/packages/_tmp_installing-i_r6q3ag-package']
uzi18 commented 4 years ago

@sa-wo you can try this and create log like before: firmware.bin.zip

sa-wo commented 4 years ago

@uzi18 Here are the log files, one in raw / Hex. I placed the token about 4 seconds on the coil.

output_2020-04-03_07-14-15.log output_2020-04-03_07-14-21.log

Thx sawo

uzi18 commented 4 years ago

@uzi18 Here are the log files, one in raw / Hex. I placed the token about 4 seconds on the coil.

output_2020-04-03_07-14-21.log

this one is the best, I see some place to improvemen in plugin - on communication side but your problem is that you want to know when card is removed?

uzi18 commented 4 years ago

@sa-wo need also log when card is removed

sa-wo commented 4 years ago

@uzi18 Here is the log with removed card, for about 10seconds.

output_2020-04-03_10-09-51.log output_2020-04-03_10-09-58.log

sawo

TD-er commented 4 years ago

@TD-er do you have issues with envs?

[ESPEasy-mega_test]$ platformio run -v -e normal_ESP8266_1M
...
Error: VCS: Could not process command ['git', 'clone', '--recursive', '--depth', '1', '--branch', '2.6.3', 'https://github.com/esp8266/Arduino.git', '/home/users/linaja/.platformio/packages/_tmp_installing-i_r6q3ag-package']

Not that I was aware of. Sometimes a delete of the packages dir in your .platformio dir (user dir, not the .pio folder in the checked out repo) does help. But just make sure to backup this folder just in case it is related to some dependency which cannot be downloaded.

uzi18 commented 4 years ago

@TD-er so we should add event "no card detected" like EVENT: rfid_tag_water#Tag=0 or/and ... plugin(s) sometimes should export some internals via predefinied variables like here rfid_tag_water#detected=1 via PLUGIN_UNCONDITIONAL_POLL

we actually repeat when card is available (maybe it should be option to report only new number?) EVENT: rfid_tag_water#Tag=3364040

Grovkillen commented 4 years ago

@TD-er so we should add event "no card detected" like EVENT: rfid_tag_water#Tag=0 or/and ... plugin(s) sometimes should export some internals via predefinied variables like here rfid_tag_water#detected=1 via PLUGIN_UNCONDITIONAL_POLL

we actually repeat when card is available (maybe it should be option to report only new number?) EVENT: rfid_tag_water#Tag=3364040

Yes a tag=0 when none is detected would be what to expect. And also if interval is set to more than zero just trigger the event. If interval=0 then trigger when a change is made, not flood the unit with events.

uzi18 commented 4 years ago

@Grovkillen via poll you only ask for variable value when needed in rules

if [rfid_tag_water#detected]=1 then
...
endif
Grovkillen commented 4 years ago

All right, so then you remove it it will not trigger an event? I find it a bit unusual compared to what I would expect.

I would believe it to work like this:

Interval = 0, the same behavior as with a switch input (only trigger on change) Interval > 0, it will trigger once per interval

Interval=0 would render in the following scenarios User expose a RFID tag to the reader: RFID#Number=123456790 is triggered User removes the RFID tag from the reader: RFID#Number=0 is triggered

Interval>0 would render in the following scenario Time000: RFID#Number=0 Time001: RFID#Number=0 Time002: RFID#Number=123456790 Time003: RFID#Number=123456790 Time004: RFID#Number=123456790 Time005: RFID#Number=0 Time006: RFID#Number=0

TD-er commented 4 years ago

I think it is also great to check a new received ID against the remembered last received one (as it is stored in the uservar) No need to give a new event immediately if the same card is detected. But it would make sense to have some timeout when we may need to detect the same one again. So either store the "0" in the Uservar when you don't see a tag and only send an event when the detected one differs from the last one. (just make sure you test unsigned long values, not floats. The unsigned longs are stored in 2 fields of the UserVar)

uzi18 commented 4 years ago

First minimal idea to reset card id to 0 when timedout. This should fullfill most of problems here.

We still not use all of data from cardid - it is 10x4 bits here and unsigned long is 32bit wide

uzi18 commented 4 years ago

@sa-wo try this build: firmware(1).bin.zip

TD-er commented 4 years ago

@uzi18 What did you change? Just set the value to 0 when not read? That will make it impossible to refer to the value from rules (apart from an event) Or just no event update if it is the same value?

We also have 2 extra fields in the UserVar we don't yet use, so you can store other values in there like the last read millis() or something like that.

uzi18 commented 4 years ago

@TD-er have set timer 500ms at end of assign cardid, when timer triggers reset cardid to 0

uzi18 commented 4 years ago
@@ -56,6 +56,17 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string)
         break;
       }

+    case PLUGIN_TIMER_IN:
+      {
+        if (Plugin_040_init) {
+            // Reset card id on timeout
+            UserVar[event->BaseVarIndex] = 0;
+            UserVar[event->BaseVarIndex + 1] = 0;
+            success = true;
+        }
+        break;
+      }
+

@@ -133,6 +160,7 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string)
               log += key;
               addLog(LOG_LEVEL_INFO, log);
               sendData(event);
+              setPluginTaskTimer(500, event->TaskIndex, event->Par1);
             }
           }
           success = true;
TD-er commented 4 years ago

But this does reset the output value, so you cannot use it anymore in rules for checks.

uzi18 commented 4 years ago

yes but who needs cardid when it is already removed?

Grovkillen commented 4 years ago

Like @TD-er said, if you have the last registered id you could have a extra event value that is 1 if the id is other than the last registered one. Else 0.

uzi18 commented 4 years ago

hey, we got here 2 issues

in my opinion for such plugin interval value should be not in use - when new card is detected (card id change) we should force to send data to controller

@Grovkillen this will be new feature :)

TD-er commented 4 years ago

You can use 2 output values (not sure what it does to controllers like Domoticz), one with the active one and one with the last one. But that also demands a new output type.

I think the main issue here is that you should only send an event when it is a new card, so use some timeout (which you can store in the last 2 values of UserVar) So a detected value of "no card" does not change anythIng (maybe send an event when the card ID has changed from "detected" to "no card detected")

To summarize:

sa-wo commented 4 years ago

Hi sorry that I am answering so late. Here is the last log with placing the tag for about 4 seconds on the coil. output_2020-04-05_10-33-18.log

and here with no tag on coil output_2020-04-05_10-34-57.log

Thx SAWO

uzi18 commented 4 years ago

@sa-wo from now you can send log without hex, please check it one more time also with different tag

firmware(3).bin.zip

uzi18 commented 4 years ago

@TD-er actual patch:

diff --git a/src/_P040_ID12.ino b/src/_P040_ID12.ino
index 40b90111..3cdf8743 100644
--- a/src/_P040_ID12.ino
+++ b/src/_P040_ID12.ino
@@ -47,7 +47,6 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string)
         break;
       }

-
     case PLUGIN_INIT:
       {
         Plugin_040_init = true;
@@ -56,6 +55,19 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string)
         break;
       }

+    case PLUGIN_TIMER_IN:
+      {
+        if (Plugin_040_init) {
+            // Reset card id on timeout
+            UserVar[event->BaseVarIndex] = 0;
+            UserVar[event->BaseVarIndex + 1] = 0;
+            String log = F("RFID : Removed Tag");
+            addLog(LOG_LEVEL_INFO, log);
+            sendData(event);
+            success = true;
+        }
+        break;
+      }

     case PLUGIN_SERIAL_IN:
       {
@@ -125,14 +155,21 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string)
               event->sensorType = Device[DeviceIndex].VType;
               // endof workaround

-              unsigned long key = 0;
+              unsigned long key = 0, old_key = 0;
+              old_key = ((uint32_t) UserVar[event->BaseVarIndex]) | ((uint32_t) UserVar[event->BaseVarIndex + 1])<<16;
               for (byte i = 1; i < 5; i++) key = key | (((unsigned long) code[i] << ((4 - i) * 8)));
-              UserVar[event->BaseVarIndex] = (key & 0xFFFF);
-              UserVar[event->BaseVarIndex + 1] = ((key >> 16) & 0xFFFF);
-              String log = F("RFID : Tag: ");
+              String log = F("RFID : ");
+              if (old_key != key) {
+                UserVar[event->BaseVarIndex] = (key & 0xFFFF);
+                UserVar[event->BaseVarIndex + 1] = ((key >> 16) & 0xFFFF);
+                sendData(event);
+                setPluginTaskTimer(500, event->TaskIndex, event->Par1);
+                log += F("New Tag: ");
+              } else {
+                log += F("Old Tag: ");
+              }
               log += key;
               addLog(LOG_LEVEL_INFO, log);
-              sendData(event);
             }
           }
           success = true;
TD-er commented 4 years ago

@uzi18 I added the syntax highligher diff to your post, makes it easier to read.

The timer to erase the value is set to 500 msec. in your code. Isn't it better to make it configurable? I can imagine it may take a while sometimes to process long rules when comparing against a number of allowed keys.

uzi18 commented 4 years ago

@TD-er if you look at logs from @sa-wo rfid reader report tag every 70-80 ms if in range, so 500ms is far optimistic in my opinion.

TD-er commented 4 years ago

OK, then leave it like that and if someone ever runs into it, we can always make it configurable. Maybe just add a comment to this line then :)

uzi18 commented 4 years ago

of course, have also looked at our other rfid plugin, we should add simmilar behavior to have consistent environment.

uzi18 commented 4 years ago

@TD-er do you think UserVar could be anonymous union or something like that? So in some situations we could access bytes of float directly without voodoo magic?

TD-er commented 4 years ago

So in some situations we could access bytes of float directly without voodoo magic?

Well it is not shared among platforms. I think we can do it, but make sure to add an assert to check its size at compile time.

Maybe a separate function (or class) to handle all these bit manipulations is a more backwards compatible solution.

The most elegant solution would be to have a single object representing all UserVar values of a single task with get/set functions for each of them. But that does require change in code of all existing plugins and most controllers. So the second best would be a get/set class that can interact with this UserVar array and then you can call those from all plugin/controller code you wish to upgrade. This can then also be used on other code that needs to store data in limited sized variables like we now do in the Dallas plugin and the places in the code using functions like getBitFromUL (or however it is called)

uzi18 commented 4 years ago

@TD-er there is a workaround above 125 line is it still needed? If remember correctly there was some fixes for this in time of development of esteron plugin.

TD-er commented 4 years ago

You mean this code?

              // temp woraround, ESP Easy framework does not currently prepare this...
              taskIndex_t index = INVALID_TASK_INDEX;
              for (taskIndex_t y = 0; y < TASKS_MAX; y++)
                if (Settings.TaskDeviceNumber[y] == PLUGIN_ID_040)
                  index = y;
              const deviceIndex_t DeviceIndex = getDeviceIndex_from_TaskIndex(index);
              if (!validDeviceIndex(DeviceIndex)) {
                break;
              }
              event->TaskIndex = index;
              event->BaseVarIndex = index * VARS_PER_TASK;
              if (!validUserVarIndex(event->BaseVarIndex)) {
                break;
              }
              event->sensorType = Device[DeviceIndex].VType;
              // endof workaround

The place where PLUGIN_SERIAL_IN is called, it is not yet known what plugin may process this data from the serial port. So it seems still needed. It is not really an elegant way of handling data from the serial port, so we may later add some handler to process this kind of data.

Right now, it does seem like it was meant to allow both serial logging and receiving commands via serial + allow a card reader to be present. Thus we have different ways plugins interact with the serial port:

The second one does allow for selecting a serial port (even SW serial or the recently added I2C serial)

uzi18 commented 4 years ago

@TD-er so in PLUGIN_TIMER_IN we also need this workaround?

TD-er commented 4 years ago

void process_plugin_task_timer(unsigned long id) {
  START_TIMER;
  const systemTimerStruct timer_data = systemTimers[id];
  struct EventStruct TempEvent;
  TempEvent.TaskIndex = timer_data.TaskIndex;
  TempEvent.Par1      = timer_data.Par1;
  TempEvent.Par2      = timer_data.Par2;
  TempEvent.Par3      = timer_data.Par3;
  TempEvent.Par4      = timer_data.Par4;
  TempEvent.Par5      = timer_data.Par5;

  // TD-er: Not sure if we have to keep original source for notifications.
  TempEvent.Source = VALUE_SOURCE_SYSTEM;
  const deviceIndex_t deviceIndex = getDeviceIndex_from_TaskIndex(timer_data.TaskIndex);

  /*
     String log = F("proc_system_timer: Pluginid: ");
     log += deviceIndex;
     log += F(" taskIndex: ");
     log += timer_data.TaskIndex;
     log += F(" sysTimerID: ");
     log += id;
     addLog(LOG_LEVEL_INFO, log);
   */
  systemTimers.erase(id);

  if (validDeviceIndex(deviceIndex)) {
    String dummy;
    Plugin_ptr[deviceIndex](PLUGIN_TIMER_IN, &TempEvent, dummy);
  }
  STOP_TIMER(PROC_SYS_TIMER);
}

As you can see, the TaskIndex is preserved, but if you need the BaseVarIndex and/or `sensorType, then it should be set in this code I showed here.

Edit: For example P091_SerSwitch does set the BaseVarIndex, which should have been set in this code calling the PLUGIN_TIMER_IN

uzi18 commented 4 years ago

@sa-wo this one: firmware(4).bin.zip

uzi18 commented 4 years ago

@TD-er not sure if we realy need validUserVarIndex() check

diff --git a/src/Scheduler.ino b/src/Scheduler.ino
index e474398c..cd61b157 100644
--- a/src/Scheduler.ino
+++ b/src/Scheduler.ino
@@ -419,6 +419,7 @@ void process_plugin_task_timer(unsigned long id) {
   const systemTimerStruct timer_data = systemTimers[id];
   struct EventStruct TempEvent;
   TempEvent.TaskIndex = timer_data.TaskIndex;
+  TempEvent.BaseVarIndex =  timer_data.TaskIndex * VARS_PER_TASK;
   TempEvent.Par1      = timer_data.Par1;
   TempEvent.Par2      = timer_data.Par2;
   TempEvent.Par3      = timer_data.Par3;
@@ -440,7 +441,8 @@ void process_plugin_task_timer(unsigned long id) {
    */
   systemTimers.erase(id);

-  if (validDeviceIndex(deviceIndex)) {
+  if (validDeviceIndex(deviceIndex) && validUserVarIndex(TempEvent.BaseVarIndex)) {
+    TempEvent.sensorType = Device[deviceIndex].VType;
     String dummy;
     Plugin_ptr[deviceIndex](PLUGIN_TIMER_IN, &TempEvent, dummy);
   }
TD-er commented 4 years ago

In that part of the code we don't as it is a valid TaskIndex, so you know for sure you will not be out of range for the UserVar array. On the other hand, it is quite a simple check and the call for this function is not done a lot per second.

fraeggle commented 4 years ago

Hi first of all. do you use f.ex IOBroker or ESP as a stand alone Reader? I am using it with IObroker and Espeasy. I use dummy device for testing if it is connected to the broker or not. If not connected i am working with timers. Checking if it is in Reboot (no weird things during boot possible), Count of allowed and not allowed Cards (only with Broker alive, because this is done by broker) and so on.. Having no Problems with openning .

Rules (using 3 of the possible 4) on System#Boot do TaskValueSet,10,4,1 TaskValueSet,9,1,1 GPIO,5,1 TaskValueSet,9,2,1 timerSet,1,600 endon

on MQTT#Connected do Publish %sysname%/status/IP,%ip% Publish,%sysname%/Reset/status,1 Publish,%sysname%/RFID/status,[status2#Wert2] TaskValueSet,9,1,[status2#Wert2] Publish,%sysname%/alive/status,0 endon

on switch#Wert3 do If %eventvalue% = 1 TaskValueSet,10,4,0 Publish,%sysname%/Reset/status,0 endif endon

on RFID#Tag do if [status1#Boot_status]=0 and [status2#alive]=0 --> allowed/not allowed triggerd by Broker TaskValueSet,12,4,1 endif if [status2#alive]=1 ----> 1 means no connection to broker ;-) so this will be your way TaskValueSet,12,4,1 event,RFIDCHECK endif EndOn

On switch#Wert4 Do If [switch#Wert4]=1 event,rfidok endif If [switch#Wert4]=2 event,rfidnook endif //If [switch#Wert4]=0 // event,rlsaus //endif endon

on zaehlerreset do TaskValueSet,10,1,0 TaskValueSet,10,2,0 Publish,%sysname%/RFID_Zaehler/ok,[status1#ok_z] Publish,%sysname%/RFID_Zaehler/nook,[status1#nook_z] endon

On Rules#Timer=1 do TaskValueSet,9,1,1
Publish,%sysname%/alive/status,1 timerSet,1,600 endon

on switch#Wert2 do If [switch#Wert2]=1 and [status1#Boot_status]=0 TaskValueSet,9,1,0 //timerSet,1,600 Publish,%sysname%/alive/status,0 EndIf Endon

On RFID_anaus#state do If [RFID_anaus#state]=0 event,rfidtoggle EndIf EndOn

on rfidtoggle do If [status2#Wert2]=1 GPIO,5,0 TaskValueSet,9,2,0 Publish,%sysname%/RFID/status,[status2#Wert2] else GPIO,5,1 TaskValueSet,9,2,1 Publish,%sysname%/RFID/status,[status2#Wert2] endif endon

On switch#Wert1 Do If [switch#Wert1]=1 event,rfidtoggle EndIf endon

on rfidok do if [status1#Boot_status]=0 and [status#Status]=1 GPIO,13,0 TaskValueSet,12,3,0 Publish,%sysname%/Fehler/status,0 GPIO,14,1 TaskValueSet,12,1,1 Publish,%sysname%/RLS/status,1 GPIO,12,1 TaskValueSet,12,2,1 Publish,%sysname%/RFID_OK/status,1 TaskValueSet,10,1,[status1#ok_z]+1 Publish,%sysname%/RFID_Zaehler/ok,[status1#ok_z] endif timerSet,2,2 endon

on rfidnook do If [status#Status]=1 GPIO,14,0 TaskValueSet,12,1,0 Publish,%sysname%/RLS/status,0 GPIO,12,0 TaskValueSet,12,2,0 Publish,%sysname%/RFID_OK/status,0 GPIO,13,1 TaskValueSet,12,3,1 Publish,%sysname%/Fehler/status,1 TaskValueSet,10,2,[status1#nook_z]+1 Publish,%sysname%/RFID_Zaehler/nook,[status1#nook_z] endif endon

on rlsaus do GPIO,14,0 TaskValueSet,12,1,0 Publish,%sysname%/RLS/status,0 GPIO,12,0 TaskValueSet,12,2,0 Publish,%sysname%/RFID_OK/status,0 GPIO,13,0 TaskValueSet,12,3,0 Publish,%sysname%/Fehler/status,0 TaskValueSet,12,4,0 TaskValueSet,10,3,0 EndOn

On RFIDCHECK do If [RFID#Tag]=1234567 event,rfidnot endif If [RFID#Tag]=1234568 event,rfidnot endif If [RFID#Tag]=1234569 event,rfidnot endif timerSet,3,4 endon

on rfidnot do if [status1#Boot_status]=0 and [status1#sperre]=0 If [status#Status]=1 GPIO,14,1 TaskValueSet,12,1,1 Publish,%sysname%/RLS/status,1 GPIO,12,1 TaskValueSet,12,2,1 Publish,%sysname%/RFID_OK/status,1 TaskValueSet,10,3,1 endif endif timerSet,2,2 endon

On Rules#Timer=2 do event,rlsaus endon

On Rules#Timer=3 do Publish,%sysname%/RFID/Tag,0 endon

grafik

uzi18 commented 4 years ago

@fraeggle did you tried my modified firmware or are you using original from release?

fraeggle commented 4 years ago

original mega-20200310

fraeggle commented 4 years ago

you have to use a timer or something to avoid multiple readings. but that is not a issue from espeasy, because the rdm6300 is reading the id as long as a card is in range, so your relais is being toggled all the time. (Works as designed). if the id was not read in all the time, you could never trigger an event with the same card one after the other, but you might have to take another id first. With a timer (as I solved it) you can also decide how long e.g. no other id can be read in or how long e.g. a relay should be activated.

fraeggle commented 4 years ago

Btw i learned not to use switch for an output or what you use the switch for? in my rules rfidnot means rfid "emergency" (No connection to broker, it has to handle the id's by itself)