从数据库中的一系列Kw读数(当时的kw值)确定每日Kwh值的正确方法是什么

时间:2013-01-06 14:32:13

标签: c# sql math physics

我有一个设备可以读取电子设备的kw值,以测量它们(能量消耗的速率)在某个时间。然后将这些值发送到轮询器(定期向设备询问值),并插入到数据库中。

示例:

1st reading - 10 kw at 1.01pm
2nd reading - 15 kw at 1.23pm
3rd reading - 11 kw at 1.30pm

如您所见,轮询间隔不固定,因此可以在不同时间将值插入数据库。为简单起见,我们可以想象数据库只是一个包含2列的表,[时间]和[kw_value]。

这实际上是一个两部分问题:

  1. 如何从这些读数中获取每日kwh值(全天的能耗)?我在数学上非常糟糕,所以我不知道从这些值中获得每日kwh值的正确方法是什么。

    我想把所有的值加起来并得到平均值,但我的妈妈说我应该绘制一整天所有读数的图表,然后得到绘制线下面的区域(有点像得到图表的积分,然后给出我当天消耗的总功率。然后我应该用这个值除以整天的持续时间,以小时为单位得到千瓦时,是吗?

  2. 如何使用数据库执行此操作?如果一天有数千个读数(来自多个电子设备,在这种情况下我们有3列 - [时间],[kw_value],[deviceid]),如果我加载所有值,我应该如何计算内存(我使用C#)并从那里计算或者我可以使用SQL来计算它吗?

  3. 编辑: 谢谢你们指出kw和kwh之间的区别。我的原始问题犯了大错,因此编辑。重申一下,设备在特定时间读取kw值(能量消耗率,以千焦耳/秒为单位),并在数据库中给出这些值的列表/图表,确定kwh的正确方法是什么(给定的一天消耗的总能量)。

3 个答案:

答案 0 :(得分:0)

此查询查找每行的上一行。然后对于每个区间,它假设整个区间从一开始就具有kwh值。

; with  numbered as 
        (
        select  *
        ,       row_number() over (partition by deviceid order by time) rn
        from    YourTable
        )
select  deviceid
,       sum(t0.kwh_value * datediff(s, t0.[time], t1.[time])/3600)
from    numbered t1
join    numbered t0
on      t1.deviceid = t0.deviceid
        and t1.rn = t0.rn + 1
group by
        deviceid

您可以修改查询以计算使用间隔的平均千瓦时:

,       sum((t1.kwh_value + t0.kwh_value)/2 * datediff(s, t0.[time], t1.[time])/3600)

答案 1 :(得分:0)

我的解决方案试图处理日间隔和测量间隔的重叠:

public class Measurement
        {
            public DateTime t;
            public double kwh;

            public Measurement(string t, double kwh)
            {
                this.t = DateTime.Parse(t);
                this.kwh = kwh;
            }
        }

        public static double getPowerConsumption(IEnumerable<Measurement> measurements, DateTime day)
        {
            DateTime never = DateTime.MinValue;
            DateTime tomorrow = day.AddDays(1);
            DateTime prev = never;
            double kwh = 0;

            foreach (Measurement m in measurements)
            {
                if (m.t >= day)
                //  measurement in our after or day
                {
                    if (m.t >= tomorrow)
                    {
                        if ((prev != never) && (prev < m.t))
                        {
                            //  add portion up to midnight
                            kwh += m.kwh * (tomorrow.Ticks - prev.Ticks) / (double)(m.t.Ticks - prev.Ticks);
                        }
                        break;
                    }
                    else if ((prev != never) && (prev < day) && (prev < m.t))
                    {
                        kwh += m.kwh * (m.t.Ticks - day.Ticks) / (double)(m.t.Ticks - prev.Ticks);
                    }
                    else
                    {
                        kwh += m.kwh;
                    }
                }
                prev = m.t;
            }

            return kwh;
        }

        static void Main(string[] args)
        {
            DateTime myDay = new DateTime(2012, 11, 2);
            List<Measurement> measurements = new List<Measurement>() { new Measurement("01.11.2012 23:30", 10), 
                                                                       new Measurement("02.11.2012 10:00", 1), 
                                                                       new Measurement("02.11.2012 23:30", 5), 
                                                                       new Measurement("03.11.2012 10:00", 6) };
            double kwh = getPowerConsumption(measurements, myDay);

            Console.WriteLine("Powerconsumption for " + myDay.ToShortDateString() + " was " + kwh.ToString("#.##") + "kWh");
        }

答案 2 :(得分:0)

你肯定不会得到精确的千瓦时价值。由于这种不常见的轮询频率,您最终可能会在估算和实际使用之间出现非常大的差异。你举了这个例子:

1st reading - 10 kW at 1.01pm
2nd reading - 15 kW at 1.23pm
3rd reading - 11 kW at 1.30pm

没有其他信息,关于唯一合理的做法是平均每对读数和多个读数。从1.01到1.23是22分钟,或.367小时。该期间的平均读数为(10 + 15)/ 2或12.5 kW,估计使用量为(12.5 * 0.367)或4.58 kWh。

但是,这种方法有一些明显的漏洞。如果实际消费是:

,会发生什么
10 kW at 1.01pm
 0 kW at 1.02pm // machine turned off
15 kW at 1.23pm // machine turned back on
11 kW at 1.29pm

您在1.01和1.23之间的实际使用时间为10千瓦,一分钟或0.16千瓦时。

在另一个方向上,这些数字可能会有相似的数量。也就是说,你的计算结果可能非常低。

如果这是合理的,我的方法是创建一个SQL查询,返回按机器排序的数据,然后按时间返回。所以你得到:

machine1, 1.01 am, reading
machine1, 1.20 am, reading
... etc. ...
machine2, 1.03, reading
machine2, 2.15, reading

所以机器1的所有读数都按时间顺序呈现给你,然后是机器2等等。

您当然可以使用ORDER BY和GROUP BY编写查询,以正确的顺序返回所有读数。然后,您可以使用SqlDataReader按顺序移动结果,计算每个时段的消耗(使用上面显示的平均值计算),并对每台机器的结果求和。我不太清楚SQL是否可以说是否可以编写一个查询来为您完成所有计算并返回一个结果集,例如:

machine1, start time, end time, total power consumed
machine2, start time, end time, total power consumed
etc