VoxCommando
Help and Support (Using VoxCommando) => Other Plugins => Topic started by: manfaiho on October 28, 2013, 02:48:27 AM
-
I am currently using TCP Plugin as TTS server for Vera Home automation. I wrote Luup code to send the sentence from Vera using socket library to Voxcommando to hook TCP event to trigger the action of speaking this sentence. It works perfectly. Awerson!!
Now I am currenlty purchasing 2.4GHz RFID reader and Active RFID tags which can send a Hexcode like a pattern of "FB 10 00 00 TagID RFGain ReadID 01" over USB or TCP/IP for the purpose of reporting tag presence . I want to make use of Voxcommando TCP Plugin to get this Hexcode then trigger event action to speak something as welcome message then execute some actions for their preference when thery are coming back home. I only found {lastresult} for TCP command which is used for string but I don't know how to decode this pattern of Hexcode to identify its TagID within TCP Plug-in to trigger Vera "Virtual Switch" (On: for some people Present Off: not here) then run various scenes. Can anyone help me how to extract Hexcode information within TCP Plug? Do you have a better solution? Really apprecaite for your advice :-)
-
Hi manifaiho, did you have tried also the VC Vera-plugin?
James wrote a short piece of Luup code that generate a event for each vera device in VC over UDP - so it is easy to use a RFID or a motion sensor to generate a event in VC.
I can't post this code here because it is not my code, but I'm sure James will do it. ;)
The attached picture show you how the event looks.
-
Thanks, Kalle. I also used what you mentioned for other purpose to hook Vera event in VC.
Actually my RFID is not Z-wave awared. It can only send its Hexcode (including TagID) to PC via USB/RS232 or over TCP/IP. I plan to receive this Hexcode from TCP in VC not Vera. I think TCP Plug is the best option compared with Vera to receive TCP data. Any good idea? But what I want is when I got this string in VC using its TCP Server from plugin, how to extract TagID from these Hexcodes so that I can use it identify the one then say welcome message etc then even call Vera scene. If you have idea on Vera to recevie TCP then extract TagID, yes I like it too. I can use it to send back my welcome message to VC to speak it also.
-
Ah ok this device is not a z-wave. If I understand you correct, each RFID chip has a different ID code (Hex code) and you search a way to send this code to VC.
How is the RFID reader connected?
-
Yes, RFID reader used RS232/USB to send Hexcodes, it also provides one more option for TCP. I plan to use TCP server to receive its Hexcode in VC. I can successfully start TCP Server to receive it but I can't extract its TagID from these Hexcodes within VC. Any clue?
-
There are some possibilities, can you post a screenshot from the received Data? If the {LastResult} contains Data like "FB 10 00 00 TagID RFGain ReadID 01" it is easy to extract any Data from there with "Results.RegEx" or "Results.RegExReplace" etc. action in VC.
-
Yes, RFID reader used RS232/USB to send Hexcodes, it also provides one more option for TCP. I plan to use TCP server to receive its Hexcode in VC. I can successfully start TCP Server to receive it but I can't extract its TagID from these Hexcodes within VC. Any clue?
Hi manfaiho. I'm very excited to hear what you are doing. I have been wanting to try this myself, but I was not sure which hardware to use. (Please send details about the RFID hardware you are using when you have a chance.)
Can you please show us what options you have when setting up TCP on the tag reader.
I think you are probably correct that using the TCP plugin for VC is the best option. I think it will be possible to do this with the plugin already, but if not, I will be happy to make whatever modifications are necessary to get it to work.
-
Data stream is not ASC character format like FB 10 00... It is hex data stream: 0xFB, 0x10, 0x00 not readable in {1} buffer from TCP plugin. So I don't know how to use Results object to manipulate the hex pattern in VC. I think Hex code in Serial port communication is common. But when using TCP server to receive it, especially for VC, we really don't know that. Any suggestion?
-
TCP server will need to generate an event. The command triggered by the event can use the payload to determine which tag has triggered the device.
I need to adjust the plugin to convert hex codes to a readable form. Please stand by, it won't take too long. ;D
-
Hi James, I have tested UHF RFID with Passive Tag but its result is not what I expect. Hence I change it to use Active RFID in 2.4GHz which can have a longer distance range (UHF: less than 8M, 2.4G: <100M). I purchased from taobao.com (you may need to read it in chinese) http://item.taobao.com/item.htm?id=13280048779 It will send hex data command via TCP/IP so I plan to use TCP Plugin to get TagID. However, I can't find Results object to manuipulate Hex data to trigger subsequent action. Any idea?
-
Thank you so much, James. You are so awersome. Look forward to seeing your great work. Taobao.com has so many cheap toys for fun. This set of 100M distance 2.4G RFID reader plus 8 active RFID 2.4G tags, only cost me less than USD200. Interesting ;D
-
If I understand correctly, this is all you will need.
Close VC
Replace the tcp plugin dll file with the attached file
Restart VC and now your hex codes will appear in the correct format (I hope).
-
Its' great, James :-) But how to extract the pattern of "FB 10 00 00 TagID RFGain ReadID 01" in Hex format from your updated TCP Plugin or direct extract TagID from this pattern? Sorry I am not quite familar with it on VC. Once I get this reader these days, I will test it then get back you the result immediately. Thank you very much.
-
Btw, I've also tested to detect the proximity using bluetooth with its Type I bluetooth adapter (longer distance, <50M). I've also downloaded a freeware software with its source code which can detect whether your registered bluetooth device is in the range. Once in-range, it will execute a batch command to trigger my Vera scene. Once out of range, it will also trigger another Vera scene. I've used it for my security system in Vera for the state of ARM and BYPASS then say welcome or bye bye message even turn on my LED in differnt color. Very intersting! But I used RFID becasue I have 4 kids who will not bring any bluetooth devices or mobile phone so I want to put this active tag into thier backpack in order to detect them when they come back home or leave from home..... ;D ;D ;D ;D ;D
-
Hi James, one more question, I used previous TCP Plugin for TTS server. I can send TCP command with speaking sentence from Vera to VC then VC will read this sentence and use TTS.Speak to sepak it out. This sentence I use is a general ASC characters. I can successfully use TTS.Speak {1} to speak it out when I got TCP event. But now, after change it the updated TCP Plugin, all {1}, {2} etc should be hex converted. Can we install two separate TCP Plugin: One for ASC and another for Hex. Or I can use object one to handle ASC and another one for Hex decoded etc...Sorry for my too many questions :bonk
-
The code will be passed as payload 1 with the event . the command triggered by the event can access this data using {1}
I must walk the dog but when I get back I will create some sample commands for you. I will send something within the next hour or two.
I am interested to try the Bluetooth method. I could use this to turn the front light on at night when we return from night-time dog walkies. :D
-
But I used RFID becasue I have 4 kids who will not bring any bluetooth devices or mobile phone so I want to put this active tag into thier backpack in order to detect them when they come back home or leave from home..... ;D ;D ;D ;D ;D
;D But what happens if someone steals your child's backpack, or they forget their bag at a friend's place? You might need to implant the tags directly into your kids. Kalle has done this with his cat!
:biglaugh
-
Haha, and it works, but I'm sure if you go with your kids to the pet doctor to implant a RFID chip, he will get problems. :biglaugh
-
Hi James, one more question, I used previous TCP Plugin for TTS server. I can send TCP command with speaking sentence from Vera to VC then VC will read this sentence and use TTS.Speak to sepak it out. This sentence I use is a general ASC characters. I can successfully use TTS.Speak {1} to speak it out when I got TCP event. But now, after change it the updated TCP Plugin, all {1}, {2} etc should be hex converted. Can we install two separate TCP Plugin: One for ASC and another for Hex. Or I can use object one to handle ASC and another one for Hex decoded etc...Sorry for my too many questions :bonk
Please post the XML for your commands that use TCP and TTS
note: you can right-click a group in the command tree and select "copy" then in the forum create a code block (# button) and paste the xml in there.
-
James wrote a short piece of Luup code that generate a event for each vera device in VC over UDP - so it is easy to use a RFID or a motion sensor to generate a event in VC.
I can't post this code here because it is not my code, but I'm sure James will do it. ;)
You don't need any special luup code any more. You just need to enable polling in the VoxCommando Vera plugin settings. Events will be generated automatically.
-
Please post the XML for your commands that use TCP and TTS
note: you can right-click a group in the command tree and select "copy" then in the forum create a code block (# button) and paste the xml in there.
-
Here is some sample code that shows you the two different types of TCP server we can create. One is for generating events. You would use this with your RFID. The other is for accepting actions from TCP. You could use this with Vera to send TTS actions.
Note that each TCP server must be created using a unique port. I am using port 1000 for events, and 1001 for actions. You can't have two servers that are both listening to the same port.
Look at the descriptions that I have put into the commands to help you understand how it works.
I am also attaching a new version of the TCP plugin dll that will hopefully work correctly for both types of messages.
<?xml version="1.0" encoding="utf-16"?>
<commandGroup open="True" name="tcp server" enabled="True" prefix="" priority="0" requiredProcess="" description="">
<command id="267" name="RFID create tcp server" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This TCP server listens on port 1000
It generates events when it receives TCP messages
the event will carry the TCP message as the payload: {1}
The event name will be "RFID" as specified by the <GenEvent> parameter when we start the server">
<action>
<cmdType>TCP.Server.Start</cmdType>
<cmdString>1000&&RFID</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<event>VC.Loaded</event>
</command>
<command id="286" name="create general tcp server" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This TCP server listens on port 1001
When it receives TCP messages, it tries to evaluate it it as an action for VC.
That is because we declared the server without using the optional parameter <GenEvent>">
<action>
<cmdType>TCP.Server.Stop</cmdType>
<cmdString>1001</cmdString>
<cmdRepeat>0</cmdRepeat>
</action>
<action>
<cmdType>TCP.Server.Start</cmdType>
<cmdString>1001</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<event>VC.Loaded</event>
</command>
<command id="262" name="onRFID event" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This command is triggered when the RFID event if fired. It attempts to find the ID and then generates a new event which includes the ID in the EVENT NAME, instead of having it in the payload.">
<action>
<cmdType>Results.SetLastResult</cmdType>
<cmdString>{1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<cmdString>(.*?)TagID</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{#M}&&1</ifParams>
<then>
<action>
<cmdType>VC.TriggerEvent</cmdType>
<cmdString>TAG.{Match.1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
<event>RFID</event>
</command>
<command id="527" name="test TCP send RFID" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This attempts to simulate the message that would be sent by the RFID hardware">
<action>
<cmdType>TCP.Single.Write</cmdType>
<cmdString>\xFB\x10\x00\x00 TagID RFGain ReadID\x01&&192.168.0.125&&1000</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
</command>
<command id="541" name="test TCP send general actions" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This sends an action string to VC on port 1001.
We can't include && in our first parameter or this will confuse VC when it is sending the action. So instead we encode the && as \x26\x26">
<action>
<cmdType>TCP.Single.Write</cmdType>
<cmdString>osd.showtext\x26\x26hello thereê&&192.168.0.125&&1001</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
</command>
</commandGroup>
-
Hi James, you are so great. I like your sample. My stupid: I copy your XML codes then put it into XMLNotepad. You can see attached XML file. But when I load into VOX Edit, it prompts exception. I can read it from XML tag to understand what the actions you created for this test that sounds good. I will try it once I got this hardware these days. Thank you very much and I really love this very powerful and strong support's products.
-
&feature=youtube_gdata_player
-
Hi James, thank your pointer. I watch it then try to drag your sample into Edit Window but it prompts me a series of error message windows. Something like weird data format: System.String or others. I don't know what's wrong. I also rebuild standard configration using basic. The problem can't be resolved. What a strange!! :bonk :bonk :bonk
-
Do following: marked the code above, hold the STRG key and then drag and drop it with the mouse to your command tree.
-
First of all, let me assure you there is nothing wrong with the xml code above.
Kalle: STRG is only on German keyboards I guess? Does it mean CTRL ? Anyway it is not necessary for dragging code from the forum window to the VC editor tree. It will still work but it should make no difference.
1) Highlight ALL the code in the "code block". Do not highlight extra text outside the box
2) on your keyboard press Ctrl-C to copy the xml text (or right-click and choose "copy")
3) select any node in your VC tree. and press Ctrl-V to paste the xml text.
(or right-click anywhere on tree and choose "paste")
A new group node named "tcp server" should be created in the tree with 5 commands in it.
DO NOT copy the xml into a file first and then try to drag the file into the tree. This will not work.
If you still get an error message, please tell us exactly what it says, or post a screen capture of the message. Better yet, make a short video showing us what you are doing so we can figure out if you are finding some creative way to make it not work, or if there actually is some kind of bug we need to fix. I have been copying and pasting code back and forth using all sorts of methods without any problems for a long time but maybe it relates to running Windows in an other language or something like that.
You should also let us know what version of VC and Windows you are using.
-
An alternative method, without using "drag and drop":
[edit: Sorry for the low quality of the video. I didn't pay attention to the settings when "publishing" it.]
-
Thank all of your help. I can fix it using right mouse click to select copy then paste on Editor.
Hi James, I try to use your action: "test TCP send RFID" to generate the hexcode stream: \xFB\x10\x00\x00\x12\x4B\x02\x01\x01 where \x4B should be TagID. onRFID event is triggered but I modified your action which only execute one action: Results.SetLastResult to test whether what I send is what I receive then I can add code to do some operation to extract the sixth character (TagID) only matching comparsion (Not finish for this part yet). Unforunately I found what I send is sometime not what I receive after copy {1} to {LastResult}. You can see my attached screen. Any problem?
Besides, if we want to only extract the sixth character from this hexcode stream, how do I use what operator to get it? :bonk
-
Hi James, I have also tried to use Luup code to send hexcode stream to VOX.
local socket = require("socket")
host = "192.168.1.12"
c = assert(socket.connect(host, 1000))
c:send(string.char(251,16,00,00,18,75,02,01,01))
c:close()
The result is same as before, you can see attach screen.
-
it is perfectly normal. \x2B is the ascii code for "+"
so \x12\x2B becomes \x12+
and \x12\x4B becomes \x12K
It will always convert this way, and there is nothing random about it, so you can still use it with confidence as an ID etc.
Only codes that cannot be converted to a character will be represented in the Hex format.
Why don't we wait until your hardware arrives to see what actual codes are generated by your device. Then I can help you to isolate the ID using a regular expression.
-
http://www.ascii-code.com/
-
If all the other codes are always the same you can isolate the tag using regex with this pattern:
\xFB\x10\x00\x00\x12(.*?)\x02\x01\x01
so it will capture whatever appears between the \xFB\x10\x00\x00\x12 and the \x02\x02\x01\x01
in your examples it will return + or K. You can consider these as valid IDs
Here is the modified command that will generate a new event with your ID as the payload:
<?xml version="1.0" encoding="utf-16"?>
<command id="270" name="onRFID event" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This command is triggered when the RFID event if fired. It attempts to find the ID and then generates a new event which includes the ID in the EVENT NAME, instead of having it in the payload.">
<action>
<cmdType>Results.SetLastResult</cmdType>
<cmdString>{1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<cmdString> \xFB\x10\x00\x00\x12(.*?)\x02\x01\x01</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{#M}&&1</ifParams>
<then>
<action>
<cmdType>VC.TriggerEvent</cmdType>
<cmdString>TAG.{Match.1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
<event>RFID</event>
</command>
-
I hope everyone recognizes the best support in the world :clap ::bow :hugs
-
Hi James, thank you so much for your quick reply. Yes, I want to test it before I got the hardware. Just for fun ;D But when I use regex with your operator pattern, I always get 0 on {#M} instead of + if i send 2B as TagID. No clue.... :bonk
-
It is only hypothetical until I can see the actual commands you are using.
Please copy and paste your group to the forum.
-
and by the way {#M} is the number of matches. If it is working you should get a value of 1 all the time and the actual ID will be in {Match.1}
-
OK. I made a mistake. Because \ is used in regex for special things, we must escape it by putting an extra \ in front. So the regex pattern should be
\\xFB\\x10\\x00\\x00\\x12(.*?)\\x02\\x01\\x01
or if you want the whole command:
<?xml version="1.0" encoding="utf-16"?>
<command id="304" name="onRFID event" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="This command is triggered when the RFID event if fired. It attempts to find the ID and then generates a new event which includes the ID in the EVENT NAME, instead of having it in the payload.">
<action>
<cmdType>Results.SetLastResult</cmdType>
<cmdString>{1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<cmdString> \\xFB\\x10\\x00\\x00\\x12(.*?)\\x02\\x01\\x01</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)==(B)</ifType>
<ifParams>{#M}&&1</ifParams>
<then>
<action>
<cmdType>VC.TriggerEvent</cmdType>
<cmdString>TAG.{Match.1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
<event>RFID</event>
</command>
Of course we don't really need to put the whole sequence in there. We could probably also use a pattern like this:
\\x12(.*?)\\x02
-
I hope everyone recognizes the best support in the world :clap ::bow :hugs
...and see how VoxCommando makes learning about hex codes, ascii, regex and other mysterious things FUN ::banana!!!
-
Excellent support, I love you guys so quick respone and really found VOX is so powerful. But my fool I can't fully make use of VOX to do what I want. :bonk My interest on this case: even the hardware is not here, I also want to take this chance to explore more power of VOX :biglaugh
Hi James, it works now.
But the RFID format data stream I mentioned previosuly, we really need to get the value of TageID and RadioGain from sixth and severth character in separate becasue we need to firstly check the severth character: RadoGain to see if it is dropped to zero level for associated TagID that means we can confirm if this associated Tag has already disappeared from the range.
For most of in-range scenrios, I should check if TagID is exactly same as the character we want first. But simply using (A contain B) operator can't show exactly what I want becasue it may have a rare case that TageID value is on RadioGain character. My solution should see if we can make use of Results object to separate TageID and RadioGain character into different varables so that I can do this check individually. I can't acheive what I want from Editor, see my screen shots below[attachment=1]!
Besides, I also need to put TagID into a global varable as a flag for the state of each TageID. Becasue my understanding is the RFID reader should continually send a lot of RFID Hexcode stream in some time interval to tell us whether TagID is in the range based on different RadioGain. The best logic we find TagID data then check TagID's RadioGain. If RadioGain>1, I need to check if this TagID flag in ON or OFF. If ON then we should ignore it. If OFF then turn it ON. For out-of-range scenrios, when its RadioGain is dropped to zero, I also need to set corresponding TagID flag OFF immedately.
I don't know if I should use Results object to manupulate these cases within VOX editor. Please advise. I want to complete this homework before my reader is shipped in order to enjoy this fun earlier ::)
Thank you very much. I've never seen the forum so active like you guys before. So VOX is exceeded my expectation. It's worth to make use of this for more home automation cases.
Best regards,
Fai
-
I'm not sure this will help you in your command, but use \\+(.*?) instead of +(.*?) in the logic block.
-
Thanks, Kalle. But I tried it before and {Match.1} is still empty. Any clue?
-
please confirm for me what you need as result in your example? perhaps x02
so you can use result replace.
-
Thanks, Kalle. But I tried it before and {Match.1} is still empty. Any clue?
Yes, use results.replace in your logic block instead of relusts.regex and also {LastResult} instead of {Match.1}
<?xml version="1.0" encoding="utf-16"?>
<commandGroup open="False" name="RFID test" enabled="True" prefix="" priority="0" requiredProcess="" description="">
<command id="604" name="RFID test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>Results.SetLastResult</cmdType>
<cmdString>{1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<cmdString>\\xFB\\x10\\x00\\x00\\x12(.*?)\\x01</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetLastResult</cmdType>
<cmdString>{Match.1}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<if ifBlockDisabled="False" ifNot="False">
<ifType>(A)Contains(B)</ifType>
<ifParams>{LastResult}&&+</ifParams>
<then>
<action>
<cmdType>Results.Replace</cmdType>
<cmdString>+\&& </cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>VC.TriggerEvent</cmdType>
<cmdString>{LastResult}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.ShowText</cmdType>
<cmdString>{LastResult}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
</then>
<else />
</if>
</command>
</commandGroup>
-
Thank you so much, Kalle :D
I can successfully extract x02 now. But, it has some issue in the logic for my RFID project.
Assume the hex code stream is \xFB\x10\x00\x00\x12+\x02\x01 where "+" is the sixth hex char and "\x02" the seventh hex char. I can only use RegEx to extract "+\x02" then put into {match.1} then use (A)Contains(B) to check if "+" is contained whatever it is from "+\x02" or "\x02+" which will make me wrong to detect exactly TagID and RadioGain information.
What I want from my case is to firstly extract the sixth hex char into the variable that's "+" then check if it is what I want (TagID). Then I can use either the same variable or another variable to extract the severth hex char that's "\x02 for another if-then condition. That can exactly avoid the problem of "+\x02" not equal to "\x02+" from above (A)Contains(B) example.
I can't see any leftchar, midchar or righchar function in Editor. Can you help me? I'm sorry to make you all trouble. :bonk :bonk :bonk :bonk :bonk
Thanks,
Fai
-
In order to solve this problem, I need to know the actual specification for the TCP messages that we can expect to receive. We need to look at all possible messages, not just a single example at one time.
What are the possible values for the ID byte?
What are the possible values for the gain byte?
What do all the other bytes mean, and can they change, or will they always remain the same?
If we know this we can solve the problem. Otherwise we are just fooling around for fun...
My main concern now is, how often do these "update" messages arrive? If you are using 5 tags and each one is sending a message every 5 seconds, VC will be constantly dealing with these messages which will most likely interfere with the normal operation of the program. In that case you should really find an alternative solution, such as a python script that is running on its own thread, which only interrupts the main program when something significant has happened, such as someone arriving, or someone leaving.
Another option would be to have a second VC running, only for this purpose. It could send updates to your regular VC.
-
Thanks, James. I have the same concern but I plan to use separate VC or find other TCP server to deal with this. What I know about the format is FB 10 00 00 TagID RFGain ReaderID 01
where FB 10 00 00 is hex header and 01 is tail. TagID is range from 00 to FF same as RFGain which is RF level from 00 to FF. ReadID is what I can preset it. The time interval to scan Tag which can be configured, assuming from 100ms to 1000ms. I like VOX becasue of its convenience and easy to script. I don't know if any other TCP server I should try. But if I can resolve (A)Contains(B) problem I mentioned above. It already resolve it in VOX for my situation. Then I only need to know how to put global variable in VOX. It look like to learn another programming language from scratch :bonk :bonk :bonk :bonk :bonk
-
OK. I will get back to you. Let me think about this a bit.
You can look at using setvar, or maps to store values.
-
Here is a starting point using python. It does not yet store the variables or decide when someone has arrived, or departed, but it is a good place to start I think.
Put the attached python file into your "VoxCommando\PY" folder
If you are not already using the python plugin you must:
- enable the plugin in Options and restart VC
- look in "VoxCommando\plugins\PY\Lib" and execute the file "Extract me here.exe" to extract the python library files.
If you are familiar with writing code in general you will not have too much trouble with python. It is similar to luup. There are many examples to be found online.
<?xml version="1.0" encoding="utf-16"?>
<commandGroup open="True" name="rfid python test" enabled="True" prefix="" priority="0" requiredProcess="" description="">
<command id="1142" name="test send" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>TCP.Single.Write</cmdType>
<cmdString>\xFB\x10\x00\x00\x18\x05\x01&&127.0.0.1&&1000</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
</command>
<command id="1146" name="python tcp server" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>PY.ExecFile</cmdType>
<cmdString>PY\rfidTcpThread.py</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<event>VC.Loaded</event>
</command>
</commandGroup>
-
Excellent, James. Nothing I can say: only one word, Awesome! I will start to learn it and explore if it is a right way to expand VOX. If I used Python to fork a thread to handle it, I think few transactions in sec should not be a big problem under VOX, is it correct? I love it so much :biglaugh :biglaugh :biglaugh :biglaugh :biglaugh
-
Yes, I think it will be OK but I would set the RFID scan period to the longest possible (which is 1 second, I guess).
You might not need to create any other threads, other than the one that I already created to listen on the TCP socket.
One thing I am not too clear about. How do you decide if someone is gone? Does the "reader" device generate TCP messages for all tags every second including the tags that are "away/missing", or only for tags that are within range?
Will you consider a tag as "away/missing" when the gain is exactly 0, or do you consider it "away/missing" when the gain is (for example) less than 15.
-
Thanks, James.
I have asked the manufacturer who said Active RFID Tag will actively send its presence signal to the reader every one second. Once the reader got it then it will send this tag information in form of hexcode stream FB 10 00.... over TCP port to our TCP server which represent this tag is presence. If no this tag signal is detected, the reader will not send this tag information which represents this tag away already. For the reader side, it is simple. But for our program, it will have a bit complicated. I need to check how long the idle time for every tag (mean how long I do not receive the tag information), once it run over this idle time, we can classify it is away. RFGain is not what my understanding before which is not a signal strength of tag to represent its distance from reader. I should not use this field to confirm if the tag is away....
-
OK. Here is your complete solution.
You just need this one command to load it and the python will do the rest, generating events when new IDs arrive or when they are absent for more than 30 seconds:
<?xml version="1.0" encoding="utf-16"?>
<command id="1146" name="python tcp server" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>PY.ExecFile</cmdType>
<cmdString>PY\rfidTcpThread.py</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<event>VC.Loaded</event>
</command>
You can test it by sending a bunch of random IDs in a loop. Ideally you would run this command from a different computer. You must trigger this command using the phrase "do R.F.I.D. test". If you just click execute from the tree editor it will not loop.
<?xml version="1.0" encoding="utf-16"?>
<command id="1142" name="do R.F.I.D. test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="True" loopDelay="5000" loopMax="200" description="">
<action>
<cmdType>TCP.Single.Write</cmdType>
<cmdString>\xFB\x10\x00\x00\x0{Rnd.2.9}\x05\x01&&127.0.0.1&&1000</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<event>test</event>
<phrase>do R.F.I.D. test</phrase>
</command>
-
James, Katte and all brothers in VOX Forum. It's great and appreciate all of your help. Excellent support :D :D :D :D :D :D :D :D :D :D
I just got 2.4GHz Active RFID Reader and some Active Tags. When I plug it then do some basic configuration. James's solution immediately works as we expect and perfectly show me Tag in and away as expect. Perfect!!!
I believe the logic must work for other RFID readers that can benefit us to start proximity detction project using VOX in the future. I will pass the information to other friends and use it good software for more advanced home automation.
This is the one I purchased from TaoBao (China ebay) http://item.taobao.com/item.htm?id=13280048779
Enjoy!!
I also used the following UHF Audio Transmitter from PC (speaker jack) to up to 6 speakers for TTS broadcasting at home. I used the following bluetooth speaker as 3.5mm AUX in becasue I like its appearance :-)
http://item.taobao.com/item.htm?id=16822952986
http://trade.taobao.com/trade/detail/tradeSnap.htm?spm=a1z09.2.9.84.hj3NN8&tradeID=441668175466002
Enjoy too and good to share more!!!
Ah, James, you may try to develop a cutomize code for bluetooth detection within Python to detect the presence of your mobile phone back or away from home. I already used a sample code in PC to detect my mobile bluetooth signal. It can trigger a series of batch commands and run different scenes (via http) in Vera for my proximity detection. Intersting :biglaugh :biglaugh :biglaugh :biglaugh :biglaugh :biglaugh
-
Very cool stuff!
@James
Did you see the pictures of the Wireless Audio device? It looks like exactly as my HALx :D
-
Yes, this is what is known as a "Chinese Box".
I have updated the python code a bit for the rfid and added a function to check "who is home".
The voice command "do rfid test" runs a loop that sends random IDs to simulate the tag reader.
Here is a demo:
The updated python code is attached. The old version might not have been safe because of different threads reading and modifying the dictionary simultaneously.
Here is the complete group including the "who is home" command.
<?xml version="1.0" encoding="utf-16"?>
<commandGroup open="True" name="rfid python test" enabled="True" prefix="" priority="0" requiredProcess="" description="">
<command id="1142" name="do R.F.I.D. test" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="True" loopDelay="150" loopMax="100" description="">
<action>
<cmdType>TCP.Single.Write</cmdType>
<cmdString>\xFB\x10\x00\x00\x{Rnd.0.1}{Rnd.0.9}\x05\x01&&127.0.0.1&&1000</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<event>test</event>
<phrase>do R.F.I.D. test</phrase>
</command>
<command id="1146" name="python tcp server" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>PY.ExecFile</cmdType>
<cmdString>PY\rfidTcpThread.py</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<event>VC.Loaded</event>
</command>
<command id="245" name="who is home" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>PY.ExecString</cmdType>
<cmdString>result = whoIsHome()</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.ShowText</cmdType>
<cmdString>{LastResult}</cmdString>
<cmdRepeat>1</cmdRepeat>
</action>
<phrase>who is home</phrase>
</command>
</commandGroup>
-
Wow, great work ::bow
Maybe this is also possible with a smartphone when it is connect to the WLAN router. My smartphone/tablet connect automatically to the WLAN. When I'm at home the MAC or IP address for the device is available and we can use this information in VC (I think, but I'm not sure) ::hmm
-
Wonderfullllllllllllllllllllllllllllllllllllll :biglaugh :biglaugh :biglaugh Excellenttttttttttttttttttttttt :biglaugh :biglaugh :biglaugh :biglaugh
I test it already as well. Work perfect. I initally plan to do who is home function but you already helped. Nothing I can say, thank you soooooooooooooooo much ;D
Yes the next proximity is for mobile phone detection by either ping your mobile IP address at home or its bluetooth address. Look forward to seeing more fun using VOX on home automation. I love you guys ;)
-
Hi Katte, what's HALx? May I know more detail? Wireless via 2.4G or Bluetooth or UHF, VHF?? My one can pass through two rooms becasue of UHF, how about your? May I have the site to check? Thanks. ;)
-
You can search the forum for HALX.
But you can't buy this anymore. Maybe one day xterminator will start selling them again...
-
Wonderfullllllllllllllllllllllllllllllllllllll :biglaugh :biglaugh :biglaugh Excellenttttttttttttttttttttttt :biglaugh :biglaugh :biglaugh :biglaugh
I test it already as well. Work perfect. I initally plan to do who is home function but you already helped. Nothing I can say, thank you soooooooooooooooo much ;D
Yes the next proximity is for mobile phone detection by either ping your mobile IP address at home or its bluetooth address. Look forward to seeing more fun using VOX on home automation. I love you guys ;)
Thanks manfaiho,
It is great to hear that it is working well.
Can you please tell us what command line program you used to detect bluetooth presence?
-
Hi James, I download the source code of BtProx from http://btprox.sourceforge.net/
".....It locks on one of your Bluetooth devices which are paired to the the machine. When you walk away from the computer the device is disconnected and the computer is locked after timeout. It is possible to run a single application together with the lock. This application may be your favorite script dismounting network drives, erasing those dirty files from the desktop or anything else. The program sits in Windows tray showing its current status with tray icon and tooltip baloons...."
I think you can modify it as your bluetooth detector then trigger waht you want. Once you integrate it into VOX, please kindly let us know. Many thanks, James ;)
-
Hi James, I found some issue for this program in these days. When the Python code run for a while and I turn on all tags, no events are triggered. Once I use FullRestart to restart VOX, all tags near to Reader can be detected, its information can be sent back to the Python code and events can be triggered again. I can reprod it at least one time per day. Not sure why.
As I restart VOX can help, I try to find a way to run VC.RestartFull in regular basis using SetTimer. I found VC.RestartFull is not same with I click the menu item for Full Restart becasue I didn't see Python code is started in the log again. What's the difference between VC.RestartFull and click Full Restart? Besides, is it something wrong in Python engine when I heavily send TCP command (1 request/sec) to its TCP server within Python? Thanks.
Best regards,
Fai
-
RestartQuick detects which groups need to be updated and rebuilds them. It then reloads all the command macros.
RestartFull purges the cache and rebuilds all groups from scratch and then reloads all groups and all command macros.
Usually you would use an action to perform a GenXML and then to a RestartQuick to update any groups that are affected by the changes to the xml files.
Neither one actually restarts the program itself.
What is the final python code that you are using?
If an error occurs on a thread the thread will quietly die without generating any error so it can be difficult to troubleshoot. It is unfortunate that you cannot set a longer delay between RFID pings.
-
I think it may be the problem. When I found it can't properly detect the tags in and out, I click Full Restart VOX that can resolve the problem. All in-range tags can be detected normally. Anything I should do? Should we include exception handling on this code such as the logic like close all threads then create all new threads to listen and time watch it again that is same for Full Restart. Or generate more informaiton for debugging?
-
What is the final python code that you are using?
?
I think it may be the problem.
You think what may be the problem?
-
I am still using the code you post on the last (thread safe one to protect data). I think the code may really got the error somewhere that as you mention so that it quietly die. Nothing it can continue to do that's my case. No tag can be detected until I restart VOX.
-
Hmmm. I am no expert in python, but I tested that code using many pings per second. I only let it run for a short time though. I would need to set up a more rigorous test to try to recreate the problem.
One thing that you can try is to set the delay of the "cleanup" loop to a longer period to reduce the chance of a collision.
-
It is probably getting some other message that has no 6th byte to read and failing on that.
Here is the same code but with some "try / except" added to it.
-
Hi James, thank you very much ;) You are so helpful.
I will test it and get back you the result.
However, I found one more issue. As it is a 2.4G RFID, I occasionally found unexpected signal comes from somewhere that accidently triggers the arrvial event then immedidately departure after its timeout. I am thinking if the code can be enhanced to add one more counter which can count how many times the Tag is continuous in the range, say continuous 2 or 3 times to confirm if it is valid or not. If the continuous 2 or 3 times for this tag in the range, it can normally trigger the arrival event in order to avoid fault alarm.
Best regards,
Fai
-
Hi James,
I got the problem. I found suddently the arrvied tages are departure then trigger tcp.error then all of those tages are arrival again. Screen attached.
-
It looks like the tag reader is actually sending some message to tell you that the tags have departed. So I think there is something in the protocol that we have not been told. Time to pull out the manual, or whatever documentation was provided, to see what message is sent when someone leaves.
Either that or you can try logging the messages yourself and trying to understand what messages are being sent under various circumstances.
If there is any documentation for this product in English please send me a link.
-
Try with this py file. It first checks to make sure the first byte of a new tcp message is /xFB
It will create a file "pyLog.txt" in the main VC folder and log every message received to it.
If you can recreate the problem with the IDs reappearing after departure, then we can look at the log file to see what message is making that happen.
-
Thanks, James. I install and run a while. I found all tags would suddently be departed simultaneously but this one is no tcp error. The log I see the last stream is just only FB then nothing else. All program stopped there. No tags are detected anyway. I need to restart it back to normal. It is different with before. Las time, once all were departed then I got TCP error then the program can be resumed and all tags can be detected automatically. Any clue?
I am thinking if something wrong in reader then it suddently sent only one byte: FB then nothing else but it can continue a normal stream. When the code trys to get the rest of bytes after FB then got buffer error. Should we check the stream length or exactly data pattern to ensure a complete stream? Every time I got this problem, it can resume normal when VOX app is fully restarted (not VC.FullRestart which will not work so it should crash internally). No idea?
-
Hi James, I checked the logs and found TCP data stream may contain many tag information being detected from reader. That may be the reason why I have occasionally observed some tag suddently departure then immediately arrival. We may need to get the data using the concept of serial communication in TCP, byte by byte check to ensure every tag information within the predefined length of byte can be retrieved. Not sure if it is also the cause we crash the buffer in tcp sometime. Any idea, James? I attached the sample from manufacturer for your reference. They only detect the frquency of tag arrival instead of the logic of arrival and depature. It looks like the reader should have no concept of departure, just stop to report its infomation of tag which is not in-range right after.
-
Try increasing the buffer size to 128
-
Hello Fai,
Have you tried James's suggestion to increase the buffer size?
I'm curious whether or not that solved your problem.
-
I'm so sorry for my late reply because I was recently super busy >:(
Hi James and nime5ter,
I've tried different buffer sizes and added the logic to check if (1) less than 8 chars on the buffer, (2) its header and footer bytes even (3) the length of buffer to ensure looping every 8-byte frame within buffer to check TagID, in order to avoid any duty bytes or any length size of buffer but no improvement. I found the "blocking" on socket.recv function very often when this sample is just startup or runing a while so I strongly suspect the part of TCP server code from this sample may not be able to handle the pattern of this continuous requests from the reader.
However, I found an temp solution but it is not perfect. I setup one more VOX on another machine B as a "bridge" and configure TCP Server there to receive these requests from the reader then immediately use TCP.SingleWrite to copy this stream back to this PY sample running on machine A. It seems running very well. I found using TCP Server from VOX's TCP Plug-in on this "bridge" machine should be much more robust than that's running on this PY sample.
I am not familiar with TCP programming but I found more information from web to point me to use socket option to set non-blocking mode for recv function and should use a very special logic to handle unknown buffer size sending from client. BUt I don't know how to change the code. What I know is TCP Plug-in as bridge to this sample can resolve my case. Any idea and suggestion?
Best regards,
Fai
-
Please try this one.
-
Hi James,
Thanks, I used 256 as the buffer size and added 8 bytes buffer test before but no improvement. I also downloaded your script and re-test it. No improvement! Any clue?
Do you know what the difference of how to code TCP server between TCP Plug-in and your sample?
Best regards,
Fai
-
No. Sorry.
Without being able to experiment with the actual device I don't know what else to try.
-
Thank all of your assitance. Yes, it is hard to trouble if lack of reader for trial and error. I will continue to test then update you all. I think it is socket issue so I will go deep for this area....
-
I used the attached code with 8 bytes TCP buffer where include a separate thread to trigger the initial arrival events within the initialization period, a loop to check every 8 bytes frame on single recv function if buffer size more than 8 bytes (of course, now is useless due to only 8 byte buffer size). Running it using bridge machine to redirect the tag information from the reader on this sample in separate machine, so far so good :-) I will continue to think how to direct recevie tag information from the reader using this sample. Update you all later....
-
The python code you just uploaded has indentation that is a mix of spaces and tabs. I am surprised that python accepts this code at all, but it is possible that this code does not do what it looks like it should be doing!
You should remove all tabs and only use spaces in python for indentation. If you use notepad++ to edit your python code (which I recommend) there is an option telling it to use only spaces.
If your code is working you should remove all logging and printing statements so that you are not causing your machine to be constantly writing to a text file (5 times per second) or overloading the text box in the python plugin window (from the print statements).
-
I don't know why but it works on VOX. I am not familar with Python so I only know to use notepad for code modification. All logics are running as expect except TCP flow control which I never changed it. You can use your sample client to do the test and I am sure you shoulf get what you want. I have no clue for this sample so I decide to use "bridge" machine running TCP Plugin on VOX to handle all tag information from reader then copy back to another machine running on this sample for RFID alert. So far so good.
-
I am glad that you have a working solution. It is too bad that we could not find a more elegant and efficient solution.
Just because your code works, does not mean that it is doing what you think it is doing.
My advice to anyone who is using any kind of Python, regardless of what editor you choose, is this:
DON'T EVER USE A SINGLE TAB. ONLY SPACES.
Because the logic of Python is based on indentation, you can't mix tabs and spaces without having a lot of problems.
I also recommend using the fantastic, small, and completely free program called notepad++ (http://notepad-plus-plus.org/)
It is superior to notepad in ALL conceivable situations, but especially when editing python, any kind of code, xml etc.
-
Hi all,
Sorry for my super busy in the past weeks no time update this thread! I took a whole day to dig into the coding (try and error) and finally identified the root cause then fix the issue. Yes, the data stream is sometime not consistent. It will even have NO data when all tags left out of home. If we assume no data then close the socket connection, the program will stop there and all tags will be departed after the timeout. Reader seems to use previous connected socket to keep the connection to send tag information. This is exactly my problem. I have changed the code especially for data stream handling below that can fix the problem eventually.
def handler(clientsock,addr):
BUFFER_SIZE = 256
while 1:
try:
data = clientsock.recv(BUFFER_SIZE)
if not data: continue
if len(data)<8:continue
for i in range(0,int(len(data)/8)):
if data[i*8]!="\xFB" or data[i*8+1]!="\x10" or data[i*8+2]!="\x00" or data[i*8+3]!="\x00" or data[i*8+7]!="\x1F": continue
tagID =ord(data[i*8+4])
updateId(tagID)
except clientsocket,e:
vc.triggerEvent("python.tcp.error",None)
continue
clientsock.close()
vc.triggerEvent("python.socket.thread.exit",None)
Of course, I have also added socketoption for timeout and created threading for each incoming socket connection for this infinite loop for recv(). Infinite looping for receving data stream is a key for Reader. If all tags not there, no data but we should wait there. Once any tags come back, the data should be continually received. It is different with so many traditional TCP server sample code whcih will close the socket then end when no data is received in buffer or specific key is treated as socket end. I attached the modified code for your reference. Enjoy!! Thanks all of your assitance and Happy VOXCOMMANDO :-)
Best regards,
Fai
-
Thanks for the update!