ArduinoConnect Server

From RasPiConnect/ArduinoConnect
Jump to: navigation, search

ArduinoConnect Home

Contents

ArduinoConnect Server Files

Description of files in the ArduinoConnectServer package:

  • ArduinoConnectServer.ino - the main sketch containing the server read/write code and the main loop
  • Config.h - configuration file for ArduinoConnectServer
  • ExecuteJSONCommand.h - The Control Execute functions
  • LocalExample.h - Example of a Local.h file for user functions
  • MD5.cpp - Calculates MD5 hashes
  • MD5.h - Calculates MD5 hashes
  • MemoryFree.h - Displays memory free on the Arduino
  • ReadMe - General Information about the server
  • WebServer.h - Webserver Code
  • smallJSON.h - a lightweight JSON parser


The Architecture of the ArduinoConnect Server

The ArduinoConnect Server is based on the Python web.py server library. The main server pages and top level functions are in the ArduinoConnectServer.py file in the top directory.

Testing

See the ArduinoConnect Server section under Getting Started

The Main Page

This page is where all the work gets done regarding sending Arduino data back to the ArduinoConnect App.

The following occurs in this page:

  • The incoming JSON from the ArduinoConnect App is parsed.
  • Each individual control request for refresh is parsed and evaluated.
  • The incoming JSON is authenticated.
  • The Control Object Type and the Control Code ID are retrieved from the incoming JSON request.
  • Then the user defined "Local" Execute file is called. The LocalExample.h file is in the main Directory (see below). This is the file where user ArduinoConnect Control Code IDs should be defined.
  • ArduinoConnect predefined objects are defined in the ExecuteJSONCommand.
  • The response is constructed, finalized and then sent back to the RasPiConnect / ArduinoConnect App as a well formed JSON command .

Latest Changes

ArduinoConnectServer 1.6 contains the following changes:

  • Initial Customer Release
  • Added support for Bar Meter
  • Minor release edits


Constructing Your Own ArduinoConnect Responses

Building your own responses is easy. You can select virtually any data to send back to the RasPiConnect / ArduinoConnect App and display it in a number of different ways.

Your own Control Code ID responses are built in the Local.h file An example Local file- LocalExample.h) is located in the local directory. If you build your own Local.h file, you will replace the LocalExample.h file include in ArduinoConnectServer.h file.

Change #define LOCALFILE "LocalExample.h" to #define LOCALFILE "Local.h" to #include "Local.h" in ArdunioConnectServer.h

Local.h will never be overwritten in a future release of ArduinoConnectServer, so it is best to put your changes in the Local.py file.

Using the ArduinoConnectServer Libraries, it is easy to construct a properly formed response to send to the RasPiConnect / ArduinoConnect App.

The LocalExample.h file gives an example of how to form a response to the RasPiConnect / ArduinoConnect App.


// Filename: LocalExample.h 
// Version 1.6 08/06/13 JS MiloCreek
 
// prototypes
 
void ExecuteLocalACTION_BUTTON_UITYPE(char returnJSON[], char *buffer, currentObjectStructure *parsedObject);
void ExecuteLocalTEXT_DISPLAY_UITYPE(char returnJSON[], char *buffer, currentObjectStructure *parsedObject);
 
void Local(char returnJSON[], char *buffer, currentObjectStructure *parsedObject)
{
#ifdef LOCALDEBUG
  printObject(parsedObject, "In LocalExample.h");
#endif
   switch (atol(parsedObject->ObjectType))
    {
 
        case FEEDBACK_ACTION_BUTTON_UITYPE:    
        case ACTION_BUTTON_UITYPE:
        {
           ExecuteLocalACTION_BUTTON_UITYPE(returnJSON, returnJSON, parsedObject);
        }
        break;
 
 
        case TEXT_DISPLAY_UITYPE:
        {
          ExecuteLocalTEXT_DISPLAY_UITYPE(returnJSON, returnJSON, parsedObject);
        }
        break;
    }
 
}
 
 
// Local Execute files
 
 
void ExecuteLocalACTION_BUTTON_UITYPE(char returnJSON[], char *buffer, currentObjectStructure *parsedObject)
{
#ifdef LOCALDEBUG  
     Serial.println("ExecuteACTION_BUTTON_UITYPE");
#endif
 
  // B-3 does a toggle on the LED on pin 13 (like B-1 does!!!)
  if (strcmp(parsedObject->ObjectServerID, "B-3") == 0)  
  {
    if (strcmp(parsedObject->Validate, "YES") == 0)
    {
      // send validated response
      returnJSONValidateResponse(returnJSON, returnJSON, parsedObject);
 
      strcpy(returnJSON, buffer);
      return;
    }
 
#define led 13
 
    pinMode(led, OUTPUT);
    digitalWrite(led, HIGH);
    delay(500);
    digitalWrite(led, LOW);
 
    returnJSONResponse(returnJSON, returnJSON, parsedObject, "OK" );
 
    strcpy(returnJSON, buffer);
    return;
  }
 
  // Note that Local objects DO NOT RETURN an Invalid Response.  That is done by the ExecuteJSONCommand function
  // returnJSONInValidResponse(returnJSON, returnJSON, parsedObject);
 
}
 
 
void ExecuteLocalTEXT_DISPLAY_UITYPE(char returnJSON[], char *buffer, currentObjectStructure *parsedObject)
{
#ifdef LOCALDEBUG
  Serial.println("ExecuteLocalTEXT_DISPLAY_UITYPE");
#endif
 
  // LT-5 returns a greeting message
  if (strcmp(parsedObject->ObjectServerID, "LT-5") == 0)  
  {
    if (strcmp(parsedObject->Validate, "YES") == 0)
    {
      // send validated response
      returnJSONValidateResponse(returnJSON, returnJSON, parsedObject);
 
      strcpy(returnJSON, buffer);
      return;
    }
 
    char responseData[40];
 
 
    sprintf(responseData,   "0, Hello from Local, Greetings",  messageCount);       
 
    returnJSONResponse(returnJSON, returnJSON, parsedObject, responseData );
 
    strcpy(returnJSON, buffer);
    return;
  }
  // Note that Local objects DO NOT RETURN an Invalid Response.  That is done by the ExecuteJSONCommand function
  // returnJSONInValidResponse(returnJSON, returnJSON, parsedObject);
}


The meaning of each part of the file is given below:

The Header

This section sets up the needed function prototypes

// Filename: LocalExample.h 
// Version 1.6 08/06/13 JS MiloCreek
 
// prototypes
 
void ExecuteLocalACTION_BUTTON_UITYPE(char returnJSON[], char *buffer, currentObjectStructure *parsedObject);
void ExecuteLocalTEXT_DISPLAY_UITYPE(char returnJSON[], char *buffer, currentObjectStructure *parsedObject);

Module Function Definition

The function Local is used in the RasPiConnectServer to call user defined objects.

  • returnJSON[] is the incoming (buffer copied and allocated as part of function call) string to be used.
  • char *buffer is a pointer to the returnJSON[] string so we can write back our results
  • parsedObject is the struct containing the current JSON object from the app
void Local(char returnJSON[], char *buffer, currentObjectStructure *parsedObject)

Look for the ObjectType (in parsedObject) and to determine what ExecuteLocal function to call

#ifdef LOCALDEBUG
  printObject(parsedObject, "In LocalExample.h");
#endif
   switch (atol(parsedObject->ObjectType))
    {
 
        case FEEDBACK_ACTION_BUTTON_UITYPE:    
        case ACTION_BUTTON_UITYPE:
        {
           ExecuteLocalACTION_BUTTON_UITYPE(returnJSON, returnJSON, parsedObject);
        }
        break;
 
 
        case TEXT_DISPLAY_UITYPE:
        {
          ExecuteLocalTEXT_DISPLAY_UITYPE(returnJSON, returnJSON, parsedObject);
        }
        break;
    }
 
}

Now call a user defined ExecuteLocal function

All ExecuteLocal functions have the same form:

         ExecuteLocalTEXT_DISPLAY_UITYPE(returnJSON, returnJSON, parsedObject);
  • returnJSON[] is the incoming (buffer copied and allocated as part of function call) string to be used.
  • char *buffer is a pointer to the returnJSON[] string so we can write back our results
  • parsedObject is the struct containing the current JSON object from the app

Check for Control Code ID

First check for the appropriate ArduinoConnect Control Code ID (set in the RasPiConnect / ArduinoConnect App).

#ifdef LOCALDEBUG  
     Serial.println("ExecuteACTION_BUTTON_UITYPE");
#endif
 
  // B-3 does a toggle on the LED on pin 13 (like B-1 does!!!)
  if (strcmp(parsedObject->ObjectServerID, "B-3") == 0)  
  {
  // B-3 does a toggle on the LED on pin 13 (like B-1 does!!!)
  if (strcmp(parsedObject->ObjectServerID, "B-3") == 0)  
  {

Check parsed JSON (located in parsedObject) and check to see if this request is a Validate request

    if (strcmp(parsedObject->Validate, "YES") == 0)
    {
      // send validated response
      returnJSONValidateResponse(returnJSON, returnJSON, parsedObject);
 
      strcpy(returnJSON, buffer);
      return;
    }

A Validate request is sent from the RasPiConnect / ArduinoConnect App to check to see if the Control Code ID is actually implemented in the ArduinoConnectServer. It does not perform the function intended but just returns a "Hey, I am here and ready to do work!". See the section below about how Validate works.

This statement checks to see if the request is a Validate request.

   if (strcmp(parsedObject->Validate, "YES") == 0)

The software then builds the outgoing JSON data and returns the JSON data in buffer


       // send validated response
      returnJSONValidateResponse(returnJSON, returnJSON, parsedObject);
 
      strcpy(returnJSON, buffer);
      return;

The Work Part of Response

User Defined Response Code

In this section of the code, we do something or report something on the Arduino. In this case, we are blinking a light.

Check ExecuteJSONCommand. for many more examples. All of the responses are formed in the same way.

  • Get the data or perform the action
  • Build the responseData ("OK" in this case, since it is an action button - but it varies according to the control type)
  • Build the JSON statement
  • return the JSON data
          #define led 13
 
    pinMode(led, OUTPUT);
    digitalWrite(led, HIGH);
    delay(500);
    digitalWrite(led, LOW);
 
    returnJSONResponse(returnJSON, returnJSON, parsedObject, "OK" );
 
    strcpy(returnJSON, buffer);
    return;
  }
 
  // Note that Local objects DO NOT RETURN an Invalid Response.  That is done by the ExecuteJSONCommand function
  // returnJSONInValidResponse(returnJSON, returnJSON, parsedObject);
 
}

That's it!

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox