Sinric & CT Coil to Update Status

Hey,

I wonder if someone can see where i am going wrong with my IF statements.

I keep getting this error when compiling:

Arduino/sinric_alexa_frontdoor_with_CT/sinric_alexa_frontdoor_with_CT.ino/sinric_alexa_frontdoor_with_CT.ino.ino: In function 'void loop()':
sinric_alexa_frontdoor_with_CT.ino:149: error: invalid operands of types 'double' and 'const char [2]' to binary 'operator>'
   if (Irms > "1"){
              Arduino/sinric_alexa_frontdoor_with_CT/sinric_alexa_frontdoor_with_CT.ino/sinric_alexa_frontdoor_with_CT.ino.ino: At global scope:
sinric_alexa_frontdoor_with_CT.ino:157: error: expected unqualified-id before 'if'
   if(isConnected) {
   ^
exit status 1
invalid operands of types 'double' and 'const char [2]' to binary 'operator>'

Here is my code:

/*
 Version 0.3 - March 06 2018
*/ 
#include "EmonLib.h"
EnergyMonitor emon1;
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h> //  https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries
#include <ArduinoJson.h> // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries
#include <StreamString.h>

ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
WiFiClient client;
const int ledPin = D1;
#define MyApiKey "*removed*" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard
#define MySSID "*removed*" // TODO: Change to your Wifi network SSID
#define MyWifiPassword "*removed*" // TODO: Change to your Wifi network password

#define HEARTBEAT_INTERVAL 300000 // 5 Minutes 

uint64_t heartbeatTimestamp = 0;
bool isConnected = false;

void setPowerStateOnServer(String deviceId, String value);
//void setTargetTemperatureOnServer(String deviceId, String value, String scale);

// deviceId is the ID assgined to your smart-home-device in sinric.com dashboard. Copy it from dashboard and paste it here

void turnOn(String deviceId) {
  if (deviceId == "*removed*") // Device ID of first device
  {  
    Serial.print("Turn on device id: ");
    Serial.println(deviceId);
     digitalWrite(ledPin, LOW);
  } 
  else 
  {
    Serial.print("Turn on for unknown device id: ");
    Serial.println(deviceId);   
  }     
}

void turnOff(String deviceId) {
   if (deviceId == "*removed*") // Device ID of first device
   {  
     Serial.print("Turn off Device ID: ");
     Serial.println(deviceId);
     digitalWrite(ledPin, HIGH);
   }
  else 
  {
     Serial.print("Turn off for unknown device id: ");
     Serial.println(deviceId);    
  }
}

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
  switch(type) {
    case WStype_DISCONNECTED:
      isConnected = false;    
      Serial.printf("[WSc] Webservice disconnected from sinric.com!\n");
      break;
    case WStype_CONNECTED: {
      isConnected = true;
      Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload);
      Serial.printf("Waiting for commands from sinric.com ...\n");        
      }
      break;
    case WStype_TEXT: {
        Serial.printf("[WSc] get text: %s\n", payload);
        // Example payloads

        // For Switch or Light device types
        // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html

        // For Light device type
        // Look at the light example in github
          
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject((char*)payload); 
        String deviceId = json ["deviceId"];     
        String action = json ["action"];
        
        if(action == "setPowerState") { // Switch or Light
            String value = json ["value"];
            if(value == "ON") {
                turnOn(deviceId);
            } else {
                turnOff(deviceId);
            }
        }
        else if (action == "SetTargetTemperature") {
            String deviceId = json ["deviceId"];     
            String action = json ["action"];
            String value = json ["value"];
        }
        else if (action == "test") {
            Serial.println("[WSc] received test command from sinric.com");
        }
      }
      break;
    case WStype_BIN:
      Serial.printf("[WSc] get binary length: %u\n", length);
      break;
  }
}

void setup() {
  Serial.begin(115200);
  emon1.current(A0, 111.1);             // Current: input pin, calibration.
  WiFiMulti.addAP(MySSID, MyWifiPassword);
  Serial.println();
  Serial.print("Connecting to Wifi: ");
  Serial.println(MySSID);  
  
  // Waiting for Wifi connect
  while(WiFiMulti.run() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  if(WiFiMulti.run() == WL_CONNECTED) {
    Serial.println("");
    Serial.print("WiFi connected. ");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }

  pinMode(ledPin, OUTPUT); // initialize digital ledPin as an output.
  delay(10);
  digitalWrite(ledPin, HIGH); // Wemos BUILTIN_LED is active Low, so high is off

  // server address, port and URL
  webSocket.begin("iot.sinric.com", 80, "/");

  // event handler
  webSocket.onEvent(webSocketEvent);
  webSocket.setAuthorization("apikey", MyApiKey);
  
  // try again every 5000ms if connection has failed
  webSocket.setReconnectInterval(5000);   // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets
}
void loop() {
  webSocket.loop();
 
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  Serial.println(Irms);  
  if (Irms > "1"){
    setPowerStateOnServer("deviceid", "ON");
  }
  else
  {
    setPowerStateOnServer("deviceid", "OFF");
  } 
  }
  if(isConnected) {
      uint64_t now = millis();
      
      // Send heartbeat in order to avoid disconnections during ISP resetting IPs over night. Thanks @MacSass
      if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
          heartbeatTimestamp = now;
          webSocket.sendTXT("H");          
      }
  }   
}

// If you are going to use a push button to on/off the switch manually, use this function to update the status on the server
// so it will reflect on Alexa app.
// eg: setPowerStateOnServer("deviceid", "ON")
void setPowerStateOnServer(String deviceId, String value) {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["deviceId"] = deviceId;
  root["action"] = "setPowerState";
  root["value"] = value;
  StreamString databuf;
  root.printTo(databuf);
  
  webSocket.sendTXT(databuf);
}

Any help would be much appreciated.

Regards,

Edd

if (Irms > "1")You are trying to compare a float (double) value with a two byte character string containing the ASCII value for the numeral 1.

What was your intention?

Hey,

I am trying to read a CT coil’s value to see if the light is on or not. Then update sinric database.

This is my changed code:

/*
 Version 0.3 - March 06 2018
*/ 
#include "EmonLib.h"
EnergyMonitor emon1;
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h> //  https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries
#include <ArduinoJson.h> // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries
#include <StreamString.h>

ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
WiFiClient client;
const int ledPin = D1;
#define MyApiKey "***" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard
#define MySSID "***" // TODO: Change to your Wifi network SSID
#define MyWifiPassword "***" // TODO: Change to your Wifi network password

#define HEARTBEAT_INTERVAL 300000 // 5 Minutes 

uint64_t heartbeatTimestamp = 0;
bool isConnected = false;

void setPowerStateOnServer(String deviceId, String value);
//void setTargetTemperatureOnServer(String deviceId, String value, String scale);

// deviceId is the ID assgined to your smart-home-device in sinric.com dashboard. Copy it from dashboard and paste it here

void turnOn(String deviceId) {
  if (deviceId == "***") // Device ID of first device
  {  
    Serial.print("Turn on device id: ");
    Serial.println(deviceId);
     digitalWrite(ledPin, LOW);
  } 
  else 
  {
    Serial.print("Turn on for unknown device id: ");
    Serial.println(deviceId);   
  }     
}

void turnOff(String deviceId) {
   if (deviceId == "***") // Device ID of first device
   {  
     Serial.print("Turn off Device ID: ");
     Serial.println(deviceId);
     digitalWrite(ledPin, HIGH);
   }
  else 
  {
     Serial.print("Turn off for unknown device id: ");
     Serial.println(deviceId);    
  }
}

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
  switch(type) {
    case WStype_DISCONNECTED:
      isConnected = false;    
      Serial.printf("[WSc] Webservice disconnected from sinric.com!\n");
      break;
    case WStype_CONNECTED: {
      isConnected = true;
      Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload);
      Serial.printf("Waiting for commands from sinric.com ...\n");        
      }
      break;
    case WStype_TEXT: {
        Serial.printf("[WSc] get text: %s\n", payload);
        // Example payloads

        // For Switch or Light device types
        // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html

        // For Light device type
        // Look at the light example in github
          
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject((char*)payload); 
        String deviceId = json ["deviceId"];     
        String action = json ["action"];
        
        if(action == "setPowerState") { // Switch or Light
            String value = json ["value"];
            if(value == "ON") {
                turnOn(deviceId);
            } else {
                turnOff(deviceId);
            }
        }
        else if (action == "SetTargetTemperature") {
            String deviceId = json ["deviceId"];     
            String action = json ["action"];
            String value = json ["value"];
        }
        else if (action == "test") {
            Serial.println("[WSc] received test command from sinric.com");
        }
      }
      break;
    case WStype_BIN:
      Serial.printf("[WSc] get binary length: %u\n", length);
      break;
  }
}

void setup() {
  Serial.begin(115200);
  emon1.current(A0, 111.1);             // Current: input pin, calibration.
  WiFiMulti.addAP(MySSID, MyWifiPassword);
  Serial.println();
  Serial.print("Connecting to Wifi: ");
  Serial.println(MySSID);  
  
  // Waiting for Wifi connect
  while(WiFiMulti.run() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  if(WiFiMulti.run() == WL_CONNECTED) {
    Serial.println("");
    Serial.print("WiFi connected. ");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }

  pinMode(ledPin, OUTPUT); // initialize digital ledPin as an output.
  delay(10);
  digitalWrite(ledPin, HIGH); // Wemos BUILTIN_LED is active Low, so high is off

  // server address, port and URL
  webSocket.begin("iot.sinric.com", 80, "/");

  // event handler
  webSocket.onEvent(webSocketEvent);
  webSocket.setAuthorization("apikey", MyApiKey);
  
  // try again every 5000ms if connection has failed
  webSocket.setReconnectInterval(5000);   // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets
}
void loop() {
  webSocket.loop();
  int volts = 1;
  int Irms = emon1.calcIrms(1480);  // Calculate Irms only
  Serial.println(Irms);  
  if (Irms > volts)
  {
    setPowerStateOnServer("***", "ON");
  }
  else if (Irms < volts)
  {
    setPowerStateOnServer("***", "OFF");
  
  }
  if(isConnected) {
      uint64_t now = millis();
      
      // Send heartbeat in order to avoid disconnections during ISP resetting IPs over night. Thanks @MacSass
      if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
          heartbeatTimestamp = now;
          webSocket.sendTXT("H");          
      }
  }   
}

// If you are going to use a push button to on/off the switch manually, use this function to update the status on the server
// so it will reflect on Alexa app.
// eg: setPowerStateOnServer("deviceid", "ON")
void setPowerStateOnServer(String deviceId, String value) {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["deviceId"] = deviceId;
  root["action"] = "setPowerState";
  root["value"] = value;
  StreamString databuf;
  root.printTo(databuf);
  
  webSocket.sendTXT(databuf);
}

You have changed your float (double) variable to an int - why? The calcIrms() function returns a float value. When you assign that to an int, it gets truncated to the integer value (3.9999 → 3, etc.) If that is what you want, that is fine. You might want this:

void loop() {
  webSocket.loop();
  float volts = 1.0;
  float Irms = emon1.calcIrms(1480);  // Calculate Irms only
  Serial.println(Irms, 2);  // print 2 decimal places
  ...

Also, you test for Irms < volts and then test for Irms > volts. What happens when they are equal? It is usually better to test for one condition (greater than, greater than or equal, etc.) and then let the else {} clause take care of the other case.

Hey,

Thanks for the advise. So my code now looks like this:

void loop() {
  webSocket.loop();
  float volts = 1.0;
  float Irms = emon1.calcIrms(1480);  // Calculate Irms only
  Serial.println(Irms, 2);  // print 2 decimal places 
  if (Irms >= volts)
  {
    setPowerStateOnServer("***", "ON");
  }
  else
  {
    setPowerStateOnServer("***", "OFF");
  
  }

But for some reason Sinric does not seem to update.

I have checked alexa app and it has not changed the status of the light.

Does anyone have any ideas as to what i am doing wrong with this sketch?

There is example on sinric github page to update their database for any change of state generated locally, look at the light examples. It does take about 10 seconds to get to Alexa device update.