TheThingSystem / node-thing-client

A node.js module to interface with TheThingSystem steward, as a thing
MIT License
2 stars 4 forks source link

Invalid thingID/response pair #4

Closed GuySawyer closed 10 years ago

GuySawyer commented 10 years ago

Running test.js I get an Invalid thingID/response pair error message.

Test.js looks like this after running it once:

var ThingAPI = require('./thing-client')
  ;

new ThingAPI.ThingAPI(
{ steward : { crtPath   : 'server.crt' }
/*, pairing : { thingUUID : 'dummy' + Math.round((Math.random() * (10000000 - 10) + 10) * 1000)
            }*/
, state   : { params    : { algorithm : "sha1"
                          , length    : 40
                          , name      : "dummy3@arden-arcade"
                          , issuer    : "arden-arcade"
                          , step      : 30
                          , base32    : "IRNFQOKIK4YUKRKFIJIXENBUHBCVA43OIVZTKYSNKFITA5C2KBUDCUDSJFCDMRRT"
                          , protocol  : "totp"
                          }
            , thingID   : "12"
            }
}).on('ready', function(state) {
  console.log('ready state='+ JSON.stringify(state));

}).on('close', function() {
  console.log('close');
  process.exit(0);
}).on('error', function(err) {
  console.log('error: ' + err.message);
  process.exit(0);
});

What does the pairing line mean, with dummy and math.random?

The D3 client, under manage looks like this (after commenting out "pairing" and running test.js another 3 times:

manage      7m    wss 192.168.2.100  60755  path=/api/v1/actor/list/, requestID=0, depth=all
    6m    wss 192.168.2.102  38094  path=/api/v1/thing/hello/12, response=480655, requestID=1
    6m    wss 192.168.2.102  38095  path=/api/v1/thing/hello/12, response=162770, requestID=1
    3m    wss 192.168.2.102  38096  path=/api/v1/thing/hello/12, response=416594, requestID=1
    22s       wss 192.168.2.100  60778  path=/api/v1/actor/list/, requestID=2, depth=all

To my knowledge, the request ID should never be the same as whats been used. But I don't see where in the test.js file a request ID is set.

The good news is that there is communication between my "thing" beaglebone and the Steward (which I've been trying to achieve for weeks now). However, I am not very clued up on how the communication between a thing and the steward should work.

Where is this thingID error coming from?

mrose17 commented 10 years ago

sorry for the late reply. i seemed to have missed this.

first, to your question:

the random is just creating a thingID that will get used once. when i was developing the library, i was creating a lot of things, and didn't want to keep editing the test file. you may notice that in the current repo, it's just 'testing0'. (but i forgot to "npm publish" that version, sigh…)

so, i've updated npm and the repo.

let's do this:

  1. revert test.'s back to its pristine state.
  2. stop the steward and

    % cd steward/steward
    % sqlite3 db/users.db
    sqlite3> select userID from users where userName='.things';

this will give you back a number, e.g., '3', then do

    sqlite3> delete from clients where clientUserID=3;
    sqlite3> .quit

and now restart the steward, what this does is get rid of any thing bindings you might already have.

then run

    % node test.js

and you'll see something like:

    ready state={"thingID":"11","params":{"algorithm":"sha1","length":40,"name":".things@arden-arcade","issuer":"arden-arcade","step":30,"base32":"MJITEY2BOEZGEY2YNVJEG4KIN5RHOZ2HPFIHGZJSGV4DMRBXIZCWWRKIGNEVORRW","protocol":"totp"}}

make the edits as you did before and run node.js again. i believe you should be working at that point. please let me know, thanks!

GuySawyer commented 10 years ago

After following your instructions exactly, I still get the same error. However, after running test.js again, I get a duplicate uuid error.

I tried running test.js again with pair uuid = test and uuid = test1. Both gave me "invalid thingID/response pair". Thereafter I checked the users in "db/users.db" again, and it gave me the same as before. Only one thingID is returned, and furthermore I can't delete it.

debian@steward:~/steward/steward$ sudo sh /etc/init.d/steward stop
Stop steward services...killing 6040
debian@steward:~/steward/steward$ sudo sqlite3 db/users.db
SQLite version 3.7.13 2012-06-11 02:05:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select userID from users where userName='.things';
2
sqlite> delete from clients where clientUserID=2;
sqlite> select userID from users where userName='.things';
2
sqlite> .quit
debian@steward:~/steward/steward$ sudo sh /etc/init.d/steward start
Start steward services... pid is 6056
debian@steward:~/steward/steward$ 

Running test.js did work a couple days ago though, I got the "ready state" response you mentioned, but now it has stopped working.

Here's the output of "node test.js" with pair uuid = testing0:

debian@debian-armhf:~/node_modules/thing-client$ node test.js
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
error: no visible stewards
debian@debian-armhf:~/node_modules/thing-client$ node test.js
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
error: invalid thingID/response pair
debian@debian-armhf:~/node_modules/thing-client$ node test.js
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
error: duplicate uuid
debian@debian-armhf:~/node_modules/thing-client$ 

This is test.js:

var ThingAPI = require('./thing-client')
  ;

/*
   get a copy of server.crt from your steward, it's the file

       steward/steward/sandbox/server.crt

   also known as

       http://steward.local/server.crt
 */

new ThingAPI.ThingAPI(
{ steward : { crtPath   : 'server.crt' }
, pairing : { thingUUID : 'testing0'
            }
, state   : null
}).on('ready', function(state) {
  console.log('ready state='+ JSON.stringify(state));

// when you get the value of state, then put it above and comment out 'pairing'
}).on('message', function(message) {
  console.log(require('util').inspect(message, { depth: null }));
}).on('close', function() {
  console.log('close');
  process.exit(0);
}).on('error', function(err) {
  console.log('error: ' + err.message);
  process.exit(0);
});

Where exactly is the thingID assigned (The Steward?), and also what does the information in that "ready state" response mean exactly?

The time that it worked, "state : null" in test.js was replaced by that ready state information. On that note, I'm not even sure how test.js gets altered during this process?

mrose17 commented 10 years ago

i can't figure what's going on here, so let's take a step back.

when you run test.'s with a pairing option, it's going to try to create a new pairing relationship with the steward. on success, it will print out the state information necessary to make use of that relationship. so you copy-paste that into test.'s and run it again. and this point, it should work.

here's what i see from your output:

  1. we ignore the avahi output from node (someday, someone will fix this… it's just an annoyance, nothing more).
  2. the first run, the steward didn't reply quickly enough. that happens sometimes, so you re-ran it.
  3. the second run, you got

    error: invalid thingID/response pair

which indicates to me that it successfully paired, and then tried to login and failed. that's really odd.

  1. the third run, you got duplicate uuid, which means that it tried to pair again, but was already paired.

this looks like some kind of timing thing, which is odd, because the steward updates its in-memory structures before it does an async update to the database. i'm going to check that.

i am pushing 0.3.0 which adds a 'paired' event that publishes the state, that way, if there is some kind of bizarre timing thing going on, you'll have the information to put in test.'s - i don't know why you're seeing the error and i am not, but i'm bringing this to ground… (-;

with respect to your questions: the thingID is a unique number assigned by the steward, as is all the state information. basically, it's a cryptographic secret and bunch of parameters to generate a time-based one-time password.

anyway, version 0.3.0 is released now and the repo updated. you can try that out until i figure out if there's a timing issue.

basically: the state will appear earlier in the process. copy-and-paste into test.'s and you should be good to go.

sorry it's taken so long to figure out what's going sideways…

thanks!

mrose17 commented 10 years ago

hi. i think i found the race condition. sorry about that. i've pushed an update to the steward repo. if this doesn't work for you, please let me know. as usual:

    % cd steward
    % git pull
    % cd steward
    % rm -rf node_modules
    % npm -l install

and restart the steward… thanks!

GuySawyer commented 10 years ago

Ok I Git Pulled the steward as you said, and I npm installed the thing-client again.

debian@debian-armhf:~/node_modules/thing-client$ node test.js
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
paired state={"thingID":"3","params":{"algorithm":"sha1","length":40,"name":"testing0@steward","issuer":"steward","step":30,"base32":"KM3DKNTUJFHFURCENQZGOUKMPBRHSQSIGVUXA6SLK5TFAVSWKJUG6UCOI5KTAVBU","protocol":"totp"}}
error: invalid thingID/response pair

No I receive the sate information, but I still get the invalid error...

I went on as if the error wasn't there. Copied the state info into test.js, and commented out pairing.

debian@debian-armhf:~/node_modules/thing-client$ node test.js
*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
error: invalid thingID/response pair

and still got the same error.

Also, that state output says that thingID = 3. However, I ran sqlite3 again and checked user.db as you described earlier. It returned 2 when I queried this:

debian@steward:~/steward/steward$ sudo sh /etc/init.d/steward stop
[sudo] password for debian: 
Stop steward services...killing 11468
debian@steward:~/steward/steward$ sqlite3 db/users.db
SQLite version 3.7.13 2012-06-11 02:05:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select userID from users where userName='.things';
2
sqlite> 

I'm sure there is something wrong with that?

GuySawyer commented 10 years ago

Update:

I found that for some reason, my ntp server information had reverted to the default, and timezone info was out by 2 hours. I have corrected it now, but might that have anything to do with these issues?

GuySawyer commented 10 years ago

Update:

Yes, It seems the time was causing all the problems. It runs through test.js smoothly now, paring the first time and receiving the state info. Then it sits in the on.ready state. I cntrl C out, paste the state info into test.js and comment out pairing then run test.js again. It runs perfectly through to the on.ready state.

Thanks once again for all your help Mr. Rose. I wander if I could ask your advice (this is unrelated to the issue). I am quite in the dark about how "things", the code, and the Steward all come together. I want to turn an I/O pin on my beaglebone into a "thing" with on.off control via the steward. Problem is, I am really not sure where or how to start. If you could give me a point in the right direction with regard to what components are needed overall, and where I should start I would really appreciate it, so much.

Thanks again! Guy

mrose17 commented 10 years ago

great catch on the time sync issue! i've updated the diagnostic to mention "check your clock".

i've got to drive to a meeting, but i plan to send you an answer later today. it should be straight-forward to do what you want!

claudiuo commented 10 years ago

I am very interested in this as well, by now I think I've read all the Steward wiki documentation but some simple steps would be so much more helpful. Thanks in advance for this and all you do!

mrose17 commented 10 years ago

well, i missed the window last night. sorry, i was traveling and got in too late...

mrose17 commented 10 years ago

new goal: i plan to get back to you this weekend! sorry for the delay.

GuySawyer commented 10 years ago

No problem

Thanks again for your help!

mrose17 commented 10 years ago

i am nearly done turning test.js into a complete example. hopefully, tonight or tomorrow i'll be able to put it in github. you'll then be able to look at that and hopefully things will be clear...

GuySawyer commented 10 years ago

Ok great!

Will that example then actually show up in the d3 main page as a thing?

mrose17 commented 10 years ago

Yes!

/mtr via iPhone

On Apr 3, 2014, at 2:41, Guy notifications@github.com wrote:

Ok great!

Will that example then actually show up in the d3 main page as a thing?

— Reply to this email directly or view it on GitHub.

GuySawyer commented 10 years ago

Good day Mr. Rose

How is it going with the test.js edit?

I have a deadline on monday, and I'm really hoping to integrate this. I don't mean to push, I really appreciate everything you are doing.

Regards Guy

mrose17 commented 10 years ago

thanks for the ping. my goal is to have this tomorrow, early evening us/pacific… in the future, if there's a deadline, let me know… it helps in scheduling... thanks!

mrose17 commented 10 years ago

i have updated the package to 0.4.0 - which includes a nearly complete test.js implementation - in doing so, i found a bug in the steward, so if you run this, please be sure to have the latest steward code. my hope is to finish testing on monday evening. good luck!

GuySawyer commented 10 years ago

Great, this looks awesome! Keep me posted as to any edits you make, I will let you know if I find any bugs.

"I tried to do an installation btw, and it's installing 0.3 test.js. I don't know why that is, but I'm sure it's simple. For now, I will copy test.js across. That is all that's changed correct?"

edit:
Nevermind, that was a silly assumption. I checked the change logs after it wasn't running so smoothly haha.
I will copy the changes properly, until you can tell me whats up with the npm install.

Ok I'm getting an error with the API. After running test.js once successfully, copying the State information and commenting out pairing, I run it again and get this error:

>>> send: {"path":"/api/v1/thing/hello/3","response":"378435","requestID":1}
>>> recv: {"error":{"permanent":false,"diagnostic":"unknown api: /api/v1/thing/hello/3"},"requestID":"1"}
error: unknown api: /api/v1/thing/hello/3

Also, just to clear up some small confusion: Where in test.js is the send taking place:

>>> send: {"path":"/api/v1/thing/hello/3","response":"378435","requestID":1}

Edit 2: Ok I figured out the unknown API issue by going through: https://github.com/TheThingSystem/steward/issues/180

I understand that it has to do with permissions. So what I have done is change the Security Services from Strict, to Developer. But, for future reference, how would the Beaglebone (or any "thing") Authenticate correctly with the Steward in Strict mode?

mrose17 commented 10 years ago

sorry about that. if you do

    npm -l install thing-client

you should now get 0.4.0

i plan to respond to the other issue late tonight...

GuySawyer commented 10 years ago

Awesome. This code is great by the way. Thanks so much. It is connected to the steward, and reporting random noise levels properly.

I'm wandering though, have you included some kind of control of the "macguffin" (even though it would be artificial) from the steward side that I can't see, or do I need to add any control code in? In short, what part of the code is supposed to give the steward control of something ie: a light switch.

Also, would it be possible for you to add a few comments to the code? I'm struggling to understand the sections of the code, and what each bit does. I'm quite new to javascript, so it doesn't pop out like c++ would.

mrose17 commented 10 years ago

i plan to make a commenting pass tomorrow (thursday) evening.

the code in test.js will respond to perform requests. i will write a second test file to invoke it.

GuySawyer commented 10 years ago

Hi Mr. Rose

How is the second test file coming on? I'm quite curious to see why a second file is required to invoke the perform request and where that file will be run from.

mrose17 commented 10 years ago

hi. sorry for the delay in replying, this is now the second thing on my list.

to answer your question: the first test file emulates a thing; but, when you want the thing to "perform", that's coming from a user interface or the steward or … - but not the thing itself. if we were talking lightbulbs, a "perform" would be something like "turn light on" … clearly, the bulb isn't generating that, but a UI or a scheduled action or something… back soon!

GuySawyer commented 10 years ago

Ok makes sense. But it sounds like a perform could be generated in a number of locations. To my understanding, wouldn't the steward just be the one to generate that perform?

How's it all going by the way?

mrose17 commented 10 years ago

quite true: any client might have a reason for telling the macguffin to speak.

in terms of how things are going… i'm shooting for this tonight, i just have three other things to deal with first. (-;

mrose17 commented 10 years ago

if you get the latest version of the node-taas-client package, you'll see there is a file there called test3.js

as usual, before you can run it, you'll need to get credentials. once you edit it and add credentials, then you can do this:

  1. start the steward
  2. start test.js in node-thing-client
  3. run test3.js in node-taas-client
GuySawyer commented 10 years ago

Ok great, I will have a look at it tomorrow.

Before looking at the code, I understand that the node-taas-client will invoke the perform commands and not the steward. Or does it tie in with the steward and the perform commands are invoked from within the steward? If not, how would the perform commands be invoked from within the steward using the node-taas-client or would that require editing of the steward code?

Thanks again for you input. Regards Guy

mrose17 commented 10 years ago

the command has to be initiated from a client. it is sent to the steward, which in turn either perform it internally or sends it to the thing to perform.

the steward can perform things internally as a result of an activity, e.g., when a particular sensor's CO2 value reaches a threshold then turn the fan on. certainly the macguffin could be made to perform things in the context of an activity.

GuySawyer commented 10 years ago

Ok that makes a lot of sense, and your comment about activities leads to the final phaze of my "project", if you will: Creating rules. But before I ask you any questions about how to create and use activities, I have a lot of reading to do on the TTS website.

mrose17 commented 10 years ago

thanks. i now have the context, sorry to be so thick. here is the backstory:

in the #thethingsystem way of looking at the world, there are three kinds of clients:

in order to create activities, you use the API. to see an example (although not a very good one) you can look at the test2.js in node-taas-client.

another contributor is thinking about writing a graphical interface to create activities.

/mtr