/// <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> /// 保存设备曲线数据段。 /// </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> /// 将指定的曲线段数据转换为另一种点数的曲线段数据。 /// </summary> /// <param name="sourceCurvePoint">源数据的曲线点数,该参数为 0:00:00 至 23:59:59 完整的曲线数据点数。</param> /// <param name="sourceStartTimeNum">源数据第一个点的数值对应的时间。</param> /// <param name="sourceValues">源数据数组。</param> /// <param name="convertedInto">转换后的曲线点数。</param> /// <param name="mergeOption">当转换后的点数小于目前曲线点数时,如何合并目前的数据。</param> /// <param name="splitOption">当转换后的点数大于目前曲线点数时,如何拆分目前的数据。</param> /// <returns>转换后的曲线数据,该数组的长度等于 convertedInto 参数指定的点数。</returns> public static decimal?[] ConvertTo(CurvePointOptions sourceCurvePoint, int sourceStartTimeNum, decimal?[] sourceValues, CurvePointOptions convertedInto, CurveMergeOptions mergeOption, CurveSplitOptions splitOption) { if (sourceCurvePoint == convertedInto) { return(sourceValues); } else { sourceStartTimeNum = sourceCurvePoint.FormatTimeNum(sourceStartTimeNum); if (sourceValues == null && sourceValues.Length == 0) { throw new Exception("传入的 sourceValues 数据数组长度需要大于 0。"); } int intEndIndex = sourceCurvePoint.GetPointIndex(sourceStartTimeNum) + sourceValues.Length - 1; if (intEndIndex >= sourceCurvePoint.GetPointCount()) { throw new Exception("传入的 sourceValues 数据数组长度超出了一天的范围。"); } int sourceEndTimeNum = sourceCurvePoint.GetTimeNum(intEndIndex); int intIntoStartTimeNum = convertedInto.FormatTimeNum(sourceStartTimeNum); //转换后的开始时间 if (sourceCurvePoint > convertedInto) { if ((sourceCurvePoint.GetPointCount() % convertedInto.GetPointCount()) == 0) { int intIntoEndTimeNum = convertedInto.FormatTimeNum(sourceEndTimeNum); //转换后的结束时间 int intIntoPointCount = convertedInto.GetTimeSpanPoint(intIntoStartTimeNum, intIntoEndTimeNum) + 1; //转换后的数据点数 decimal?[] decValue = new decimal?[intIntoPointCount]; int intSourceIntoDiffPoint = sourceCurvePoint.GetTimeSpanPoint(intIntoStartTimeNum, sourceStartTimeNum); //源数据起始点与目标数据起始点相差的点数。 int intCurveMergeNum = sourceCurvePoint.GetPointCount() / convertedInto.GetPointCount(); //转换后数据的一个点对应源数据的几个点 for (int intIndex = 0; intIndex < decValue.Length; intIndex++) { AC.Base.Drives.CurveValue.ICurveMerge _CurveMerge = null; switch (mergeOption) { case CurveMergeOptions.Addition: _CurveMerge = new AC.Base.Drives.CurveValue.CurveMergeAddition(); break; case CurveMergeOptions.Average: _CurveMerge = new AC.Base.Drives.CurveValue.CurveMergeAverage(); break; case CurveMergeOptions.First: _CurveMerge = new AC.Base.Drives.CurveValue.CurveMergeFirst(); break; case CurveMergeOptions.Maximum: _CurveMerge = new AC.Base.Drives.CurveValue.CurveMergeMaximum(); break; case CurveMergeOptions.Minimum: _CurveMerge = new AC.Base.Drives.CurveValue.CurveMergeMinimum(); break; default: throw new Exception("无 " + mergeOption.ToString() + " 数据转换方法。"); } int intIntoTimeNum = convertedInto.GetTimeNum(intIntoStartTimeNum, intIndex); for (int intCurveMergeIndex = 0; intCurveMergeIndex < intCurveMergeNum; intCurveMergeIndex++) { int intSourceTimeNum = sourceCurvePoint.GetTimeNum(intIntoTimeNum, intCurveMergeIndex); if (sourceStartTimeNum <= intSourceTimeNum && intSourceTimeNum <= sourceEndTimeNum) { _CurveMerge.Value.Add(sourceValues[intIndex * intCurveMergeNum + intCurveMergeIndex - intSourceIntoDiffPoint]); } } decValue[intIndex] = _CurveMerge.GetValue(); } return(decValue); } else if (sourceCurvePoint == CurvePointOptions.Point144 && convertedInto == CurvePointOptions.Point96) { //将144点转为96点。先将144点转为288点,然后将288点转为96点。 decimal?[] decValue288 = ConvertTo(CurvePointOptions.Point144, sourceStartTimeNum, sourceValues, CurvePointOptions.Point288, mergeOption, splitOption); return(ConvertTo(CurvePointOptions.Point288, sourceStartTimeNum, decValue288, CurvePointOptions.Point96, mergeOption, splitOption)); } else { throw new Exception("尚不支持将 " + sourceCurvePoint.GetPointCount() + " 点数据转为 " + convertedInto.GetPointCount() + " 点数据。"); } } else { //sourceCurvePoint < convertedInto if ((convertedInto.GetPointCount() % sourceCurvePoint.GetPointCount()) == 0) { int intIntoEndTimeNum = convertedInto.GetTimeNum(sourceCurvePoint.GetTimeNum(sourceEndTimeNum, 1), -1); //转换后的结束时间。源时间加一个点的时间转成目标时间后,再计算目标时间减一个点的时间 int intIntoPointCount = convertedInto.GetTimeSpanPoint(intIntoStartTimeNum, intIntoEndTimeNum) + 1; //转换后的数据点数 decimal?[] decValue = new decimal?[intIntoPointCount]; int intCurveSplitNum = convertedInto.GetPointCount() / sourceCurvePoint.GetPointCount(); //源数据的一个点对应转换后数据的几个点 for (int intIndex = 0; intIndex < sourceValues.Length; intIndex++) { if (sourceValues[intIndex] != null) { for (int intCurveSplitIndex = 0; intCurveSplitIndex < intCurveSplitNum; intCurveSplitIndex++) { switch (splitOption) { case CurveSplitOptions.Division: decValue[intIndex * intCurveSplitNum + intCurveSplitIndex] = sourceValues[intIndex] / intCurveSplitNum; break; case CurveSplitOptions.Copy: decValue[intIndex * intCurveSplitNum + intCurveSplitIndex] = sourceValues[intIndex]; break; default: throw new Exception("无 " + splitOption.ToString() + " 数据转换方法。"); } } } } return(decValue); } else if (sourceCurvePoint == CurvePointOptions.Point96 && convertedInto == CurvePointOptions.Point144) { //将96点转为144点。先将96点转为288点,然后将288点转为144点。 decimal?[] decValue288 = ConvertTo(CurvePointOptions.Point96, sourceStartTimeNum, sourceValues, CurvePointOptions.Point288, mergeOption, splitOption); return(ConvertTo(CurvePointOptions.Point288, sourceStartTimeNum, decValue288, CurvePointOptions.Point144, mergeOption, splitOption)); } else { throw new Exception("尚不支持将 " + sourceCurvePoint.GetPointCount() + " 点数据转为 " + convertedInto.GetPointCount() + " 点数据。"); } } } }