1.使用svg实现组态画面和动态数据展示
通过js的定时器调用webservice方法获取数据后更新节点数据
/// <summary>启动定时刷新</summary> function Start() { InitSvgElement(); this.timer = setInterval("GetTagValues()", 1000); } /// <summary>启动定时刷新</summary> function Stop() { clearInterval(this.timer); }
初始化svg的节点变量
/// <summary>初始化SVG元素</summary> function InitSvgElement() { this.svgDoc = document.getElementById('svgDoc').getSVGDocument(); this.svgRoot = this.svgDoc.documentElement; this.svg_jzwd = this.svgDoc.getElementById("tspan-jzwd"); this.svg_jzyl = this.svgDoc.getElementById("tspan-jzyl"); this.svg_czyl = this.svgDoc.getElementById("tspan-czyl"); this.svg_czwd = this.svgDoc.getElementById("tspan-czwd"); this.svg_yl = this.svgDoc.getElementById("tspan-yl"); this.svg_wd = this.svgDoc.getElementById("tspan-wd"); this.svg_yll = this.svgDoc.getElementById("rect-ylg"); }
通过ajax访问webservice
/// <summary>获取测点数据</summary> function GetTagValues() { try { $.ajax({ type: "POST", url: "../PsWebService.asmx/GetTagValues", data: { ip: ip, port: port, tagNames: tags }, dataType: 'xml', error: function (request) { alert("调用webService异常"); }, success: function (msg) { var tagValueJSON = $(msg).find("string").text(); UpdateTagLables(tagValueJSON); } }); } catch (e) { alert(e.Message); } }
更新节点变量的值
/// <summary>更新标签数据</summary> function UpdateTagLables(valueJSON) { var tagValueArray = eval('(' + valueJSON + ')'); if (tagValueArray.length != 6) { // alert("数据长度不足,请按照顺序设置测点!" + tagValueArray.length); return; } else { this.SetElementValue(this.svg_jzwd, tagValueArray[0].Value, " ℃"); this.SetElementValue(this.svg_jzyl, tagValueArray[1].Value, " MPa"); this.SetElementValue(this.svg_czwd, tagValueArray[2].Value, " ℃"); this.SetElementValue(this.svg_czyl, tagValueArray[3].Value, " MPa"); this.SetElementValue(this.svg_wd, tagValueArray[4].Value, " ℃"); this.SetElementValue(this.svg_yl, tagValueArray[5].Value, " MPa"); var yl = (tagValueArray[5].Value / 1000) * 68; //当前值除以量程(1000)得到百分比,然后乘以压力计的最大宽度得出实际应该显示的高度 yl = CurrencyFormatted(yl); this.svg_yll.setAttributeNS(null, "width", yl); } } /// <summary>设置元素值,数据进行格式化保留两位小数</summary> function SetElementValue(element, value, unit) { var newValue = CurrencyFormatted(value); if ($.browser.msie&&$.browser.version=="8.0") { //IE 下的写法 element.getFirstChild().setNodeValue(newValue + unit); } if ($.browser.msie && $.browser.version == "9.0") { //IE 下的写法 element.firstChild.textContent = newValue + unit; } if ($.browser.msie && $.browser.version == "10.0") { //IE 下的写法 element.firstChild.textContent = newValue + unit; } if ($.browser.chrome) { //Chrome下的写法 element.firstChild.textContent = newValue + unit; } else { element.firstChild.textContent = newValue + unit; } }
2.webservice方法调用pSpace的sdk类库获取数据
[WebMethod] public string GetTagValues(string ip, string port, string tagNames) { try { //\TestTag\mnl_1 List<PsPointValue> list = new List<PsPointValue>(); PsApi api = new PsApi(); api.Init(ip, port, "admin", "admin888"); if (api.Conn()) { PsPointValue ps = new PsPointValue(); string[] tagNameArray = tagNames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); list = api.GetDataSnapshot(tagNameArray); api.DisConn(); } return JsonConvert.SerializeObject(list); } catch (Exception ex) { return ex.Message; } }
/// <summary> /// pSpaceCTL.NET.dll 的接口服务封装 /// </summary> public class PsApi : IDisposable { #region 属性 /// <summary> /// IP地址 /// </summary> public string IP { get; set; } /// <summary> /// 是否空闲 /// </summary> public bool IsFree { get; set; } /// <summary> /// 数据库连接信息 /// </summary> public DbConnector Dbconn { get; private set; } /// <summary> /// 测点树 /// </summary> public TagTree TagTree { get; private set; } /// <summary> /// 根节点 /// </summary> public TagNode RootNode { get; private set; } /// <summary> /// 测点管理类 /// </summary> public TagManager TagManager { get; private set; } /// <summary> /// 实时数据变更订阅器类 /// </summary> public RealSubscriber RealDataSubScriber { get; private set; } /// <summary> /// 最后的异常 /// </summary> public PsApiException LastError { get; private set; } #endregion #region 事件 public event Action<PsApiException> OnPsApiException; #endregion #region Init() /// <summary> /// 初始化PsServer连接属性 /// 注:从app.config文件读取PsServerIP、PsServerPort、PsServerUser、PsServerUserPwd 属性 /// </summary> public void Init() { string ip = ConfigurationManager.AppSettings["PsServerIP"]; string port = ConfigurationManager.AppSettings["PsServerPort"]; string user = ConfigurationManager.AppSettings["PsServerUser"]; string pwd = ConfigurationManager.AppSettings["PsServerUserPwd"]; this.Init(ip, port, user, pwd); } /// <summary> /// 初始化PsServer连接属性 /// </summary> /// <param name="ip">PsServer 地址</param> /// <param name="port">PsServer 端口</param> /// <param name="user">用户名</param> /// <param name="userPwd">密码</param> public void Init(string ip, string port, string user, string userPwd) { if (ip.Trim().Equals("")) throw new ArgumentException("参数不能为空", "ip", null); if (port.Trim().Equals("")) throw new ArgumentException("参数不能为空", "port", null); if (user.Trim().Equals("")) throw new ArgumentException("参数不能为空", "user", null); if (userPwd.Trim().Equals("")) throw new ArgumentException("参数不能为空", "userPwd", null); this.IP = ip; this.Dbconn = new DbConnector(); this.Dbconn.UserName = user; this.Dbconn.Password = userPwd; this.Dbconn.ServerName = ip + ":" + port; } #endregion #region Conn() and DisConn() /// <summary> /// 连接psServer /// </summary> /// <returns>True:成功,False:失败</returns> public bool Conn() { try { Common.StartAPI(); if (this.Dbconn.IsConnected()) this.Dbconn.Disconnect(); this.Dbconn.CanReconnect = false; //不自动重连 DbError dbError = this.Dbconn.Connect(); if (dbError.HasErrors) { this.LastError = new PsApiException(dbError.ErrorMessage + "(" + this.Dbconn.ServerName + ")", null); return false; } else { this.TagTree = TagTree.CreateInstance(this.Dbconn); this.RootNode = this.TagTree.GetTreeRoot(); this.RealDataSubScriber = new RealSubscriber(); return true; } } catch (Exception ex) { this.LastError = new PsApiException("连接psServer失败", ex); return false; } } /// <summary> /// 是否已经连接 /// </summary> /// <returns></returns> public bool IsConnected() { return this.Dbconn.IsConnected(); } /// <summary> /// 断开连接 /// </summary> /// <returns> /// True:成功,False:失败 /// </returns> public bool DisConn() { if (this.Dbconn.IsConnected()) { try { this.Dbconn.Disconnect(); Common.StopAPI(); return true; } catch (Exception) { return false; } } return true; } #endregion #region GetAllTags() /// <summary> /// 获取所有节点 /// </summary> public List<PsPointInfo> GetAllTags() { if (this.RootNode == null) throw new Exception("根节点未实例化"); TagVector tagList = this.RootNode.GetSubTags(true);//从根节点获取所有子节点 List<PsPointInfo> pointList = new List<PsPointInfo>(); for (int i = 0; i < tagList.Count; i++) { TagNode node = tagList[i] as TagNode; if (node == null) continue; PsPointInfo info = new PsPointInfo() { TagId = node.TagId, ParentTagId = (uint)node.Properties["ParentId"], Unit = node.Properties.ContainsKey("EngineeringUnit") ? node.Properties["EngineeringUnit"].ToString() : "", Name = node.TagName, LongName = node.TagLongName, Desc = node.Properties["Description"].ToString(), IsNode = (bool)node.Properties["IsNode"] }; pointList.Add(info); } return pointList; } /// <summary> /// 获取所有测点 /// </summary> /// <param name="parentTagLongName">上级节点."0"或""表示根节点</param> /// <param name="allLevel"></param> /// <returns></returns> public TagVector GetSubTags(string parentTagLongName, bool allLevel) { if (this.RootNode == null) throw new Exception("根节点未实例化"); TagVector tagList = null; if (parentTagLongName == "0" || parentTagLongName == "") tagList = this.RootNode.GetSubTags(allLevel);//从根节点获取所有子节点 else { TagNode parentTag = this.RootNode.SelectSingleNode(parentTagLongName + "@LongName") as TagNode; if (parentTag != null) tagList = parentTag.GetSubTags(allLevel);//从根节点获取所有子节点 } return tagList; } /// <summary> /// 根据测点标识获取测点 /// </summary> /// <param name="tagIdsLongList">测点标识列表, 测点要大于uint.MinValu,小于 uint.MaxValue</param> /// <returns></returns> public TagVector GetTags(List<long> tagIdsLongList) { List<uint> tagIdsIntList = new List<uint>(); foreach (long tagIds in tagIdsLongList) { if (tagIds >= uint.MinValue && tagIds <= uint.MaxValue) { tagIdsIntList.Add((uint)tagIds); } } List<PropField> list = new List<PropField>(); TagManager tmg = new TagManager(this.TagTree);//测点管理器 return tmg.GetTagListById(tagIdsIntList, list); } /// <summary> /// 获取节点列表 /// </summary> /// <param name="tagLongName"></param> /// <returns></returns> public List<ITag> GetTags(List<string> tagLongName) { List<ITag> list = new List<ITag>(); foreach (string tagName in tagLongName) { ITag tag = this.RootNode.SelectSingleNode(tagName + "@LongName"); if (tag != null) list.Add(tag); } return list; } /// <summary> /// 根据测点标识获取测点 /// </summary> /// <param name="tagId"></param> /// <returns></returns> public ITag GetTag(uint tagId) { TagManager tmg = new TagManager(this.TagTree);//测点管理器 List<PropField> list = new List<PropField>(); PropField aa = new PropField(); // AnalogTagElement tag=this.TagTree.CreateTag<AnalogTagElement>(""); AnalogTagElement tag = tmg.GetTagById(tagId, list) as AnalogTagElement; AnalogTagElement tag2 = tmg.GetTagById(tagId, tag.TagType.PropFields) as AnalogTagElement; return tag; } /// <summary> /// 判断节点是否存在 /// </summary> /// <param name="tagLongName">节点长名</param> /// <returns></returns> public bool ExistTagNode(string tagLongName) { return this.RootNode.SelectSingleNode(tagLongName + "@LongName") is TagNode; } /// <summary> /// 判断节点是否存在 /// </summary> /// <param name="tagLongName">节点长名</param> /// <returns></returns> public bool FindNode(string tagLongName) { ITag tag = this.RootNode.SelectSingleNode(tagLongName + "@LongName"); //AnalogTagElement aa = tag as AnalogTagElement; DigitalTagElement aa = tag as DigitalTagElement; StringBuilder sb = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); for (int i = 0; i < aa.TagType.PropFields.Count; i++) { pSpaceCTLNET.PropField pro = aa.TagType.PropFields[i]; sb.AppendFormat("PropId:{0} PropDesc:{1} PropName:{2} ReadOnly:{3} DataType:{4}", pro.PropId, pro.PropDesc, pro.PropName, pro.ReadOnly, pro.DataType); sb.AppendLine(); } for (int i = 0; i < aa.TagType.PropFields.Count; i++) { pSpaceCTLNET.PropField pro = aa.TagType.PropFields[i]; // sb2.AppendFormat("dic.Add(\"{0}\", this.{0}); //{1}",pro.PropName,pro.DataType); sb2.AppendLine(" /// <summary>"); sb2.AppendFormat(" /// {0}", pro.PropDesc); sb2.AppendLine(); sb2.AppendLine(" /// </summary>"); sb2.AppendFormat(" public {0} {1};", pro.DataType, pro.PropName); sb2.AppendLine(); sb2.AppendLine(); } string str2 = sb2.ToString(); string str = sb.ToString(); return true; } #endregion #region Ps6服务器数据点操作 #region 添加根节点 /// <summary> /// 创建或查询节点 /// 如果 /// </summary> /// <param name="parentTagID">父节点长名,为空时创建根节点</param> /// <param name="tagName">长名</param> /// <param name="desc">长名描述</param> /// <returns>0:创建失败 大于0:创建成功,为TagId</returns> public TagNode CreateOrFindTagNode(uint parentTagID, string tagName, string desc) { try { TagNode tagNode = null; if (parentTagID == 0) { tagNode = this.RootNode.SelectSingleNode(tagName + "@LongName") as TagNode; if (tagNode != null) return tagNode; tagNode = this.TagTree.CreateTag<TagNode>(tagName); tagNode.Properties["Description"] = desc; if (this.RootNode.AppendChild(tagNode) == 0) return tagNode; else return null; } else { TagManager tmg = new TagManager(this.TagTree);//测点管理器 List<PropField> list = new List<PropField>(); TagNode parentTag = tmg.GetTagById(parentTagID, list) as TagNode; if (parentTag == null) throw new ArgumentException("父节点不存在", parentTagID.ToString()); tagNode = this.TagTree.CreateTag<TagNode>(tagName); tagNode.Properties["Description"] = desc; if (tmg.AddTag(parentTag, tagNode) == 0) return tagNode; else return null; } } catch (Exception ex) { throw new Exception("CreateOrFindTagNode Exception", ex); } } /// <summary> /// 创建数据点 /// </summary> /// <param name="parentTagName"></param> /// <param name="tagType"></param> /// <param name="tagName"></param> /// <param name="attributes"></param> /// <returns></returns> public ITag CreateTag(TagNode parentTag, string tagType, string tagName, Dictionary<string, object> attributes) { try { string longTagName = parentTag == null ? tagName : parentTag.TagLongName + "\\" + tagName; if (parentTag == null) parentTag = this.RootNode; longTagName = longTagName.Replace("/", ""); ITag newTag = null; ITag oldTag = null; if (tagType == "psAnalog") { oldTag = this.RootNode.SelectSingleNode(longTagName + "@LongName") as AnalogTagElement; if (oldTag == null) newTag = this.TagTree.CreateTag<AnalogTagElement>(tagName); } else if (tagType == "psDigital") { oldTag = this.RootNode.SelectSingleNode(longTagName + "@LongName") as DigitalTagElement; if (oldTag == null) newTag = this.TagTree.CreateTag<DigitalTagElement>(tagName); } else if (tagType == "psStringType") { oldTag = this.RootNode.SelectSingleNode(longTagName + "@LongName") as StringTagElement; if (oldTag == null) newTag = this.TagTree.CreateTag<StringTagElement>(tagName); } if (oldTag == null) { foreach (string key in attributes.Keys) { newTag[key] = attributes[key]; } TagManager tmg = new TagManager(this.TagTree); if (tmg.AddTag(parentTag, newTag) == 0) { newTag = tmg.GetTagById(newTag.TagId, newTag.TagType.PropFields); //添加成功后接着查询 } } else { TagManager tmg = new TagManager(this.TagTree); newTag = tmg.GetTagById(oldTag.TagId, oldTag.TagType.PropFields); //添加成功后接着查询 } return newTag; } catch (Exception ex) { throw new Exception("CreateTag Error:" + ex.Message); } } /// <summary> /// 设置测点属性 /// </summary> /// <param name="parentTag"></param> /// <param name="tagType"></param> /// <param name="tagID"></param> /// <param name="tagName"></param> /// <param name="attributes"></param> /// <returns></returns> public ITag SetTagProperties(string tagType, uint tagID, string tagName, Dictionary<string, object> attributes) { try { TagManager tmg = this.TagTree.GetMgr(); ITag newTag = null; List<PropField> list = new List<PropField>(); if (tmg.IsTagExist(tagID)) { ITag tag = tmg.GetTagById(tagID, list); tag.TagName = tagName; if (tagType == "psAnalog") newTag = this.TagTree.CreateTag<AnalogTagElement>(tagName); else if (tagType == "psDigital") newTag = this.TagTree.CreateTag<DigitalTagElement>(tagName); else if (tagType == "psStringType") newTag = this.TagTree.CreateTag<StringTagElement>(tagName); foreach (string key in attributes.Keys) { tag[key] = attributes[key]; } tmg.SetTagProperties(tag, newTag.TagType.PropFields); newTag = tmg.GetTagById(tagID, newTag.TagType.PropFields); } return newTag; } catch (Exception ex) { throw new Exception("设置测点属性失败:" + ex.Message); } } /// <summary> /// 删除测点 /// </summary> /// <param name="tagID">测点标识</param> /// <returns>成功时返回0,失败时返回-1</returns> public int RemoveTag(uint tagID) { try { TagManager tmg = this.TagTree.GetMgr(); List<PropField> list = new List<PropField>(); if (tmg.IsTagExist(tagID)) { ITag tag = tmg.GetTagById(tagID, list); return tmg.RemoveTag(tag); } return -1; } catch (Exception ex) { throw new Exception("CreateTag Error:" + ex.Message); } } #endregion #region 添加模拟量测点 #endregion #region 添加开关量测点 /// <summary> /// 向服务器添加一个开关量测点 /// </summary> /// <param name="psTagPointInfo">测点参数类</param> /// <returns></returns> public bool AddDigitalTag(PsTagPointInfo psTagPointInfo) { DigitalTagElement digitalTag = new DigitalTagElement(); TagNode test_Tag = this.RootNode.SelectSingleNode(psTagPointInfo.ParentTagName + "@LongName") as TagNode; if (test_Tag == null) throw new Exception("根节点不存在"); try { // 创建一个开关量测点 digitalTag = this.TagTree.CreateTag<DigitalTagElement>(psTagPointInfo.TagName); digitalTag["His_IsSave"] = psTagPointInfo.His_IsSave;//是否保存历史 digitalTag["EnableAlarm"] = psTagPointInfo.EnableAlarm;//是否报警 } catch (DbException ex) { throw new Exception("创建模拟量测点失败!" + ex.Message); } TagManager tmg = new TagManager(this.TagTree);//测点管理器 int result = tmg.AddTag(test_Tag, digitalTag);//向服务器添加一个测点 if (result == 0) return true; else if (result == -1) throw new Exception("测点已存在!"); return true; } #endregion #region 根据指定测点,删除节点及其子节点 /// <summary> /// 根据指定测点,删除节点及其子节点 /// </summary> /// <param name="tagName"></param> /// <returns></returns> public bool DeleteTagPoint(string tagName) { TagNode test_Tag = this.RootNode.SelectSingleNode(tagName + "@LongName") as TagNode; if (test_Tag == null) throw new Exception("根节点不存在"); int result = test_Tag.RemoveTag(test_Tag); //从服务器删除指定测点或节点,当前删除根节点及其子节点 if (result == 0) return true; else throw new Exception("删除测点失败!"); } #endregion #region 修改测点属性 /// <summary> /// 修改测点的属性 /// </summary> /// <param name="psTagPointInfo">测点信息</param> /// <returns></returns> public bool updateTagProperties(PsTagPointInfo psTagPointInfo) { AnalogTagElement analogTag = new AnalogTagElement(); TagNode test_Tag = this.RootNode.SelectSingleNode(psTagPointInfo.ParentTagName + "@LongName") as TagNode; if (test_Tag == null) throw new Exception("根节点不存在"); test_Tag.Properties["PV_Quality"] = QUALITY_MASK.GOOD;//质量戳 192 =Good test_Tag.Properties["His_IsSave"] = psTagPointInfo.His_IsSave;//是否保存历史 test_Tag.Properties["His_CompressMode"] = psTagPointInfo.His_CompressMode; // 旋转门压缩 test_Tag.Properties["His_IsCompressRatePercentage"] = psTagPointInfo.His_IsCompressRatePercentage; // 是否使用百分比 test_Tag.Properties["His_CompressRate"] = psTagPointInfo.His_CompressRate; // 压缩率为10% test_Tag.Properties["EnableAlarm"] = psTagPointInfo.EnableAlarm;//是否报警 test_Tag.Properties["RangeMinimum"] = psTagPointInfo.RangeMinimum; // 量程下限 test_Tag.Properties["RangeMaximum"] = psTagPointInfo.RangeMaximum; // 量程上限 test_Tag.Properties["Desc"] = psTagPointInfo.Desc; //描述 //更新测点所有属性 int t = test_Tag.Update(); if (t == 0) return true; else return false; } #endregion #region 根据点长名获取实时值 /// <summary> /// 根据点长名获取实时值 /// </summary> /// <param name="longTagName">点长名</param> /// <returns></returns> public PsPointValue GetDataSnapshot(string longTagName) { ITag tag = this.RootNode.SelectSingleNode(longTagName + "@LongName") as ITag; if (tag == null) return null; RealHisData data = DataIO.Snapshot(this.Dbconn, tag as ITagElement); return new PsPointValue() { Time = data.TimeStamp, Value = (short)(char)data.Value }; } /// <summary> /// 根据点长名获取实时值 /// </summary> /// <param name="longTagName">点长名</param> /// <returns></returns> public List<PsPointValue> GetDataSnapshot(string[] tagLongNameArray) { List<PsPointValue> psPointValueList = new List<PsPointValue>(); TagVector vector = new TagVector(); for (int i = 0; i < tagLongNameArray.Length; i++) { ITag tag = this.RootNode.SelectSingleNode(tagLongNameArray[i] + "@LongName") as ITag; if (tag == null) throw new ArgumentException(string.Format("测点{0}不存在", tagLongNameArray[i])); vector.Add(tag); } RealDataSet ds = new RealDataSet(); BatchResults data = DataIO.Snapshot(this.Dbconn, vector, ds); for (int i = 0; i < ds.Count; i++) { psPointValueList.Add(new PsPointValue() { TagName = tagLongNameArray[i], Time = ds[i].TimeStamp, Value = ds[i].Value.ToString() }); } return psPointValueList; } #endregion #region 根据点长名获取历史值 /// <summary> /// 读历史值 返回String类型值 /// </summary> public string ReadRawData(string longTagName, DateTime StartTime, DateTime EndTime) { DateTime[] times = new DateTime[] { StartTime, EndTime }; string result = ""; ITag tag = this.RootNode.SelectSingleNode(longTagName + "@LongName") as ITag; if (tag != null) { //添加模拟点 TagVector tagVector = new TagVector(); //模拟测点集合 tagVector.Add(tag); HisDataSet hisDataSet = new HisDataSet(); //批量操作的结果集类 BatchResults batchResults = DataIO.ReadRaw(this.Dbconn, tagVector, StartTime, EndTime, hisDataSet); //插入历史数据 int totalCount = 0; foreach (TagHisValues val in hisDataSet) { for (int i = 0; i < val.Data.Count; i++) { string timeStamp = val.Data[i].TimeStamp.ToString(); object value = val.Data[i].Value != null ? val.Data[i].Value : "0"; result += "TimeStamp:" + timeStamp + ",Value:" + value + ";"; } //计数 totalCount += val.Data.Count; } result = string.Format("结果:{0}, 共{1}条记录,用时:{2}秒,历史值:{3}", !batchResults.HasErrors, totalCount, (EndTime - StartTime).TotalMilliseconds.ToString(), result); } return result; } /// <summary> /// 获取历史值 返回Dictionary /// </summary> /// <param name="longTagName"></param> /// <param name="StartTime"></param> /// <param name="EndTime"></param> /// <returns></returns> public Dictionary<DateTime, string> ReadRawData1(string longTagName, DateTime StartTime, DateTime EndTime) { Dictionary<DateTime, string> dic = new Dictionary<DateTime, string>(); DateTime[] times = new DateTime[] { StartTime, EndTime }; string result = ""; ITag tag = this.RootNode.SelectSingleNode(longTagName + "@LongName") as ITag; if (tag != null) { //添加模拟点 TagVector tagVector = new TagVector(); //模拟测点集合 tagVector.Add(tag); HisDataSet hisDataSet = new HisDataSet(); //批量操作的结果集类 BatchResults batchResults = DataIO.ReadRaw(this.Dbconn, tagVector, StartTime, EndTime, hisDataSet); //插入历史数据 int totalCount = 0; foreach (TagHisValues val in hisDataSet) { for (int i = 0; i < val.Data.Count; i++) { DateTime timeStamp = val.Data[i].TimeStamp; object value = val.Data[i].Value != null ? val.Data[i].Value : "0"; string value1 = Convert.ToString(value); result += "TimeStamp:" + timeStamp + ",Value:" + value + ";"; dic.Add(timeStamp, value.ToString()); } //计数 totalCount += val.Data.Count; } result = string.Format("结果:{0}, 共{1}条记录,用时:{2}秒,历史值:{3}", !batchResults.HasErrors, totalCount, (EndTime - StartTime).TotalMilliseconds.ToString(), result); } return dic; } #endregion #endregion #region 报警事件管理 #region 获取实时报警数据 /// <summary> /// 获取实时报警数据 /// </summary> /// <param name="tagName"></param> /// <returns></returns> public AlarmDataSet GetRealAlarmData(string tagId, string alarmTopic, string alarmLevel, bool isNoAck) { //实例化报警类 DbAlarmIO dbAlarmIo = new DbAlarmIO(); //实例化报警过滤器 DbAlarmFilter alarmfilters = new DbAlarmFilter(); AlarmDataSet alarmDataSet = new AlarmDataSet(); uint uTagId = 0; if (uint.TryParse(tagId, out uTagId)) alarmfilters.TagId = uTagId; uint uAlarmTopic = 0; if (uint.TryParse(alarmTopic, out uAlarmTopic)) alarmfilters.AlarmTopic = (DbAlarmTopicEnum)uAlarmTopic; byte bAlarmLevel = 0; if (byte.TryParse(alarmLevel, out bAlarmLevel)) { alarmfilters.AlarmLowLevel = bAlarmLevel; alarmfilters.AlarmHighLevel = bAlarmLevel; } if (isNoAck) alarmfilters.bAlarmHaveAcked = false; //填充报警集合 dbAlarmIo.Alarm_Real_Query(this.Dbconn, alarmfilters, alarmDataSet); return alarmDataSet; } /// <summary> /// 获取实时报警数据 /// </summary> /// <param name="tagName"></param> /// <returns></returns> public AlarmDataSet GetRealAlarmData() { //实例化报警类 DbAlarmIO dbAlarmIo = new DbAlarmIO(); //实例化报警过滤器 DbAlarmFilter alarmfilters = new DbAlarmFilter(); AlarmDataSet alarmDataSet = new AlarmDataSet(); //填充报警集合 dbAlarmIo.Alarm_Real_Query(this.Dbconn, alarmfilters, alarmDataSet); return alarmDataSet; } #endregion #region 获取历史报警数据 /// <summary> /// 获取历史报警数据 /// </summary> /// <param name="longTagName">点长名</param> /// <param name="startTime">开始时间</param> /// <param name="endTime">结束时间</param> /// <returns></returns> public AlarmDataSet GetHisAlarmData(DateTime startTime, DateTime endTime, string tagId, string alarmTopic, string alarmLevel, bool isNoAck) { //实例化报警类 DbAlarmIO dbAlarmIo = new DbAlarmIO(); //实例化报警过滤器 DbAlarmFilter alarmfilters = new DbAlarmFilter(); AlarmDataSet alarmDataSet = new AlarmDataSet(); uint uTagId = 0; if (uint.TryParse(tagId, out uTagId)) alarmfilters.TagId = uTagId; uint uAlarmTopic = 0; if (uint.TryParse(alarmTopic, out uAlarmTopic)) alarmfilters.AlarmTopic = (DbAlarmTopicEnum)uAlarmTopic; byte bAlarmLevel = 0; if (byte.TryParse(alarmLevel, out bAlarmLevel)) { alarmfilters.AlarmLowLevel = bAlarmLevel; alarmfilters.AlarmHighLevel = bAlarmLevel; } if (isNoAck) alarmfilters.bAlarmHaveAcked = false; //填充报警集合 dbAlarmIo.Alarm_His_Query(this.Dbconn, alarmfilters, startTime, endTime, alarmDataSet); return alarmDataSet; } #endregion #region 报警实时订阅 /// <summary> /// 实时报警订阅 /// </summary> public string RealSubScriber() { //初始化事件结束的通知 AutoResetEvent realSubscriber_evt = new AutoResetEvent(false); //实时数据订阅器类 RealSubscriber realSubscriber = new RealSubscriber(); //将方法加入线程 ThreadPool.QueueUserWorkItem(new WaitCallback(TestRealView), realSubscriber_evt); return "123"; } /// <summary> /// 实时报警订阅 /// </summary> /// <param name="state"></param> public void TestRealView(object state) { } /// <summary> /// 实时报警订阅 /// </summary> /// <param name="state"></param> public void TestRealView2(object state, string l) { //实时报警变更订阅器类 RealSubscriber realSubScriber = new RealSubscriber(); //测点树 TagTree tagTree = TagTree.CreateInstance(this.Dbconn); //获得根节点 TagNode root = tagTree.GetTreeRoot(); //点表 TagVector vector = new TagVector(); //向点表添加测点 vector.Add(root); //实时数据集 RealDataSet realData = new RealDataSet(); //根据点表创建订阅器 realSubScriber.CreateAndRead(this.Dbconn, vector, realData); //创建检测测点是否变化的事件 realSubScriber.RealDataChanged += new RealDataChangedEventHandler(realSubscriber_RealDataChanged); //测点有变化时通知 realSubScriber.Enabled = true; //通知等待线程 AutoResetEvent evt = (AutoResetEvent)state; //等待接收信号 evt.WaitOne(); //关闭订阅器 realSubScriber.Close(); } #endregion #endregion #region 实时数据订阅 /// <summary> /// 启动实时数据的订阅 /// </summary> /// <param name="tagLongNameList"></param> public void StartRealDataSubScriber(List<string> tagLongNameList) { //点表 TagVector vector = new TagVector(); List<ITag> list = this.GetTags(tagLongNameList); list.ForEach(q => vector.Add(q)); //实时数据集 RealDataSet realData = new RealDataSet(); //根据点表创建订阅器 this.RealDataSubScriber.CreateAndRead(this.Dbconn, vector, realData); //创建检测测点是否变化的事件 this.RealDataSubScriber.RealDataChanged += new RealDataChangedEventHandler(realSubscriber_RealDataChanged); } /// <summary> /// 停止实时数据的订阅 /// </summary> public void EndRealDataSubScriber() { this.RealDataSubScriber.RealDataChanged -= realSubscriber_RealDataChanged; this.RealDataSubScriber.Close(); } /// <summary> /// 订阅报警事件 /// </summary> /// <param name="sender"></param> /// <param name="dataset"></param> public void realSubscriber_RealDataChanged(object sender, RealDataSet dataset) { StringBuilder sb = new StringBuilder(); foreach (TagValue val in dataset) { sb.Append(val.TagId); sb.Append(":("); sb.Append(val.Value.ToString()); sb.Append(","); sb.Append(val.TimeStamp.ToString()); sb.Append(","); sb.Append(val.QualityStamp.ToString()); sb.Append(")|"); } //String.Format("检测到 {0}条实时值变化。{1}", dataset.Count, sb.ToString()); } #endregion #region IDisposable 成员 public void Dispose() { throw new NotImplementedException(); } #endregion }
如果是winform程序使用iocomp控件库实现组态界面比较方便。web程序中也可以使用html 5 去做,但电力、工业上使用svg的方案比较多。