The home gas-meter is providing the actual gas count. With the subtraction (last minus before) I get 'Delta_Gas'. This is working.
Now I am trying to sum up gas these consumption values greater 0. In a typical cycle after gas burner ON max.10 values need to be summed up every minute. With burner OFF gas consumption should be set to zero(0).
Finally I want to see the gas consumption values for each single burner ON/OFF cycle.
Who can support my approach as I am a little bit lost?
var v1 = dp('/User Registers/Delta_Gas');
var sum = dp('/User Registers/Sum_Gas')
var s1;
AddValues(s1);
setInterval(AddValues, 3600000, s1); //1h Laufzeit
function AddValues(s1)
const add = add + v1
const sum = add
{
if(v1 > 0) { for (var i = 0; i < 10; i++) {
console.log(sum)
}else{
console.log(0)
}
Related
My validate line function below appears to only work on the second time of clicking add. So if the amount is 500 and I set the discount to 100, on hitting the add button it should be 400. It doesn't work. If I click the line again, the it seems the discount applies twice - amount becomes 300. How do I resolve this?
function OnValidateLine(type, name) {
var count = nlapiGetLineItemCount('expense')
var total = nlapiGetFieldValue('usertotal')
for (var x = 1; x <= count; x++) {
var amount = nlapiGetCurrentLineItemValue('expense', 'amount');
var discount = nlapiGetCurrentLineItemValue('expense', 'custcolptc_discount');
if (discount) {
nlapiSetCurrentLineItemValue('expense', 'amount', amount - discount)
}
return true;
}
return true;
}
You are not actually doing anything with your loop.
Also the way you are going about this is fraught with issues.
You should probably do this in the recalc event rather than a line validation event.
If I were doing this I'd tend manage a 'synthetic' expense line that is the total of calculated discounts. The way you are currently doing this if someone changes the expense description you'll end up with the discount applied twice. If you use a discount line then you'll just total up the discounts and add or update the discount line.
Typically for a Client script you would need to advance the pointer for each line you are looking at. In the untested example below the 'id field?' would be memo or account columns (you'll have to set the account anyway):
var totalDiscount = 0;
var discountExpenseAt = 0;
for(var i = nlapiGetLineItemCount('expense'); i> 0; i--){
if(nlapiGetLineItemValue('expense', 'id field?', i) == 'discount identifier') {
discountExpenseAt = i;
continue;
}
totalDiscount += parseFloat(nlapiGetLineItemValue('expense', 'custcolptc_discount', i)) ||0;
}
if(totalDiscount) {
if(discountExpenseAt){
nlapiSelectCurrentLineItem('expense', discountExpenseAt);
nlapiSetCurrentLineItemValue('expense', 'amount', totalDiscount.toFixed(2));
nlapiSetCurrentLineItemValue('expense', 'id field?', 'discount identifier');
nlapiCommitCurrentLineItem('expense');
}
Azure Rate Card API returns a MeterRates field (see documentation).
Azure UsageAggregate gives a quantity (see documentation).
According to the azure support page. This is the forum to ask questions.
So, how are meter rates applied?
Example meter rates:
{"0":20, "100":15, "200":10}
If I have a quantity of 175 is the amount 100*20 + 75*15 or 175*15?
Why specify an included quantity?
Example: rates:{"0":23} with included quantitiy 10 could be expressed as rates:
{"0":0, "10":23}
example meter rates: {"0":20, "100":15, "200":10}
if I have a quantity of 175 is the amount 100*20 + 75*15 or 175*15 ?
The pricing is tiered pricing. So when you get the rates it essentially tells you that:
from 0 - 99 units, the unit rate is 20
from 100 - 199 units, the unit rate is 15
from 200 units and above, the unit rate is 10
Based on this logic, your calculation should be:
99 * 20 + 75 * 15 = 3105
One thing which confuses me though is the upper limit. Above calculation is based on the information I received from Azure Billing team. What confused me is what would happen if the consumption is say 99.5 units? For the first 99 units it is fine but I am not sure how the additional 0.5 units will be calculated.
Guarav gets at the core of the issue and is why I marked it as the answer. Based on that I devised the following code to implement the logic. It falls in two parts:
Creating a bucket list from the meter rates
Processing a quantity with the bucket list to determine an amount
The following function creates a list of buckets (each bucket object is a simple POCO with Min, Max and Rate properties). The list is attached to a meter object that has the other properties from the rate card api.
private Dictionary<int, RateBucket> ParseRateBuckets(string rates)
{
dynamic dRates = JsonConvert.DeserializeObject(rates);
var rateContainer = (JContainer)dRates;
var buckets = new Dictionary<int, RateBucket>();
var bucketNumber = 0;
foreach (var jToken in rateContainer.Children())
{
var jProperty = jToken as JProperty;
if (jProperty != null)
{
var bucket = new RateBucket
{
Min = Convert.ToDouble(jProperty.Name),
Rate = Convert.ToDouble(jProperty.Value.ToString())
};
if (bucketNumber > 0)
buckets[bucketNumber - 1].Max = bucket.Min;
buckets.Add(bucketNumber, bucket);
}
bucketNumber++;
}
return buckets;
}
The second function uses the meter object with two useful properties: the bucket list, and the included quantity. According to the rate card documentation (as I read it) you don't start counting billable quantity until after you surpass the included quantity. I'm sure there's some refactoring that could be done here, but the ordered processing of the buckets is the key point.
I think I've addressed issue on the quantity by recognizing that it's a double and not an integer. Therefore the quantity associated with any single bucket is the difference between the bucket max and the bucket min (unless we've only filled a partial bucket).
private double CalculateUsageCost(RateCardMeter meter, double quantity)
{
var amount = 0.0;
quantity -= meter.IncludedQuantity;
if (quantity > 0)
{
for (var i = 0; i < meter.RateBuckets.Count; i++)
{
var bucket = meter.RateBuckets[i];
if (quantity > bucket.Min)
{
if (bucket.Max.HasValue && quantity > bucket.Max)
amount += (bucket.Max.Value - bucket.Min)*bucket.Rate;
else
amount += (quantity - bucket.Min)*bucket.Rate;
}
}
}
return amount;
}
Finally, the documentation is unclear about the time scope for the tiers. If I get a discounted price based on quantity, over what time scope do I aggregate quantity? The usage api allows me to pull data either daily or hourly. I want to pull my data hourly so I can correlate my costs by time of day. But when is it appropriate to actually calculate the bill? Seems like hourly is wrong, daily may work, but it might only be appropriate over the entire month.
Recently I just did this similar task. Following is my example (I think you can use regex to remove those characters rather than like me using replace). The first function parse the rate info string to generate a key-value pair collection, and the second function is used to calculate the total price.
private Dictionary<float, double> GetRatesDetail(string r)
{
Dictionary<float, double> pairs = null;
if(string.IsNullOrEmpty(r) || r.Length <=2)
{
pairs = new Dictionary<float, double>();
pairs.Add(0, 0);
}
else
{
pairs = r.Replace("{", "").Replace("}", "").Split(',')
.Select(value => value.Split(':'))
.ToDictionary(pair => float.Parse(pair[0].Replace("\"", "")), pair => double.Parse(pair[1]));
}
return pairs;
}
public decimal Process(Dictionary<float, double> rates, decimal quantity)
{
double ret = 0;
foreach (int key in rates.Keys.OrderByDescending(k => k))
{
if (quantity >= key)
{
ret += ((double)quantity - key) * rates[key];
quantity = key;
}
}
return (decimal)ret;
}
I'm trying to calculate the standard deviation of a set of numbers as Excel would with the STDEVPA() function, but I'm not getting the correct result. I'm following this formula:
Here is my [Node] code:
var _ = require('underscore');
var prices = [
1.37312,
1.35973,
1.35493,
1.34877,
1.34853,
1.35677,
1.36079,
1.36917,
1.36769,
1.3648,
1.37473,
1.37988,
1.37527,
1.38053,
1.37752,
1.38652,
1.39685,
1.39856,
1.39684,
1.39027
];
var standardDeviation = 0;
var average = _(prices).reduce(function(total, price) {
return total + price;
}) / prices.length;
var squaredDeviations = _(prices).reduce(function(total, price) {
var deviation = price - average;
var deviationSquared = deviation * deviation;
return total + deviationSquared;
});
var standardDeviation = Math.sqrt(squaredDeviations / prices.length);
console.log(standardDeviation);
When I run this, I get 0.26246286981807065, and instead I should get 0.0152.
Please note that I posted on StackOverflow and not the Mathematics site because, in my opinion, this is more geared toward programming than mathematics. If I post there, they will tell me to post here because this is related to programming.
If you console.log(total) inside your calculation of squaredDeviations, you'll see you're starting out with the value 1.37312, namely the first thing in your list. You need to explicitly tell it to start at 0, which is the third optional argument to reduce. Just replace:
var squaredDeviations = _(prices).reduce(function(total, price) {
var deviation = price - average;
var deviationSquared = deviation * deviation;
return total + deviationSquared;
});
with
var squaredDeviations = _(prices).reduce(function(total, price) {
var deviation = price - average;
var deviationSquared = deviation * deviation;
return total + deviationSquared;
}, 0);
See the underscore documentation for more details. In particular, note that things work when calculating the mean without passing this additional argument because, in said case, the iteratee function will not be applied to the first element.
I'm new to node.js, I'm trying to determine the elapsed time between an on and an off event of a switch (using BeagleBone Black), the script works, somewhat with .getTime() however from what I read it's not particularly accurate. So I did some research and attempted to use console.time, however from what I read there is no way to export the time value into a variable in this particular application.
I'm trying to write a script that times valve open and close events for an engine, so accuracy is paramount. The only input is a reed switch that is triggered by a passing magnet attached to a rotating flywheel.
More concisely, is there a way to time on/off events accurately in node.js?
var b = require('bonescript');
b.pinMode('P8_19', b.INPUT);
b.pinMode('P8_17', b.OUTPUT);
b.pinMode('USR3', b.OUTPUT);
b.attachInterrupt('P8_19', true, b.CHANGE, interruptCallback);
var cycle = 0;
//var t = 0;
var start, end;
function interruptCallback() {
if (b.digitalRead('P8_19') == 1)
{
console.log('Magnetic field present!');
cycle=cycle+1;
console.log ('cycle: ' + cycle);
}
else
{
//console.time('t');
start = (new Date()).getTime();
}
//console.timeEnd('t');
//console.log(t);
end = (new Date()).getTime();
console.log('elapsed time: ' + (end - start));
}
This is the full code that I'm currently using. Note: I've also displayed how I attempted to use console.time.
Thank you for your help!
For the most accurate time measure possible, use process.hrtime(). From the documentation:
Returns the current high-resolution real time in a [seconds,
nanoseconds] tuple Array. It is relative to an arbitrary time in the
past. It is not related to the time of day and therefore not subject
to clock drift. The primary use is for measuring performance between
intervals.
The function returns a two-element array that contains the count of seconds and count of nanoseconds. Passing one time object into another will return the difference between the two objects.
For your case:
function interruptCallback() {
if (b.digitalRead('P8_19') == 1) {
cycle = cycle + 1;
} else {
start = process.hrtime();
}
end = process.hrtime(start);
console.log('elapsed time: ' end[0] + ' seconds and ' + end[1] + 'nanoseonds.');
};
How can I use the Timer class and timer events to turn this loop into one that executes chunks at a time?
My current method of just running the loop keeps freezing up the flash/air UI.
I'm trying to acheive psuedo multithreading. Yes, this is from wavwriter.as:
// Write to file in chunks of converted data.
while (dataInput.bytesAvailable > 0)
{
tempData.clear();
// Resampling logic variables
var minSamples:int = Math.min(dataInput.bytesAvailable/4, 8192);
var readSampleLength:int = minSamples;//Math.floor(minSamples/soundRate);
var resampleFrequency:int = 100; // Every X frames drop or add frames
var resampleFrequencyCheck:int = (soundRate-Math.floor(soundRate))*resampleFrequency;
var soundRateCeil:int = Math.ceil(soundRate);
var soundRateFloor:int = Math.floor(soundRate);
var jlen:int = 0;
var channelCount:int = (numOfChannels-inputNumChannels);
/*
trace("resampleFrequency: " + resampleFrequency + " resampleFrequencyCheck: " + resampleFrequencyCheck
+ " soundRateCeil: " + soundRateCeil + " soundRateFloor: " + soundRateFloor);
*/
var value:Number = 0;
// Assumes data is in samples of float value
for (var i:int = 0;i < readSampleLength;i+=4)
{
value = dataInput.readFloat();
// Check for sanity of float value
if (value > 1 || value < -1)
throw new Error("Audio samples not in float format");
// Special case with 8bit WAV files
if (sampleBitRate == 8)
value = (bitResolution * value) + bitResolution;
else
value = bitResolution * value;
// Resampling Logic for non-integer sampling rate conversions
jlen = (resampleFrequencyCheck > 0 && i % resampleFrequency < resampleFrequencyCheck) ? soundRateCeil : soundRateFloor;
for (var j:int = 0; j < jlen; j++)
{
writeCorrectBits(tempData, value, channelCount);
}
}
dataOutput.writeBytes(tempData);
}
}
I have once implemented pseudo multithreading in AS3 by splitting the task into chunks, instead of splitting the data into chunks.
My solution might not be optimal, but it worked nicely for me in the context of performing a large Depth-First Search while allowing the Flash game to flow nicely.
Use a variable ticks to count computation "ticks", similar to CPU clock cycles. Every time you perform some operation, you increment this counter by 1. Increment it even more after a heavier operation is performed.
In specific parts of your code, insert checkpoints where you check if ticks > threshold, where threshold is a parameter you want to tune after you have this pseudo multithreading working.
If ticks > threshold at the checkpoint, you save the current state of your task, set ticks to zero, then exit the function.
The method has to be retried later, so here you employ a Timer with an interval parameter that should also be tuned later.
When restarting the method, use the saved state of your paused task to detect where your task should be resumed.
For your specific situation, I would suggest splitting the tasks of the for loops, instead of thinking about the while loop. The idea is to interrupt the for loops, remember their state, then continue from there after the resting interval.
To simplify, imagine that we have only the outmost for loop. A sketch of the new method is:
WhileLoop: while (dataInput.bytesAvailable > 0 && ticks < threshold)
{
if(!didSubTaskA) {
// do subtask A...
ticks += 2;
didSubTaskA = true;
}
if(ticks > threshold) {
ticks = 0;
restTimer.reset();
restTimer.start(); // This dispatches an event that should trigger this method
break WhileLoop;
}
for (var i:int = next_unused_i;i < readSampleLength;i+=4) {
next_unused_i = i+1;
// do subtask B...
ticks += 1;
if(ticks > threshold) {
ticks = 0;
restTimer.reset();
restTimer.start();
break WhileLoop;
}
}
next_unused_i = 0;
didSubTaskA = false;
}
if(ticks > threshold) {
ticks = 0;
restTimer.reset();
restTimer.start();
}
The variables ticks, threshold, restTimer, next_unused_i, and didSubTaskA are important, and can't be local method variables. They could be static or class variables. Subtask A is that part where you "Resampling logic variables", and also the variables used there can't be local variables, so make them class variables as well, so their values can persist when you leave and come back to the method.
You can make it look nicer by creating your own Task class, then storing there the whole state of interrupted state of your "threaded"-algorithm. Also, you could maybe make the checkpoint become a local function.
I didn't test the code above so I can't guarantee it works, but the idea is basically that. I hope it helps