您的当前位置:首页正文

智能电表管理系统

2024-10-18 来源:威能网
姓 名 专 业 班 级 论 文 名 称 指 导 教 师

目录

摘要 ............................................................................ 1矚慫润厲钐瘗睞枥庑赖。 一、选题背景 .................................................................. 2聞創沟燴鐺險爱氇谴净。 1.1课题概述 .....................................................................2残骛楼諍锩瀨濟溆塹籟。 1.2技术背景 .....................................................................2酽锕极額閉镇桧猪訣锥。 二、用户需求分析.......................................................... 7彈贸摄尔霁毙攬砖卤庑。 2.1技术需求 .....................................................................7謀荞抟箧飆鐸怼类蒋薔。 2.2功能需求 .....................................................................7厦礴恳蹒骈時盡继價骚。 三、概要设计 .................................................................. 8茕桢广鳓鯡选块网羈泪。 3.1系统的构成 .................................................................8鹅娅尽損鹌惨歷茏鴛賴。 3.2系统的主要功能及特点 .............................................9籟丛妈羥为贍偾蛏练淨。 四、详细设计 ................................................................ 10預頌圣鉉儐歲龈讶骅籴。 4.1数据库设计 ...............................................................10渗釤呛俨匀谔鱉调硯錦。 4.2系统界面设计 ...........................................................14铙誅卧泻噦圣骋贶頂廡。 4.3系统程序设计 ...........................................................27擁締凤袜备訊顎轮烂蔷。 五、关键技术 ................................................................ 52贓熱俣阃歲匱阊邺镓騷。 5.1构造合适的16进制通信数据 .................................52坛摶乡囂忏蒌鍥铃氈淚。 5.2串口通信发送16进制数据实现 .............................55蜡變黲癟報伥铉锚鈰赘。 5.3串口通信接收硬件返回的16进制数据的实现 .....56買鲷鴯譖昙膚遙闫撷凄。 5.4分析硬件返回数据转换为用户可读数据 ...............57綾镝鯛駕櫬鹕踪韦辚糴。 六、安装与使用说明 ................................................... 60驅踬髏彦浃绥譎饴憂锦。 6.1安装说明 ...................................................................60猫虿驢绘燈鮒诛髅貺庑。 6.2使用说明 ...................................................................60锹籁饗迳琐筆襖鸥娅薔。 6.3注意事项 ...................................................................60構氽頑黉碩饨荠龈话骛。 七、致谢 ........................................................................ 62輒峄陽檉簖疖網儂號泶。 八、参考资料.......................................................... 63尧侧閆繭絳闕绚勵蜆贅。

摘要

智能电表管理系统是为了在物业管理中对用电状况进行智能化管理的解决方案,使得电能的管理更加简洁、人性化和自动化。目前企业宿舍、公寓用电管理是其中重要的一个环节,同时随着电力系统及其相关产业的发展以及电能管理系统的不断完善,且伴随着计算机技术、通信技术、网络技术和控制技术的交叉和综合发展,人们进入了高度发达的信息时代。本系统就是结合这些发展中的优势资源而融合出来的产品,可以让使用者更方便快捷的享受高科技所提供的服务。智能电表管理系统主要有计算机、智能电表、数据库、服务器等各部分组成,对各个楼栋的电表实行用电管理,此管理系统可以高效快捷的完成任务,省去了传统普通电表需要定期派专人上门抄表催收电费等耗时费力的工作。系统采用C#语言在Microsoft Visual Studio 2005集成开发平台上进行编程开发,并使用微软的SQL Server 2005数据库存储数据以提高数据的安全性,系统使用了SerialPort控件组织十六进制数据实现了串口通信功能。系统共包含四项主要功能,一、包括数据库管理功能,系统采用的数据库设计科学合理,字段命名规范,键值设置合理,易于后期的维护和管理;二、具有用户信息管理功能,可以进行(1)操作员信息管理,编辑用户使用权限.(2)电表信息管理,可以查看并修改住宅小区的用户电表信息.(3)楼栋信息管理,可以查看并修改小区内楼栋的名称及楼层数量.(4)用户用电记录查询,可以多条件查询用户的用电信息;三、系统同时具有串口通信功能,可以完成(1)显示当前正向有功总电能.(2)查询电表地址.(3)通断电控制;四、系统还具有权限管理功能,任何越权操作都将被拒绝,当用户具有较高使用权限时才可以使用系统中的较多功能,例如”admin”用户可以更改系统中其他操作员的使用权限,提高系统管理的质量与效率。识饒鎂錕缢灩筧嚌俨淒。

关键字:智能电表管理系统;C#;Visual Studio 2005;SQL Server 2005

第1页

一、选题背景

1.1课题概述

物业系统是一个庞大的管理体系,企业宿舍、公寓用电管理是其中重要的一个环节,企业宿舍、公寓内偷电、漏电、超负荷用电等现象一直是困扰物业管理的普遍问题;近几年随着经济的飞速发展,企业宿舍、公寓内电脑以及各种电器逐渐的普及,导致用电量与日俱增,以往的单一照明用电已不能满足日常需求,同时企业宿舍、公寓电费开支日益增多,各单位也不时出现用电安全问题。凍鈹鋨劳臘锴痫婦胫籴。 目前在社区、公寓使用的智能电表管理系统主要是能符合当今各大单位物业关于对公寓用电管理改革的所有需求,并彻底解决以往偷电、漏电、管理混乱等诸多问题。基本实现了自助购电、用电科学收费、安全管理等多项功能。恥諤銪灭萦欢煬鞏鹜錦。 由此可见,智能电表管理系统将是物业用电管理发展的必然趋势。传统普通电表需要定期派专人上门抄表催收电费,工作量大,给公寓供电集中管理带来很多的不便。例如需要将众多的电表集中安放到一个专门的房间要占很大的空间,此外,其工程的复杂性及后续结构、电器的配置等费用也比较昂贵,同时仍需派专人催收电费。鯊腎鑰诎褳鉀沩懼統庫。 鉴于以上有原因我们有必要开发出一种帮助物业管理人员管理智能电表的软件系统,可以完成的功能包括:

(1)发送串口通信数据操作硬件。 (2)读取硬件接口返回的数据。

(3)读取数据库,将信息显示至操作界面。 (4)对用户的用电额度进行多条件选择查询。

(5)对操作员编辑完成的数据,准确的写入数据库。 (6)对使用电表系统的用户进行权限管理。

本系统主要使用C#语言在Microsoft Visual Studio 2005集成开发平台上编程实现,智能电表系统的业务数据主要由SQL Server 2005数据库存储以保证其安全性,系统的总体界面尽量具有美观性、人性化、简洁性,由系统维护的数据库在操作过程中也尽量做到安全可靠。

硕癘鄴颃诌攆檸攜驤蔹。 1.2技术背景

伴随着电力系统及其相关产业的发展以及电能管理系统的不断完善,电能表的结构和性能也经历了不断更新、优化的发展过程:由最初的感应电能表,发展到后来的感应系脉冲电能表,直到现在的纯电子式电能表。阌擻輳嬪諫迁择楨秘騖。 随着计算机技术、通信技术、网络技术和控制技术的交叉和综合发展,人们进入了高度发达的信息时代。现代化的电能管理模式,需要访问电能表的很多信息,同时决策还要与电能表进行双向通讯。由于数字型电能表是以微处理器为核心,所以功能容易扩展,容易和配电自动化系统集成,所以数字型电能表有取代传统感应式电表的趋势。氬嚕躑竄贸恳彈瀘颔澩。 (1) 电能表的历史及发展趋势

作为测量电能的专用仪表电能表,自诞生至今已经有一百多年的历史。随着电力系统及

第2页

其相关产业的发展以及电能管理系统的不断完善,电能表的结构和性能也经历了不断更新、优化的发展过程:最初的感应电能表,发展到后来的感应脉冲电能表,直至现在的纯电子式电能表。感应式电能表是利用处于交变磁场的金属圆盘中的感应电流与有关磁场形成力的原理制成的。感应脉冲电能表仍然采用感应式电能表的测量机构作为工作元件,有光电传感器完成电能脉冲转换,然后经电子电路对脉冲进行处理,从而实现对电能的测量。纯电子式电能表的原理是采用电子电路对脉冲进行处理,从而实现对电能的测量。纯电子式电能表的原理是采用电子电路来实现电能计量,所以电子式电能表的共同特点是采用乘法器,更具所依托的乘法器为模拟的还是数字的可分为模拟乘法器型电子电能表和数字乘法器型电子电能表。釷鹆資贏車贖孙滅獅赘。 感应式电能表已经完成它的历史使命。因为感应式电能表有着无法克服的缺陷。首先,机械磨损是感应式电能表无法克服的缺陷,磨损的后果是表越走越慢。其次,偷窃电现象严重:感应式电能表由于电流、电压接线端子外露,很容易采用改接线或倒表手段进行偷窃电,这是包括我国在内的发展中国家普遍存在的严重问题。再次,抄表方式单一落后:感应式电能表采用的是人工登门手工抄表,抄表人员要走家串户上楼、下楼,这种原始的查表方法不仅造成了人力、物力的浪费,而且在查表时会打扰居民的正常生活,甚至给居民带来安全隐患,这与现代化用电管理极不适应。怂阐譜鯪迳導嘯畫長凉。 未来电能表有以下几个发展趋势: 1.电子式电能表全面替代感应表

电子式电能表之所以能取代感应表而成为市场的宠儿,有诸多的优势:(1)可靠性:精度长时间不变、无须轮校、无安装、运输影响等;(2)准确度:宽量程、宽功率因数、启动灵敏、防潜可靠等;(3)功能:可实行集中抄表、多费率、预付费、防窃电、多功能等;(4)性价比:性价比高、可预留扩展功能、受原材料涨价影响小等。谚辞調担鈧谄动禪泻類。 2. 液晶显示器加速替代字轮计度器

液晶显示器之所以能获得越来越多的客户的认可,主要是因为:(1)液晶显示器的可靠性和寿命得到行业的普遍认可;(2)液晶显示器能显示更多信息(汉子提示、多排显示等);(3)集中抄表数据和人工读表数据的一致性要求;(4)液晶显示器功耗低,可以停电时显示;(5)液晶显示器在黑暗中还可以采用背光显示。嘰觐詿缧铴嗫偽純铪锩。 3.防窃电要求进一步加强

随着窃电方式的更加多样化和隐蔽化,对电能表防窃电的要求也越来越高,机械表对此已越来越力不从心,电子式电能表则表现出强大的优势。目前窃电的主要方式有:干扰计量元件,更改接线方式,打开表盖更改为内部线路或数据等。熒绐譏钲鏌觶鷹緇機库。 4.具有通信接口尤其是RS485接口成为趋势

随着抄表到户的逐步实施以及电力部门的体制改革,自动抄表成为用户强烈的需求,因此越来越多地要求电表配备通信接口。电表配备RS485接口具有成熟和性价比的优势,适合未来采用更新、更好的通信技术,因此成为用户目前较为理想的选择而逐步成为标准配置。

鶼渍螻偉阅劍鲰腎邏蘞。 (2)抄表方式的现状及其特点

目前,国内抄表方式有人工抄表、有线远程抄表、无线远程抄表。

人工抄表模式有产品生产和运行成本低的优点,但是也有很难以克服的缺点: ①由于人为因素的存在,抄表质量难以保证。

②不利于大批量数据处理,需要人工输入和校验,增加电力部门人员编制。

第3页

③入户抄表难度大,而且需要抄表人员爬楼,增加抄表人员的工作量。

无线抄表模式是指采用无线通信方式来实现远程抄表的方式。主要有以下两种实现方式:

一种方式是大功率无线传输,利用固有的无线服务运营商的网络:如GSM、GPRS、CDMA网等实现远程抄表,该方式使用范围广,通信成功率高,无需额外申请频段。纣忧蔣氳頑莶驅藥悯骛。 另一种方式是手持无线超标装置或车载无线抄表装置,属于小功率无线传输,这种方式必须首先向有关部门申请频段,且信号只能在一定的范围内有效,抄表范围较小如一个生活小区。颖刍莖蛺饽亿顿裊赔泷。 用无线自动抄表技术,不仅能节约人力资源,更重要的是可提高抄表的准确性、实时性,使管理部门能即时准确获得数据信息。但是,无线抄表技术投入巨大,在短时间难以取得明显的经济效益。濫驂膽閉驟羥闈詔寢賻。 有线抄表模式可以分为以下几类: 1.基于有线电视宽带的自动抄表

它是将用户的用电数据通过特殊的电视信号,将之转换为能在有线网上传输的信号,然后进行解调,达到信息通信的目的。但在硬件实现上存在较大难度、可行性差,有待理论和技术上进一步的突破。銚銻縵哜鳗鸿锓謎諏涼。 2.基于电力载波的远程抄表

基于电力线载波的远程抄表技术以低压电力线为通信媒介,用户终端的用电数据与集中器之间的通信通过电力线载波技术来完成。挤貼綬电麥结鈺贖哓类。 3.基于总线技术的远程抄表

①基于RS485总线技术的远程抄表

用户的电能表通过总线与集中器连接,一个小区安装一个或多个集中器进行数据采集,数据采集一次性抄读成功率及可靠性较高。赔荊紳谘侖驟辽輩袜錈。 ②基于LONWORKS技术的远程抄表

LONWORKS网络是通过一种或多种通信媒体相互连接的智能化设备或节点构成的,具有开放的技术标准、较好的互换性及可构造性和优良的可靠性。这种抄表方式的核心是芯片Neuron,通过该芯片来完成数据的采集、处理以及与上位机的通信等等。塤礙籟馐决穩賽釙冊庫。 (3)软件系统架构C#语言

C#是一种精确、简单、类型安全、面向对象的语言。说到C#,就不得不先得简单介绍一下.net。到底什么是.net呢:按照微软的定义为:.net代表一个集合,一个环境,它可以作为平台支持下一代Internet的可编程结构。C#是.net的代表语言。裊樣祕廬廂颤谚鍘羋蔺。 1.首先,它完全支持面向对象。

2.支持分布式,之所以有C#是因为微软相信分布式应用程序是未来的趋势,即处理过程分布在客户机和服务器上。所以C#一出生就注定了能很好解决分布式问题。仓嫗盤紲嘱珑詁鍬齊驁。 3.跟Java类似,C#代码经过编译后,成为了一种IL(中间语言)。在运行时,再把IL编译为平台专用的代码。绽萬璉轆娛閬蛏鬮绾瀧。 4.健壮,C#在检查程序错误和编译与运行时错误一点也不逊于Java,C#也用了自动管理内存机制。

5.C#不像Java那样完全摒弃了指针和手动内存管理。C#默认情况下是不能使用指针的,

第4页

程序员在有必要时可以打开指针来使用。这样可以保证编程的灵活性。骁顾燁鶚巯瀆蕪領鲡赙。 6.安全性:C#的安全性是由.net平台来提供的。C#代码编译后成为IL语言。是一种受控代码,.net提供类型安全检查等机制保证代码是安全的。瑣钋濺暧惲锟缟馭篩凉。 7.可移植性:由于C#使用类似Java的中间语言机制。使得C#也跟Java类似,可以很方便的移植到其他系统。在运行时,再把中间代码编译为合适特定机器的代码。鎦诗涇艳损楼紲鯗餳類。 8.解释性:C#也是一种特殊的解释性语言。

9.高性能:C#八代码编译成中间语言后,可以高效的执行程序。

10.多线程:与Java类似,可以由一个主进程分出多个执行小任务的多线程。

11.在本系统中,由于C#语言有专门处理串口通信的SerialPort控件,以及连接数据库的SqlConnection控件,因此使得程序员的编程效率得到了很大的提升,这是.net平台为处理底层硬件平台所做的努力。栉缏歐锄棗鈕种鵑瑶锬。 C#的强大时依赖于.net的发展,而.net的发展是看微软在.net上的决心和投入的多少。C#目前主要是应用在网络编程上,其他领域比如数据库、窗体编程,都在逐渐增大。辔烨棟剛殓攬瑤丽阄应。 (4)系统存储使用的数据库SQL Server 2005

Microsoft SQL Server2005是用于大规模联机事务处理、数据仓库和电子商务应用的数据库和数据分析平台。峴扬斕滾澗辐滠兴渙藺。 SQL Server 2005旨在帮助企业迎接这些挑战。这个下一代数据管理和分析解决方案将给企业数据和分析应用程序带来增强的安全性、可伸缩性和可用性,使得它们更易于创建、部署和管理。詩叁撻訥烬忧毀厉鋨骜。 SQL Server 2005基于SQL Server 2000的强大功能之上,提供了一个完整的数据管理和分析解决方案,它将会给不同规模的组织带来帮助:则鯤愜韋瘓賈晖园栋泷。 ①构建、部署和管理企业应用程序,使其更加安全、伸缩性更强和更可靠。 ②降低开发和支持数据库应用程序的复杂性,实现了IT生产力的最大化。

③能够在多个平台、应用程序和设备之间共享数据,更易于连接内部和外部系统。胀鏝彈奥秘孫戶孪钇賻。 ④在不牺牲性能、可用性、可伸缩性或安全性的前提下有效控制成本。

SQL Server 2005在以下三个重要方面改善了我们的数据基础架构:企业数据管理、开发人员效率和商业智能。它在可接受的价格和许可费用以及升级到最新的SQL Server和Windows Server System的途径方面也有新的突破。鳃躋峽祷紉诵帮废掃減。 在智能电表管理系统软件的制作过程中也是用到了SQL Server 2005数据库系统提供的多个功能,并获益于数据库管理系统多项安全性支持,使得架构的应用系统的安全性更高,更有保障。稟虛嬪赈维哜妝扩踴粜。 (5)专业知识

字节格式:每个字节含8位二进制码,传输时加上一个起始位(0)、一个偶校验位和一个停止位(1),共11位。D0是字节的最低有效位,D7是字节的最高有效位。先传低位。后传高位。陽簍埡鲑罷規呜旧岿錟。 帧格式:帧是传送信息的基本单元。帧格式如图1-1。

第5页

 帧起始符68H:标识一帧信息的开始,其值为68H=01101000B.

 地址域A0~A5:地址域由6个字节构成,每字节2位BCD码。地址长度可达12

位十进制数,可以为表号、资产号、用户号、设备号等。具体使用可由用户自行决定。当使用的地址码长度不足6字节时,用十六进制AAH补足6字节。低地址位在先,高地址位在后。沩氣嘮戇苌鑿鑿槠谔應。 当地址为999999999999H时,为广播地址。

 控制码C:其中01表示读数据,04表示写数据,而控制码前面为0或是8表示方

向。

 数据长度L:L为数据域的字节数。读数据时L<200,写数据时L<50,L=0表示无

数据域。

 数据域DATA:数据域包括数据标识和数据、密码等,其结构随控制码的功能而改

变。传输时发送方按字节进行加33H处理,接收方按字节进行减33H处理。钡嵐縣緱虜荣产涛團蔺。  校验码

CS:从帧起始符开始到校验码之前的所有各字节的模256的和,即各字节二进制算术和,不计超过256的溢出值。懨俠劑鈍触乐鹇烬觶騮。  结束符16H:标识一帧信息的结束,其值为16H=00010110B.

第6页

二、用户需求分析

2.1技术需求

本系统采用C#语言在Microsoft Visual Studio 2005集成开发平台上进行编程开发,并使用微软的SQL Server 2005数据库存储数据以提高数据的安全性,在系统编写上具有可行性。从经济经济方面看,本系统可以服务电厂,电费管理单位、小区物业部等,可以为企业节省人力开支。从社会方面看,服务于大众,方便电表抄表人员工作,且可靠便捷。謾饱兗争詣繚鮐癞别瀘。 2.2功能需求

系统外观:管理系统界面简洁美观、易于使用,具有较强的人机交互性。 数据库管理:所使用的数据库设计科学合理,能够根据数据库设计的范式要求对其进行关系规范化。并且数据库设计的字段命名清晰,各个键值设置合理,易于后期的维护和管理。

呙铉們欤谦鸪饺竞荡赚。 用户信息管理:能根据各具体要求将数据库内的信息读取至系统界面,并对其进行精确的管理与维护,主要包括:(1) 操作员信息管理,超级用户可以对使用该智能电表管理系统的用户信息进行准确编辑。(2) 电表信息管理,授权用户可以对住宅小区内安装智能电表的用户进行信息的查询与编辑。(3) 楼栋信息管理,授权用户可以对本小区内的楼房信息进行管理,对楼房的名称与楼层数量进行查询与编辑(4) 用户用电信息记录查询,授权用户可以进入查询窗口查找各家电表各时段的电力计量信息,同时用户的查询支持多条件选择查询的

第7页

灵活方式。莹谐龌蕲賞组靄绉嚴减。 串口通信:本系统主要是针对DDS1317-A型单相电子式电能表所进行的485集抄实现,其中通讯功能要求(1)可通过PC机RS485通讯,完成编程设置和抄表。(2)RS485接口与电表内部实行电气隔离。(3)通讯规约参照DL/T645-1997规约实现。使得管理系统具有基本的:(a).显示当前正向有功总电能。(b).查询电表地址。(c).通断电控制。麸肃鹏镟轿騍镣缚縟糶。 权限管理:为了保证智能电表管理系统的安全性,需要对系统使用的用户赋予相应的使用权限。数据库的超级用户账号和密码由服务器的系统管理员设定,数据库的一般用户账户号和权限由数据库管理员用户设定。并且所有的操作人员进入系统前均应登陆自己的账号和密码,并通过权限管理的认证,所有操作人员均应规定相应的权限,任何越权的操作必须被拒绝。所有的登陆成功与失败的记录均应有日志记录,除了用户管理的基本资料外,工作人员也应该根据自己的权限进行其他的数据查询与编辑。納畴鳗吶鄖禎銣腻鰲锬。 三、概要设计

3.1系统的构成

选择基于C#语言开发的智能电表管理系统以及管理业务数据的SQL Server 2005数据库系统,是立足于供电部门当前和未来发展的需要及电能消费者的需求,同时也顺应了当前软件开发中的大体趋势。本系统界面使用流程如图3-1所示,系统共含有十个交互界面,分别负责各自特定的任务和功能,系统包含登陆界面、主控制界面、设置参数界面以及查询编辑信息界面。風撵鲔貓铁频钙蓟纠庙。

第8页

3.2系统的主要功能及特点

1. 本系统在程序编写上尽量做到了模块化编程使得各程序模块分工明确、运行独立,系统功能模块如图3-2所示,其主要功能有:灭嗳骇諗鋅猎輛觏馊藹。 (1)操作员信息管理,管理员可以增删改使用系统的用户信息,保证信息的时效性。 (2)用户权限管理,较高权限的用户可以改变其他用户使用系统功能的范围,例如当一个新用户被增加进来,而且该用户只拥有收银员的权限,那么该用户就没有增删改数据库中信息的权限。铹鸝饷飾镡閌赀诨癱骝。 (3)电表信息管理,操作员可以对数据库内的电表信息进行查询操作、增删改电表相关信息操作。

(4)楼栋信息管理,系统管理员可以对小区楼栋的名称和楼层信息进行相应的编辑处理,为了保证数据库信息不受破坏,系统会对不具备删除或修改条件的楼栋给予提示。攙閿频嵘陣澇諗谴隴泸。 (5)用户用电查询,具备查询权限的用户可以使用多种条件来查询用户用电信息,包括按表号、按用户姓名、按冻结日期、按楼栋号等多个条件查询。趕輾雏纨颗锊讨跃满賺。 (6)串口通信,系统可以发送串口通信数据操作硬件,使电表跳闸或合闸,同时系统可以读取硬件接口返回的数据,查询电表当前电量。夹覡闾辁駁档驀迁锬減。

2. 本系统有以下几大特点:

(1)较强的系统登陆验证功能,在数据库设计时规定了用户名是唯一标识符,保证了登陆系统的人员能够一人一个账号登陆,同时在用户名输入中规定了一些非数字与字母的符号

第9页

字符为非法字符;为了节约服务器的内存资源,当用户名密码均为空时并不执行数据库查询操作,而一直待用户的信息填写完整;为了保障系统不受黑客等的干扰,采用了随机验证码功能,增强系统健壮性。视絀镘鸸鲚鐘脑钧欖粝。 (2)简洁的系统操作性,主界面采用了多种界面优化措施,不仅将繁杂的数据显示功能保留了下来,同时还并不影响其系统的整体观赏性。偽澀锟攢鴛擋緬铹鈞錠。 (3)灵活的系统参数设置能力,操作用户可以根据自己的意愿对通信的串口进行设置,对自己登陆系统的密码进行修改。緦徑铫膾龋轿级镗挢廟。 (4)完善的小区住宅之楼栋管理与电表管理的功能,用户可以通过系统界面方便的修改存储于数据库中的信息,而不会破坏数据的准确性騅憑钶銘侥张礫阵轸蔼。 (5)便捷的硬件电表操作能力,通过管理系统可以轻松快速的抄写电表电量并控制电表的通断电能力,改变了以往抄表人员辛苦爬楼抄表的经历。疠骐錾农剎貯狱颢幗騮。 四、详细设计

4.1数据库设计

数据库名为SmartMeterSystemDB.mdf,其中数据库共包括4张表,分别是电表信息表(如表4-1所示)、楼栋管理表(如表4-2所示)、操作员信息表(如表4-3所示)和用电查询表(如表4-4所示)。表结构如下所示。镞锊过润启婭澗骆讕瀘。

表4-1 电表信息表 Ammeter_Management表各字段定义 字段名 Ammeter_ID Ammeter_Meter_User_Name Ammeter_Address Ammeter_PassWord Ammeter_State Meter_Building_Name Meter_Layer_Num Create_Meter_Date Create_Meter_UserName Modify_Meter_Date Modify_Meter_UserName Ammeter_Meter_User_PhotoID 类型 int nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar 长度 系统 20 20 30 30 10 20 20 20 20 20 20 10 描述 ID值,自动编号 主键,电表号 表计名称 安装地址 电表密码 表计状态 外键,所属楼 所属层 创建日期 创建人员 修改日期 修改人员 用户照片 是否空值 not NULL not NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Ammeter_Meter_Query_Number nvarchar 表4-2楼栋管理表

Building_Management表各字段定义 字段名 Building_ID Meter_Building_Name Building_Layer_Num 类型 int nvarchar nvarchar 长度 系统 20 10 描述 主键,楼名称 楼层数 是否空值 not NULL NULL ID值,自动编号 not NULL 第10页

Create_Building_Date Create_Building_UserName Modify_Building_Date nvarchar nvarchar nvarchar 20 20 20 20 创建日期 创建人员 修改日期 修改人员 NULL NULL NULL NULL Modify_Building_UserName nvarchar 表4-3操作员信息表 Operator_Information表各字段定义 字段名 Operator_ID Operator_Name Operator_Sex Operator_UserID Operator_Address Operator_TelPhone Operator_State Create_User_Date Create_User_Name Modify_User_Date Modify_User_Name Limits_Of_Add Limits_Of_Change Limits_Of_Delete Admin_Status Cashier_Status MeterState_Operator_Status Query_Operator_Status Login_System_Time Login_System_Num Operator_PassWord Operator_PhotoID 类型 int nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar int nvarchar nvarchar 长度 系统 20 10 20 50 20 10 20 20 20 20 10 10 10 10 10 10 10 20 系统 30 10 描述 ID值,自动编号 操作员性别 身份证号码 家庭住址 联系电话 操作状态 创建日期 创建人员 修改日期 修改人员 添加权限 修改权限 删除权限 管理员状态 收银员状态 表计状态操作 查询权限 最后登录时间 登录次数 登录密码 操作员照片 是否空值 not NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 主键,操作员姓名 not NULL 表4-4 用电查询表 Query_Power表各字段定义 字段名 Query_User_ID Ammeter_Meter_Query_Number Query_Meter_Name Power_Freeze_Date Power_Return_Time User_FreezeNow_Power User_DayUse_Power User_BackupBefore_Power 类型 int nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar nvarchar 长度 系统 20 20 20 20 20 20 20 描述 主键,自动编号 外键,电量查询表号 表计名称 冻结日期 返回时间 冻结电量 当日用电量 前一天用电量 是否空值 not NULL NULL NULL NULL NULL NULL NULL NULL SQL Server 2005数据库创建语句:

第11页

CREATE DATABASE SmartMeterSystemDB ON (

NAME=SmartMeterSystemDB,

FILENAME=’C:\\ SmartMeterSystemDB.mdf’ )

LOG ON (

NAME=SmartMeterSystemDB_log,

FILENAME=’C:\\ SmartMeterSystemDB_log.ldf’ ) GO

USE SmartMeterSystemDB GO

CREATE TABLE Ammeter_Management (

Ammeter_ID int NOT NULL,

Ammeter_Meter_Query_Number nvarchar(20) NULL, Ammeter_Meter_User_Name nvarchar(20) NULL, Ammeter_Address nvarchar(30) NULL, Ammeter_PassWord nvarchar(30) NULL, Ammeter_State nvarchar(10) NULL,

Meter_Building_Name nvarchar(20) NULL, Meter_Layer_Num nvarchar(20) NULL, Create_Meter_Date nvarchar(20) NULL,

Create_Meter_UserName nvarchar(20) NULL, Modify_Meter_Date nvarchar(20) NULL,

Modify_Meter_UserName nvarchar(20) NULL,

Ammeter_Meter_User_PhotoID nvarchar(10) NULL ) GO

ALTER TABLE Ammeter_Management

ADD CONSTRAINT PK_Ammeter_Meter_Query_Number PRIMARY KEY(Ammeter_Meter_Query_Number)

榿贰轲誊壟该槛鲻垲赛。 GO

CREATE TABLE Building_Management (

Building_ID int NOT NULL,

Meter_Building_Name nvarchar(20) NULL, Building_Layer_Num nvarchar(10) NULL, Create_Building_Date nvarchar(20) NULL,

Create_Building_UserName nvarchar(20) NULL, Modify_Building_Date nvarchar(20) NULL,

Modify_Building_UserName nvarchar(20) NULL

第12页

) GO

ALTER TABLE Building_Management

ADD CONSTRAINT PK_Meter_Building_Name PRIMARY(Meter_Building_Name)邁茑赚陉宾呗擷鹪讼凑。 GO

CREATE TABLE Operator_Information (

Operator_ID int NOT NULL,

Operator_Name nvarchar(20) NOT NULL, Operator_Sex nvarchar(10) NULL, Operator_UserID nvarchar(20) NULL, Operator_Address nvarchar(50) NULL, Operator_TelPhone nvarchar(20) NULL, Operator_State nvarchar(10) NULL, Create_User_Date nvarchar(20) NULL, Create_User_Name nvarchar(20) NULL, Modify_User_Date nvarchar(20) NULL, Modify_User_Name nvarchar(20) NULL, Limits_Of_Add nvarchar(10) NULL, Limits_Of_Change nvarchar(10) NULL, Limits_Of_Delete nvarchar(10) NULL, Admin_Status nvarchar(10) NULL, Cashier_Status nvarchar(10) NULL,

MeterState_Operator_Status nvarchar(10) NULL, Query_Operator_Status nvarchar(10) NULL, Login_System_Time nvarchar(20) NULL, Login_System_Num int NULL,

Operator_PassWord nvarchar(30) NULL, Operator_PhotoID nvarchar(10) NULL ) GO

ALTER TABLE Operator_Information

ADD CONSTRAINT PK_Operator_Name PRIMARY KEY(Operator_Name)嵝硖贪塒廩袞悯倉華糲。 GO

CREATE TABLE Query_Power (

Query_User_ID int NOT NULL,

Ammeter_Meter_Query_Number nvarchar(20) NULL, Query_Meter_Name nvarchar(20) NULL, Power_Freeze_Date nvarchar(20) NULL, Power_Return_Time nvarchar(20) NULL, User_FreezeNow_Power nvarchar(20) NULL, User_DayUse_Power nvarchar(20) NULL,

第13页

User_BackupBefore_Power nvarchar(20) NULL

) GO

ALTER TABLE Query_Power

ADD CONSTRAINT PK_Query_User_ID PRIMARY KEY(Query_User_ID)该栎谖碼戆沖巋鳧薩锭。 GO

4.2系统界面设计

系统包含一个登陆窗口,一个主程序窗口和主界面下关联的八个功能窗口。所有窗体的设计视图如下所示:

(1)登陆界面

登陆界面主要由3个标识Label,3个文本输入框,一个随机码生成Label以及两个按钮元素构成。其中密码输入的文本框的PasswordChar的替代字符设置为“*”,随机码生成的Label由函数getRandomizer()实现。劇妆诨貰攖苹埘呂仑庙。 控件类型 Label Label Label Label TextBox TextBox TextBox Button Button 控件命名 lblAccount lblPassword lblVerification lblVerificationCode txtAccount txtPassword txtVerificationCode btnLogin btnLogout 控件解释 账号标签 密码标签 验证码标签 验证码生成 账号输入框 密码输入框 验证码输入框 系统登陆 退出系统 备注 PasswordChar属性“*” 第14页

(2)智能电表管理系统主界面

系统管理主界面,此界面是登陆系统的操作员管理系统的主要交互窗口,窗体中包含的

第15页

控件有菜单栏、快捷菜单栏、系统导航条、数据显示控件以及状态栏等,包含内容较为丰富。系统的主要控件构成如下所示。 臠龍讹驄桠业變墊罗蘄。 控件类型 MenuStrip ToolStrip StatusStrip Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel Panel PictureBox PictureBox Button Button Button Button Button Button TabControl TabControl TabControl TabControlPage TabControlPage TabControlPage 控件命名 menuStripMainSystem toolStripMainSystem statusStripMainSystem panelSystem panFunTwo panFunMain panSystemMainWork panSystemMainWork2 panPowerMeter panMeterListView panMeterListViewRight panDailyBusiness panQueryAll panUsersManagement panEmergencyResponse panMeterInform panMeterInform2 panPicture panPicture2 panSystemAllInterval panSystemInterval panSystemMainWorkOther panSystemMainWorkOther2 panTabChkWork panTabChkWork2 pictureMain pictureMain2 btnPowerMeter btnMeterListView btnDailyBusiness btnQueryAll btnUsersManagement btnEmergencyResponse tabPowerMeter tabSystemWork tabSystemWork2 tabPageData tabPageEvents tabPageOperator 控件解释 菜单栏 快捷菜单栏 状态栏 整体背景框面板 小背景面板 折叠菜单栏面板 全局工作界面的面板 局部工作界面的面板 电力计量面板 电表点抄列表面板 电表点抄列表面板 日常业务面板 查询统计面板 档案管理面板 应急处理面板 整体电表信息面板 局部电表信息面板 企业标志图片面板 企业标志图片面板 系统间隔面板 系统间隔面板(左侧) 系统全局工作面板 系统局部工作面板 Tab全局控件选择面板 Tab控件选择面板 公司图片框 公司图片框 电力计量按钮 电表点抄列表 日常业务 查询统计 档案管理 应急处理 数控件列表选项 大窗口系统事件记录 小窗口系统事件记录 原始数据选项 事件列表选项 操作记录选项 备注 第16页

TabControlPage ListView ListView ListView ListView ListView ListView RadioButton RadioButton RadioButton RadioButton RadioButton RadioButton RadioButton RadioButton GroupBox GroupBox GroupBox GroupBox GroupBox GroupBox Label Label Label Label Label Label Label ProgressBar Splitter ToolStripButton ToolStripButton ToolStripButton ToolStripButton ToolStripButton ToolStripButton ToolStripButton ToolStripButton ToolStripButton ToolStripButton CheckBox CheckBox tabPagePowerMeter lsvOperator lsvData lsvEvents lsvMeter lsvOperatorListView lsvOperatorListViewRight radio1Day radioUpMeter radioDownMeter radioAllPower radio1DayRight radioUpMeterRight radioDownMeterRight radioAllPowerRight groupMeterListView groupMeterListViewRight groupOperatorListView groupOperatorListViewRight groupMeterInform groupMeterInform2 lblFixed lblFixedRight labelBlueLine lblDailyBusiness1 lblEmergencyResponse1 lblQueryAll1 lblUsersManagement1 progressBarLsvOperator splitterFunMainAndTwo toolStripBtnMainSystem toolStripButtonImplementMission toolStripBtnAuto toolStripBtnAutoImplementAll toolStripButtonLogoutSystem toolStripButtonTempLogout toolStripButtonReLogin toolStripButtonUserAdd toolStripButtonMeterManagement toolStripButtonUserQuery chkSystemWork chkSystemWork2 电力计量选项 操作记录 原始数据 事件列表 表计信息 执行任务列表 执行任务列表 上一天冻结 跳闸 合闸 当前电能 上一天冻结 跳闸 合闸 当前电能 电表点抄列表 电表点抄列表 执行任务列表 执行任务列表 表计信息 表计信息 固定/松开 固定/松开 界面蓝线标记 日常业务 应急处理 查询统计 档案管理 进度条 分隔线 主界面图标按钮 执行任务图标按钮 自动抄表图标按钮 一键集抄图标按钮 系统退出图标按钮 临时注销图标按钮 重新登录图标按钮 开户图标按钮 电表管理图标按钮 用户查询图标按钮 自动滚屏 自动滚屏 第17页

ContextMenuStrip ToolStripMenuItem ImageList Timer Timer Timer Timer ToolStripStatusLabel ToolStripStatusLabel ToolStripStatusLabel TreeView contextMenuStripClearTabData toolStripMenuItemClearData imageListForListView timerFunOutLook timerFunOutLookRight timerLabelBtnEvents timerToolStripTime toolStripStatusLabelOperatorName toolStripStatusLabelSuccessFail toolStripStatusLabelTime treeViewPowerMeter 鼠标右击事件 右键清空选项 图片存储列表 系统折叠菜单栏隐显 系统右侧单栏隐显 折叠菜单Label事件 系统时间计量 操作员姓名 登陆成功与否 系统登陆时间 树形控件 (3)电表信息管理界面

电表信息管理界面,主要是由数据显示的控件DataGridView,以及查询窗口中的TextBox、RadioButton、GroupBox、ComboBox等控件组成,窗口的主要构成部件如下所示:

鰻順褛悦漚縫冁屜鸭骞。 控件类型 Button Button 控件命名 btnChangeAddInform 控件解释 添加按钮 备注 btnAmmeterManagementSimplify “新版”按钮 第18页

Button Button Button Button Button ComboBox ComboBox ComboBox DataGridView GroupBox GroupBox GroupBox Label Label Label Label Label Label Label Panel Panel RadioButton RadioButton TextBox TextBox TextBox TextBox TextBox btnChangeDelInform btnChangeInform btnChangeMeter btnMeterQuery btnMeterQueryAll comboMeterBuildingFloor comboMeterLayer comboMeterState dataGridViewDataList groupDataChange groupDataView groupQueryMeter lblMeterAddress lblMeterFloor lblMeterLayer lblMeterName lblMeterNum lblMeterPassword lblMeterState panDataQuery panDataView radioMeterName radioMeterNum txtMeterAddress txtMeterName txtMeterNum txtMeterPassword txtQueryMeter 删除按钮 修改按钮 换表按钮 条件查询 全部查询 所属楼 所属层 表计状态 数据显示窗口 添加修改记录 数据显示 查询 安装地址标签 所属楼标签 所属层标签 表计名称标签 表号标签 电表密码标签 表计状态标签 数据显示面板 其余控件面板 表计名称 表号 安装地址 表计名称 表号 电表密码 查询窗口 第19页

(4)楼栋信息管理界面

楼栋信息管理界面,主要是由数据显示控件DataGridView、以及TextBox窗口、Button按钮、GroupBox等信息组合而成。窗口的主要构成部件由以下控件组成。穑釓虚绺滟鳗絲懷紓泺。 控件类型 Button Button Button Button Button DataGridView GroupBox GroupBox GroupBox Label Label Label Panel Panel TextBox TextBox 控件命名 btnChangeAddInform btnChangeDelInform btnChangeNowInform btnQueryBuilding btnQueryBuildingAll groupBuildingDataListView groupChangeData groupQueryData lblChangeBuildingLayerNum lblChangeBuildingName lblQueryBuildingName panBuildingDataChange panBuildingDataListView txtChangeBuildingLayerNum txtChangeBuildingName 控件解释 添加 删除 修改 条件查询 全部查询 数据显示组 添加修改记录组 查询记录组 楼层数 楼宇名称 楼名称 楼栋修改面板 数据显示面板 楼层数 楼宇名称 备注 dataGridVBuildingDataListView 数据显示列表 第20页

TextBox txtQueryBuildingName 楼名称 (5)操作员信息管理界面

操作员信息管理界面,主要是由DataGridView控件显示数据信息,GroupBox控件显示权限列表信息、查询条件、添加修改记录等多种功能,TextBox控件决定输入输出信息、Button按钮负责各种功能的事件响应。窗口的主要控件构成如下。隶誆荧鉴獫纲鴣攣駘賽。 控件类型 Button Button Button Button Button Button CheckBox CheckBox CheckBox CheckBox ComboBox ComboBox DataGridView GroupBox GroupBox GroupBox Label Label Label 控件命名 btnOperatorInformSimplify btnUserDel btnQueryOperator btnQueryOperatorAll btnUserAdd btnUserChange chkAdministrator chkCashier chkMeterState chkQueryCompetence comboUserSex comboUserState dataGViewOperatorInform groupChangeOperator groupCompetenceList groupQueryOperator lblUserAddress lblUserID lblUserName 控件解释 新版按钮 删除 条件查询 全部查询 添加按钮 修改按钮 管理员选项 收银员选项 表计状态操作 查询权限 性别选择 状态选择 数据显示控件 添加修改组 权限列表组 查询操作组 地址 身份证号码 姓名 备注 第21页

Label Label Label Panel Panel RadioButton RadioButton TextBox TextBox TextBox TextBox TextBox lblUserSex lblUserState lblUserTelPhone panOperatorData panOperatorQuery radioQueryUserID radioQueryUserName txtQueryOperator txtUserAddress txtUserID txtUserName txtUserTelPhone 性别 状态 联系电话 操作数据面板 信息查询面板 按用户名选项 按身份证号选项 查询输入框 地址输入框 身份证号码 姓名输入框 联系电话框 (6)用户用电信息记录查询

用户用电信息记录查询界面,主要由TabControl、CheckBox、DataGridView、TextBox、RadioButton、DateTimePicker、Label等控件构成。窗口的主要控件构成如下所示。浹繢腻叢着駕骠構砀湊。 控件类型 Button Button Button Button ComboBox ComboBox DataGridView DataGridView DateTimerPicker DateTimerPicker DateTimerPicker DateTimerPicker 控件命名 btnCountQuery btnCountQueryAll btnQuery btnQueryAll comboBuildingLayer comboBulidingName dataGridVQueryInform dataGridVTempInform dateTimePickerBegin dateTimePickerCountDateBegin dateTimePickerCountDateEnd dateTimePickerEnd 控件解释 统计条件查询 统计全部查询 条件查询 全部查询 楼层数 楼名称 数据显示控件 临时控件 统计起始日 统计结束日 起始日 结束日 备注 第22页

GroupBox GroupBox GroupBox GroupBox Label Label Label Label Label Label Label Label Label Panel RadioButton RadioButton RadioButton RadioButton TabControl TabControlPage TabControlPage TextBox TextBox groupBuildingNum groupQueryData groupQuerySelect lblBuildingLayer lblCountDateBegin lblCountDateEnd lblCountSelectDate lblQueryPowerSimplify lblSelectDate lblSelectDateBegin lblSelectDateEnd lblUserName panQueryPower radioBuildingNum radioFreezeDate radioMeterNum radioUserName tabControlQueryPower tabPageInformCount tabPageInformQuery txtQueryRadioSelect txtUserName 查询组 查询数据组 查询选项组 查询“层” 统计起始日 统计结束日 统计选择日期 新版 查询选择日期 查询起始日 查询结束日 统计用户名称 用电查询面板 按楼栋号 按冻结日期 按表号 按用户姓名 选项框控件 查询选项框 统计选项框 查询输入框 统计输入框 groupInformCountQueryCondition 统计查询条件组 (7)操作员修改密码界面

操作员修改密码界面,主要是由Label、TextBox以及Button按钮等简单的界面元素构成。窗口的主要界面构成元素如下。鈀燭罚櫝箋礱颼畢韫粝。 控件类型 Button 控件命名 btnExitNo 控件解释 退出按钮 备注 第23页

Button GroupBox Label Label Label Label TextBox TextBox TextBox btnSureChange lblNewPassword lblOldPassword lblSureNewPassword lblSystemNowUser txtNewPassword txtOldPassword txtSureNewPassword 确定按钮 新密码 旧密码 确认新密码 当前登陆用户 输入新密码 输入旧密码 输入确认新密码 groupChangePassword 修改密码组 (8)系统设置界面

系统设置界面,主要由GroupBox、Label、ComboBox、Button按钮等控件元素构成。窗口的主要布局元素如下所示。惬執缉蘿绅颀阳灣熗鍵。 控件类型 Button Button Button ComboBox GroupBox Label Label 控件命名 btnCheckSerialPort btnExitFrom btnSetSerialPort comboSelectSerialPort lblSerialPort lblStatus 控件解释 串口检测按钮 退出按钮 设置按钮 串口选择 串口 串口个数 备注 groupSetSystemSerialPort 串口设置组 第24页

(9)新版操作员信息管理界面

操作员信息管理,主要由Label、ComboBox、Panel、PictureBox、Button、TextBox、CheckBox等控件构成,窗口的主要构成元素如下所示。贞廈给鏌綞牵鎮獵鎦龐。 控件类型 Button Button Button Button Button CheckBox CheckBox CheckBox CheckBox ComboBox ComboBox ComboBox GroupBox Label Label Label 控件命名 btnSimplifyAdd btnSimplifyChange btnSimplifyDel btnUserBefore btnUserNext chkSimplifyAdministrator chkSimplifyCashier chkSimplifyMeterState comboOperatorSex comboOperatorState comboSelectUser lblOperatorAddress lblOperatorID lblOperatorName 控件解释 添加按钮 修改按钮 删除按钮 向前翻 向后翻 管理员选项 收银员选项 表计状态操作 性别选择 状态选择 选择用户框 地址 身份证号码 姓名 备注 chkSimplifyQueryCompetence 查询权限 groupSimplifyCompetenceList 权限列表组 第25页

Label Label Label Label Label Label Panel PictureBox TextBox TextBox TextBox TextBox TextBox lblOperatorPhone lblOperatorPhotoID lblOperatorSex lblOperatorState lblReturnOld lblSelectUser panPictureUserPhoto pictureBoxUserPhoto txtOperatorAddress txtOperatorID txtOperatorName txtOperatorPhone txtOperatorPhotoID 联系电话 照片号 性别 状态 返回上页 选择用户 操作员照片面板 操作员照片 住址输入框 身份证号输入框 姓名输入框 联系电话输入框 照片号码输入框 (10)新版电表信息管理界面

新版电表信息管理界面,主要构成元素包括Button按钮、Label标签、ComboBox选项框、TextBox输入框、Panel图片面板、PictureBox图片显示。嚌鲭级厨胀鑲铟礦毁蕲。 控件类型 Button Button Button Button Button Button ComboBox ComboBox ComboBox ComboBox 控件命名 btnMeterBefore btnMeterNext btnSimplifyMeterAdd btnSimplifyMeterChange btnSimplifyMeterConversion btnSimplifyMeterDelete comboSimplifyMeterFloor comboSimplifyMeterLayer comboSimplifyMeterSelect comboSimplifyMeterState 控件解释 向前翻 向后翻 添加按钮 修改按钮 换表按钮 删除按钮 所属楼选项框 所属层选项框 选择用户选项框 表计状态选项框 备注 第26页

Label Label Label Label Label Label Label Label Label Label Panel Panel PictureBox TextBox TextBox TextBox TextBox TextBox

lblReturnPage lblSimplifyMeterAddress lblSimaplifyMeterFloor lblSimplifyMeterLayer lblSimplifyMeterName lblSimplifyMeterNum lblSimplifyMeterPassword lblSimplifyMeterSelect lblSimplifyMeterState lblSimplifyUserPhotoID panMeterUserPhoto pictureMeterUserPhoto txtSimplifyMeterAddress txtSimplifyMeterName txtSimplifyMeterNum txtSimplifyMeterPassword txtSimplifyUserPhotoID 返回上页 安装地址 所属楼标志 所属层标志 表计名称 表号 电表密码 选择用户标志 表计状态 照片号标志 照片面板框 用户照片 安装地址输入框 表计名称输入框 表号输入框 电表密码输入框 照片号输入框 panSimplifyAmmeterManagement 新版界面面板框 4.3系统程序设计 (1)登陆系统程序设计

登陆界面以简洁美观为主,但同时登陆的安全性也需要重视,系统规定用户的账号中不可包含非法字符如:“!、@、#、$、%、^、&、*”等。密码输入框采用界面字符替代的方法保证密码输入的安全性。系统还包含验证码输入功能,这样可以保证系统免受像黑客暴力破解等方式的攻击。薊镔竖牍熒浹醬籬铃騫。 ① 非法字符判断程序如下:

char[] charStr ={ '!','@','#','$','%','^','&','*','(',')','<','>','?'};齡践砚语蜗铸转絹攤濼。 char[] charAccount = txtAccount.Text.ToString().Trim().ToCharArray();绅薮疮颧訝标販繯轅赛。 int IntCountAccount = 0;//记录有多少个非法字符 for (int i = 0; i < charStr.Length;i++ ) {

for (int j = 0; j < charAccount.Length;j++ ) {

if(charStr[i]==charAccount[j]) {

IntCountAccount++; } }

第27页

}

if (IntCountAccount != 0) {

MessageBox.Show(\"\\\"账号\\\"存在\" + IntCountAccount.ToString() + \"个非法字符!\",\"提示\");饪箩狞屬诺釙诬苧径凛。 txtVerificationCode.Text = \"\";

lblVerificationCode.Text = getRandomizer(4, true, false, true, true);烴毙潜籬賢擔視蠶贲粵。 txtAccount.Focus(); return; }

② 随机函数生成程序如下:

public string getRandomizer(int intLength,bool boolNumber,bool booSign,bool booSmallword,bool booBigword)鋝岂涛軌跃轮莳講嫗键。 //name=\"intLength\"需要位数 //name=\"booNumber\"是否生成数字 //name=\"booSign\"是否生成符号

//name=\"booSmallword\"是否生成小写字母 //name=\"booBigword\"是否生成大写字母 { //定义

Random ranA = new Random(); int intResultRound = 0; int intA = 0; string strB = \"\";

while (intResultRound < intLength) {

//生成随机数A,表示生成类型

//1=数字,2=符号,3=小写字母,4=大写字母 intA = ranA.Next(1, 5);

//如果随机数A=1,则运行生成数字 //生成随机数A,范围在0-10 //把随机数A,转成字符

//生成完,位数+1,字符串累加,结束本次循环

if (intA == 1 && boolNumber) {

intA = ranA.Next(0, 10); strB = intA.ToString() + strB;

intResultRound = intResultRound + 1; continue; }

//如果随机数A=2,则运行生成符号 //生成随机数A,表示生成值域

//1:33-47值域,2:58-64值域,3:91-96值域,4:123-126值域

第28页

if (intA == 2 && booSign == true)

{

intA = ranA.Next(1, 5); //如果A=1

//生成随机数A,33-47的Ascii码 //把随机数A,转成字符

//生成完,位数+1,字符串累加,结束本次循环 if (intA == 1) {

intA = ranA.Next(33, 48);

strB = ((char)intA).ToString() + strB; intResultRound = intResultRound + 1; continue; }

//如果A=2

//生成随机数A,58-64的Ascii码 //把随机数A,转成字符

//生成完,位数+1,字符串累加,结束本次循环 if (intA == 2) {

intA = ranA.Next(58, 65);

strB = ((char)intA).ToString() + strB; intResultRound = intResultRound + 1; continue; }

//如果A=3

//生成随机数A,91-96的Ascii码 //把随机数A,转成字符

//生成完,位数+1,字符串累加,结束本次循环 if (intA == 3) {

intA = ranA.Next(91, 97);

strB = ((char)intA).ToString() + strB; intResultRound = intResultRound + 1; continue; }

//如果A=4

//生成随机数A,123-126的Ascii码 //把随机数A,转成字符

//生成完,位数+1,字符串累加,结束本次循环 if (intA == 4) {

intA = ranA.Next(123, 127);

strB = ((char)intA).ToString() + strB;

第29页

intResultRound = intResultRound + 1; continue; } }

//如果随机数A=3,则运行生成小写字母 //生成随机数A,范围在97-122 //把随机数A,转成字符

//生成完,位数+1,字符串累加,结束本次循环 if (intA == 3 && booSmallword == true) {

intA = ranA.Next(97, 123);

strB = ((char)intA).ToString() + strB; intResultRound = intResultRound + 1; continue; }

//如果随机数A=4,则运行生成大写字母 //生成随机数A,范围在65-90 //把随机数A,转成字符

//生成完,位数+1,字符串累加,结束本次循环 if (intA == 4 && booBigword == true) {

intA = ranA.Next(65, 89);

strB = ((char)intA).ToString() + strB; intResultRound = intResultRound + 1; continue; } }

return strB; }

(2)能源管理系统主界面程序设计

①主界面运行后,会出现一个折叠菜单选项,这主要是通过Button按钮和Panel面板的组合制作出的运行效果。程序代码如下:撷伪氢鱧轍幂聹諛詼庞。 private void InitPanFun()//用于初始化Panel面板下的各个Label图标,实现鼠标移动事件踪飯梦掺钓貞绫賁发蘄。 {

lblFixed.BorderStyle = BorderStyle.Fixed3D; lblFixed.BackColor = Color.Gray;

lblFixedRight.BorderStyle = BorderStyle.None; lblFixedRight.BackColor = Color.Silver; this.panFunMain.Width = m_nPanFunWidth;

this.panMeterListViewRight.Height = m_nPanFunHideHeight;婭鑠机职銦夾簣軒蚀骞。 第30页

this.panFunMain.Dock = DockStyle.Left; m_nPanFunWidth = panFunMain.Width; ArrFunButton.Add(this.btnPowerMeter); ArrFunButton.Add(this.btnMeterListView); ArrFunButton.Add(this.btnDailyBusiness); ArrFunButton.Add(this.btnQueryAll); ArrFunButton.Add(this.btnUsersManagement); ArrFunButton.Add(this.btnEmergencyResponse); ArrFunPanelView.Add(this.panPowerMeter); ArrFunPanelView.Add(this.panMeterListView); ArrFunPanelView.Add(this.panDailyBusiness); ArrFunPanelView.Add(this.panQueryAll); ArrFunPanelView.Add(this.panUsersManagement); ArrFunPanelView.Add(this.panEmergencyResponse); ArrFunPanelView.Add(this.panFunMain);

ArrFunGroupBox.Add(this.groupMeterListViewRight);

ArrFunGroupBox.Add(this.groupOperatorListViewRight);譽諶掺铒锭试监鄺儕泻。 ArrFunPanelViewRight.Add(this.panMeterListViewRight);俦聹执償閏号燴鈿膽賾。 ArrFunLabelRight.Add(this.lblFixedRight);

ArrFunMainLabelButton.Add(this.lblDailyBusiness1);

ArrFunMainLabelButton.Add(this.lblEmergencyResponse1);缜電怅淺靓蠐浅錒鵬凜。 ArrFunMainLabelButton.Add(this.lblQueryAll1);

ArrFunMainLabelButton.Add(this.lblUsersManagement1);骥擯帜褸饜兗椏長绛粤。 lblFixed.Dock = DockStyle.Bottom; int nCount = ArrFunButton.Count; int pCount = ArrFunPanelView.Count; int gCount = ArrFunGroupBox.Count;

int pCountRight = ArrFunPanelViewRight.Count; int lblCountRight = ArrFunLabelRight.Count;

int lblMainLabelButtonCount = ArrFunMainLabelButton.Count;癱噴导閽骋艳捣靨骢鍵。 for (int i = nCount - 1; i >= 0;i-- ) {

Button btn = ArrFunButton[i] as Button; btn.Width = this.panFunMain.Width; btn.Left = 0;

btn.MouseMove += new MouseEventHandler(FunListView_MouseMove);鑣鸽夺圆鯢齙慫餞離龐。 }

for (int i = pCount - 1; i >= 0; i--) {

Panel pan = ArrFunPanelView[i] as Panel; pan.Width = this.panFunMain.Width; pan.Left = 0;

pan.MouseMove += new MouseEventHandler(FunListView_MouseMove);榄阈团皱鹏緦寿驏第31页

頦蕴。 }

for (int i = gCount - 1; i >= 0;i-- ) {

GroupBox groupBox = ArrFunGroupBox[i] as GroupBox;

groupBox.MouseMove += new MouseEventHandler(FunListViewRight_MouseMove);逊输吴贝义鲽國鳩犹騸。 }

for (int i = pCountRight - 1; i >= 0; i--) {

Panel panRight = ArrFunPanelViewRight[i] as Panel;

panRight.MouseMove += new MouseEventHandler(FunListViewRight_MouseMove);幘觇匮骇儺红卤齡镰瀉。 }

for (int i = lblCountRight - 1; i >= 0; i--) {

Label lblRightNow = ArrFunLabelRight[i] as Label; lblRightNow.Top = 0;

lblRightNow.MouseMove += new MouseEventHandler(FunListViewRight_MouseMove);誦终决懷区馱倆侧澩赜。 }

for (int i = lblMainLabelButtonCount - 1; i >= 0; i--)医涤侣綃噲睞齒办銩凛。 {

Label lblMainButton = ArrFunMainLabelButton[i] as Label;舻当为遙头韪鳍哕晕糞。 lblMainButton.MouseMove += new MouseEventHandler(FunListView_MouseMove);鸪凑鸛齏嶇烛罵奖选锯。 }

this.timerFunOutLook.Enabled = false; this.timerFunOutLookRight.Enabled = true; }

private void FrmMainSystem_Load(object sender, EventArgs e) 筧驪鴨栌怀鏇颐嵘悅废。 {//此处用于对所有的按钮控件进行初始化的排版布局操作

. . .

btnEmergencyResponse.SendToBack();

btnEmergencyResponse.Dock = DockStyle.Top; btnUsersManagement.SendToBack();

btnUsersManagement.Dock = DockStyle.Top; btnQueryAll.SendToBack(); btnQueryAll.Dock = DockStyle.Top; btnDailyBusiness.SendToBack();

btnDailyBusiness.Dock = DockStyle.Top; btnMeterListView.SendToBack();

第32页

btnMeterListView.Dock = DockStyle.Top; btnPowerMeter.SendToBack(); btnPowerMeter.Dock = DockStyle.Top; lblFixed.SendToBack();

lblFixed.Dock = DockStyle.Bottom; panPowerMeter.Visible = false;/**/

. . .

} }

//Main_Load()函数结束

②系统界面的面板框所具有的动态效果主要是由timerFunOutLook_Tick()函数完成,对

timerFunOutLook控件的Enable属性进行True或False的设置即可。韋鋯鯖荣擬滄閡悬贖蘊。 private void timerFunOutLook_Tick(object sender, EventArgs e)涛貶騸锬晋铩锩揿宪骟。 { if(true) {

Point p1 = this.panFunMain.PointToScreen(new Point(0, 0));钿蘇饌華檻杩鐵样说泻。 Point p2 =

this.panFunMain.PointToScreen(newPoint(this.panFunMain.Right,this.panFunMain.Bottom));戧礱風熗浇鄖适泞嚀贗。 Point pCur = Cursor.Position;

if (pCur.X < p1.X || pCur.X > p2.X || pCur.Y < p1.Y || pCur.Y > p2.Y)購櫛頁詩燦戶踐澜襯鳳。 {

this.panFunMain.Width = m_nPanFunHideWidth; this.timerFunOutLook.Enabled = false; } } }

③此处代码负责完成当用户点击“电力计量”时,将楼栋、楼层、电表信息显示在treeViewPowerMeter的控件当中。嗫奐闃頜瑷踯谫瓒兽粪。 public void RefreshTreeViewBuilding()//等同于上面_Load方法中最后部分的代码,只是此处单独提取出来使用虚龉鐮宠確嵝誄祷舻鋸。 {

TreeNode treeNodeBuilding; TreeNode treeNodeBuildingLayer;

connection = new SqlConnection(strConnection); string strTempTreeViewBuildingName = null; string strTempTreeViewBuildingLayerNum = null; string strTempTreeViewBuildingAmmeterName = null;

string strTempTreeViewBuildingAmmeterNameMeter_Building_Name = null;與顶鍔笋类謾蝾纪黾廢。 string strTempTreeViewBuildingAmmeterNameMeter_Layer_Num = null;結释鏈跄絞塒繭绽綹蕴。 第33页

string strQuerySQLBuilding = \"SELECT Meter_Building_Name,Building_Layer_Num FROM Building_Management\";餑诎鉈鲻缥评缯肃鮮驃。 this.treeViewPowerMeter.Nodes.Clear(); try {

using (connection = new SqlConnection(strConnection))爷缆鉅摯騰厕綁荩笺潑。 {

connection.Open();

using (command = new SqlCommand(strQuerySQLBuilding, connection))锞炽邐繒萨蝦窦补飙赝。 {

reader = command.ExecuteReader(); while (reader.Read()) {

int IntTempTreeViewBuildingLayerNum;

strTempTreeViewBuildingName =

reader.GetString(reader.GetOrdinal(\"Meter_Building_Name\"));曠戗輔鑽襉倆瘋诌琿凤。 strTempTreeViewBuildingLayerNum =

reader.GetString(reader.GetOrdinal(\"Building_Layer_Num\"));轉厍蹺佥诎脚濒谘閥糞。 treeNodeBuilding =

treeViewPowerMeter.Nodes.Add(strTempTreeViewBuildingName);嬷鯀賊沣謁麩溝赉涞锯。 IntTempTreeViewBuildingLayerNum =

int.Parse(strTempTreeViewBuildingLayerNum);讯鎬謾蝈贺綜枢辄锁廪。 for (int i = 1; i <= IntTempTreeViewBuildingLayerNum; i++)兒躉讀闶軒鲧擬钇標藪。 {

treeNodeBuilding.ImageIndex = 0; treeNodeBuilding.SelectedImageIndex = 0;

treeNodeBuildingLayer = treeNodeBuilding.Nodes.Add(i.ToString() + \"层楼\");

繅藺詞嗇适篮异铜鑑骠。 } } } }

}

catch (Exception) {

toolStripStatusLabelSuccessFail.Text = \"与MIS连接失败\"; MessageBox.Show(\"未连接上,数据库连接超时!\", \"提示\"); }

string strQuerySQLBuildingAmmeter = \"SELECT

第34页

Ammeter_Meter_User_Name,Meter_Building_Name,Meter_Layer_Num FROM Ammeter_Management\";鮒簡觸癘鈄餒嬋锵户泼。 try {

using (connection = new SqlConnection(strConnection))眯毆蠐謝银癩唠阁跷贗。 {

connection.Open();

using (command = new SqlCommand(strQuerySQLBuildingAmmeter, connection))闵屢螢馳鑷隽劍颂崗鳳。 {

reader = command.ExecuteReader(); while (reader.Read()) {

strTempTreeViewBuildingAmmeterName =

reader.GetString(reader.GetOrdinal(\"Ammeter_Meter_User_Name\"));檁傷葦开阈灯伞馑諧粮。 strTempTreeViewBuildingAmmeterNameMeter_Building_Name =

reader.GetString(reader.GetOrdinal(\"Meter_Building_Name\"));鄭饩腸绊頎鎦鹧鲕嘤錳。 strTempTreeViewBuildingAmmeterNameMeter_Layer_Num =

reader.GetString(reader.GetOrdinal(\"Meter_Layer_Num\"));弃铀縫迁馀氣鰷鸾觐廩。 int IntTreeViewPowerMeterCount = treeViewPowerMeter.Nodes.Count;调谇續鹨髏铖馒喪劉薮。 int[] IntTreeViewEveryLayerCount = new int[IntTreeViewPowerMeterCount];厲耸紐楊鳝晋頇兗蓽驃。 for (int i = 0; i < IntTreeViewPowerMeterCount; i++)苧瑷籮藶黃邏闩巹东澤。 {

IntTreeViewEveryLayerCount[i] = treeViewPowerMeter.Nodes[i].Nodes.Count;鴿摄禱鋅儀憚銼嚕缗赞。 }

for (int i = 0; i < IntTreeViewPowerMeterCount; i++)箪啬癲剀净赶钩嬙鳄凫。 {

if (treeViewPowerMeter.Nodes[i].Text.ToString() ==

strTempTreeViewBuildingAmmeterNameMeter_Building_Name)顽鷙瑪滨廈岘轆庫糞糧。 {

for (int j = 1; j <= IntTreeViewEveryLayerCount[i]; j++)漬閫熾诀团諳赓戰餛锰。 {

if (j.ToString() == strTempTreeViewBuildingAmmeterNameMeter_Layer_Num)鐸輜澠顶嫻塊謂斕痹廪。 {

treeViewPowerMeter.Nodes[i].Nodes[j -

1].Nodes.Add(strTempTreeViewBuildingAmmeterName);抢觀淚婭师讴论櫚阵蘚。 }

第35页

treeViewPowerMeter.Nodes[i].Nodes[j - 1].ImageIndex = 3;贼組櫻種愨单蝕渾潷骡。 treeViewPowerMeter.Nodes[i].Nodes[j - 1].SelectedImageIndex = 3;圓漣檸賡捣蕷舻燁錘泽。 } } } } } } }

catch (Exception) {

toolStripStatusLabelSuccessFail.Text = \"与MIS连接失败!!!\";蟄彎擼鯁棖佇緡癟椠贊。 MessageBox.Show(\"未连接上,数据库连接超时!\", \"提示\"); }

treeViewPowerMeter.Nodes[0].Expand(); }

④对Label标签lblFixed进行单机事件的响应。使得标签为固定状态时单机后成为松开状态、而为松开状态时单击后则与之相反。义淨擁扪殴胁纸窺钣鳧。 private void lblFixed_Click(object sender, EventArgs e)绥骅懸缙澀鷂禍紳撻粮。 {

if (lblFixed.Text == \"固定\")//此时半屏 {

lblFixed.Text = \"松开\";

lblFixed.BorderStyle = BorderStyle.Fixed3D; lblFixed.BackColor = Color.Gray; this.timerFunOutLook.Enabled = false; panFunTwo.Visible = true;

lblInterfacePanSystemNewOperatorInform.Visible = false;馒锁開钥焖緒珏編軻錙。 lblInterfacePanSystemNewAmmeterManagement.Visible = false;獄质嶇僅痺鲒潰脫帧開。 }

else if (lblFixed.Text == \"松开\")//此时全屏 {

lblFixed.Text = \"固定\";

lblFixed.BorderStyle = BorderStyle.None; lblFixed.BackColor = Color.Silver; this.timerFunOutLook.Enabled = true; panFunTwo.Visible = false;

if(panSystemMainWork.Visible == true) {

lblInterfacePanSystemNewOperatorInform.Visible = false;鍥苋娛殫秽笾殇蕢谬藓。 lblInterfacePanSystemNewAmmeterManagement.Visible = false;杂砖墳雖紜飯曇覡第36页

墾騾。 }

else if (panSystemMainWork.Visible == false) {

lblInterfacePanSystemNewOperatorInform.Visible = true;轼栀嗶鑊绷瘍懔諍訝澤。 lblInterfacePanSystemNewAmmeterManagement.Visible = true;

尋头厭呛羈阴帥讕匦赞。 } } }

⑤选择操作的用户后,当点击跳闸指令或合闸指令时,程序会自动组织好需要发送的16进制数,通过串口发送到电表硬件设备。訪齙剛玺苏滥夹趕萤凭。 private void radioUpMeterRight_Click(object sender, EventArgs e)//跳闸写韞僂谌虛鍤囈辮褻糝。 {

progressBarLsvOperator.Value = 0; flag = false;

if (groupMeterListViewRight.Text.Length == 4) {

return; }

string strRadioUpMeterRight = null; strRadioUpMeterRight =

StringsConvertHexadecimal(groupMeterListViewRight.Text.Substring(5, 12), \"04\", \"C028\", \"\", \"9966\");罴醬畝饼誊歿凑鈑繳锱。 string strGetInform=AboutRadioUpDownMeter(strRadioUpMeterRight);鲢診龄師該铃書銨鴇开。 if (strGetInform==null) {

return; }

MessageBox.Show(\"已跳闸!\",\"提示\"); }

private void radioDownMeterRight_Click(object sender, EventArgs e)//合闸磚緙鹅綱谩擞鴻鑌纸蘚。 {

progressBarLsvOperator.Value = 0; flag = false;

if (groupMeterListViewRight.Text.Length == 4) {

return; }

string strRadioDownMeterRight =

第37页

StringsConvertHexadecimal(groupMeterListViewRight.Text.Substring(5, 12), \"04\", \"C028\", \"\", \"3355\");鬮煒鳍輥賠還鲂隊驼骡。 string strGetInform=AboutRadioUpDownMeter(strRadioDownMeterRight);毕懍鲅鵑较惻飾顳矯泾。 if (strGetInform==null) {

return; }

MessageBox.Show(\"已合闸!\",\"提示\"); }

⑥以下这段程序是对serialComm这个串口控件的各属性进行初始化,主要包括波特率设置、停止位设置、奇偶校验设置、数据位数设置以及串口名的设置。钆歷驾无醬赔隽驍韉贈。 public void SetSerialPortInFrmMainSystem_Load() {

if(frmMainSystem.serialComm.IsOpen==true) {

frmMainSystem.serialComm.Close(); }//此处实现不管怎样,打开串口时不会有冲突存在 string[] ports = SerialPort.GetPortNames(); Array.Sort(ports);

serialComm.RtsEnable = true; try {

serialComm.PortName=ports[0];//设置串口名

MessageBox.Show(\"串口打开\\\"成功\\\"!\", \"提示\");/**/ }

catch(Exception) {

MessageBox.Show(\"串口打开\\\"失败\\\"!\", \"提示\"); return; }

serialComm.BaudRate = 1200;//设置波特率 serialComm.StopBits = StopBits.One;//设置停止位 serialComm.Parity = Parity.Even;//设置偶校验 serialComm.DataBits = 8; //设置数据位 try {

serialComm.Open(); }

catch(Exception ex) {

serialComm = new SerialPort(); MessageBox.Show(ex.Message); }

第38页

}

⑦此段程序重写了WinForm窗体本身所拥有的OnFormClosing()的关闭窗口的事件方法,使得当点击关闭按钮时,系统会判断是否存在除主界面以外的其它窗口,若存在便会提示要关闭其它窗口才可以退出程序。徠鲣饮脸铄尝鏍鯢炀憑。 protected override void OnFormClosing(FormClosingEventArgs e)謂镊颇铵鋃誼铰鸚镉糁。 {

DialogResult result = MessageBox.Show(\"退出该窗口?\", \"提示\", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);变赵陧涼镦囑釧亿殮錙。 if (result == DialogResult.Cancel) {

e.Cancel = true; this.Visible = true; return; }

if (FrmOperatorInform.frmOperatorInform == null && FrmAmmeterManagement.frmAmmeterManagement == null &&

FrmBuildingManagement.frmBuildingManagement == null && FrmQueryPower.frmQueryPower == null && FrmSimplifyAmmeterManagement.frmSimplifyAmmeterManagement == null &&

FrmSimplifyOperatorInform.frmSimplifyOperatorInform == null)荟蓥闶漸陸讣轾减鈿異。 {

base.OnFormClosing(e);

FrmLoginSystem.frmLoginSystem.ClearTextBoxVerificationCode();鹏筛镐討颛办費叹摄虏。 FrmLoginSystem.frmLoginSystem.Show();

FrmLoginSystem.frmLoginSystem.SetTextVerificationCodeFocus();糝殒锔雋駛鶯诼垆辐驄。 }

else if(FrmSetSystemSerialPort.frmSetSystemSerialPort.IsDisposed==false)頜层铢壶鲜儀計尧當涇。 {

MessageBox.Show(\"该系统中还有未关闭的界面,请先关闭其他界面!\", \"提示\"); e.Cancel = true; }

else if (FrmSimplifyOperatorInform.frmSimplifyOperatorInform.IsDisposed == false)

滚伛钮硕鷙耸蒋忆貯赠。 {

MessageBox.Show(\"该系统中还有未关闭的界面,请先关闭其他界面!\", \"提示\"); e.Cancel = true; } else {

FrmLoginSystem.frmLoginSystem.ClearTextBoxVerificationCode();铣饜酝贻龙鵠臚拧奥凭。 FrmLoginSystem.frmLoginSystem.Show();

第39页

FrmLoginSystem.frmLoginSystem.SetTextVerificationCodeFocus();撾鉬辙魇侨絢绾来诔緊。 }/**/ }

(3)操作员信息管理程序设计

①窗口出现后,将自动从数据库读取信息并将数据显示至DataGridView控件中。程序代码如下:

public void Bind() {

dataGViewOperatorInform.DataSource = null; connection = new SqlConnection(strConnection);

string strSelect = \"SELECT Operator_ID,Operator_Name '用户姓名',Operator_Sex '性别',Operator_UserID '身份证号码',Operator_Address '家庭住址',Operator_TelPhone '联系电话',Operator_State,Admin_Status,Cashier_Status,MeterState_Operator_Status,Query_Operator_Status FROM Operator_Information WHERE Operator_Name!='\" +

FrmLoginSystem.frmLoginSystem.strOperatorName + \"' AND Operator_Name!='admin'\";賒調轧憊劌髋糾殡縣锲。 SqlDataAdapter adapter = new SqlDataAdapter(strSelect,connection);垒羥赎緙呒窍砀渖虯异。 DataSet dataset = new DataSet(); adapter.Fill(dataset);

dataGViewOperatorInform.DataSource=dataset.Tables[0];衅璉贡釙壘颯狽狰侦虜。 dataGViewOperatorInform.Columns[\"Operator_ID\"].Visible=false;畝擱谎为寻瓊涞瞩肾骢。 dataGViewOperatorInform.Columns[\"Operator_State\"].Visible = false;綿嘮诠榉異阌欏箫鹉泾。 dataGViewOperatorInform.Columns[\"Admin_Status\"].Visible = false;騶鸲记蒉戗渗摆绞絎贍。 dataGViewOperatorInform.Columns[\"Cashier_Status\"].Visible = false;现闾袜镒攆錘惻缮騫凱。 dataGViewOperatorInform.Columns[\"MeterState_Operator_Status\"].Visible = false;镄辉蔺敘档檻岂苈祸紧。 dataGViewOperatorInform.Columns[\"Query_Operator_Status\"].Visible = false;梟裥荞獰淪钲壚蚀颈鍥。 dataGViewOperatorInform.RowHeadersVisible = false; }

②如果用户点击条件查询,只有当用户是“admin”时,才有权限查看并修改所有人的信息;如果是其他用户,都将不可以查看和修改“admin”与自己的系统使用权限。程序代码关键内容如下:輟绀脑誒滢搂厨议犧異。 if(radioQueryUserName.Checked==true) {

第40页

if (txtQueryOperator.Text==\"\") {

MessageBox.Show(\"请\\\"输入\\\"查询信息!\", \"提示\"); return; }

else if (FrmLoginSystem.frmLoginSystem.strOperatorName == \"admin\")屡浔缱飛獼轄黨诼鐙虏。 {

//MessageBox.Show(\"存在\\\"admin\\\"用户,但不允许查询!\");

strQuerySelection = \"SELECT Operator_ID,Operator_Name '用户姓名',Operator_Sex '性别',Operator_UserID '身份证号码',Operator_Address '家庭住址',Operator_TelPhone '联系电话

',Operator_State,Admin_Status,Cashier_Status,MeterState_Operator_Status,Query_Operator_Status FROM Operator_Information WHERE Operator_Name='\" + txtQueryOperator.Text + \"'\";诏弑缁岘睑慫龜贮沩驏。 } else {

strQuerySelection = \"SELECT Operator_ID,Operator_Name '用户姓名',Operator_Sex '性别',Operator_UserID '身份证号码',Operator_Address '家庭住址',Operator_TelPhone '联系电话

',Operator_State,Admin_Status,Cashier_Status,MeterState_Operator_Status,Query_Operator_Status FROM Operator_Information WHERE Operator_Name='\" + txtQueryOperator.Text + \"' AND Operator_Name!='\" + FrmLoginSystem.frmLoginSystem.strOperatorName + \"' AND Operator_Name!='admin'\";鳧冲经粮籩赂鸡躯铠潔。 if (txtQueryOperator.Text ==

FrmLoginSystem.frmLoginSystem.strOperatorName && txtQueryOperator.Text!=\"admin\")聰駘絷轳终实騭逻顯赡。 {

MessageBox.Show(\"存在\" + txtQueryOperator.Text + \"用户,但不允许查询自己!\", \"提示\");鯧鋱窃鸨緶諏颤钻邇凯。 }

else if (txtQueryOperator.Text == \"admin\") {

MessageBox.Show(\"存在\\\"admin\\\"用户,但不允许查询!\", \"提示\"); } } }

③当点击DataGridView控件中的任意单元格时,程序会根据唯一标识符自动将信息填入窗体的对应输入框中,以便于操作员修改相关信息。碱賢矫攝胆嘮闊锑恺緊。 private void dataGViewOperatorInform_CellClick(object sender, DataGridViewCellEventArgs e)阕蘆画腎藎觉锼镱赉锲。 {

chkAdministrator.Checked = false;

第41页

chkCashier.Checked = false; chkMeterState.Checked = false; chkQueryCompetence.Checked = false; //将初始化设为\"未选\"

string strAdminStatus = null; string strCashierStatus = null;

string strMeterStateOperatorStatus = null; string strQueryOperatorStatus = null;

txtUserName.Text = dataGViewOperatorInform.CurrentRow.Cells[\"用户姓名\"].Value.ToString();溝礬爷銦蝈刚銪霁寧弃。 txtUserID.Text = dataGViewOperatorInform.CurrentRow.Cells[\"身份证号码\"].Value.ToString();鈣槍滤党許蕁郐饫誥慮。 txtUserAddress.Text = dataGViewOperatorInform.CurrentRow.Cells[\"家庭住址\"].Value.ToString();怿處浊浑诽買躦骟呛骣。 txtUserTelPhone.Text = dataGViewOperatorInform.CurrentRow.Cells[\"联系电话\"].Value.ToString();谢齿毁览賬缲财鳞蠼洁。 comboUserState.Text =

dataGViewOperatorInform.CurrentRow.Cells[\"Operator_State\"].Value.ToString();吶韦桢阖践鴟諍齑蘭贍。 comboUserSex.Text = dataGViewOperatorInform.CurrentRow.Cells[\"性别\"].Value.ToString();萊郦晋壩辭終裥俠輿擊。 strAdminStatus =

dataGViewOperatorInform.CurrentRow.Cells[\"Admin_Status\"].Value.ToString();鷲诅捡瞇钗骘蓀剝黃絷。 strCashierStatus =

dataGViewOperatorInform.CurrentRow.Cells[\"Cashier_Status\"].Value.ToString();纫绾懔賬鍘禅耧啞绵鍇。 strMeterStateOperatorStatus =

dataGViewOperatorInform.CurrentRow.Cells[\"MeterState_Operator_Status\"].Value.ToString();颟灿忏騅锰顆繡奪鲔棄。 strQueryOperatorStatus =

dataGViewOperatorInform.CurrentRow.Cells[\"Query_Operator_Status\"].Value.ToString();潛愦巅怼閑貓简巒競虑。 if(strAdminStatus==\"1\") {

chkAdministrator.Checked = true; }

if (strCashierStatus == \"1\") {

chkCashier.Checked = true; }

if (strMeterStateOperatorStatus == \"1\") {

chkMeterState.Checked = true;

第42页

}

if (strQueryOperatorStatus == \"1\") {

chkQueryCompetence.Checked = true; } }

(4)电表信息管理程序设计

①当连接数据库时,程序所使用的连接字符串的标准格式。

string strConnection = @\"Data Source=.\\SQLEXPRESS;Initial

Catalog=SmartMeterSystemDB;Integrated Security=true;User ID=sa;Password=sa\";鏟却审绪鞑闻癬惱颯驏。 ②当用户在ComboBox下拉框中选择完成一个楼栋后,程序将自动得到对应该楼栋的楼层数量,并从数值1开始依次排至对应数量值,供用户选择。掳鱘壳郏餳涡烂摻玺灑。 private void comboMeterBuildingFloor_SelectedIndexChanged(object sender, EventArgs e)

赝鐨喾龉骐銻潑櫟闻赢。 {

this.comboMeterLayer.Items.Clear(); string strTempBuildingLayer = null; int IntTempBuildingLayer;

string strTempQuerySqlLayer = \"SELECT Building_Layer_Num FROM Building_Management WHERE Meter_Building_Name='\" + comboMeterBuildingFloor.Text + \"'\";殼贈叹橈鯛槳栌滄滸击。 using(connection=new SqlConnection(strConnection)) {

connection.Open();

using(command=new SqlCommand(strTempQuerySqlLayer,connection))襉藍动蔭鹗钣掙濰鋱縶。 {

reader = command.ExecuteReader(); while(reader.Read()) {

strTempBuildingLayer =

reader.GetString(reader.GetOrdinal(\"Building_Layer_Num\"));伞箋内鍶乐捞忆瓊柠锴。 //comboMeterLayer.Items.Add(strTempBuildingLayer); }

IntTempBuildingLayer = int.Parse(strTempBuildingLayer);缅殲伤却兗輔宮礡酽弃。 for (int i = 1; i <= IntTempBuildingLayer;i++ ) {

comboMeterLayer.Items.Add(i); } }

第43页

}

comboMeterLayer.SelectedIndex = 0; }

③当点击添加按钮时,SqlCommand控件对象command需要先连接数据库,然后再执行相应的语句,并通过一个int对象来记录添加结果的数量,如果结果为零则说明数据库中为主键的字段产生重复值,即“已存在该电表表号”。程序代码如下:骊嘗丛烟协彈噜約戲虛。 private void btnChangeAddInform_Click(object sender, EventArgs e)畫價鸚诠喲贳區綢躉骤。 {

if (txtMeterName.Text == \"\" || txtMeterNum.Text == \"\" ||

comboMeterBuildingFloor.Text == \"\" || comboMeterLayer.Text==\"\")鏜飘鳶颗奁娱侨聹屿洒。 {

MessageBox.Show(\"请输入电表基本信息!\"); return; }

connection = new SqlConnection(strConnection);

string strTimeNow=DateTime.Now.ToString(\"yyyy-MM-dd hh:mm:ss\");栖钸鰹尋嵐詡黪滎谌贏。 string strInsert = \"INSERT INTO

Ammeter_Management(Ammeter_Meter_User_Name,Ammeter_Meter_Query_Number,Ammeter_Address,Ammeter_PassWord,Ammeter_State,Meter_Building_Name,Meter_Layer_Num,Create_Meter_Date,Create_Meter_UserName,Modify_Meter_Date,Modify_Meter_UserName) VALUES('\" + txtMeterName.Text + \"','\" + txtMeterNum.Text + \"','\" + txtMeterAddress.Text + \"','\" + txtMeterPassword.Text + \"','\" + comboMeterState.Text + \"','\" + comboMeterBuildingFloor.Text + \"','\" + comboMeterLayer.Text + \"','\" + strTimeNow + \"','\" + FrmLoginSystem.frmLoginSystem.strOperatorName + \"','\" + strTimeNow + \"','\" + FrmLoginSystem.frmLoginSystem.strOperatorName + \"')\";辩诿驂籌怃詠鰈蠷嚳擊。 SqlCommand command = new SqlCommand(strInsert, connection);崢罚饋蹤擁袭驻詐覬絷。 connection.Open(); int IntMeterAddCount; try {

IntMeterAddCount = (int)command.ExecuteNonQuery(); }

catch(Exception) {

MessageBox.Show(\"已存在该电表\\\"表号\\\"!\"); return; }

if (IntMeterAddCount != 0)

MessageBox.Show(\"\\\"添加\\\"电表成功!\"); else {

MessageBox.Show(\"\\\"添加\\\"电表失败!\");/**/ return; }

第44页

connection.Close(); Bind();

FrmMainSystem.frmMainSystem.RefreshTreeViewBuilding();誕珏顳鰭晕净頗諤凯鏘。 }

④当点击修改按钮时,需要注意的是系统会自动记录下当前的表号,使得修改者只能修改除表号之外的其它信息,使用的是一个全局变量OverAllMeterNum。关键代码如下所示:

刽掺韉挣櫧煢闺賅茧弒。 connection = new SqlConnection(strConnection);

string strUpdate = \"UPDATE Ammeter_Management SET Ammeter_Meter_User_Name='\" + txtMeterName.Text + \"',Ammeter_Meter_Query_Number='\" + txtMeterNum.Text + \"',Ammeter_Address='\" + txtMeterAddress.Text + \"',Ammeter_PassWord='\" + txtMeterPassword.Text + \"',Ammeter_State='\" + comboMeterState.Text + \"',Meter_Building_Name='\" + comboMeterBuildingFloor.Text + \"',Meter_Layer_Num='\" + comboMeterLayer.Text +

\"',Modify_Meter_Date='\"+DateTime.Now.ToString(\"yyyy-MM-dd

hh:mm:ss\")+\"',Modify_Meter_UserName='\"+FrmLoginSystem.frmLoginSystem.strOperatorName+\"' WHERE Ammeter_ID='\" + MeterID + \"'\";胶哜閶罚测丟錕轎與虚。 SqlCommand command = new SqlCommand(strUpdate,connection);鳏鸕鐓铃爐缢钺鑑緩驟。 connection.Open(); int IntChangeCount;

if (txtMeterName.Text == \"\" || txtMeterNum.Text == \"\")祕閨鍵儕瓯鱧遠鋮鯛灑。 {

MessageBox.Show(\"请选择有效的\\\"修改\\\"条目!\"); return; } else { try {

IntChangeCount = (int)command.ExecuteNonQuery(); }

catch(Exception) {

MessageBox.Show(\"已存在该电表\\\"表号\\\"!\"); return; } }

⑤当用户点击删除按钮时,程序会对用户所选择的电表将其删除。程序代码如下:

connection = new SqlConnection(strConnection);

string strDelete = \"DELETE FROM Ammeter_Management WHERE Ammeter_ID='\"+MeterID+\"'\";陘輔銨澩礙紛赶錙类赢。 SqlCommand command = new SqlCommand(strDelete,connection);泻襠鐵補粤骄謗闥饽凿。 connection.Open(); int IntDelCount;

if (txtMeterName.Text == \"\" || txtMeterNum.Text == \"\")钨紡釤閭綆硗诌顧癢糾。 第45页

{

MessageBox.Show(\"请选择有效的\\\"删除\\\"条目!\"); return; } else

IntDelCount = command.ExecuteNonQuery(); if(IntDelCount!=0) {

MessageBox.Show(\"\\\"删除\\\"电表成功!\"); } else {

MessageBox.Show(\"\\\"删除\\\"电表失败!\"); return; }

⑥因为一般情况下,当一个用户所对应的电表投入使用后,电表是不易损坏的,故只有用户明确要换电表时,才会去修改表名——表号对应信息。当用户点击换表按钮时,也才会允许用户修改电表表号。其与“修改” 按钮的不同点在于数据库的执行语句上:慳瀏遲嘘缨預蝸饞闕锵。 string strUpdate = \"UPDATE Ammeter_Management SET Ammeter_Meter_User_Name='\" + txtMeterName.Text + \"',Ammeter_Meter_Query_Number='\" + txtMeterNum.Text + \"',Ammeter_Address='\" + txtMeterAddress.Text + \"',Ammeter_PassWord='\" + txtMeterPassword.Text + \"',Ammeter_State='\" + comboMeterState.Text + \"',Meter_Building_Name='\" + comboMeterBuildingFloor.Text + \"',Meter_Layer_Num='\" + comboMeterLayer.Text +

\"',Modify_Meter_Date='\"+DateTime.Now.ToString(\"yyyy-MM-dd

hh:mm:ss\")+\"',Modify_Meter_UserName='\"+FrmLoginSystem.frmLoginSystem.strOperatorName+\"' WHERE Ammeter_ID='\" + MeterID + \"'\";譜廩軾痪輿猶苏鮐湿弑。 (5)楼栋信息管理程序设计

①该部分内容中所包含的程序功能同样是:查询、增加信息、修改信息、删除信息。不同之处在于当删除所选择的楼栋时,程序会自动查找该楼栋上是否存在用户,如果存在那么不允许删除楼栋。关键代码如下所示:哒寫趙谪蒉闪纓鴯锟虛。 string strSelectInform = \"SELECT Ammeter_Meter_User_Name FROM

Ammeter_Management WHERE Meter_Building_Name='\" + strBuildingName + \"'\";萨驼貰驺襤浈绊丝檢骥。 int IntCount = 0;

using (connection = new SqlConnection(strConnection))鼍铸讜強诒鏈窮傩鐘洼。 {

connection.Open();

using (command = new SqlCommand(strSelectInform, connection))紓负誨絨諤棟畴卧拨贛。 {

reader = command.ExecuteReader();

第46页

while(reader.Read()) {

IntCount++; } } }

if(IntCount!=0) {

MessageBox.Show(\"该栋楼仍存在用户,不可\\\"删除\\\"楼栋!\"); return; }

②当用户点击修改按钮时,如果被修改的楼层上仍有用户存在,则提示“不可修改”,只有当用户移除时,才允许减少楼栋上的楼层数量。程序代码如下所示:飛节評違贽钐瀟嗳轭鑿。 using (connection = new SqlConnection(strConnection))炜瞒覬麥轉拦氩婶幃纠。 {

connection.Open();

using (command = new SqlCommand(strQuerySelectOldLayerNum, connection))锂枢蠱枨递轤條广謹鏘。 {

reader = command.ExecuteReader(); while(reader.Read()) {

strBuildingName =

reader.GetString(reader.GetOrdinal(\"Meter_Building_Name\"));搖壮蒔茏鈀廡抟戆坟張。 strBuildingLayerNum =

reader.GetString(reader.GetOrdinal(\"Building_Layer_Num\"));踐鼉艷错铹贤庫敌讲虬。 } } }

int IntTempCount = 0;

for (int i = 0; i < strArraySelectBuildingOldLayerNum.Length; i++)妇靜聶務鎳奋娆椭勞驥。 {

if (strArraySelectBuildingOldName[i] == strBuildingName)觏郟縷瀾阋誠噦浍蕕窪。 {

break; } else {

IntTempCount++; } } int

第47页

IntOldBuildingNum=int.Parse(strArraySelectBuildingOldLayerNum[IntTempCount]);偵証繡診頌嗎刹烛亚赣。 int IntNewBuildingNum=int.Parse(strTextBoxBuildingNewLayerNum);縷綹綱顧馅蝇儀痫缮凿。 int IntSubtract=IntOldBuildingNum-IntNewBuildingNum;騫滅篩婵髕兹鶚窍鸢紆。 string strSQLCountInLayerUser=null; int IntQueryAllLayerUser = 0;

for (int i = IntNewBuildingNum + 1; i < IntOldBuildingNum+1; i++)痨憚礙穷鳢薌鲟绁納锶。 {

strSQLCountInLayerUser = \"SELECT Ammeter_Meter_Query_Number FROM

Ammeter_Management WHERE Meter_Building_Name='\" + strArraySelectBuildingOldName[IntTempCount] + \"' AND Meter_Layer_Num='\" + i.ToString() + \"'\";镪盧癉赝黷龉饋缒駙张。 using (connection = new SqlConnection(strConnection))櫺鲚獵鲨眾缒韪脑睐虯。 {

connection.Open();

using (command = new SqlCommand(strSQLCountInLayerUser, connection))

遲锾災掄凉鰒鐲萨靓骥。 {

reader = command.ExecuteReader(); while(reader.Read()) {

IntQueryAllLayerUser++; } } } }

if (IntQueryAllLayerUser != 0) {

MessageBox.Show(\"失败!被\\\"修改\\\"的楼层上还有\" + IntQueryAllLayerUser + \"个用户存在!\");帏赛澗縑縣約锁觇燈洼。 return; }

(6)用户用电信息记录查询程序设计

当用户希望查询用电记录时,可以通过多种条件进行查询。例如可以直接通过DateTimePicker控件进行时间范围内的查询或者通过“时间范围”外加“按表号”三个条件进行查询,程序代码如下所示:诮蒇沒鈄囱驴鈑诠鏤趙。 string strSmartMeterDBData = null;

connection = new SqlConnection(strConnection);

if (radioMeterNum.Checked == false && radioUserName.Checked == false && radioFreezeDate.Checked == false && radioBuildingNum.Checked == false)勞笃欖优嬸瞩辐谬殁芻。 第48页

{

strSmartMeterDBData = \"SELECT Query_User_ID,Ammeter_Meter_Query_Number '表号',Query_Meter_Name '表名称',Power_Freeze_Date '冻结日期',Power_Return_Time '返回时间',User_FreezeNow_Power '冻结电量(度)',User_DayUse_Power '当日用电(度)' FROM Query_Power WHERE Power_Freeze_Date>='\" + dateTimePickerBegin.Text + \"' AND Power_Freeze_Date<='\" + dateTimePickerEnd.Text + \"'\";膃檩樅氇帐頁賚赡钺纡。 MessageBox.Show(\"请\\\"选择\\\"一个查询的条件!\\n允许此次!\"); }

else if(radioMeterNum.Checked==true) {

if (txtQueryRadioSelect.Text==\"\") {

MessageBox.Show(\"请\\\"输入\\\"需要查询的信息!\"); return; } else

strSmartMeterDBData = \"SELECT

Query_User_ID,Ammeter_Meter_Query_Number '表号',Query_Meter_Name '表名称',Power_Freeze_Date '冻结日期',Power_Return_Time '返回时间',User_FreezeNow_Power '冻结电量(度)',User_DayUse_Power '当日用电(度)' FROM Query_Power WHERE Ammeter_Meter_Query_Number='\" + txtQueryRadioSelect.Text + \"' AND Power_Freeze_Date>='\" + dateTimePickerBegin.Text + \"' AND Power_Freeze_Date<='\" + dateTimePickerEnd.Text + \"'\"; }雞寿擺蛊憫燴谌辙擱鍶。 (7)系统设置程序设计

当用户点击“串口检测”按钮时,程序需要自动检测出当前系统所存在的串口列表。

Private void btnCheckSerialPort_Click(object sender, EventArgs e)窦从掄门掳镦諱钟輞張。 {

comboSelectSerialPort.Items.Clear();

FrmMainSystem.frmMainSystem.serialComm.Close();//此处语句是为了当要设置新串口时需要关闭原旧串口,否则会出错霭颮慟嗶梟泶虏铲弯虽。 for (int i = 0; i < 256;i++ ) {

try

FrmMainSystem.frmMainSystem.serialComm = new SerialPort(“COM” + (i + 1));澮鉗廬 {

瑤毂錚膃镐贩驤。 FrmMainSystem.frmMainSystem.serialComm.Open(); FrmMainSystem.frmMainSystem.serialComm.Close();

comboSelectSerialPort.Items.Add(“COM”+(i+1)); }

catch(Exception) {

第49页

} }

lblStatus.Text = “COM” + (i + 1) + “不可用”;

continue;

lblStatus.Text = comboSelectSerialPort.Items.Count + “个COM口可用”;鈽讀屜諤淥樞缏阖奩浹。 if (comboSelectSerialPort.Items.Count != 0) { } else { } }

comboSelectSerialPort.Text = “”;

comboSelectSerialPort.SelectedIndex = 0;

(8)修改操作员密码程序设计

①当用户准备修改自己的密码时,程序会询问用户是否自动填写用户旧密码,以此方便操作员操作。当然在自动填写信息时会使用“*”来影藏密码信息,以此保护密码安全。懑纘嫗餿爱酾紕颚詔赵。 Using (connection = new SqlConnection(strConnection))账瑋場帼癟扫碜驽厣刍。 {

connection.Open();

using (command = new SqlCommand(strSQLSelectPass, connection))嗇擄嗚纽稳躥獺鲰藓紆。 {

reader = command.ExecuteReader(); while(reader.Read()) {

strUserPassword =

reader.GetString(reader.GetOrdinal(“Operator_PassWord”));藹嗶衛辔紗帥渑鹜體锷。 } } }

DialogResult result= MessageBox.Show(“\\”旧密码\\”自动填写?”,”提示”,MessageBoxButtons.OKCancel,MessageBoxIcon.Question);齲鸨鳧鹎绻谭櫞畝肅弥。 if(result==DialogResult.OK) {

txtOldPassword.Text = strUserPassword; txtOldPassword.PasswordChar = ‘*’; }

②确认新密码框主要是为了保证用户所输入的密码是用户自己确认的、可知的。所以在程序的设置密码过程中,首先会对确认框内容进行判断,再才会进行后面的判断。程序代码

第50页

如下:绌闶儔曉翹堕斓淨鵝雖。

{

.

. .

if (txtNewPassword.Text != txtSureNewPassword.Text)饲辁書艦茏診慣敘绑骧。 MessageBox.Show(\"\\\"确认新密码\\\"框有变动,请重新输入\\\"新密码\\\"!\",\"提示\");

燼袅黾鏗蝦廚嵘塢骚浃。 ClearTextBox(); return; }

connection = new SqlConnection(strConnection);

string strUpdatePassword = \"UPDATE Operator_Information SET

Operator_PassWord='\" + txtNewPassword.Text + \"' WHERE Operator_Name='\" + strUpdatePassUser + \"' AND Operator_PassWord='\" + txtOldPassword.Text + \"'\";鋦纶鸹击讣蚂殼將礡趙。 . . .

(9)权限管理

由于系统的运行需要一定的安全性,所以对所有使用该系统的用户进行一定的权限管理是非常必要的。在智能电表管理系统的设计过程中,以用户查看用电记录窗口为例,如果自己有查询权限,那么便可以查看用电记录,否则会被系统提示“没有查询权限”。关键判断代码如下:斋浊鲸溃諢偬吗彥預劉。 string strSelectCompetence = \"SELECT

Operator_State,Limits_Of_Add,Limits_Of_Change,Limits_Of_Delete,Admin_Status,Cashier_Status,MeterState_Operator_Status,Query_Operator_Status FROM Operator_Information WHERE

Operator_Name='\" + FrmMainSystem.frmMainSystem.ReturnSystemOperatorName() + \"'\";躜应髋讳谬臘決攏爱红。 string strOperatorState = null; string strQueryOperatorStatus = null;

using (connection = new SqlConnection(strConnection))嬰冁驶靓賴黪举殺镦鍔。 {

connection.Open();

using (command = new SqlCommand(strSelectCompetence, connection))訌駙饥奩辆缁鸶殞灃彌。 {

reader = command.ExecuteReader(); while (reader.Read()) {

strOperatorState = reader.GetString(reader.GetOrdinal(\"Operator_State\"));偻鐋顿礡釃鯖髕瀆鐺虽。 strQueryOperatorStatus =

第51页

reader.GetString(reader.GetOrdinal(\"Query_Operator_Status\"));缥譫阵資铈類饩獨时驤。 } } }

if (strOperatorState == \"正常\") {

if (strQueryOperatorStatus == \"0\") {

MessageBox.Show(\"对不起,该用户没有\\\"用电查询\\\"权限!\", \"提示

\",MessageBoxButtons.OK,MessageBoxIcon.Information);魉艫问鮒鋦馈陝睞远淺。 frmQueryPower.Dispose();//此句非常重要,不可以省略 return; } }

五、关键技术

5.1构造合适的16进制通信数据

此段程序来源于另一个项目“串口调试助手”,其中程序会将用户输入的表号、控制码、数据标示等信息通过发送按钮自动转换成了字符格式的16进制数据,在此处本程序将该功能封装成了一个函数,供其他控件进行调用。皸睜镄慑镪皱镒篋懇赶。

public string StringsConvertHexadecimal(string strMeterNumber,string strControlCode,string strDataMark,string strMeterPassword,string strDataInformation)//转换程序,由输入的标志码转换成需要发送给电表的进制形式的字符串問榪锉缌陳霧鎩絢資刘。 {

string ConvertResult = null; string t = null;

第52页

int t1 = (strDataMark.Length + strMeterPassword.Length + strDataInformation.Length) / 2;

横堝铗钕颞煬钇繆嬷紅。 string[] a = null; string zhuan = null;

t = t1.ToString(\"X2\");//此处用于计算'数据标示','密码','数据'的进制长度值邬黩钦鄉駙镓軼蘆诬锷。 //此处要恢复

a = new string[strMeterNumber.Length];

for (int i = 0; i < (strMeterNumber.Length) / 2; i++)應雾邻櫓鲠汇贲虯嚦弥。 {

a[2 * i] = strMeterNumber[strMeterNumber.Length - 2 - 2 * i].ToString();誹邮辐驀鴰銅誦讓蟈蝦。 a[2 * i + 1] = strMeterNumber[strMeterNumber.Length - 1 - 2 * i].ToString();卧讽蹑鏞龟暉觐諸儿髅。 }

for (int i = 0; i < strMeterNumber.Length; i++) {

zhuan = zhuan + a[i]; }

ConvertResult = \"FE68\" + zhuan + \"68\" + strControlCode + t;芦绵赅吨侪邬營貪腻浅。 string text = strDataInformation + strMeterPassword + strDataMark;鸵澜谲猃剮愦肿躕鹾趕。 char[] ch;

ch = text.ToCharArray(); string sum = null;

string[] r = new string[ch.Length]; string s = null;

string[] b = new string[2]; string fin = null;

for (int k = 0; k < ch.Length; k++) {

for (int x = 0; x < 2; x++) {

if (k - 2 * (k / 2) == 0) {

sum = null; sum = sum + ch[k]; k++; } else

sum = sum + ch[k];

}

int i = int.Parse(sum, System.Globalization.NumberStyles.HexNumber);籌惩谄课呕蹌綬選綽劉。 i += 51;

第53页

s = i.ToString(\"X2\"); for (int j = 0; j < 2; j++) {

b[1 - j] = s[s.Length - 1 - j].ToString(); }

for (int j = 0; j < 2; j++) {

fin += b[j]; } }

string all = null;

string[] c = new string[fin.Length]; for (int l = 0; l < (ch.Length) / 2; l++) {

c[2 * l] = fin[2 * ((ch.Length) / 2 - 1 - l)].ToString();頂华诗饬墊嶧粝鈽鮑纣。 c[2 * l + 1] = fin[2 * ((ch.Length) / 2 - 1 - l) + 1].ToString();润鮭讦崢寿谝睪鋒窥鍤。 }

for (int l = 0; l < ch.Length; l++) {

all += c[l]; }

ConvertResult = ConvertResult + all; string add1 = ConvertResult; char[] add2;

add2 = add1.ToCharArray(); int add3 = 0; string add4 = null;

string[] add5 = new string[2]; string add6 = null;

for (int k = 0; k < add2.Length; k++) {

for (int l = 0; l < 2; l++) {

if (k - 2 * (k / 2) == 0) {

add1 = null;

add1 = add1 + add2[k]; k++; } else {

add1 = add1 + add2[k]; } }

第54页

add3 = add3 + int.Parse(add1, System.Globalization.NumberStyles.HexNumber);铆鍬蠼纖張坞牍鑊颦弳。 }

add3 = add3 - 254;

add4 = add3.ToString(\"X2\"); for (int i = 0; i < 2; i++) {

add5[1 - i] = add4[add4.Length - 1 - i].ToString();揚賴蓝軾戬許渾雛瑪虾。 }

for (int i = 0; i < 2; i++) {

add6 += add5[i]; }

ConvertResult += add6.ToString() + \"16\"; return ConvertResult; }

5.2串口通信发送16进制数据实现

此段程序使用了正则表达式的手法将通信数据写入了串口中,从而实现了发送数据操作硬件的功能。

public string AboutRadioUpDownMeter(string strInformation)貴縈茑鴛攛臥桩餳閌髏。 {

//我们不管规则了。如果写错了一些,我们是允许的,只用正则得到有效的十六进制数 int IntCount = 0;/**/

MatchCollection mc = Regex.Matches(strInformation, @\"(?i)[\\da-f]{2}\");园竇胧撵桥蔺攙騖浍淺。 List buf = new List();//填充到这个临时列表中 //依次添加到列表中 foreach (Match m in mc) {

buf.Add(byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber));蚂櫫缨胪滬侣恋鱉铸趋。 }

if(FrmMainSystem.frmMainSystem.serialComm.IsOpen==false)嚴寢绸铩滥朧屜黿棖则。 {

try { }

catch(Exception) {

MessageBox.Show(\"对不起,串口打开失败!\",\"提示

\",MessageBoxButtons.OK,MessageBoxIcon.Information);絕親织內貓鹨坛伫鄖紂。 FrmMainSystem.frmMainSystem.serialComm.Open();

第55页

return null; } } try { }

catch(Exception) {

MessageBox.Show(\"端口被关闭!\", \"提示\", MessageBoxButtons.OK, MessageBoxIcon.Information);饋颤类潿瞒绯壓剀懑锸。 return null; }

string strCount=buf.Count.ToString(); //记录发送的字节数 IntCount = buf.Count;

send_count += IntCount; //累加发送字节数 return buf.Count.ToString(); }

//转换列表为数组后发送

serialComm.Write(buf.ToArray(), 0, buf.Count);

5.3串口通信接收硬件返回的16进制数据的实现

通过从串口以此读取数据,首先需要获取接收缓冲区中数据的字节数,然后从serialComm串口对象中读取数据,最后以2字节的形式将数据读取到全局变量中供后面程序使用。狈钯积觴箏鮫傥咏赵弪。 public string comm_DataReceived()//对于程序接收了电表的返回数值时的相应接收程序模块锩请眯階绊簽龉复屆蝦。 {

int n = serialComm.BytesToRead; //获取接收缓冲区中数据的字节数 byte[] buf = new byte[n]; serialComm.Read(buf, 0, n); buffer.AddRange(buf); if (flag == true) {

foreach (byte b in buf) {

builder += b.ToString(\"X2\"); }

strGetReturnCommDataReceived = builder; }

return strGetReturnCommDataReceived; }//需要完善的程序

第56页

5.4分析硬件返回数据转换为用户可读数据

此段程序仍然来源于“串口调试助手”,其作用是程序自动分析电表返回的字符形式的数据,以查询电量为例,程序发送查询指令后,将自动接收返回的数据,对其进行16进制转换10进制操作,从而可以得到用户当前用电量的功能。暉缱琐垩緩饱鱖峄誶髋。 public string HexadecimalConvertStrings(string strMeterUsePowerNow)//转换程序,将电表返回的进制形式的电量值数值码转换成人可读的具体当前电量值軸献烩矶胧痒骏恸啭浆。 {

string strTextBox3 = null;//可能是没用的一个变量,但是源程序存在

StringBuilder strbuf = new StringBuilder(strTextBox3);//初始化缓存块审捡溆贮葒隴顏据视趨。 string str1 = null; str1 = strMeterUsePowerNow; string[] str2 = new string[8]; string[] str3 = new string[4]; string str5 = null; string str15 = null; string str7 = null; string str17 = null;

string[] str8 = new string[2]; string[] str9 = new string[2]; string[] str19 = new string[2]; string fin2 = null; string fin3 = null; int i2; int i12; int i3 = 0; char[] ch;

string[] str13=null; //ch = str1.ToCharArray(); try {

ch = str1.ToCharArray();

while ((str1[i3].ToString() != \"6\") || (str1[i3 + 1].ToString() != \"8\"))许响洁骞蝎瀠阌栊凜則。 {

i3++; }

for (int i = 23 + i3, j = 0; j < 4; i--, j++) {

str3[j] = str1[i].ToString(); }

第57页

str13 = new string[str1.Length - 5 - 23 - i3]; }

catch(Exception) {

return null; }

for (int i = (str1.Length - 1 - 4), j = 0; i > (23 + i3); i--, j++)茲鳶歼愷訟锾鏘沣蘢纣。 {

str13[j] = str1[i].ToString(); } try {

for (int k = 0; k < str3.Length; k++) {

for (int l = 0; l < 2; l++) {

if (k - 2 * (k / 2) == 0) {

str5 = null; str5 += str3[k]; k++; } else {

str5 += str3[k]; } }

i2 = int.Parse(str5, System.Globalization.NumberStyles.HexNumber);繳閑栌綿诿殓铋滩龔鍤。 i2 -= 51;

str7 = i2.ToString(\"X2\"); for (int j = 0; j < 2; j++) {

str9[1 - j] = str7[str7.Length - 1 - j].ToString();鱭軾斩醬販鈰鄺珑缍彎。 }

for (int j = 1; j >= 0; j--) {

fin2 += str9[j]; } } }

catch (Exception) {

第58页

return null; } try {

for (int k = 0; k < str13.Length; k++) {

for (int l = 0; l < 2; l++) {

if (k - 2 * (k / 2) == 0) {

str15 = null; str15 += str13[k]; k++; } else {

str15 += str13[k]; } }

strTextBox3 = str15.ToString();

i12 = int.Parse(str15, System.Globalization.NumberStyles.HexNumber);瞩補挠万跸齋踬碍鲲虿。 i12 -= 51;

str17 = i12.ToString(\"X2\"); for (int j = 0; j < 2; j++) {

str19[1 - j] = str17[str17.Length - 1 - j].ToString();闼紗惮梦邊违譴红籬髖。 }

for (int j = 1; j >= 0; j--) {

fin3 += str19[j]; } } }

catch (Exception) {

return null; }

if (fin3 == null) {

fin3 += \"\"; } else

第59页

fin3 += \" \";

strbuf.Append(fin3 + fin2 + \"\\r\\n\"); strTextBox3= strbuf.ToString(); int IntResult=0; try {

IntResult = int.Parse(fin3); }

catch(Exception) {

return null; }

float FloatResult = (float)IntResult / 100; return FloatResult.ToString(); }

六、安装与使用说明

6.1安装说明

确保所使用的是运行库是Microsoft .Net Framework 2.0,若使用了Microsoft .Net Framework 3.5或者Microsoft .Net Framework 4.0,请同时安装2.0版本的。数据库请使用微软平台的SQL Server系列,以此保证数据库文件能够装载成功并使用正常。殞淺归莶钛悫话维饒漿。 6.2使用说明

智能电表管理系统主要包含四个方面的特色及功能:

(1)简洁的操作界面,操作员可以很轻松的掌握系统中各个功能的使用方法;

(2)串口通信能力,使用本系统,操作员可以直接管理电表硬件,读取电量、控制电表通断电流等。

(3)相对完善的数据库设计,在设计过程中数据库个字段命名合理规范,在满足系统当前使用需求的前提下,仍考虑了系统的扩展性需求,因而增加了部分有意义的字段。釃慶峥镀鋌賺襪聂疡趋。 (4)较强的权限管理功能,在使用过程中每个用户的使用操作范围应该是不同的,也只有这样,整个系统的运行与管理才可能更安全,通过在数据库中设定字段,而让权限管理更方便。强興嬷廁锴層荣荡阔则。 6.3注意事项

(1)智能电表管理系统在使用过程中包含一定的权限管理功能,所以请系统管理者慎重的分配操作员使用权限。

第60页

(2)设置COM串口方式

首先运行PL-2303 Driver Installer.exe驱动文件,然后在任意一个USB口插上USB TO RS232转接口。谌驴埘煥閔谎罰蝉瀋纖。

右键“属性”

第61页

选择“高级”

七、致谢

感谢我的导师乔晓琳老师和班主任池瑞楠老师,他们一直在努力开导我,让我在面对困难时要保持信心,他们工作严谨细致,是我学习的榜样;他们循循善诱的教导给予我无尽的启迪。廚铯唤諢韧囱络诃錯锹。 感谢贝纳微电有限公司的王力工程师,虽然他并不懂得我所使用的编程语言,不能在这个项目中给我直接的帮助。因为他本身是一位硬件专家,精通电路板等底层硬件的编程,所以在涉及串口通信方面的知识时,他还是给了我非常大的帮助,没有他我就不可能在如此短的时间内完成C#串口通行部分的操作,没有他我更不可能在编程方面得到如此快速的进步。

煢谱参顙飪訌籠谐桧弯。 感谢的人员还有很多很多,贝纳工程部的赵姐、索意姆有限公司的罗总等等,他们都给

第62页

了我很大的支持与鼓励。

八、参考资料

【1】《21天学通C#》 秦婧 电子工业出版社 2011年 【2】《C#语言基础教程》 张威 人民邮电出版社 2011年 【3】《软件测试技术》 徐芳 机械工业出版社 2006年 【4】《ASP.NET 3.5宝典》 靳华 电子工业出版社 2009年 【5】《精通ASP.NET 2.0企业级项目开发》 陈冠军 人民邮电出版社第63页

2007年

因篇幅问题不能全部显示,请点此查看更多更全内容