/// <summary> /// 获取指定索引位置的时间。 /// </summary> /// <param name="curvePoint"></param> /// <param name="pointIndex">从 0 开始的曲线索引位置。</param> /// <returns>从 0:00:00 开始的格式为 hhmmss 6位整型时间。</returns> public static int GetTimeNum(this CurvePointOptions curvePoint, int pointIndex) { int intPointSecond = CurvePointOptions.Point86400.GetPointCount() / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(秒)。 int intSecond = intPointSecond * pointIndex; //该点所经历过的时间(秒) return((intSecond / 60 / 60) * 10000 + ((intSecond / 60) % 60) * 100 + (intSecond % 60)); }
/// <summary> /// 将当前的曲线数据转换为另一种点数的曲线数据。 /// </summary> /// <param name="convertedInto">转换后的曲线点数。</param> /// <param name="mergeOption">当转换后的点数小于目前曲线点数时,如何合并目前的数据。</param> /// <param name="splitOption">当转换后的点数大于目前曲线点数时,如何拆分目前的数据。</param> public void Convert(CurvePointOptions convertedInto, CurveMergeOptions mergeOption, CurveSplitOptions splitOption) { this.m_Values = ConvertTo(this.CurvePoint, this.StartTimeNum, this.Values, convertedInto, mergeOption, splitOption); this.m_CurvePoint = convertedInto; this.m_StartTimeNum = this.CurvePoint.FormatTimeNum(this.StartTimeNum); this.m_EndTimeNum = this.CurvePoint.FormatTimeNum(this.EndTimeNum); }
/// <summary> /// 查询一段日期的温度曲线数据,并确保该曲线具有指定的点数。 /// </summary> /// <param name="startDate">数据起始日期。</param> /// <param name="endDate">数据结束日期。</param> /// <param name="convertedInto">返回的曲线数据应具有的点数。转换方法可参见 AMS.Drives.CurveValue.ConvertTo</param> /// <returns>无论有无数据,返回的日温度曲线数组长度均为起始日期与结束日期所相差的天数,并且数组内的数据按照起始日期至结束日期的顺序排列。</returns> public TemperatureCurveValue[] GetData(DateTime startDate, DateTime endDate, CurvePointOptions convertedInto) { TimeSpan tsDay = endDate - startDate; if (tsDay.Days < 0) { throw new Exception("结束日期不得小于起始日期。"); } else { if (this.m_Reader == null || this.m_Reader.Contains(this.Device, startDate, endDate) == false) { new TemperatureCurveDataReader(this.Device, startDate, endDate, convertedInto); } TemperatureCurveValue[] values = new TemperatureCurveValue[tsDay.Days + 1]; for (int intIndex = 0; intIndex <= tsDay.Days; intIndex++) { values[intIndex] = this.m_Reader.GetData(this.Device, startDate.AddDays(intIndex)); } return(values); } }
/// <summary> /// 根据两个时间之间的点数计算该曲线的类型。 /// </summary> /// <param name="startTimeNum">起始时间。</param> /// <param name="endTimeNum">结束时间。</param> /// <param name="pointCount">两个时间之间的点数,该点数至少需要 ≥2</param> /// <returns></returns> public static CurvePointOptions GetCurvePoint(int startTimeNum, int endTimeNum, int pointCount) { if (pointCount < 2) { throw new Exception("两个时间之间的点数至少需要 ≥2"); } if (startTimeNum >= endTimeNum) { throw new Exception("开始时间不能大于等于结束时间。"); } int intStartSecond = (startTimeNum / 10000) * 3600 + ((startTimeNum / 100) % 100) * 60 + (startTimeNum % 100); int intEndSecond = (endTimeNum / 10000) * 3600 + ((endTimeNum / 100) % 100) * 60 + (endTimeNum % 100); int intPointSecond = (intEndSecond - intStartSecond) / (pointCount - 1); //每两个点之间的间隔(秒) foreach (int intEnumValue in Enum.GetValues(typeof(CurvePointOptions))) { CurvePointOptions _CurvePoint = (CurvePointOptions)intEnumValue; if (_CurvePoint.GetTimeSpan() == intPointSecond) { return(_CurvePoint); } } throw new Exception("未发现 " + ((startTimeNum / 10000) + ":" + ((startTimeNum / 100) % 100) + ":" + (startTimeNum % 100)) + " 至 " + ((endTimeNum / 10000) + ":" + ((endTimeNum / 100) % 100) + ":" + (endTimeNum % 100)) + " 之间有 " + pointCount + " 个点的曲线类型。"); }
/// <summary> /// 查询指定日期的温度曲线数据,并确保该曲线具有指定的点数。 /// </summary> /// <param name="date">数据日期。</param> /// <param name="convertedInto">返回的曲线数据应具有的点数。转换方法可参见 AMS.Drives.CurveValue.ConvertTo</param> /// <returns>无论该日有无数据,均返回 TemperatureCurveValue 的实例。</returns> public TemperatureCurveValue GetData(DateTime date, CurvePointOptions convertedInto) { if (this.m_Reader == null || this.m_Reader.Contains(this.Device, date, date) == false) { new TemperatureCurveDataReader(this.Device, date, date, convertedInto); } return(this.m_Reader.GetData(this.Device, date)); }
/// <summary> /// 获取曲线指定时间段的点数。 /// </summary> /// <param name="curvePoint">曲线点数。</param> /// <param name="startTimeNum">起始时间。</param> /// <param name="endTimeNum">结束时间。</param> /// <returns>两个时间之间的曲线点数,如果起始时间等于结束时间则返回1。</returns> public static int GetPointCount(this CurvePointOptions curvePoint, int startTimeNum, int endTimeNum) { if (startTimeNum > endTimeNum) { throw new Exception("开始时间不能大于结束时间。"); } else { return(curvePoint.GetPointIndex(endTimeNum) - curvePoint.GetPointIndex(startTimeNum) + 1); } }
/// <summary> /// 按设定周期运行的自动任务周期配置界面。 /// </summary> public CurvePointTaskPeriodConfig() { this.DropDownStyle = ComboBoxStyle.DropDownList; foreach (int intEnumValue in Enum.GetValues(typeof(CurvePointOptions))) { //if (intEnumValue < (int)CurvePointOptions.Point1440) { CurvePointOptions enumValue = (CurvePointOptions)intEnumValue; this.Items.Add(new CurvePointItem(enumValue)); } } }
/// <summary> /// 根据一个时间值判断该曲线最小的密度点是何种类型。例如 090000 返回 Point24;092500 返回 Point288;092530 返回 Point2880。 /// </summary> /// <param name="timeNum"></param> /// <returns></returns> public static CurvePointOptions GetCurvePoint(int timeNum) { foreach (int intCurvePoint in Enum.GetValues(typeof(CurvePointOptions))) { CurvePointOptions _CurvePoint = (CurvePointOptions)intCurvePoint; int intTimeNum = FormatTimeNum(_CurvePoint, timeNum); if (intTimeNum == timeNum) { return(_CurvePoint); } } return(CurvePointOptions.Point24); }
/// <summary> /// 保存设备日温度曲线数据段(非完整的曲线数据,曲线中的一个点或连续的几个点),如果数据点数大于96点,则每次保存时一次传入15分钟周期的全部数据,将获得最佳性能。(每月产生一张名为 TemperatureF 或 TemperatureS 的数据表) /// </summary> /// <param name="date">数据段中数据的起始日期及时间。使用其中的年、月、日、时、分、秒。。</param> /// <param name="curvePoint">该数据的点数类型。</param> /// <param name="values">日温度曲线数据段值,该数组仅存放曲线中的一部分数据。</param> /// <param name="save96Point">当 curvePoint 大于 96 点时是否另外计算一份96点的数据进行保存。当 curvePoint 小于等于 96 点时该参数无任何作用。</param> public void Save(DateTime date, CurvePointOptions curvePoint, decimal?[] values, CurvePartDataSave96PointOptions save96Point) { Database.DbConnection dbConn = this.Device.Application.GetDbConnection(); try { Save(dbConn, this.Device.DeviceId, date, curvePoint, values, save96Point); } catch (Exception ex) { throw ex; } finally { dbConn.Close(); } }
/// <summary> /// 开始将分秒曲线数据转换为指定的点数。 /// </summary> protected override void DoConvertS() { if (base.CurvePoint > 0) { CurvePointOptions _CurvePoint = (CurvePointOptions)base.CurvePoint; foreach (KeyValuePair <int, SortedList <int, HumidityCurveValue> > kvpDevice in this.m_Data) { foreach (KeyValuePair <int, HumidityCurveValue> kvpDateNum in kvpDevice.Value) { if (kvpDateNum.Value.CurvePoint != _CurvePoint) { kvpDateNum.Value.Convert(_CurvePoint); } } } } }
/// <summary> /// 获取曲线点数的文字说明。 /// </summary> /// <param name="curvePoint">曲线点数。</param> /// <returns>曲线点数的文字说明</returns> public static string GetDescription(this CurvePointOptions curvePoint) { switch (curvePoint) { case CurvePointOptions.Point6: return("4小时"); case CurvePointOptions.Point12: return("2小时"); case CurvePointOptions.Point24: return("1小时"); case CurvePointOptions.Point48: return("30分钟"); case CurvePointOptions.Point96: return("15分钟"); case CurvePointOptions.Point144: return("10分钟"); case CurvePointOptions.Point288: return("5分钟"); case CurvePointOptions.Point1440: return("1分钟"); case CurvePointOptions.Point2880: return("30秒钟"); case CurvePointOptions.Point5760: return("15秒钟"); case CurvePointOptions.Point17280: return("5秒钟"); case CurvePointOptions.Point86400: return("1秒钟"); default: throw new NotImplementedException("尚未实现该枚举。"); } }
/// <summary> /// 获取曲线的总点数。 /// </summary> /// <param name="curvePoint">曲线点数。</param> /// <returns>曲线总点数。</returns> public static int GetPointCount(this CurvePointOptions curvePoint) { switch (curvePoint) { case CurvePointOptions.Point6: return(6); case CurvePointOptions.Point12: return(12); case CurvePointOptions.Point24: return(24); case CurvePointOptions.Point48: return(48); case CurvePointOptions.Point96: return(96); case CurvePointOptions.Point144: return(144); case CurvePointOptions.Point288: return(288); case CurvePointOptions.Point1440: return(1440); case CurvePointOptions.Point2880: return(2880); case CurvePointOptions.Point5760: return(5760); case CurvePointOptions.Point17280: return(17280); case CurvePointOptions.Point86400: return(86400); default: throw new NotImplementedException("尚未实现该枚举。"); } }
/// <summary> /// 使用数据数组初始化一天从 0:00:00 至 23:59:59 之间多个数值组成的数值集合。 /// </summary> /// <param name="values">数据数组。数据数组的长度必须符合 CurvePointOptions 中定义的长度。</param> public CurveValue(decimal?[] values) { string strPoint = ""; foreach (int intEnumValue in Enum.GetValues(typeof(CurvePointOptions))) { CurvePointOptions curvePoint = (CurvePointOptions)intEnumValue; if (values.Length == curvePoint.GetPointCount()) { this.m_CurvePoint = curvePoint; this.m_Values = values; return; } strPoint += "、" + curvePoint.GetPointCount(); } throw new Exception("数据数组的长度必须等于 " + strPoint.Substring(1) + "。"); }
/// <summary> /// 一天曲线数据数值集合中的一部分数值。 /// </summary> /// <param name="curvePoint">曲线点数,该参数为 0:00:00 至 23:59:59 完整的曲线数据点数。</param> /// <param name="startTimeNum">第一个点的数值所对应的时间(hhmmss)。</param> /// <param name="values">曲线段各点数据。</param> public CurvePartValue(CurvePointOptions curvePoint, int startTimeNum, decimal?[] values) { if (values == null && values.Length == 0) { throw new Exception("传入的 values 数据数组长度需要大于 0。"); } this.m_CurvePoint = curvePoint; this.m_StartTimeNum = this.CurvePoint.FormatTimeNum(startTimeNum); int intEndIndex = this.CurvePoint.GetPointIndex(this.StartTimeNum) + values.Length - 1; if (intEndIndex >= curvePoint.GetPointCount()) { throw new Exception("传入的 values 数据数组长度超出了一天的范围。"); } this.m_Values = values; this.m_EndTimeNum = curvePoint.GetTimeNum(intEndIndex); }
/// <summary> /// 将时间转为对应数据点的准确时间,返回的时间年月日部分与参数 dateTime 一致。 /// </summary> /// <param name="curvePoint"></param> /// <param name="dateTime">日期时间</param> /// <returns>返回的时间值一定小于或等于传入的时间值。</returns> public static DateTime FormatDateTime(this CurvePointOptions curvePoint, DateTime dateTime) { if (curvePoint < CurvePointOptions.Point48) { int intPointHour = 24 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(小时)。 return(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, (dateTime.Hour / intPointHour) * intPointHour, 0, 0)); } else if (curvePoint < CurvePointOptions.Point2880) { int intPointMinute = 1440 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(分钟)。 return(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, (dateTime.Minute / intPointMinute) * intPointMinute, 0)); } else { int intPointSecond = 86400 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(秒)。 return(new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, (dateTime.Second / intPointSecond) * intPointSecond)); } }
/// <summary> /// 将时间转为对应数据点的准确时间。 /// </summary> /// <param name="curvePoint"></param> /// <param name="timeNum">整型时间(hhmmss)。</param> /// <returns>整型时间(hhmmss),返回的时间值一定小于或等于传入的时间值。</returns> public static int FormatTimeNum(this CurvePointOptions curvePoint, int timeNum) { if (curvePoint < CurvePointOptions.Point48) { int intPointHour = 24 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(小时)。 return(((timeNum / 10000) / intPointHour) * intPointHour * 10000); } else if (curvePoint < CurvePointOptions.Point2880) { int intPointMinute = 1440 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(分钟)。 return((timeNum / 10000) * 10000 + (((timeNum / 100) % 100) / intPointMinute) * intPointMinute * 100); } else { int intPointSecond = 86400 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(秒)。 return((timeNum / 10000) * 10000 + ((timeNum / 100) % 100) * 100 + ((timeNum % 100) / intPointSecond) * intPointSecond); } }
/// <summary> /// 获取指定时间的从 0 开始的曲线索引位置。 /// </summary> /// <param name="curvePoint"></param> /// <param name="timeNum">从 0:00:00 开始的格式为 hhmmss 6位整型时间。</param> /// <returns></returns> public static int GetPointIndex(this CurvePointOptions curvePoint, int timeNum) { if (curvePoint < CurvePointOptions.Point48) { int intPointHour = 24 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(小时)。 return((timeNum / 10000) / intPointHour); } else if (curvePoint < CurvePointOptions.Point2880) { int intPointMinute = 1440 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(分钟)。 int intHourPoint = 60 / intPointMinute; //一个小时有几个点 return((timeNum / 10000) * intHourPoint + ((timeNum / 100) % 100) / intPointMinute); } else { int intPointSecond = 86400 / curvePoint.GetPointCount(); //曲线上的一个点,对应多少长度的时间(秒)。 int intMinutePoint = 60 / intPointSecond; int intHourPoint = 3600 / intPointSecond; return((timeNum / 10000) * intHourPoint + ((timeNum / 100) % 100) * intMinutePoint + (timeNum % 100) / intPointSecond); } }
/// <summary> /// 保存设备日温度曲线数据段(非完整的曲线数据,曲线中的一个点或连续的几个点),如果数据点数大于96点,则在每小时的00分、15分、30分、45分时自动进行96点数据的计算。(每月产生一张名为 TemperatureF 或 TemperatureS 的数据表) /// </summary> /// <param name="dbConnection">活动的数据库连接。</param> /// <param name="deviceId">设备编号。</param> /// <param name="date">数据段中数据的起始日期及时间。使用其中的年、月、日、时、分、秒。。</param> /// <param name="curvePoint">该数据的点数类型。</param> /// <param name="values">日温度曲线数据段值,该数组仅存放曲线中的一部分数据。</param> public static void Save(Database.DbConnection dbConnection, int deviceId, DateTime date, CurvePointOptions curvePoint, decimal?[] values) { Save(dbConnection, deviceId, date, curvePoint, values, CurvePartDataSave96PointOptions.Auto); }
/// <summary> /// 查询指定日期的温度曲线数据中的一段数据,并确保该曲线具有指定的点数。 /// </summary> /// <param name="date">数据日期。</param> /// <param name="startTimeNum">曲线数据段的起始时间。</param> /// <param name="endTimeNum">曲线数据段的结束时间。</param> /// <param name="convertedInto">返回的曲线数据应具有的点数。转换方法可参见 AMS.Drives.CurveValue.ConvertTo</param> /// <returns>无论该日有无数据,均返回 TemperatureCurvePartValue 的实例。</returns> public TemperatureCurvePartValue GetPartData(DateTime date, int startTimeNum, int endTimeNum, CurvePointOptions convertedInto) { if (this.m_PartReader == null || this.m_PartReader.Contains(this.Device, date, date, startTimeNum, endTimeNum) == false) { new TemperatureCurvePartDataReader(this.Device, date, date, startTimeNum, endTimeNum, convertedInto); } return(this.m_PartReader.GetData(this.Device, date)); }
/// <summary> /// 保存设备曲线数据段。 /// </summary> /// <param name="tableTypeF">96及以下点数数据表类型声明。</param> /// <param name="tableNameF">96及以下点数数据表名。</param> /// <param name="tableTypeS">96以上点数数据表类型声明。</param> /// <param name="tableNameS">96以上点数数据表名。</param> /// <param name="mergeOption">当转换后的点数小于目前曲线点数时,如何合并目前的数据。</param> /// <param name="splitOption">当转换后的点数大于目前曲线点数时,如何拆分目前的数据。</param> /// <param name="dbConnection">活动的数据库连接。</param> /// <param name="deviceId">设备编号。</param> /// <param name="date">数据起始日期及时间。使用其中的年、月、日、时、分、秒。</param> /// <param name="curvePoint">该数据的点数类型。</param> /// <param name="values">曲线数据值,该数组长度必须是 CurvePointOptions 中指定的长度之一。</param> /// <param name="save96Point">当 curvePoint 大于 96 点时是否另外计算一份96点的数据进行保存。当 curvePoint 小于等于 96 点时该参数无任何作用。</param> /// <param name="keyColumns">该数据所属数据表的额外主键字段,及这些主键字段的数值。</param> public static void Save(Type tableTypeF, string tableNameF, Type tableTypeS, string tableNameS, CurveMergeOptions mergeOption, CurveSplitOptions splitOption, Database.DbConnection dbConnection, int deviceId, DateTime date, CurvePointOptions curvePoint, decimal?[] values, CurvePartDataSave96PointOptions save96Point, params KeyValuePair <string, string>[] keyColumns) { CurvePartValue _CurvePartValue = new CurvePartValue(curvePoint, date.Hour * 10000 + date.Minute * 100 + date.Second, values); string strSql; string strTableName; bool bolSave96 = true; //是否保存96点数据 if (_CurvePartValue.CurvePoint > CurvePointOptions.Point96) { //储存分秒数据表 strTableName = Database.DbConnection.GetMonthlyName(tableNameS, date.Year, date.Month); if (dbConnection.TableIsExist(strTableName) == false) { dbConnection.CreateTable(tableTypeS, strTableName); } string strWhere = ""; foreach (KeyValuePair <string, string> kvp in keyColumns) { strWhere += " AND " + kvp.Key + "=" + kvp.Value; } strSql = "Delete From " + strTableName + " Where DateNum=" + Function.ToIntDate(date) + " AND TimeNum>=" + _CurvePartValue.StartTimeNum + " AND TimeNum<=" + _CurvePartValue.EndTimeNum + " AND DeviceId=" + deviceId + strWhere; dbConnection.ExecuteNonQuery(strSql); string strValue = ""; string strColumn = ""; foreach (KeyValuePair <string, string> kvp in keyColumns) { strValue += "," + kvp.Value; strColumn += "," + kvp.Key; } for (int intIndex = 0; intIndex < _CurvePartValue.Values.Length; intIndex++) { try { strSql = Function.ToIntDate(date) + "," + _CurvePartValue.GetTimeNum(intIndex) + "," + deviceId + strValue + "," + Function.SqlDecimal(values[intIndex]); strSql = "INSERT INTO " + strTableName + " (DateNum,TimeNum,DeviceId" + strColumn + ",DataValue) VALUES (" + strSql + ")"; dbConnection.ExecuteNonQuery(strSql); } catch { } } if (save96Point == CurvePartDataSave96PointOptions.No) { bolSave96 = false; } else if (save96Point == CurvePartDataSave96PointOptions.Auto) { if (curvePoint == CurvePointOptions.Point144) { if (values.Length <= 3) { if (((_CurvePartValue.EndTimeNum / 100) % 100) != 20 && ((_CurvePartValue.EndTimeNum / 100) % 100) != 50) { bolSave96 = false; } } } else { if (values.Length <= (curvePoint.GetPointCount() / CurvePointOptions.Point96.GetPointCount())) { if (curvePoint.GetTimeNum(_CurvePartValue.EndTimeNum, 1) != CurvePointOptions.Point96.GetTimeNum(_CurvePartValue.EndTimeNum, 1)) { bolSave96 = false; } } } } if (bolSave96) { int intStartTimeNum96 = CurvePointOptions.Point96.FormatTimeNum(_CurvePartValue.StartTimeNum); if (curvePoint == CurvePointOptions.Point144) { if (((_CurvePartValue.StartTimeNum / 100) % 100) == 20) { intStartTimeNum96 = (intStartTimeNum96 / 10000) * 10000; } else if (((_CurvePartValue.StartTimeNum / 100) % 100) == 50) { intStartTimeNum96 = (intStartTimeNum96 / 10000) * 10000 + 3000; } } if (intStartTimeNum96 < _CurvePartValue.StartTimeNum) { //如果数据的起始时间不是每小时的00分、15分、30分、45分,则从数据库取出该一刻钟缺少的数据。 CurvePartValue _CurvePartValueTemp = new CurvePartValue(curvePoint, intStartTimeNum96, _CurvePartValue.EndTimeNum); for (int intIndex = 0; intIndex < _CurvePartValue.Values.Length; intIndex++) { _CurvePartValueTemp.SetValue(_CurvePartValue.GetTimeNum(intIndex), _CurvePartValue.Values[intIndex]); } strSql = "SELECT * FROM " + strTableName + " WHERE DateNum=" + Function.ToIntDate(date) + " AND TimeNum>=" + intStartTimeNum96 + " AND TimeNum<" + _CurvePartValue.StartTimeNum + " AND DeviceId=" + deviceId + strWhere; System.Data.IDataReader dr = dbConnection.ExecuteReader(strSql); while (dr.Read()) { _CurvePartValueTemp.SetValue(Function.ToInt(dr["TimeNum"]), Function.ToDecimal(dr["DataValue"])); } dr.Close(); //转换为96点数据 _CurvePartValueTemp.Convert(CurvePointOptions.Point96, mergeOption, splitOption); _CurvePartValue = _CurvePartValueTemp; } } } if (bolSave96) { //96点数据储存 strTableName = Database.DbConnection.GetMonthlyName(tableNameF, date.Year, date.Month); if (dbConnection.TableIsExist(strTableName) == false) { dbConnection.CreateTable(tableTypeF, strTableName); } if (_CurvePartValue.CurvePoint > CurvePointOptions.Point96) { _CurvePartValue.Convert(CurvePointOptions.Point96, mergeOption, splitOption); } try { string strValue = ""; string strColumn = ""; foreach (KeyValuePair <string, string> kvp in keyColumns) { strValue += "," + kvp.Value; strColumn += "," + kvp.Key; } string strColumnValues = ""; string strColumnNames = ""; for (int intIndex = 0; intIndex < _CurvePartValue.Values.Length; intIndex++) { strColumnValues += "," + Function.SqlDecimal(_CurvePartValue.Values[intIndex]); strColumnNames += ",Value" + ((_CurvePartValue.GetPointIndex(intIndex) * (96 / _CurvePartValue.CurvePoint.GetPointCount())) + 1); } strSql = Function.ToIntDate(date) + "," + deviceId + strValue + strColumnValues; strSql = "INSERT INTO " + strTableName + " (DateNum,DeviceId" + strColumn + strColumnNames + ") VALUES (" + strSql + ")"; dbConnection.ExecuteNonQuery(strSql); } catch { string strWhere = ""; foreach (KeyValuePair <string, string> kvp in keyColumns) { strWhere += " AND " + kvp.Key + "=" + kvp.Value; } string strColumns = ""; for (int intIndex = 0; intIndex < _CurvePartValue.Values.Length; intIndex++) { strColumns += ",Value" + ((_CurvePartValue.GetPointIndex(intIndex) * (96 / _CurvePartValue.CurvePoint.GetPointCount())) + 1) + "=" + Function.SqlDecimal(_CurvePartValue.Values[intIndex]); } strSql = "UPDATE " + strTableName + " Set " + strColumns.Substring(1) + " Where DateNum=" + Function.ToIntDate(date) + " AND DeviceId=" + deviceId + strWhere; dbConnection.ExecuteNonQuery(strSql); } } }
/// <summary> /// 处理数据库中读取到的96点曲线数据。 /// </summary> /// <param name="device">该数据相关的设备。</param> /// <param name="dr"></param> /// <param name="curvePoint">曲线点数。</param> /// <param name="values">经计算转换过的数据值集合。</param> protected abstract void DoDataReaderF(Device device, System.Data.IDataReader dr, CurvePointOptions curvePoint, decimal?[] values);
/// <summary> /// 从保存此任务周期数据的 XML 文档节点初始化当前任务。 /// </summary> /// <param name="taskConfig">该对象节点的数据</param> public override void SetTaskPeriodConfig(System.Xml.XmlNode taskConfig) { this.CurvePoint = (Drives.CurvePointOptions)Function.ToInt(taskConfig.InnerText); }
/// <summary> /// 各相位的曲线段值。 /// </summary> /// <param name="phase">曲线数据的相位。</param> /// <param name="curvePoint">曲线点数,该参数为 0:00:00 至 23:59:59 完整的曲线数据点数。</param> /// <param name="startTimeNum">第一个点的数值所对应的时间(hhmmss)。</param> /// <param name="values">曲线段各点数据。</param> public PhaseCurvePartValue(PhaseOptions phase, CurvePointOptions curvePoint, int startTimeNum, decimal?[] values) : base(curvePoint, startTimeNum, values) { this.Phase = phase; }
/// <summary> /// 各相位的曲线段值。 /// </summary> /// <param name="phase">曲线数据的相位。</param> /// <param name="curvePoint">曲线点数,该参数为 0:00:00 至 23:59:59 完整的曲线数据点数。</param> /// <param name="startTimeNum">第一个点的数值所对应的时间(hhmmss)。</param> /// <param name="endTimeNum">最后一个点的数值所对应的时间(hhmmss)。</param> public PhaseCurvePartValue(PhaseOptions phase, CurvePointOptions curvePoint, int startTimeNum, int endTimeNum) : base(curvePoint, startTimeNum, endTimeNum) { this.Phase = phase; }
/// <summary> /// 将当前的温度曲线数据转换为另一种点数的温度曲线数据。 /// </summary> /// <param name="convertedInto">转换后的曲线点数。</param> public void Convert(CurvePointOptions convertedInto) { base.Convert(convertedInto, CurveMergeOptions.Addition, CurveSplitOptions.Division); }
/// <summary> /// 日温度曲线段值。 /// </summary> /// <param name="device">该数据所属的设备。</param> /// <param name="date">该数据的日期。</param> /// <param name="curvePoint">曲线点数,该参数为 0:00:00 至 23:59:59 完整的曲线数据点数。</param> /// <param name="startTimeNum">第一个点的数值所对应的时间(hhmmss)。</param> /// <param name="values">曲线段各点数据。</param> public TemperatureCurvePartValue(Device device, DateTime date, CurvePointOptions curvePoint, int startTimeNum, decimal?[] values) : base(curvePoint, startTimeNum, values) { this.m_Device = device; this.m_Date = date; }
/// <summary> /// 日温度曲线值。 /// </summary> /// <param name="device">该数据所属的设备。</param> /// <param name="date">该数据的日期。</param> /// <param name="curvePoint">该曲线的点数。</param> public TemperatureCurveValue(Device device, DateTime date, CurvePointOptions curvePoint) : base(curvePoint) { this.m_Device = device; this.m_Date = date; }
/// <summary> /// 保存设备日温度曲线数据段(非完整的曲线数据,曲线中的一个点或连续的几个点),如果数据点数大于96点,则每次保存时一次传入15分钟周期的全部数据,将获得最佳性能。(每月产生一张名为 TemperatureF 或 TemperatureS 的数据表) /// </summary> /// <param name="dbConnection">活动的数据库连接。</param> /// <param name="deviceId">设备编号。</param> /// <param name="date">数据段中数据的起始日期及时间。使用其中的年、月、日、时、分、秒。</param> /// <param name="curvePoint">该数据的点数类型。</param> /// <param name="values">日温度曲线数据段值,该数组仅存放曲线中的一部分数据。</param> /// <param name="save96Point">当 curvePoint 大于 96 点时是否另外计算一份96点的数据进行保存。当 curvePoint 小于等于 96 点时该参数无任何作用。</param> public static void Save(Database.DbConnection dbConnection, int deviceId, DateTime date, CurvePointOptions curvePoint, decimal?[] values, CurvePartDataSave96PointOptions save96Point) { DeviceCurvePartDataReader.Save(typeof(TemperatureF), TemperatureF.TableName, typeof(TemperatureS), TemperatureS.TableName, CurveMergeOptions.Average, CurveSplitOptions.Copy, dbConnection, deviceId, date, curvePoint, values, save96Point, new KeyValuePair <string, string>[] { }); }
/// <summary> /// 日温度曲线段值。 /// </summary> /// <param name="device">该数据所属的设备。</param> /// <param name="date">该数据的日期。</param> /// <param name="curvePoint">曲线点数,该参数为 0:00:00 至 23:59:59 完整的曲线数据点数。</param> /// <param name="startTimeNum">第一个点的数值所对应的时间(hhmmss)。</param> /// <param name="endTimeNum">最后一个点的数值所对应的时间(hhmmss)。</param> public TemperatureCurvePartValue(Device device, DateTime date, CurvePointOptions curvePoint, int startTimeNum, int endTimeNum) : base(curvePoint, startTimeNum, endTimeNum) { this.m_Device = device; this.m_Date = date; }
/// <summary> /// 设备曲线数据读取器。 /// </summary> /// <param name="device">设备集合中的第一次访问的设备对象。</param> /// <param name="startDate">访问数据的起始日期,如果未设置过 DateRange 日期范围则以该日期作为数据筛选的起始日期。</param> /// <param name="endDate">访问数据的结束日期,如果未设置过 DateRange 日期范围则以该日期作为数据筛选的结束日期。</param> /// <param name="startTimeNum">曲线数据段的起始时间。</param> /// <param name="endTimeNum">曲线数据段的结束时间。</param> /// <param name="curvePoint">是否将曲线数据强制转换为指定的点数。如果该值为 0 则表示不转换,设备曲线数据点数使用各设备的默认值。</param> /// <param name="mergeOption">当转换后的点数小于目前曲线点数时,如何合并目前的数据。</param> /// <param name="splitOption">当转换后的点数大于目前曲线点数时,如何拆分目前的数据。</param> /// <param name="tableNameF">96及以下点数数据表名。</param> /// <param name="selectColumnNameF">96及以下点数数据表需要额外输出的字段,如无额外字段可传 null。</param> /// <param name="tableNameS">96以上点数数据表名。</param> public DeviceCurvePartDataReader(Device device, DateTime startDate, DateTime endDate, int startTimeNum, int endTimeNum, int curvePoint, CurveMergeOptions mergeOption, CurveSplitOptions splitOption, string tableNameF, string selectColumnNameF, string tableNameS) { this.m_CurvePoint = curvePoint; this.m_FirstDevice = device; this.StartTimeNum = startTimeNum; this.EndTimeNum = endTimeNum; if (device.DateRange != null && device.DateRange.ContainsDay(startDate, endDate)) { this.m_DateRange = device.DateRange; } else { this.m_DateRange = new DateRange(startDate, endDate); } string strDeviceIdWhereF = ""; string strDeviceIdWhereS = ""; if (device.Source != null && device.Source.Contains(device)) { foreach (Device device1 in device.Source) { CurvePointOptions _CurvePoint = this.GetDeviceCurvePoint(device1); if (_CurvePoint <= CurvePointOptions.Point96 || (curvePoint > 0 && curvePoint < (int)CurvePointOptions.Point96)) { strDeviceIdWhereF += "," + device1.DeviceId; } else { strDeviceIdWhereS += "," + device1.DeviceId; } if (device1.DateRange == null || device1.DateRange.UniqueId != this.m_DateRange.UniqueId) { device1.DateRange = this.m_DateRange; } this.SetReader(device1); } if (strDeviceIdWhereF.Length > 0) { strDeviceIdWhereF = " IN (" + strDeviceIdWhereF.Substring(1) + ")"; } if (strDeviceIdWhereS.Length > 0) { strDeviceIdWhereS = " IN (" + strDeviceIdWhereS.Substring(1) + ")"; } } else { CurvePointOptions _CurvePoint = this.GetDeviceCurvePoint(device); if (_CurvePoint <= CurvePointOptions.Point96 || (curvePoint > 0 && curvePoint < (int)CurvePointOptions.Point96)) { strDeviceIdWhereF = "=" + device.DeviceId; } else { strDeviceIdWhereS = "=" + device.DeviceId; } if (device.DateRange == null || device.DateRange.UniqueId != this.m_DateRange.UniqueId) { device.DateRange = this.m_DateRange; } this.SetReader(device); } AC.Base.Database.DbConnection dbConn = device.Application.GetDbConnection(); if (dbConn != null) { try { int intStartPointF = CurvePointOptions.Point96.GetPointIndex(startTimeNum) + 1; int intEndPointF = CurvePointOptions.Point96.GetPointIndex(endTimeNum) + 1; string strSelectF = "DateNum,DeviceId" + (selectColumnNameF != null && selectColumnNameF.Length > 0 ? "," + selectColumnNameF : ""); for (int intPointIndex = intStartPointF; intPointIndex <= intEndPointF; intPointIndex++) { strSelectF += ",Value" + intPointIndex; } foreach (DateRange.MonthlyForDayRange range in this.DateRange.GetMonthRanges()) { if (strDeviceIdWhereF.Length > 0) { string strTableName = Database.DbConnection.GetMonthlyName(tableNameF, range.Date.Year, range.Date.Month); if (dbConn.TableIsExist(strTableName)) { string strSqlDate = range.GetSqlWhere("DateNum"); if (strSqlDate.Length > 0) { strSqlDate = " AND " + strSqlDate; } string strSql = "SELECT " + strSelectF + " FROM " + strTableName + " WHERE DeviceId" + strDeviceIdWhereF + strSqlDate; System.Data.IDataReader dr = dbConn.ExecuteReader(strSql); while (dr.Read()) { Device deviceF = this.GetDevice(Function.ToInt(dr["DeviceId"])); CurvePointOptions _DeviceCurvePointF = this.GetDeviceCurvePoint(deviceF); if (_DeviceCurvePointF > CurvePointOptions.Point96) { _DeviceCurvePointF = CurvePointOptions.Point96; //如果设备默认的曲线数据点数大于96点,则使用96点数据。 } decimal?[] decValues = new decimal?[_DeviceCurvePointF.GetPointCount(startTimeNum, endTimeNum)]; int intPointIndex = 0; for (int intIndex = intStartPointF; intIndex <= intEndPointF; intIndex++) { if (((intIndex - 1) % (96 / _DeviceCurvePointF.GetPointCount())) == 0) { decValues[intPointIndex++] = Function.ToDecimalNull(dr["Value" + intIndex]); } } if (curvePoint != 0 && curvePoint != (int)_DeviceCurvePointF) { //需要对曲线数据进行转换 decValues = CurvePartValue.ConvertTo(_DeviceCurvePointF, this.StartTimeNum, decValues, (CurvePointOptions)curvePoint, mergeOption, splitOption); _DeviceCurvePointF = (CurvePointOptions)curvePoint; } this.DoDataReaderF(deviceF, dr, _DeviceCurvePointF, decValues); } dr.Close(); } } if (strDeviceIdWhereS.Length > 0) { string strTableName = Database.DbConnection.GetMonthlyName(tableNameS, range.Date.Year, range.Date.Month); if (dbConn.TableIsExist(strTableName)) { string strSqlDate = range.GetSqlWhere("DateNum"); if (strSqlDate.Length > 0) { strSqlDate = " AND " + strSqlDate; } strSqlDate += " AND TimeNum>=" + startTimeNum + " AND TimeNum<=" + endTimeNum; string strSql = "SELECT * FROM " + strTableName + " WHERE DeviceId" + strDeviceIdWhereS + strSqlDate; System.Data.IDataReader dr = dbConn.ExecuteReader(strSql); while (dr.Read()) { this.DoDataReaderS(this.GetDevice(Function.ToInt(dr["DeviceId"])), dr); } dr.Close(); } } } } catch (Exception ex) { throw ex; } finally { dbConn.Close(); } if (curvePoint > 0 && strDeviceIdWhereS.Length > 0) { //通知继承的曲线读取器转换分秒数据点数。 this.DoConvertS(); } } }