Help calling a function via homeseer

Hi all,

I have a particle photon with a simple program installed that can control my ceiling fan. It used to work with IFTTT, but that is no longer an option for me. Now (years later) I am trying to figure out how to use a URL string to push a command (via homeseer) like "1f" to my particle device. I've been reading and experimenting half the day and am stuck.

I created and access token and tried using it, but it does not appear to be working. If someone could please walk me through this, I would be truly grateful.

/********************************************************************************************************************
* Code to control Harbor breeze Saratoga ceiling fan using a Particle Photon.  Code should work for and Harbor 
* Breeze fan with the 6 speed remote <https://images-na.ssl-images-amazon.com/images/I/41GdQZ4%2BDwL.jpg>
* 
* Components used:
*    Particle photon: https://www.amazon.com/gp/product/B016YNU1A0/ref=oh_aui_detailpage_o07_s00?ie=UTF8&psc=1
*    RF transmitter (315Mhz): https://www.amazon.com/gp/product/B00LNADJS6/ref=oh_aui_detailpage_o06_s00?ie=UTF8&psc=1
* 
* Device wiring:
*    https://gethookblog.wordpress.com/2015/10/30/hook-early-beta-testing/
* 
* All credit goes to the following:
*    veggiebenz @ http://www.instructables.com/id/Reverse-Engineer-RF-Remote-Controller-for-IoT/
*    veggiebenz @ https://bitbucket.org/veggiebenz/fancontrol/src
*    Rahil from Hook Smarthome
* 
* To control the fan:
*    1. Go to a command prompt that talks to the photon (in my case windows command prompt
*    2. Type the command without parenthesis
*       particle call (device id or device name) Transmit (command)
*    3. Commands include light, power, 1f (speed 1 forward), 5r (speed 5 reverse), etc
*
* To control from the internet using IFTTT just setup a trigger and look for "particle"
* IFTTT will connect to your particle easily and will run the Transmit function.  Just
* define which command you want to send.  I use google home to voice activate the fan 
* this way.
*
**********************************************************************************************************************/

const int TX_PIN = D3;   // Particle photon pin 3

typedef struct  {
    boolean power;
    int duration;   // micro seconds
} signal;

const signal SHORT_ON { true, 400 };
const signal SHORT_OFF { false, 500 };
const signal LONG_ON { true, 850 };
const signal LONG_OFF { false, 950 };
const int REST = 10000;

const char* host = "fancontrol";

signal sig_preamble [] {   // 50 items total
    SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF, SHORT_ON, LONG_OFF
};

signal sig_light [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_power [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_1f [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_2f [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_3f [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_4f [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_5f [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_6f [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_1r [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_2r [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_3r [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_4r [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_5r [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_6r [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_breeze [] { // runs in the forward direction
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_breeze_reverse [] { // runs in the reverse direction
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_house [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_delay [] {  // This button will turn off the light and fan after 1 minutes (works if light is on or off)
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_2h [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_4h [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_8h [] {
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_summer [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};

signal sig_winter [] {
    SHORT_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, SHORT_OFF,
    LONG_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, LONG_OFF,
    SHORT_ON, SHORT_OFF,
    LONG_ON, LONG_OFF
};


// This routine executes transmission of the code out to the RF transmitter
// Signal sent in 3 pcs  PREAMBLE + SIGNAL + POSTAMBLE
void doTransmission(signal array[16]) {
    Serial.println("Doing transmission...");
    for (int burst = 1; burst <= 6; burst++) {
        for (int pre = 0; pre < 32; ++pre) {    // transmits the Preamble
            digitalWrite(TX_PIN, sig_preamble[pre].power);
            delayMicroseconds (sig_preamble[pre].duration);
        }
        for (int idx = 0; idx < 16; ++idx ) {   // transmits the payload (signal command)
            digitalWrite(TX_PIN, array[idx].power);
            delayMicroseconds( array[idx].duration );
        }
        digitalWrite(TX_PIN, SHORT_ON.power);   // transmits the postamble - is that a word?
        delayMicroseconds(SHORT_ON.duration);
        digitalWrite(TX_PIN, SHORT_OFF.power);
        delayMicroseconds(REST);                // rest between bursts
    }
}

// This routine is called from the windows command line using the following string (leave out the < and > symbols)
// particle call <device_id> Transmit <command in yellow below>
int Transmit(String cmd) {

    if (cmd == "light"){
        doTransmission(sig_light);}
    else if (cmd == "power"){
        doTransmission(sig_power);}
    else if (cmd == "1f" || cmd == "low"){
        doTransmission(sig_1f);}
    else if (cmd == "2f" || cmd == "medium low"){
        doTransmission(sig_2f);}
    else if (cmd == "3f" or cmd == "medium"){
        doTransmission(sig_3f);}
    else if (cmd == "4f"){
        doTransmission(sig_4f);}
    else if (cmd == "5f" || cmd == "medium high"){
        doTransmission(sig_5f);}
    else if (cmd == "6f" || cmd == "high"){
        doTransmission(sig_6f);}
    else if (cmd == "1r" || cmd == "low reverse"){
        doTransmission(sig_1r);}
    else if (cmd == "2r" || cmd == "medium low reverse"){
        doTransmission(sig_2r);}
    else if (cmd == "3r" || cmd == "medium reverse"){
        doTransmission(sig_3r);}
    else if (cmd == "4r"){
        doTransmission(sig_4r);}
    else if (cmd == "5r" || cmd == "medium high reverse"){
        doTransmission(sig_5r);}
    else if (cmd == "6r" || cmd == "high reverse"){
        doTransmission(sig_6r);}
    else if (cmd == "breeze" || cmd == "circulate"){
        doTransmission(sig_breeze);}
    else if (cmd == "breeze reverse" || cmd == "circulate reverse"){
        doTransmission(sig_breeze_reverse);}
    else if (cmd == "house"){
        doTransmission(sig_house);}
    else if (cmd == "delay"){
        doTransmission(sig_delay);}
    else if (cmd == "2h"){
        doTransmission(sig_2h);}
    else if (cmd == "4h"){
        doTransmission(sig_4h);}
    else if (cmd == "8h"){
        doTransmission(sig_8h);}
    else if (cmd == "summer" || cmd == "forward"){ // respond to either summer or forward command
        doTransmission(sig_summer);}
    else if (cmd == "winter" || cmd == "reverse"){ // respond to either winter or reverse command
        doTransmission(sig_winter);}
    else {
        return -1;} // returns -1 if unrecognized command was sent

    return 1; // returns 1 for a successful command
}

void loop() {
    // nothing to loop
}


void setup() {
    
    pinMode(TX_PIN, OUTPUT); // required for output, deleting will cost you hours of pain...
    
    Particle.function("Transmit", Transmit);  // defines the transmit function
}

Still trying to get something to work. I created another token and get the following error:

{"error":"invalid_token","error_description":"The access token provided is invalid."}

The url that I am using is this:

https://api.particle.io/v1/devices/2a00250011473434383xxxxx/Transmit?access_token=2dc9d5d409d868c66e175f46ba2e8866427xxxxx

Here is the description of the URL:
2a00250011473434383xxxxx = my device ID
2dc9d5d409d868c66e175f46ba2e8866427xxxxx = newly created token
Transmit = The name of the function I am trying to communicate with though I think I need to also send an input since the function is actually "int Transmit(String cmd) {"

Hi, it could be that you need to send the token in the body, not in the url.

Docs here say:

Cheers

Hi! Thanks for responding! So I learned that I can't do this from a browser and installed git bash. I modified the string like you suggested but still get an error about my token. I don't think I am setting up the token correctly. I am not experienced in this.

I only have one device that is claimed by me as the owner. I don't have a "customer". These are the simple steps that I did.

  1. Went to "Authentication"
  2. Chose "New client"
  3. Chose "simple app (mobile auth)"
  4. Generated and copied my token

I have not created any customers nor have I created any integrations. I am just using the token in the string below, and getting token errors. I see in the console for scope it says "create customer", but I have no clue how to do this or if it is necessary.

Here is what I got from BASH:
jason@LAPTOP-LENOVO xxxx64 ~
$ curl https://api.spark.io/v1/devices/2a00250011473434383xxxxx/Transmit
-d access_token=2dc9d5d409d868c66e175f46ba2e88664xxxxxxx
-d "cmd=1f"
{"error":"invalid_token","error_description":"The access token provided is inval
id."}

Hey, it's been a while I generate a token like you described, so I'm not sure.

How about you look at this resource?

from there you can copy the token:

OR you ca ncreate one with the CLI:

I'm not sure about when we should use

-d access_token=<access_token>

versus:

-H "Authorization: Bearer <access_token>"

So I would try one and then the other.
Best of luck!

1 Like

Thanks so much! I am still not fluent in all of this, but here is what worked....

  1. I was not understanding that the client secret key was NOT a token
  2. From the cloud API tutorial, I was able to use the built in web interface to create a product bearer token
  3. Using the new token, I was able to build this string which worked when pasted into git bash

curl https://api.particle.io/v1/devices/2a0025001147343438xxxxxx/Transmit
-d access_token=e8ea57a5659385aa14241d90a1bc16ef0xxxxxxx
-d "cmd=1f"

Now I just need to figure out how to integrate it into Homeseer. Thanks again!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.