RemoteXY Graphical Dashboard Android App for Node Red

2,331 views
Skip to first unread message

Dean Cording

unread,
Jun 19, 2016, 4:19:16 AM6/19/16
to Node-RED
RemoteXY is an Android app that provides a graphical dashboard with controls and indicators.  The original app was designed to control Arduino projects.  Through a bit of reverse engineering, I have developed a Node Red node that mimics the Arduino and allows the RemoteXY dashboard to control and display outputs of Node Red flows.

Check it out at https://www.npmjs.com/package/node-red-contrib-remote-xy



Dean

Marko S

unread,
Jun 19, 2016, 6:00:30 AM6/19/16
to Node-RED
So how does the app in the android phone then interface to Node-red, via Wifi or is a bluetooth connection with the phone to the computer required ?

Very interesting!



Dne nedelja, 19. junij 2016 10.19.16 UTC+2 je oseba Dean Cording napisala:

Marko S

unread,
Jun 19, 2016, 6:49:39 AM6/19/16
to Node-RED
Also, do you know what are the differences between the free and the paid app?

Dne nedelja, 19. junij 2016 12.00.30 UTC+2 je oseba Marko S napisala:

Dean Cording

unread,
Jun 19, 2016, 8:18:41 AM6/19/16
to Node-RED
The app interfaces to directly Node Red via Wifi or mobile internet.  As far as it is concerned it is connecting to an Arduino with a Wifi or Ethernet shield.  I've used it to display data from my Node Red system remotely over a VPN using mobile internet.

The difference between the free and paid app is that the free app is limited to 30 second sessions before it times out.  The paid app is a bit expensive but is ad free and helps cover the cost of using the online editor.

Marko S

unread,
Jun 19, 2016, 8:23:42 AM6/19/16
to Node-RED
I see yeah, I got it to work really quickly, nice work on the node. :). How come you don't just use the node-red dashboard for displaying the data. The joystick widget is nice i don't have that one anywhere in contrib-ui hehe :).

Dne nedelja, 19. junij 2016 14.18.41 UTC+2 je oseba Dean Cording napisala:

Dean Cording

unread,
Jun 19, 2016, 11:58:53 PM6/19/16
to Node-RED
Must admit I was looking for a dashboard from the Android perspective and I hadn't considered using the contrib-ui dashboard.  There are a couple of nice MQTT based Android dashboards but they tend to use propriety topic hierarchies that would involve an ugly degree of topic remapping.

Marko S

unread,
Jun 20, 2016, 12:11:00 PM6/20/16
to Node-RED
I tried with those new "Pages" feature in the RemoteXY, does that work? Since I get now lots of errors and I don't know anymore what I'm doing wrong since before it worked (and I do have the config selected - the ino copied etc):

Errors:

TypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56button_6msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_1_xmsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_1_ymsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_2_xmsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_2_ymsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:566ebd973c.89bf68msg : errorRangeError: index out of range
20. 6. 2016 18:03:57slider_4msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_6msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_7msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_8msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_1msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_5msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_3msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_2msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_3msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_4msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_2msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_1msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_5msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_6msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57select_1msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_1msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_2msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_7msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_3msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_8msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_4msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_5msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_9msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57button_6msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57joystick_1_xmsg : string [24]Dashboard config missing
20. 6. 2016 18:03:57joystick_1_ymsg : string [24]Dashboard config missing
20. 6. 2016 18:03:57joystick_2_xmsg : string [24]Dashboard config missing
20. 6. 2016 18:03:57joystick_2_ymsg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_4msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19slider_6msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19slider_7msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19slider_8msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19switch_1msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19slider_5msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19slider_3msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19switch_2msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19switch_3msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19switch_4msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19slider_2msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19slider_1msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19switch_5msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19switch_6msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19select_1msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_1msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_2msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_7msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_3msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_8msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_4msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_5msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_9msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19button_6msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19joystick_1_xmsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19joystick_1_ymsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19joystick_2_xmsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:19joystick_2_ymsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:09:196ebd973c.89bf68msg : errorRangeError: index out of range
20. 6. 2016 18:09:19slider_4msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_6msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_7msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_8msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19switch_1msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_5msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_3msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19switch_2msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19switch_3msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19switch_4msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_2msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19slider_1msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19switch_5msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19switch_6msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19select_1msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_1msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_2msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_7msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_3msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_8msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_4msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_5msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_9msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19button_6msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19joystick_1_xmsg : string [24]Dashboard config missing
20. 6. 2016 18:09:19joystick_1_ymsg : string [24]Dashboard config missing
20. 6. 2016 18:09:19joystick_2_xmsg : string [24]Dashboard config missing
20. 6. 2016 18:09:19joystick_2_ymsg : string [24]Dashboard config missing
20. 6. 2016 18:09:19level_1msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19level_2msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19level_3msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19level_4msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19level_5msg : string [24]Dashboard config missing
20. 6. 2016 18:09:19level_6msg : string [24]Dashboard config missing

Dne ponedeljek, 20. junij 2016 05.58.53 UTC+2 je oseba Dean Cording napisala:

Marko S

unread,
Jun 20, 2016, 12:20:44 PM6/20/16
to Node-RED
I can confirm that it was because of the "Pages" thing - see here this feature -> http://remotexy.com/en/help/decorations/page/
Hopefully you can support it in the node.

Dne ponedeljek, 20. junij 2016 18.11.00 UTC+2 je oseba Marko S napisala:
I tried with those new "Pages" feature in the RemoteXY, does that work? Since I get now lots of errors and I don't know anymore what I'm doing wrong since before it worked (and I do have the config selected - the ino copied etc):

Errors:

TypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56button_6msg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_1_xmsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_1_ymsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_2_xmsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:56joystick_2_ymsg : errorTypeError: Cannot read property 'unsubscribe' of null
20. 6. 2016 18:03:566ebd973c.89bf68msg : errorRangeError: index out of range
20. 6. 2016 18:03:57slider_4msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_6msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_7msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_8msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_1msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_5msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_3msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_2msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_3msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_4msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_2msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57slider_1msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_5msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57switch_6msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57select_1msg : string [24]Dashboard config missing
20. 6. 2016 18:03:57<span class="debug-message-name" style="padding: 1px 5px; font-size: 9px; color: rgb(170, 170, 204); background-image: initial; background-attachment: initial; background-size: initial; background-origin: initial; background-clip: initial; background-position: initia

Dean Cording

unread,
Jun 20, 2016, 5:43:17 PM6/20/16
to Node-RED
The pages feature is purely a client based feature - the Node Red app still sends all of the data and the client just filters which widgets are displayed.

It looks like a problem with the parsing of the config.  Could you send me a copy of the project.ino you are using.

Thanks

Dean

Marko S

unread,
Jun 21, 2016, 3:05:46 AM6/21/16
to Node-RED
But how could it be then explained, that if I don't use this "Pages" it works just fine, but in that flow with the pages, it totally errors out?

Here is the config that errors out:


////////////////////////////////////////////// 
//        RemoteXY include library          // 
//     use  library  version 2.2.2 or up    // 
//   use ANDROID app version 3.5.1 or up    // 
////////////////////////////////////////////// 

/* RemoteXY select connection mode and include library */ 
#define REMOTEXY_MODE__HC05_SOFTSERIAL
#include <SoftwareSerial.h> 

#include <RemoteXY.h> 

/* RemoteXY connection settings */ 
#define REMOTEXY_SERIAL_RX 2 
#define REMOTEXY_SERIAL_TX 3 
#define REMOTEXY_SERIAL_SPEED 9600 


/* RemoteXY configurate  */ 
unsigned char RemoteXY_CONF[] = 
  { 28,6,123,1,5,5,4,4,0,3
  ,11,5,16,2,3,4,0,9,11,5
  ,16,2,3,4,0,3,31,5,16,2
  ,3,4,0,9,31,5,16,2,3,4
  ,0,83,10,5,16,2,3,4,0,89
  ,10,5,16,2,3,4,0,83,34,5
  ,16,2,3,4,0,89,34,5,16,2
  ,3,2,0,4,12,10,5,2,1,79
  ,78,0,79,70,70,0,2,0,4,19
  ,10,5,2,1,79,78,0,79,70,70
  ,0,2,0,4,26,10,5,2,1,79
  ,78,0,79,70,70,0,2,0,4,33
  ,10,5,2,1,79,78,0,79,70,70
  ,0,2,0,4,40,10,5,2,1,79
  ,78,0,79,70,70,0,2,0,4,47
  ,10,5,2,1,79,78,0,79,70,70
  ,0,3,3,89,11,4,10,2,1,1
  ,0,81,11,6,6,2,1,65,0,1
  ,0,81,19,6,6,2,1,66,0,1
  ,0,91,24,6,6,2,1,88,0,1
  ,0,81,27,6,6,2,1,67,0,1
  ,0,91,32,6,6,2,1,72,0,1
  ,0,81,35,6,6,2,1,68,0,1
  ,0,81,42,6,6,2,1,69,0,1
  ,0,91,40,6,6,2,1,71,0,1
  ,0,87,48,6,6,2,1,70,0,5
  ,0,1,9,23,23,2,4,5,0,76
  ,30,22,22,2,4,66,130,3,10,13
  ,10,2,2,66,130,3,22,13,10,2
  ,2,66,130,3,35,13,10,2,2,66
  ,130,83,12,13,10,2,2,66,130,83
  ,25,13,10,2,2,66,130,83,39,13
  ,10,2,2,131,1,2,3,15,5,2
  ,1,80,97,103,101,95,49,0,131,0
  ,2,55,15,5,2,2,80,97,103,101
  ,95,50,0,131,0,80,3,15,5,2
  ,3,80,97,103,101,95,51,0,131,0
  ,81,55,15,5,2,4,80,97,103,101
  ,95,52,0 }; 
   
/* this structure defines all the variables of your control interface */ 
struct { 

    /* input variable */
  signed char slider_1; /* =0..100 slider position */
  signed char slider_2; /* =0..100 slider position */
  signed char slider_3; /* =0..100 slider position */
  signed char slider_4; /* =0..100 slider position */
  signed char slider_5; /* =0..100 slider position */
  signed char slider_6; /* =0..100 slider position */
  signed char slider_7; /* =0..100 slider position */
  signed char slider_8; /* =0..100 slider position */
  unsigned char switch_1; /* =1 if switch ON and =0 if OFF */
  unsigned char switch_2; /* =1 if switch ON and =0 if OFF */
  unsigned char switch_3; /* =1 if switch ON and =0 if OFF */
  unsigned char switch_4; /* =1 if switch ON and =0 if OFF */
  unsigned char switch_5; /* =1 if switch ON and =0 if OFF */
  unsigned char switch_6; /* =1 if switch ON and =0 if OFF */
  unsigned char select_1; /* =0 if select position A, =1 if position B, =2 if position C, ... */
  unsigned char button_1; /* =1 if button pressed, else =0 */
  unsigned char button_2; /* =1 if button pressed, else =0 */
  unsigned char button_7; /* =1 if button pressed, else =0 */
  unsigned char button_3; /* =1 if button pressed, else =0 */
  unsigned char button_8; /* =1 if button pressed, else =0 */
  unsigned char button_4; /* =1 if button pressed, else =0 */
  unsigned char button_5; /* =1 if button pressed, else =0 */
  unsigned char button_9; /* =1 if button pressed, else =0 */
  unsigned char button_6; /* =1 if button pressed, else =0 */
  signed char joystick_1_x; /* =-100..100 x-coordinate joystick position */
  signed char joystick_1_y; /* =-100..100 y-coordinate joystick position */
  signed char joystick_2_x; /* =-100..100 x-coordinate joystick position */
  signed char joystick_2_y; /* =-100..100 y-coordinate joystick position */

    /* output variable */
  signed char level_1; /* =0..100 level position */
  signed char level_2; /* =0..100 level position */
  signed char level_3; /* =0..100 level position */
  signed char level_4; /* =0..100 level position */
  signed char level_5; /* =0..100 level position */
  signed char level_6; /* =0..100 level position */

    /* other variable */
  unsigned char connect_flag;  /* =1 if wire connected, else =0 */

} RemoteXY; 

///////////////////////////////////////////// 
//           END RemoteXY include          // 
///////////////////////////////////////////// 

#define PIN_SWITCH_1 13
#define PIN_SWITCH_2 13
#define PIN_SWITCH_3 13
#define PIN_SWITCH_4 13
#define PIN_SWITCH_5 13
#define PIN_SWITCH_6 13


void setup()  
  RemoteXY_Init ();  
   
  pinMode (PIN_SWITCH_1, OUTPUT);
  pinMode (PIN_SWITCH_2, OUTPUT);
  pinMode (PIN_SWITCH_3, OUTPUT);
  pinMode (PIN_SWITCH_4, OUTPUT);
  pinMode (PIN_SWITCH_5, OUTPUT);
  pinMode (PIN_SWITCH_6, OUTPUT);
   

  // TODO you setup code 
   

void loop()  
{  
  RemoteXY_Handler (); 
   
  digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_2, (RemoteXY.switch_2==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_3, (RemoteXY.switch_3==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_4, (RemoteXY.switch_4==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_5, (RemoteXY.switch_5==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_6, (RemoteXY.switch_6==0)?LOW:HIGH);
   

  // TODO you loop code 
  // use the RemoteXY structure for data transfer 




Dne ponedeljek, 20. junij 2016 23.43.17 UTC+2 je oseba Dean Cording napisala:

Dean Cording

unread,
Jun 21, 2016, 8:48:28 AM6/21/16
to Node-RED
Ok, it turns out that adding the pages pushed the config size over 256 entries which triggered a bug. So it wasn't pages causing it, just the size of the config.

Anyhow, it is fixed now and an update pushed to npm.  Thanks for reporting it.

Dean

Marko S

unread,
Jun 21, 2016, 11:39:46 AM6/21/16
to Node-RED
No problem, glad to report. Thanks for the fix! I will try it out.

Dne torek, 21. junij 2016 14.48.28 UTC+2 je oseba Dean Cording napisala:
Reply all
Reply to author
Forward
0 new messages