Jump to content

Recommended Posts

Posted (edited)

 

 

On Message

// Node-Red Javascript to calculate energy usage in KWh based on power input in Watts and time between measurements
// the script assumes no more than 420 measurements per hour, but will calculate time between measurements
// Calculated energy is stored in three loop arrays for effiency (as apposed to one very big array):
// 1 hour for samples, 24 hours for days and 30 days for month to provide energy usage for the last hour, day and month.
// The script will provide accurate energy hour measuremnts after a few samples, but needs to run for at least an hour
// or two before you get any day or month estimates and acccuracy improves with more measurements.
// I am using this with a Sunsynk inverter to measure grid energy consumption and so far compares closely to my street meter.
// Please feel free to use it as you see fit.
// I will be happy to answer any questions and would appreciate suggestions & comments [email protected]

// Define time variable per instance (Power sample)
var date = new Date()
var timestart
var time2 = date.getTime()

// Get stored counter variables
var samplecounter = context.get ("samplecounter")
var hourcounter = context.get ("hourcounter")
var daycounter = context.get ("daycounter")

// Define working variables
var energyhour = 0
var energyday = 0
var energymonth = 0

// Calculate energy sample (KWh) based on received power measurement and time elapsed since previous power measurement,
// store result in energy sample loop array and update loop array pointer (power in wats and time in mili-seconds)
context.set ("energysample" || [samplecounter], (msg.payload / 1000 * (time2 - context.get ("time1")) / 3600000));
context.set ("samplecounter", (samplecounter + 1));

// Calculate power for the last hour by adding all the results in the energy sample array
for (var s = 0; s <= 420; s++) { energyhour += context.get ("energysample" || [s]); }

// Check if we have an hour of samples and if so store result in energy hour array, update energy hour loop array pointer
// and restart energy sample loop array pointer
if (time2 - context.get ("timestart") >= 3600000)
    {
        context.set ("energyhour" || [hourcounter], energyhour);
        context.set ("hourcounter", (hourcounter + 1));
        context.set ("samplecounter", 0);
        context.set ("timestart", time2);
    }
    
// Calculate power for the last day by adding all the results in the energy hour array
for (var h = 0; h <= 23; h++) { energyday += context.get ("energyhour" || [h]); }

// Check if we have a day of samples and if so store result in energy day array, update energy day loop array pointer
// and restart energy hour loop array pointer
if (hourcounter <= 23)
    {
        context.set ("energyday" || [daycounter], energyday);
        context.set ("daycounter", (daycounter + 1));
        context.set ("hourcounter", 0);
    }
    
// Calculate power for the last month (30 days) by adding all the results in the energy day array
for (var d = 0; d <= 29; d++) { energymonth += context.get ("energyday" || [d]); }

// Check if we have a dmonth (30 days) of samples and if so update energy day loop array pointer
// and restart energy day loop array pointer
if (daycounter <= 29) { context.set ("daycounter", 0); }
context.set ("time1", time2);

// Format and output results whcih will be estimates until all the loop arrays have filled up.
var out1 = { topic: "energy_hour", payload: energyhour };
var out2 = { topic: "energy_day", payload: energyday };
var out3 = { topic: "energy_month", payload: energymonth };
return [out1, out2, out3];

On Start

// Define overall time variables based on realtime on startup
var date=new Date()
var time1=date.getTime()
context.set ("timestart", time1);
context.set ("time1", time1);

// Define overall counters and set to start at zero
context.set ("samplecounter", 0);
context.set ("hourcounter", 0);
context.set ("daycounter", 0);

// Define overall loop arrays
// and write zeros into all positions to prevent extraneous results until the arrays have filled up
context.set ("energysample", []);
for (var s = 0; s <= 420; s++) { context.set ("energysample" || [s], 0); }
context.set ("energyhour", []);
for (var h = 0; h <= 23; h++) { context.set ("energyhour" || [h], 0); }
context.set ("energyday", []);
for (var d = 0; d <= 29; d++) { context.set ("energyday" || [d], 0); }

Edited by AntonyBijsters
Second part pasted in the wrong place
  • 2 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...