Tuesday, November 9, 2010

XML Config File

Its starting to be pain to setup on the constants in both Arduino and processing and in the future php so it's time to create a configuration file that all of these different languages can use (sort of)

And here it is:
<?xml version="1.0"?>
<configuration>

<devices>
  <device id="0x01" code="DVC_TMP37">Temperature Sensor TMP37</device>
  <device id="0x02" code="DVC_LIGHT">Light Sensor LDR</device>
  <device id="0x03" code="DVC_SHT21">Temperature and Humidy Sensor SHT21</device>
  <device id="0x04" code="DVC_DOORCONTACT">Door Contact Sensor</device>
  <device id="0x05" code="DVC_WINDOWCONTACT">Window Contact Sensor</device>
  <device id="0x06" code="DVC_MOTION">Motion Sensor</device>
  <device id="0x07" code="DVC_2LINEDISPLAY">2 Line Character Display</device>
  <device id="0x08" code="DVC_POWER30">30A Current Sensor</device>
  <device id="0x09" code="DVC_POWER100">100A Current Sensor</device>
  <device id="0x10" code="DVC_SMARTOUTLET">Smart Outlet</device>
  <device id="0x11" code="DVC_RGBLIGHT">RGN LED Light</device>
  <device id="0x12" code="DVC_sound">Sound Sensor</device>
  <device id="0x13" code="DVC_SWITCH">Simple Switch</device>
  <device id="0x14" code="DVC_STATUSLED">Simple Status LEDS</device>
  <device id="0x15" code="DVC_BUZZER">Alert Buzzer</device>
</devices>

<commands>

  <!-- System Commands Port 0 -->
  <command id="0x00" code="CMD_ERROR"  payload="message" return="CMD_ACK"></command>

  <command id="0x01" code="CMD_VERSION" payload="" return="CMD_FLOAT">
    Get current version of firmware on the node
  </command>
  <command id="0x03" code="CMD_BATTERYLEVEL" payload="" return="">
    Get current battery level
  </command>
  <command id="0x3E" code="CMD_PING" payload="varies" return="CMD_PONG">
    Send Test Pack, node should reply back pong
  </command>
  <command id="0xE3" code="CMD_PONG" payload="varies" return="CMD_ACK">
    Response to a Ping Command
  </command>
  <command id="0x11" code="CMD_ACK" payload="packetid" return="CMD_BYTE">
    Acknowledge Packet, letting the sender of a packet know that data arriced safely
  </command>
  <command id="0x21" code="CMD_GETNODEID" payload="" return="CMD_BYTE">
    Get Node's current ID (node id 0 is for broadcast)
  </command>
  <command id="0x22" code="CMD_SETNODEID" payload="passcode" return="CMD_ACK">
    Changes NODE ID, used for initial setup
  </command>
  <command id="0x23" code="CMD_GETPLUG" payload="byte port" return="CMD_BYTE">
    Get the device code for what is attached on the node
  </command>
  <command id="0x24" code="CMD_SETPLUG" payload="passcode" return="CMD_ACK">
    Changes Device ID, used for initial setup
  </command>

  <!-- Plug commands Ports 1-15 -->
  <command id="0xC1" code="CMD_AUTOSENDSTART" payload="node to, int" return="CMD_ACK">
    Set up the node to automatically send sensor data to a particular node 
  </command>
  <command id="0xC2" code="CMD_AUTOSENDSTOP" payload="node to" return="CMD_ACK">
    Stop auto sending sensor data
  </command>
  <command id="0xD0" code="CMD_GETVALUE" payload="" return="Value">
    Get a value from a plug
  </command>
  <command id="0xD1" code="CMD_SETVALUE" payload="" return="Value">
    Send a value to a plug
  </command>

  <command id="0xE0" code="CMD_ON" payload="" return="CMD_ACK">
    Simple Turn on
  </command>
  <command id="0xE1" code="CMD_OFF" payload="" return="CMD_ACK">
    Simple Turn Off
  </command>
  <command id="0xE2" code="CMD_LEVEL" payload="byte" return="CMD_ACK">
    Set a light to a level 0-255
  </command>

  <!-- Value commands -->
  <command id="0xF0" code="CMD_BYTE"   payload="byte" return="CMD_ACK"></command>
  <command id="0xF1" code="CMD_STRING" payload="string" return="CMD_ACK"></command>
  <command id="0xF2" code="CMD_INT"    payload="int" return="CMD_ACK"></command>
  <command id="0xF3" code="CMD_FLOAT"  payload="float" return="CMD_ACK"></command>
  <command id="0xF4" code="CMD_LONG"   payload="long" return="CMD_ACK"></command>
</commands>

<!-- One day more stuff will be setup too  -->
<pachube>
  <apikey></apikey>
  <feeds>
    <feed name="Bedroom">
      <datastream id="0" node="" plug="" device="" />
    </feed>
  </feeds>
</pachube>

<webserver>
  <address></address>
</webserver>

</configuration>

Processing has built in tools for reading XML and this quick sketch reads the XML file a translates it in to list of #defines for the Arduino. this way as the lists of devices and commands evolve, it's very easy to translate it from one language to another.
XMLElement xml;

PFont myFont;
PrintWriter file;

int i;
String spaces(int count){
 String spaces = "";
  for(int a = 0;a<count;a++){
   
   spaces += " ";
  } 
  return spaces;
}

void setup() {
  size(200, 200);
  
  myFont = createFont("Consolas", 14);
  textFont(myFont);
  
  xml = new XMLElement(this, "config.txt"); //in txt
  file = createWriter("define.txt");
  
  XMLElement commands[] = xml.getChildren("commands/command");
  
  for(i = 0; i<commands.length;i++){
    file.println("#define "+ commands[i].getAttribute("code")+spaces(20 - commands[i].getAttribute("code").length())+commands[i].getAttribute("id"));
  }
  file.println(""); //blank line
  XMLElement devices[] = xml.getChildren("devices/device");
  
  for(i = 0; i<devices.length;i++){
    file.println("#define "+ devices[i].getAttribute("code")+spaces(20 - devices[i].getAttribute("code").length())+devices[i].getAttribute("id"));
  }
  file.flush(); // Write the remaining data
  file.close();
  exit();
}
And here is the Arduino Code the script above generated for me
#define CMD_ERROR           0x00
#define CMD_VERSION         0x01
#define CMD_BATTERYLEVEL    0x03
#define CMD_PING            0x3E
#define CMD_PONG            0xE3
#define CMD_ACK             0x11
#define CMD_SETNODEID       0x21
#define CMD_GETNODEID       0x21
#define CMD_SETNODEID       0x22
#define CMD_GETPLUG         0x23
#define CMD_SETPLUG         0x24
#define CMD_AUTOSENDSTART   0xC1
#define CMD_AUTOSENDSTOP    0xC2
#define CMD_GETVALUE        0xD0
#define CMD_SETVALUE        0xD1
#define CMD_ON              0xE0
#define CMD_OFF             0xE1
#define CMD_LEVEL           0xE2
#define CMD_BYTE            0xF0
#define CMD_STRING          0xF1
#define CMD_INT             0xF2
#define CMD_FLOAT           0xF3
#define CMD_LONG            0xF4

#define DVC_TMP37           0x01
#define DVC_LIGHT           0x02
#define DVC_SHT21           0x03
#define DVC_DOORCONTACT     0x04
#define DVC_WINDOWCONTACT   0x05
#define DVC_MOTION          0x06
#define DVC_2LINEDISPLAY    0x07
#define DVC_POWER30         0x08
#define DVC_POWER100        0x09
#define DVC_SMARTOUTLET     0x10
#define DVC_RGBLIGHT        0x11
#define DVC_sound           0x12
#define DVC_SWITCH          0x13
#define DVC_STATUSLED       0x14
#define DVC_BUZZER          0x15

No comments:

Post a Comment