IBM Watson Sensor Support

I am uploading data from a range of sensors to the IBM Watson cloud and trying to build an app using this application. How do make the sensor inputs into variables and see if they exceed a certain threshold value and add to a counter. I was thinking something like this but I may be on the wrong path

var sprint = global.get( "count")||0;
var accel = msg.payload.d.Z
if (accel > 1500) {
sprint++;
global.set('count', sprint);
}
return {payload : sprint };

forgive my mistakes I have minimal experience with Java script
Also does anyone know anyway to incorporate python or export data to a python application

Does your function work? You can test it by using inject nodes to feed it data. If not then what happens.

For the second question you can use an exec node to run a python script, passing it data and getting the results back.

1 Like

Thank you colon for your reply <3,
When I test the function it gives an error that it isn’t able to read the input data however if I simply print the data without using a function beforehand to process it, the correct values print

Take a look at https://nodered.org/docs/user-guide/messages which will show you how to use a debug node to check the path to any piece of data


This is what shows up

It looks like two other function nodes have issues. They are fairly self explanatory...

  1. You are not returning an object in node "... for kicks". E.g you should be retuning msg or {payload: x} but you are returning x
  2. In node analyzing sprints, you are trying to access a property .Z of something that is undefined. Without seeing the code, it is impossible to say what. At a guess, in the previous node, where you return {payload : sprint }; you should instead do this...
msg.payload.sprint = sprint;
return msg;

By retuning msg you keep everything that was inside of it. My guess is .Z was in the original msg.payload but you lose that when you return a NEW message (this line creates a NEW message: return {payload : sprint }; that ONLY contains a .payload set to sprint)

1 Like

Thanks for the reply. I have attached screenshots of the functions. I am currently working on editing them according to your advice


Heres my third function (as a new user I can only upload two per post) Thanks for all the help I really appreciate it. Let me give you some background on what I am trying to do. This is a school project and I am using a variety of sensors connected to a chip that is cloud connected to import it's data into IBM Watson. For example I am looking at Accelerometer Z axis movement to detect a sprint. If the accel Z value exceeds a threshold value, I would like to count it as a sprint. As you can see I am also trying to implement a basic finite state machine with the accelerometer which is either in state 0 (resting) or in state 1 (sprinting). I am also using the gyroscope y axis to detect kicking of a ball during a soccer game. similar to the sprinting code it counts kicks after the value has exceeded a specific threshold value. However this is more simple since it does not need to implement a FSM. In addition to all that I would like to display the battery level which does not need to be processed unlike the other two features of my app. IF i can get some guidance how to do this I would greatly appreciate it :slight_smile:

The 'analyzing for kicks' function receives input from the ibm node, but not msg.payload.d.Y but sends it anyway.

So you first need verify if the input exists; ie.

if("Y" in msg.payload){
  return {payload:msg.payload.d.Y}
}

Same applies to the Z axis.

Or you could use a switch-node to direct each axis to its own output.

Same as @Steve-Mcl said in different words.

Like i said already...

so...

  1. Change "analyze for kicks" code to ...

    msg.payload = msg.payload.d.Y;
    return msg;  //<<< return the msg OBJECT not the value!
    
  2. Change last line in node analyzing sprints
    from ...

    return {payload : sprint };
    

    to...

    msg.payload.sprint = sprint;
    return msg;
    




NOTES:

  • Use debug nodes with "show full object" set - ON THE OUTPUT OF EVERY NODE to see what happens to the message as it travels down the wires
  • Try not to delete the original payload by returning a new {object}. Instead, just add to the original msg. e.g. msg.newPropery = "hello new property inside the msg object". This way you still have access to anything added to msg as it travels through your flow.
  • In future, please post code (between three backticks ``` code here ``` ) instead of screen shots of function code
1 Like

Thanks for the help Steve. I integrate the changes you suggested but I getting the "TypeError: Cannot read property 'Z' of undefined" or it says undefined for my other nodes." What do you recommend that I do. Thanks for all the help I highly appreciate it

Def sprint code:

var sprint = global.get( "count")||0;
sprint++;
global.set('count', sprint);
return {payload : sprint };

Analyzing Sprints Code

var accel = msg.payload.d.Z 
if (accel > 1500) {
   sprint++;
   global.set('count', sprint);
}
msg.payload.sprint = sprint;
return msg;

Please read my comment above.
You have to check if you actually get an object/key that you are expecting.

1 Like

Thanks I tried it and it says "TypeError: Cannot use 'in' operator to search for 'Z' in 303"

Do you know what this means then?

Also do you know how I can get a print statement before a value for the battery level so it's like "Battery Percentage: [battery level]"

Always worthwhile - note however he is still sending a value rather than an object

In Def sprint code (which is wired to Analyzing Sprints Code) he returns...
return {payload : sprint }
There is no way he can access msg.payload.d.Z in the next node.

@rayy please read what we have posted - in particular...

AND



Firstly- for your understanding - look at this...

image

So on that 2nd point - dont delete the msg -- change Def sprint code as follows...

var sprint = global.get( "count")||0;
sprint++;
global.set('count', sprint);
msg.payload.sprint = sprint; //<<just add a property to msg instead of returning a new one!
return msg;//return the original msg that was passed in - it will still have stuff from previous node!

now when the msg gets sent to the next node (Analyzing Sprints Code) it will still have all of the original stuff in it FROM THE PREVIOUS NODE - including the msg.payload.d.Z part you are trying to access! (you can verify this my putting debug nodes (set for "show full msg") connected to the output of every node)

Also, change Analyzing Sprints Code to (explanation in the comments)...

var accel = msg.payload.d.Z ////get the accel value sent by the node BEFORE 'Def sprint'
var sprint = msg.payload.sprint;//get the sprint value you added to payload in 'Def sprint'
if (accel > 1500) {
   sprint++;
   global.set('count', sprint);
}
msg.payload.sprint = sprint;//update payload.sprint for the next node!
return msg;//return msg with all the original stuff + the updated sprint value

IMPORTANT NOTE...

I have no idea what your logic is supposed to do - I am just correcting the obvious errors and misunderstandings. Even if you get this bit to work, I suspect it will not function as you expect. Hopefully, what I have written here will help you grasp whats going on.
And dont forget - add DEBUG nodes to EVERY OUTPUT & look at what they contain.

1 Like

Thanks very much it actually works without any errors.

Do you know anyway I can take the output from the nodes and import them back to the IBM cloud to make some kind of user interface?

Also to clarify
sprint++;
simply does +1 correct?

Yes

Why not use the dashboard?

You can add dashboard by the pallete manager.

I think you should experiment first then when you get stuck, create a new thread with suitable topic.