Hello,
Like many others, it seems that my free sandbox data operation limit is being reached well before the monthly billing cycle refreshes. I only have three devices running right now. Two Photons control lights for a couple of aquariums and one Photon controls a hydroponic garden. I have a raspberry pi running Node-Red which calls functions and variables on the photons and displays them on a dashboard.
I have tried everything within reason to reduce the amount of data operations, however, no matter how much I reduce the calls, the amount I see in the usage data does not change. I have changed the refresh rate of every variable from 15 min to 1 hour and have greatly reduced the number of variables being called to the bare minimum. For one light, I have removed the particle.variables and functions altogether. But it’s usage report is not changing.
Here is the code currently running on that Photon, which is identical to my other Photon minus a temperature sens. Yet the other photon has no data usage being incurred.
#include <spark-dallas-temperature.h>
#define ONE_DAY_MILLIS (24 * 60 * 60 * 1000)
unsigned long lastSync = millis();//variable for syncing clock to Particle cloud
#define timeOnSummer 6 //start fading at 6, fully on by 7
#define timeOffSummer 19 //start fading at 7, off by 8 *13 hours of full light
#define timeOnSpringFall 7 //start fading at 7, fully on by 8
#define timeOffSpringFall 18 //start fading at 6, off by 7 *11 hours of full light
#define timeOnWinter 8 //start fading at 8, fully on by 9
#define timeOffWinter 17 //start fading at 5, off by 6 *8 hours of full light
#define TIMER_LENGTH 10000// ms
int pwmVal;
int pwmPin = A5;
int ACPowerPin = D5;
int counter = 0;
bool debug = 0;
STARTUP(WiFi.selectAntenna(ANT_EXTERNAL));//Use external Antenna
#define ONE_WIRE_BUS D4
#define TEMPERATURE_PRECISION 12
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress inWaterThermometer = { 0x28, 0xC3, 0xD1, 0x5F, 0x07, 0x00, 0x00, 0x73 };
double waterTempC = -1;
double watertempf = -1;
long tempCheckTimer = 0;
// --------------------------------------------------------------------
void setup()
{
pinMode(pwmPin, OUTPUT);
analogWrite(pwmPin, 0);
pinMode(ACPowerPin, OUTPUT);
digitalWrite(ACPowerPin, LOW);
//Particle.variable("watertempf", watertempf);
//Particle.variable("pwmVal", pwmVal);
//Particle.function("ACPower", ACPower);
if(debug)
Serial.begin(9600);
RGB.control(true);
RGB.color(0, 0, 0);//Turn RGB LED Off
Time.zone(-6);//Set Time zone to MDT
Particle.syncTime();
// DS18B20 initialization
//Initialize the I2C sensors and ping them
sensors.begin();
sensors.setResolution(inWaterThermometer, TEMPERATURE_PRECISION);
checkDateTime();
getTemp();
if(debug)
Serial.println(Time.timeStr());
}
// --------------------------------------------------------------------
void loop()
{
checkDateTime();
if((millis() - tempCheckTimer) > TIMER_LENGTH)
{
getTemp();
//getWeather();
tempCheckTimer = millis();
}
// DST adjstment
//bool daylightSavings = IsDST(Time.day(), Time.month(), Time.weekday());
//Time.zone(daylightSavings? -6 : -7);
if (millis() - lastSync > ONE_DAY_MILLIS) {
// Request time synchronization from the Particle Device Cloud
Particle.syncTime();
lastSync = millis();
}
}
//---------------------------------------------------------------
// int ACPower(String command)
// {
// if(command == "on")
// {
// digitalWrite(ACPowerPin, HIGH);
// return 1;
// }
// if(command == "off")
// {
// digitalWrite(ACPowerPin, LOW);
// return 2;
// }
// else return -1;
// }
//---------------------------------------------------------------
void update18B20Temp(DeviceAddress deviceAddress, double &tempC)
{
tempC = sensors.getTempC(deviceAddress);
}
//---------------------------------------------------------------
void getTemp()
{
//get temp from DS18B20
sensors.requestTemperatures();
update18B20Temp(inWaterThermometer, waterTempC);
if(waterTempC < -100)
{
watertempf = watertempf;//push last value so data isn't out of scope
}
else
{
watertempf = (waterTempC * 9)/5 + 32;//convert to F
}
}
//---------------------------------------------------------------
void getWeather()
{
// Measure Relative Humidity from the HTU21D or Si7021
// humidity = sensor.getRH();
// // Measure Temperature from the HTU21D or Si7021
// tempf = sensor.getTempF();
// // Temperature is measured every time RH is requested.
// // It is faster, therefore, to read it from previous RH
// // measurement with getTemp() instead with readTemp()
// //Measure the Barometer temperature in F from the MPL3115A2
// baroTemp = sensor.readBaroTempF();
// //Measure Pressure from the MPL3115A2
// pascals = sensor.readPressure();
//If in altitude mode, you can get a reading in feet with this line:
//float altf = sensor.readAltitudeFt();
}
////////////////////////////////////////////////////////////////////////////////
void checkDateTime()
{
counter++;
if(counter == 6000)//check every ~30 seconds
{
int month = Time.month();
if(month == 12 || month == 1 || month == 2)
winter();//if == the months above, run the winter routine
if(month == 3 || month == 4 || month == 5 || month == 9 || month == 10 || month == 11)
springFall();//if == the months above, run the spring/fall routine
if(month == 6 || month == 7 || month == 8)
summer();//if == the months above, run the summer routine
if(debug)
Serial.println(Time.timeStr());
//For AC power control
if(pwmVal == 255)
{
digitalWrite(ACPowerPin, HIGH);
}
else
{
digitalWrite(ACPowerPin, LOW);
}
counter = 0;
}
}
////////////////////////////////////////////////////////////////////////////////
void summer()
{
//Fade On Gradually
if(Time.hour() == timeOnSummer)
{
pwmVal = map(Time.minute(), 1, 59, 1, 255);
analogWrite(pwmPin, pwmVal);
}
//Fully On
else if(Time.hour() > timeOnSummer && Time.hour() < timeOffSummer)
{
pwmVal = 255;
analogWrite(pwmPin, pwmVal);
}
//Fade Off Gradually
else if(Time.hour() == timeOffSummer)
{
pwmVal = map(Time.minute(), 1, 59, 255, 1);
analogWrite(pwmPin, pwmVal);
}
//Fully Off
else
{
pwmVal = 0;
analogWrite(pwmPin, pwmVal);
}
}
////////////////////////////////////////////////////////////////////////////////
void winter()
{
//Fade On Gradually
if(Time.hour() == timeOnWinter)
{
pwmVal = map(Time.minute(), 1, 59, 1, 255);
analogWrite(pwmPin, pwmVal);
}
//Fully On
else if(Time.hour() > timeOnWinter && Time.hour() < timeOffWinter)
{
pwmVal = 255;
analogWrite(pwmPin, pwmVal);
}
//Fade Off Gradually
else if(Time.hour() == timeOffWinter)
{
pwmVal = map(Time.minute(), 1, 59, 255, 1);
analogWrite(pwmPin, pwmVal);
}
//Fully Off
else
{
pwmVal = 0;
analogWrite(pwmPin, pwmVal);
}
}
////////////////////////////////////////////////////////////////////////////////
void springFall()
{
//Fade On Gradually
if(Time.hour() == timeOnSpringFall)
{
pwmVal = map(Time.minute(), 1, 59, 1, 255);
analogWrite(pwmPin, pwmVal);
}
//Fully On
else if(Time.hour() > timeOnSpringFall && Time.hour() < timeOffSpringFall)
{
pwmVal = 255;
analogWrite(pwmPin, pwmVal);
}
//Fade Off Gradually
else if(Time.hour() == timeOffSpringFall)
{
pwmVal = map(Time.minute(), 1, 59, 255, 1);
analogWrite(pwmPin, pwmVal);
}
//Fully Off
else
{
pwmVal = 0;
analogWrite(pwmPin, pwmVal);
}
}
/////////////////////////////////////////////////////////////
bool IsDST(int dayOfMonth, int month, int dayOfWeek)
{
if (month < 3 || month > 11)
{
return false;
}
if (month > 3 && month < 11)
{
return true;
}
int previousSunday = dayOfMonth - (dayOfWeek - 1);
if (month == 3)
{
return previousSunday >= 8;
}
return previousSunday <= 0;
}
That code was uploaded several days ago, commenting out the particle.variables and functions, however, as the report downloaded from the billing page shows, it’s still incurring data usage (Photon_B5 Turtles). I checked on the Particle Console, and the variables and function that were on that Photon are no longer available, so I know that this version of the code is running on it.
What am I missing? I deleted the objects from the Node-Red flow altogether, but that hasn’t changed the amount of data being used either.
Any help is appreciated. These limits placed on the free plan are very restrictive and are causing headaches for long-time, loyal Particle customers unnecessarily. It would be very helpful if these usage reports from the billing page had more information such as which operations were the ones incurring an operation charge rather than just usage by device. It feels like there is an issue in how these are calculated to force people to upgrade to the paid plans. It makes no sense that I should be reaching my limit with two devices in less than a month when there are up to 100 devices allowed on the free plan.