Announcement

Collapse
No announcement yet.

Noob API startup help

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Noob API startup help

    Hi, I have been playing around with the basic plugin functions. And it is great.

    But I want to read a value from a water meter like this one: http://forum.arduino.cc/index.php?topic=8548.0
    and
    K type temperature sensor:
    https://github.com/adafruit/Adafruit...ermocouple.ino

    #2
    The API route is a good move if:

    1. You have devices that are not supported by the standard plugin sketch
    2. You are willing to learn how to interact and control devices with code.

    If those are true, then your best route is to select a device to start with and then find example sketches to work with that device. They are all over. Now the challenge is integrating that example code into the API sketch. Actually very easy. Several examples in this forum. But.... you gotta understand how to deal with devices/sensors at the code level first.

    Comment


      #3
      Originally posted by logbuilder View Post
      If those are true, then your best route is to select a device to start with and then find example sketches to work with that device. They are all over. Now the challenge is integrating that example code into the API sketch. Actually very easy. Several examples in this forum. But.... you gotta understand how to deal with devices/sensors at the code level first.
      I have not found any sketch send several onewire probes that send to homeseer.

      I don't know how I can address two or more different sensors "SendToHS(1,celsius)"
      See the code.
      Thanks for all your help so far.

      Code:
      /************************************************************
       *Arduino to Homeseer 3 Plugin API written by Enigma Theatre.*
       * V1.0.0.118                                                 *
       *                                                           *
       *******Change the values below only*************************
       */
      
      //************Do not change anything in Here*****************
       
      #define ISIP 0
      #if ISIP == 1
      #include <EEPROM.h>
      #include <SPI.h>       
      #endif
      
      
      const byte BoardAdd = 1;
      
      #include <Ethernet.h>
      #include <EthernetUdp.h> 
      
      #if ISIP == 1
      byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01};
      IPAddress ip(192,168,0,110);     //IP entered In HS config.
      const unsigned int localPort = 8900;      //port entered In HS config.
      IPAddress HomeseerIP(192,168,0,109); //Homeseer IP address
      IPAddress ServerIP(EEPROM.read(2),EEPROM.read(3),EEPROM.read(4),EEPROM.read(5));
      IPAddress gateway(192,168,0,1);
      IPAddress subnet(255,255,255,0);
      byte EEpromVersion = EEPROM.read(250);
      #endif
      
      int FromHS[10];                                          // *
      boolean IsConnected = false;                             // *
      #if ISIP == 1                                            // *
      char packetBuffer[UDP_TX_PACKET_MAX_SIZE];               // *
      EthernetUDP Udp;                                         // *
      const unsigned int ServerPort = 8888;                    // *
      #endif                                                   // *
      void(* resetFunc) (void) = 0;                            // *
      //***********************************************************
      #include <OneWire.h>
      
      // OneWire DS18S20, DS18B20, DS1822 Temperature Example
      //
      // http://www.pjrc.com/teensy/td_libs_OneWire.html
      //
      // The DallasTemperature library can do all this work for you!
      // http://milesburton.com/Dallas_Temperature_Control_Library
      
      OneWire  ds(2);  // on pin 2 (a 4.7K resistor is necessary)
      int ledPin = 5;
      unsigned long previousMillis = 0;        // will store last time LED was updated
      
      // constants won't change:
      const long interval = 1000;           // interval pause (milliseconds)
      
      
      
      void setup() {
        HSSetup();
        //************************
        //Add YOUR SETUP HERE;
        //************************
      
        Serial.begin(9600);
        pinMode(ledPin, OUTPUT);
      
      
      }
      
      
      
      
      void loop() {
      #if ISIP == 1
        IsUDP();
      #endif
      
          //************************
          //Add YOUR CODE HERE;
          //************************
           unsigned long currentMillis = millis();
      
        if (currentMillis - previousMillis >= interval) {
          // save the last time you blinked the LED
          previousMillis = currentMillis;
      
        byte i;
        byte present = 0;
        byte type_s;
        byte data[12];
        byte addr[8];
        float celsius;
        digitalWrite(ledPin, HIGH);
        
        if ( !ds.search(addr)) {
          Serial.println("No more addresses.");
          Serial.println();
          ds.reset_search();
          //delay(250);
          return;
        }
      digitalWrite(ledPin, LOW);
        Serial.print("ROM =");
        for( i = 0; i < 8; i++) {
          Serial.write(' ');
          Serial.print(addr[i], HEX);
        }
      
        if (OneWire::crc8(addr, 7) != addr[7]) {
            Serial.println("CRC is not valid!");
            return;
        }
        Serial.println();
      
        // the first ROM byte indicates which chip
        switch (addr[0]) {
          case 0x10:
            Serial.println("  Chip = DS18S20");  // or old DS1820
            type_s = 1;
            break;
          case 0x28:
            Serial.println("  Chip = DS18B20");
            type_s = 0;
            break;
          case 0x22:
            Serial.println("  Chip = DS1822");
            type_s = 0;
            break;
          default:
            Serial.println("Device is not a DS18x20 family device.");
            return;
        } 
      
        ds.reset();
        ds.select(addr);
        ds.write(0x44);        // start conversion, use ds.write(0x44,1) with parasite power on at the end
      
       // delay(1000);     // maybe 750ms is enough, maybe not
        // we might do a ds.depower() here, but the reset will take care of it.
      
        present = ds.reset();
        ds.select(addr);    
        ds.write(0xBE);         // Read Scratchpad
      
        Serial.print("  Data = ");
        Serial.print(present, HEX);
        Serial.print(" ");
        for ( i = 0; i < 9; i++) {           // we need 9 bytes
          data[i] = ds.read();
          Serial.print(data[i], HEX);
          Serial.print(" ");
        }
        Serial.print(" CRC=");
        Serial.print(OneWire::crc8(data, 8), HEX);
        Serial.println();
      
        // Convert the data to actual temperature
        // because the result is a 16 bit signed integer, it should
        // be stored to an "int16_t" type, which is always 16 bits
        // even when compiled on a 32 bit processor.
        int16_t raw = (data[1] << 8) | data[0];
        if (type_s) {
          raw = raw << 3; // 9 bit resolution default
          if (data[7] == 0x10) {
            // "count remain" gives full 12 bit resolution
            raw = (raw & 0xFFF0) + 12 - data[6];
          }
        } else {
          byte cfg = (data[4] & 0x60);
          // at lower res, the low bits are undefined, so let's zero them
          if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
          else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
          else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
          //// default is 12 bit resolution, 750 ms conversion time
        }
        celsius = (float)raw / 16.0;
        Serial.print("  Temperature = ");
        Serial.print(celsius);
        Serial.println(" Celsius, ");
        SendToHS(1,celsius);
        }
          /* To Send Data to Homeseer use SendToHS(Device,Value)
           Eg.. SendToHS(1,200); where 1 is the API device in homeseer and 200 is the value to send
           To Recieve data from Homeseer look up the FromHS array that is updated when the device value changes.
           Eg.. FromHS[5] would be the data from API Output device 5
           All code that is located just below this block will execute regardless of connection status!
           You can include SendToHS() calls, however when there isn't an active connection, it will just return and continue.
           If you only want code to execute when HomeSeer is connected, put it inside the if statement below.
           */
      
      /*Execute regardless of connection status*/
      
      
       if (IsConnected == true) {
         /*Execute ONLY when HomeSeer is connected*/
      
        }
      }
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      char* Version = "API1.0.0.118";
      
      byte Byte1,Byte2,Byte3;
      int Byte4,Byte5;
      
      
      void HSSetup() {
      
      #if ISIP == 1
          if (EEpromVersion!=22) {
          ServerIP=HomeseerIP;
          EEPROM.write(2,ServerIP[0]);
          EEPROM.write(3,ServerIP[1]);
          EEPROM.write(4,ServerIP[2]);
          EEPROM.write(5,ServerIP[3]);
          EEPROM.write(250,22); //Store the version where the eeprom data layout was last changed
          EEpromVersion=22;
        }
      Ethernet.begin(mac,ip);
        Udp.begin(localPort);
        Udp.setTimeout(0);
        delay(1000);
      SendConnect();
      #else
        Serial.begin(115200);
        Serial.flush();
        Serial.setTimeout(0);
        delay(1000);
        Serial.print("Connect ");
        Serial.println(BoardAdd);
      #endif
      
        IsConnected = false;
      
      }
      
      void SendConnect()
      {
      #if ISIP == 0
        Serial.print("Connect ");
        Serial.println(BoardAdd);
      #else
          Udp.beginPacket(ServerIP,ServerPort);  //First send a connect packet to the dynamic IP stored in eeprom
          Udp.print("Connect ");
          Udp.print(BoardAdd);
          Udp.endPacket();
          if (ServerIP!=HomeseerIP) {
            Udp.beginPacket(HomeseerIP,ServerPort);  //Then if the stored value doesn't match the pre-specified one, send a connect packet there also
            Udp.print("Connect ");
            Udp.print(BoardAdd);
            Udp.endPacket();
          }
       
      #endif
      }
      
      
      #if ISIP == 1
      void IsUDP(){
        int packetSize = Udp.parsePacket();
        if(packetSize)
        {
          IPAddress remote = Udp.remoteIP();
          Byte1 =Udp.parseInt();
          Udp.read(); 
          Byte2 =Udp.read(); 
          Byte3 =Udp.parseInt();
          Byte4 =Udp.parseInt();
          Byte5 =Udp.parseInt();
          DataEvent();
        }
      }
      
      #else
      void serialEvent() {
        while (Serial.available() > 0) {
          delay(17);
      
      
          Byte1 = Serial.parseInt();
          Serial.read();  
          Byte2 = Serial.read(); 
          Byte3 = Serial.parseInt();
          Byte4 = Serial.parseInt();
          Byte5 = Serial.parseInt();
          DataEvent();
        }
      }
      #endif
      
      
      /*
      
      Used Data Input Cases
      D Disconnect
      r reset
      K Keepalive
      O PinMode Output Set
      d Input debounce time set
      C Connect request
      c Connection established - report current status
      */
      void DataEvent() {
      
      
      
        if (Byte1 == BoardAdd) {
          switch (Byte2) {
      
          case 'c':
            IsConnected = true;
      #if ISIP == 1
            if (Udp.remoteIP() != ServerIP) {
              ServerIP=Udp.remoteIP();
              EEPROM.write(2,ServerIP[0]);
              EEPROM.write(3,ServerIP[1]);
              EEPROM.write(4,ServerIP[2]);
              EEPROM.write(5,ServerIP[3]);
            }     
      #endif
      
            break;
      
          case 'C':   
      #if ISIP == 1
            Udp.beginPacket(Udp.remoteIP(), ServerPort);
            Udp.print("Version ");
            Udp.print(BoardAdd);
            Udp.print(" ");
            Udp.print(Version);
            Udp.println(" HS3");
            Udp.endPacket();
      
            Udp.beginPacket(Udp.remoteIP(), ServerPort);
            delay(100);
            Udp.print("Connected ");
            Udp.println(BoardAdd);
            Udp.endPacket();
      #else
            Serial.print("Version ");
            Serial.print(BoardAdd);
            Serial.print(" ");
            Serial.print(Version);
            Serial.println(" HS3"); 
            delay(100);
            Serial.print("Connected ");
            Serial.println(BoardAdd);
      #endif
            delay(100);
            IsConnected = false;
            break;
      
          case 'K':
            delay(200);
      #if ISIP == 1
            Udp.beginPacket(Udp.remoteIP(), ServerPort);
            Udp.print("Alive ");
            Udp.println(BoardAdd);
            Udp.endPacket();
            if (Udp.remoteIP() != ServerIP) {
              ServerIP=Udp.remoteIP();
              EEPROM.write(2,ServerIP[0]);
              EEPROM.write(3,ServerIP[1]);
              EEPROM.write(4,ServerIP[2]);
              EEPROM.write(5,ServerIP[3]);
            }     
      #else     
            Serial.print("Alive ");
            Serial.println(BoardAdd);
      #endif
            break; 
            
            case 'r':
            delay(200);
            resetFunc();  //call reset
            break; 
      
          case 'O':
            FromHS[Byte3] = Byte4;
            break; 
      
          case 'D':
            IsConnected = false;
            break;   
          }
        }
      }
      
      void SendToHS(byte Device, long Data){
      if (IsConnected == true) {
      #if ISIP == 1
        Udp.beginPacket(Udp.remoteIP(), ServerPort);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
      #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
      #endif
      }
      }
      
      void SendToHS(byte Device, int Data){
      if (IsConnected == true) {
      #if ISIP == 1
        Udp.beginPacket(Udp.remoteIP(), ServerPort);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
      #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
      #endif
      }
      }
      
      void SendToHS(byte Device, float Data){
      if (IsConnected == true) {
      #if ISIP == 1
        Udp.beginPacket(Udp.remoteIP(), ServerPort);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
      #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
      #endif
      }
      }
      Last edited by Beerpal; November 26, 2017, 02:37 PM.

      Comment


        #4
        Must I use this (https://www.hacktronics.com/Tutorial...ss-finder.html) to address all probes and make individual API input to
        each?

        Comment


          #5
          I have solved this after using my weekend to try to find out how this works.
          I needed to update to beta version since the current version doesn't support comma as a decimal and therefore I got no value if I used float,

          Comment


            #6
            I'm glad you solved your problem.

            The point I was trying to make is that if you have a new sensor you want to add to an API sketch, the best way is to take a vanilla example sketch for that sensor, understand it, get it working, and then incorporate it onto the API sketch. You only have to deal with 'includes', globals, HSSetup, and HSloop. Call SendToHs and FromHS at the right times and you are good to go.

            Comment


              #7
              Hi can you share your code how you got multiple one wire addressed in api sketch.

              Comment


                #8
                Where can I get a copy of the API and the documentation that shows how to use it?

                Comment


                  #9
                  Originally posted by sweet View Post
                  Hi can you share your code how you got multiple one wire addressed in api sketch.
                  Yes, please share what you found

                  Comment

                  Working...
                  X