【问题标题】:Get the total machine running hours between two dates but split into 3 time ranges: standard time, peak time and off-peak time获取两个日期之间的总机器运行时间,但分为 3 个时间范围:标准时间、高峰时间和非高峰时间
【发布时间】:2015-08-03 10:35:20
【问题描述】:

获取两个日期之间的总机器运行时间,但分为 3 个时间范围:标准时间、高峰时间和非高峰时间。

上下文
编程环境: Wonderware ArchestrA
编程语言: ArchestrA Quick Script .Net
数据库:Historian - SQL Server (In-SQL)
外部: 采矿业的几个水泵,需要知道水泵在 3 个不同的电价时间(高峰期)的使用情况,标准,非高峰时间)。

工作日:
标准时间: 09:00 至 17:00 和 19:00 至 22:00
高峰时间: 06:00 至09:00 和 17:00 至 19:00
非高峰时间: 22:00 至 06:00

星期六:
标准时间: 07:00 至 12:00 和 18:00 至 20:00
非高峰时间: 20: 00 至 07:00 和 12:00 至 18:00

星期日:
非高峰时间:整个星期日都是非高峰时间

我需要
两个日期之间:

  • 泵在高峰时间运行的总小时数。
  • 泵在非高峰时间运行的总小时数。
  • 泵在标准时间内运行的总小时数。

我尝试过的方法:(机器运行的总非高峰时间(以小时为单位)。
它有效,但大多数时候我得到的时间少于我应该得到的时间。

-- This script only gets the total off-peak time hours
SET NOCOUNT ON  
        DECLARE @StartDate DateTime  
        DECLARE @EndDate DateTime  
        DECLARE @var1 REAL;  
        DECLARE @var2 REAL; 
        DECLARE @var3 REAL; 

        SET @StartDate = '2015/08/01 05:00:00.000'  
        SET @EndDate = GetDate()  
        SET NOCOUNT OFF  

        SET @var1 = 
           (
           SELECT   
               'Count' = Count(DiscreteHistory.Value)/60.0  
           FROM   
               DiscreteHistory  
           WHERE  
               DiscreteHistory.TagName  
               IN ('KDCE_S04_22PMP01_Machine.FA_RF') 
               AND DiscreteHistory.Value = 1  
               AND wwRetrievalMode = 'Cyclic' 
               AND wwResolution = 60000  
               AND DateTime >= @StartDate  
               AND DateTime <= @EndDate  
               AND DATEPART(dw, DateTime) NOT IN (2, 3, 4, 5, 6, 7)
           )

        SET @var2 = 
           ( 
           SELECT   
               'Count' = Count(DiscreteHistory.Value)/60.0  
           FROM  
               DiscreteHistory 
           WHERE  
               DiscreteHistory.TagName 
               IN ('KDCE_S04_22PMP01_Machine.FA_RF')  
               AND DiscreteHistory.Value = 1  
               AND wwRetrievalMode = 'Cyclic'  
               AND wwResolution = 60000  
               AND DateTime >= @StartDate  
               AND DateTime <= @EndDate  
               AND DATEPART(dw, DateTime) NOT IN (1, 2, 3, 4, 5, 6)
               AND (CAST(DateTime as time) >= '20:00:00' AND CAST(DateTime as time) < '07:00:00') 
           )

        SET @var3 = 
           ( 
           SELECT   
               'Count' = Count(DiscreteHistory.Value)/60.0  
           FROM   
               DiscreteHistory  
           WHERE 
               DiscreteHistory.TagName 
               IN ('KDCE_S04_22PMP01_Machine.FA_RF') 
               AND DiscreteHistory.Value = 1  
               AND wwRetrievalMode = 'Cyclic'  
               AND wwResolution = 60000  
               AND DateTime >= @StartDate  
               AND DateTime <= @EndDate  
               AND DATEPART(dw, DateTime) NOT IN (1, 2, 3, 4, 5, 6) 
               AND (CAST(DateTime as time) >= '12:00:00' AND CAST(DateTime as time) < '18:00:00') 
           )

        IF @var1 IS NULL SET @var1 = 0
        IF @var2 IS NULL SET @var2 = 0 
        IF @var3 IS NULL SET @var3 = 0 

        SELECT  
           'Count' = (Count(DiscreteHistory.Value)/60.0) + @var1 + @var2 + @var3  
        FROM  
           DiscreteHistory 
        WHERE  
           DiscreteHistory.TagName 
           IN ('KDCE_S04_22PMP01_Machine.FA_RF') 
           AND DiscreteHistory.Value = 1  
           AND wwRetrievalMode = 'Cyclic'
           AND wwResolution = 60000 
           AND DateTime >= @StartDate
           AND DateTime <= @EndDate
           AND DATEPART(dw, DateTime) NOT IN (1, 7)
           AND (CAST(DateTime as time) >= '22:00:00' OR CAST(DateTime as time) < '06:00:00');  

谢谢。

样本数据

我将以下信息记录到数据库中:

运行反馈的唯一标签名称:KDCE_S04_22PMP01_Machine.FA_RF这是一个运行反馈,它是“1”或“0”或“null”值

机器运行小时数的唯一标记名称:me.a0_MainPump.RunningHours.FA_PV,它是泵运行小时数的整数值。

两个标签名称都记录有 TagName、Value、DateTime、质量等。

我有一个包含以下列的表格:

| DateTime | TagName | Value | QualityDetail |   

在 DB 中获取样本数据的脚本:

SET NOCOUNT ON  

DECLARE @StartDate DateTime  
DECLARE @EndDate DateTime  

SET @StartDate = '20150701 05:00:00.000'  
SET @EndDate = '20150731 05:00:00.000'  
SET NOCOUNT OFF  

SELECT 
    DateTime, TagName, Value, Quality  
FROM 
    DiscreteHistory  
WHERE 
    DiscreteHistory.TagName IN ('KDCE_S04_22PMP01_Machine.FA_RF')  
    AND DateTime >= @StartDate AND DateTime <= @EndDate  

如果我导出到 csv,它会返回这个输出:(我已经缩短了它)

DateTime,TagName,Value,Quality
2015/07/01 05:00:00 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,133
2015/07/01 05:09:46 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/01 05:09:53 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/01 06:44:20 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/01 06:45:54 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/01 07:36:22 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/01 07:36:48 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/01 01:53:44 PM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/01 01:53:44 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/01 02:04:52 PM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/01 02:05:27 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/01 02:07:25 PM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/01 02:09:13 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/01 02:14:54 PM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/02 12:10:48 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/02 05:24:06 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/02 05:24:16 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/02 05:50:52 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/02 05:50:59 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/02 06:00:15 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/02 06:55:18 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/02 06:55:18 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/02 09:46:58 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/02 09:46:58 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/02 01:30:27 PM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/02 01:30:27 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/02 05:38:03 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/02 07:01:56 PM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/03 03:41:09 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/03 09:05:18 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/03 10:42:00 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/03 10:57:31 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/03 04:53:36 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/04 10:08:17 PM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/05 06:43:50 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/05 09:43:08 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/05 01:04:03 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/06 09:37:53 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/06 11:07:15 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/06 11:29:48 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/06 05:02:38 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/07 06:15:33 AM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/07 06:32:24 AM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/07 09:05:20 AM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/07 01:10:09 PM,KDCE_S04_22PMP01_Machine.FA_RF,(null),1
2015/07/07 01:10:16 PM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/07 04:45:12 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0
2015/07/07 08:19:40 PM,KDCE_S04_22PMP01_Machine.FA_RF,1,0
2015/07/07 09:01:35 PM,KDCE_S04_22PMP01_Machine.FA_RF,0,0

【问题讨论】:

  • 请从输入数据中添加一些样本!你是什​​么意思“有时”?请添加工作样本,而不是工作样本!
  • 您好我已经添加了一些数据,希望它是您正在寻找的。 “有时”是指它有时给我正确的数据,有时它给我的数据不加起来,也就是说,如果我加上分钟,它给了我更多的可能。
  • 如果它加起来,您可能有连接问题或您的时间间隔重叠。下一个合乎逻辑的步骤是查看细节并找出数字过高的原因。
  • 谢谢尼克,我会尽力做到的。我仍然是 SQL 的新手,没有上过它的课程。基本上这是我的第一个 SQL 脚本。
  • 经过更多测试后,我发现我 CAST 时间的部分在“标准时间”下无法正常运行:我使用 cast 的第一部分:AND (CAST(DateTime as time) >= '10:00:00' AND CAST(DateTime as time) '20:00:00' AND CAST(DateTime作为时间)

标签: sql-server wonderware


【解决方案1】:

好的,所以上面编辑的脚本现在可以正常工作了,基本上我在下面看到的每个时间范围(峰值、标准和非峰值)的代码的三种变体。
唯一的问题是,如果 PLC 和 Historian/SQL 数据库之间存在网络通信问题,那么您将“丢失”数据,最终会在数据库中得到大量“空”读数。这就是为什么时间没有加起来的原因。更好的方法是在 PLC 中以 SCADA IO 标签为代价实现此功能。
尽管如此,下面的脚本仍然有效。

    -- this script only gets the total off-peak time hours
    SET NOCOUNT ON  
    DECLARE @StartDate DateTime  
    DECLARE @EndDate DateTime  
    DECLARE @var1 REAL;  
    DECLARE @var2 REAL; 
    DECLARE @var3 REAL; 

    SET @StartDate = '2015/08/01 05:00:00.000'  
    SET @EndDate = GetDate()  
    SET NOCOUNT OFF  

    SET @var1 = 
       (
       SELECT   
           'Count' = Count(DiscreteHistory.Value)/60.0  
       FROM   
           DiscreteHistory  
       WHERE  
           DiscreteHistory.TagName  
           IN ('KDCE_S04_22PMP01_Machine.FA_RF') 
           AND DiscreteHistory.Value = 1  
           AND wwRetrievalMode = 'Cyclic' 
           AND wwResolution = 60000  
           AND DateTime >= @StartDate  
           AND DateTime <= @EndDate  
           AND DATEPART(dw, DateTime) NOT IN (2, 3, 4, 5, 6, 7)
       )

    SET @var2 = 
       ( 
       SELECT   
           'Count' = Count(DiscreteHistory.Value)/60.0  
       FROM  
           DiscreteHistory 
       WHERE  
           DiscreteHistory.TagName 
           IN ('KDCE_S04_22PMP01_Machine.FA_RF')  
           AND DiscreteHistory.Value = 1  
           AND wwRetrievalMode = 'Cyclic'  
           AND wwResolution = 60000  
           AND DateTime >= @StartDate  
           AND DateTime <= @EndDate  
           AND DATEPART(dw, DateTime) NOT IN (1, 2, 3, 4, 5, 6)
           AND (CAST(DateTime as time) >= '20:00:00' AND CAST(DateTime as time) < '07:00:00') 
       )

    SET @var3 = 
       ( 
       SELECT   
           'Count' = Count(DiscreteHistory.Value)/60.0  
       FROM   
           DiscreteHistory  
       WHERE 
           DiscreteHistory.TagName 
           IN ('KDCE_S04_22PMP01_Machine.FA_RF') 
           AND DiscreteHistory.Value = 1  
           AND wwRetrievalMode = 'Cyclic'  
           AND wwResolution = 60000  
           AND DateTime >= @StartDate  
           AND DateTime <= @EndDate  
           AND DATEPART(dw, DateTime) NOT IN (1, 2, 3, 4, 5, 6) 
           AND (CAST(DateTime as time) >= '12:00:00' AND CAST(DateTime as time) < '18:00:00') 
       )

    IF @var1 IS NULL SET @var1 = 0
    IF @var2 IS NULL SET @var2 = 0 
    IF @var3 IS NULL SET @var3 = 0 

    SELECT  
       'Count' = (Count(DiscreteHistory.Value)/60.0) + @var1 + @var2 + @var3  
    FROM  
       DiscreteHistory 
    WHERE  
       DiscreteHistory.TagName 
       IN ('KDCE_S04_22PMP01_Machine.FA_RF') 
       AND DiscreteHistory.Value = 1  
       AND wwRetrievalMode = 'Cyclic'
       AND wwResolution = 60000 
       AND DateTime >= @StartDate
       AND DateTime <= @EndDate
       AND DATEPART(dw, DateTime) NOT IN (1, 7)
       AND (CAST(DateTime as time) >= '22:00:00' OR CAST(DateTime as time) < '06:00:00');  

【讨论】:

    【解决方案2】:

    我不知道您是否还需要有关此主题的帮助,但我们实际上使用事件系统在泵未运行时触发并将记录插入到我们自己的表中。该表有一个触发器,可以将 0 和 1 扁平化为一条记录,从而更容易分析数据。我们数据库的示例记录如下所示:

    brake_start_time | brake_end_time | (downtime calculation) | (uptime before it broke) | reasons why it stopped working | comments
    

    使用类似的概念,您可以简单地拥有类似的东西

    pump_start_time | pump_end_time | runtime | run_category ( standard time, peak time and off-peak time )
    

    【讨论】:

    • 谢谢 EH_warch,我会看看我怎样才能做到这一点。它将显着减少代码。目前我只有来自现场的运行反馈(数字 1 或 0)。所以我必须找到一种方法来创建开始时间和停止时间,这不应该太难。异常处理可能会使它变得更复杂一些。即未检测到启动或未检测到停止时。
    猜你喜欢
    • 1970-01-01
    • 2018-03-02
    • 2014-05-22
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 2018-10-16
    相关资源
    最近更新 更多