地震台站数字化改造以来,前人即进行了关于地震前兆台站环境监控系统简单应用的相关研究(刘春国等,2002;周振安等,2006);随后,王秀英等(2009)针对前兆动态报警信息发送问题给出了TCP/UDP解决方案,该方案通过FTP协议、SQL/Oracle数据库语句操作等方式提高了前兆台网数据监控的效率(王建国等,2010;马文娟等,2011);黑龙江省地震局、湖北省地震局等基于Nagios、HostMonitor等应用软件编程,实现了地震网络化设备的实时监控(李刚等,2012;高东辉等,2013;胡玉良等,2016)。
地震系统编程技术逐渐普及以来,出现了应用VB、C#等语言自主研发的台站智能单台/套数据监控软件及可实现台网模拟数据智能下载、上传的软件(殷志刚等,2012;程冬焱等,2016;王莉森等,2016);安凯杰等(2020)则研发出了基于手机平台上的地震台站电源监控系统。近年来,Python语言的开源性、易操作性使其成为最流行的编程语言之一,赵祖虎等(2022)基于Python语言研发了地震观测仪器自动监控软件,实现部分前兆仪器可视化监控。虽然已研发的监控软件较多,但关于监测台站的测震与前兆仪器、分钟采样数据与秒采样数据综合监控软件的研究并不多。本研究基于Python语言设计研发1款能够监测前兆全学科和测震多台/套仪器的综合监控软件。
1 研究思路及技术路径巴彦淖尔地震监测中心站(以下简称巴彦淖尔站)位于内蒙古巴彦淖尔市临河区。巴彦淖尔站现共有15套仪器设备。观测山洞地处河套盆地北缘和阴山山脉的交界带,开凿于1972年,山洞洞室进深253 m,台基岩性为花岗岩,完整性好,平均覆盖厚度189 m,观测条件较好(胡玮等,2022)。山洞内现有形变观测仪器4套,气象三要素仪1套,重力仪1套,测震仪器1套。地电观测台位于乌拉特中旗乌加河镇,观测场地面积为150亩,现有地电阻率仪、地电场仪2套设备。地磁台位于临河区八一乡,占地7亩,现有地磁观测仪器3套。此外,还在乌拉特前旗西山咀设有形变仪器2套,在额济纳旗策克口岸设有测震仪器1套(表 1)。
设计的综合监控软件程序框架如图 1所示。程序的整体程序框架是以Schedule方法建立1个无限循环,设置固定的巡检时间间隔(如10 min)以及下载仪器数据的时间节点(如08:30、12:00、15:00、21:00等),每天在这些时间节点上运行以Multiprocessing()(本文提到的Python函数后带括号,意为立即执行该函数并获得返回值)方法建立的包含15套仪器在内的访问、实时数据下载与存储、数据绘图与存储、网络通断检测(仅用于测震仪器)、仪器异常检查、故障报警等在内的15个多线程并行任务。经巡检,判断为仪器状态正常的线程结束此次任务,判断为仪器故障的线程则启动警报任务。对于程序判断为状态正常的仪器,仍需值班人员定期查看已存储的数据图件以最终确定仪器状态。判断不同学科的仪器状态有不同的标准,详见下文。
将所有仪器的URL访问、数据下载、异常判断各自写为1个仪器函数,共计15个仪器函数;所有仪器函数共用的绘图功能、警报功能、EP-Ⅲ型IP采集控制器的URL英文字母推算功能、自动获取浏览器安装位置功能等均单独写为1个功能函数。巡检的每1次循环运行均由Schedule模块调用Multiprocessing()函数并传递相关参数,由Multiprocessing()函数调用15个仪器函数并传递相关参数,再由仪器函数调用功能函数。
2 综合监控的设计与实现 2.1 测震仪器针对测震仪器所产生的数据编码方式为CMPDATAFRM格式。由于该格式的文件数据量大且解压缩算法复杂,若以Python程序计算并判断仪器状态将导致程序运行负荷过大、效率低下,而测震仪器要求数据的实时记录不可中断,只要网络出现故障就需要值班人员第一时间查找并解决问题。故监控软件跳过测震仪器的访问和数据下载等环节,直接采用第三方库pythonping中的ping()函数来检测测震仪器的网络是否通畅来判断仪器运行是否正常。利用ping()函数来检测网络通断代码如下:
ping_result=str(ping(ip, timeout=4)) # str()函数将ping()函数返回信息转为字符串格式
ping()函数默认发出4个请求数据包,目标IP服务器接收到数据包后会发送返回数据包,借此检测仪器的网络状态。将ping()函数超时访问参数timeout设置为4 s,若4 s内目标IP进行了响应,且ping()函数返回信息显示丢包数小于2,则判定仪器状态为正常;否则,为异常。当值班人员发现监控软件发出的测震仪器异常时,应首先检查测震仪器与值班室之间的网络,若网络一切正常,再检查测震数据采集器、地震计等设备运转情况,直到查清故障并排除。
2.2 前兆仪器巴彦淖尔站13套前兆仪器的每日自动监控任务包括各学科前兆仪器访问、实时数据下载及存储、仪器数据绘图与存储等。
2.2.1 仪器访问访问前兆仪器实时数据的方式有别于调取数据库,能直接查看当前时刻仪器数据采集器(或主机)的数据流传输状况。
(1)常规仪器访问
一般而言,前兆各学科仪器均可通过Python第三方requests库中的get()函数来实现程序对指定URL的访问,并返回指定URL下的HTML内容和HTTP状态码,代码如下:
res_tj=requests.get(url_tj, headers=headers, timeout=(21, 100))
if str(res_tj.status_code)!=200:
alarm(‘体应变’) # 若HTTP状态码不是200,则启动警报
若get()函数返回的HTTP状态码为200,程序则将该仪器运行状态判断为正常;否则,为异常。该方法访问仪器需注意设置虚拟请求头(即headers参数),以免被仪器数据采集器拒绝频繁访问。在程序运行调试过程中发现,由于一些数据采集器使用年限较长、响应速度较慢,有时会将仪器访问线程卡在系统任务中成为“僵尸线程”,这将不断增加服务器的缓存负担并可能造成数据采集器死机,故还需进行合理的请求超时(即timeout)参数设置。考虑到部分老旧数据采集器仍在使用中,软件设置的请求超时时间和读取超时时间分别为21 s、100 s。
目前,地震监测站的伸缩仪、水管仪常配套使用的数据采集器有EP-Ⅲ型、EP-Ⅳ型IP采集控制器。这2种数据采集器产生实时数据文件URL的规律不同,用程序访问的方式也不相同。EP-Ⅳ型数据采集器产生的实时数据URL格式固定,可直接访问获取数据。EP-Ⅲ型数据采集器产生的实时数据URL的特定位置为1个可变字母,该字母在英文大写字母A—O之间依次出现,每1天的URL对应1个字母,在字母O结束之后重新从字母A开始,依此循环下去。若数据采集器因故障重启,URL中的字母则为A—O之间随机出现的1个,对此专门编写了1个字母推算函数,代码如下:
def name_cal(start_letter, start_date):
dt1=datetime.datetime.strptime(today, ’%Y-%m-%d’) #当前日期转时间格式
dt2=datetime.datetime.strptime(start_date, ’%Y-%m-%d’) #起算日期转时间格式
n=int(str(dt1-dt2)[: -13]) #计算日期差
letter_list=[‘A’, ’B’, ’C’, ’D’, ’E’, ’F’, ’G’, ’H’, ’I’, ’J’, ’K’, ’L’, ’M’, ’N’, ’O’]
start_num=letter_list.index(start_letter)
return letter_list[(start_num+n)%15] #计算并返回当天URL字母
EP-Ⅲ型数据采集器每次故障重启之后,故障日期为起算日期(start_date),重启后新生成文件的URL字母为起算字母(start_letter),只需向该函数传递这2个参数,后续的URL字母均可由该函数算出。
对于一些设置了简单的访问限制的数据采集器,将其用户名和密码信息写入URL中直接访问即可(如伸缩仪);若不能直接访问(如VP垂直摆),则改用requests库的post()函数来实现带参数访问,代码如下:
data={‘Username’: ’***’, ’pwd’: ’***’, ’submit’: ’**’}
res_vp=requests.post(url_vp, headers=headers, data=data, timeout=(21, 100))
***为监测台站前兆仪器网页登录的用户名和密码。其他参数的设置与get()函数相同(图 2)。
(2)ZD8M地电阻率仪
ZD8M地电阻率仪(以下简称ZD8M)以小时采样的方式产出6个测项的实时数据。但这些数据不会在当天形成文件,而是在次日0时后产生1个全天小时数据的文件,因此无法直接访问该仪器实时数据的URL。监控软件仍采用get()方法访问其发布实时数据的网页,再对该网页的HTML进行解析,提取所需的当天6个测项小时数据(具体方法见2.2.2),将其显示在监控软件的窗口,待值班人员查看(图 3)。若该网页的HTTP状态码为200且能够顺利提取到相关数据,则判断该仪器运行状态正常;否则,判断为异常。爬取网页信息时需注意地电阻率仪网页编码方式为gbk,需按照对应方式解码才能顺利提取到有效的实时数据。
(3)应用Selenium模块访问
FDHZ-M15型磁通门磁力仪(以下简称M15)启用于2006年,其网页使用版本较早的frameset框架写成,虽然网页中数据结构较简单,但是无论程序何时访问该网页,M15的主机(即数据采集器)会即刻将一部分数据发送到访问端,并用较长时间(约20—40 s)继续加载和发回剩余数据,总数据个数始终为432 009(包括NULL在内),这种数据传输方式可导致程序执行到该行后被迫终止运行,并把所获取的部分数据直接输出,因此,无法通过直接访问M15实时数据URL的方式来访问该套仪器。监控软件采用Python第三方库Selenium的浏览器控制方法,通过模拟人工打开浏览器上M15实时数据块对应的URL,设置合适的数据加载等待时间,获取并存储其实时数据文件(图 4)。Selenium获取M15实时数据代码如下:
options.add_experimental_option(‘prefs’, prefs) #添加默认参数
s=Service(current_dir+”\chromedriver\chromedriver.exe”) #指定浏览器驱动位置
driver = webdriver.Chrome(service=s, options=options)
driver.get(‘http://**.**.***.**/0.sec’) #访问HTML
time.sleep(50) #设置50 s等待加载时间
data=driver.page_source #提取该HTML内容
driver.quit() #退出浏览器
经测试发现,浏览器加载M15实时数据网页的时间并非为固定值,最快也需十几秒,最慢可达40 s,故程序将加载等待时间设置为50 s,留下足够的时间余量,以使程序在各种情况下均可顺利完成仪器访问和数据下载的任务。
(4)应用session会话访问
出于数据保密性的需求,在程序访问PET-gPhone型重力仪系统(以下简称PET)的过程中需要先加载登录信息,然后在其cookie中始终保持这些信息,数据采集器才会开放访问权限。若直接应用get()方法,则会被数据采集器拒绝访问,用selenium模拟浏览器也极不稳定,故程序首先应用requests库的session()方法建立1个程序与数据采集器之间的持续会话,再用post()方法传递多个登录参数,在获取访问权限的情况下,最后用get()方法获取实时数据。session会话获取PET重力仪访问权限的代码如下:
s=requests.session() #建立程序-仪器会话
url= ‘http://**.**.***.***/login.php’
headers={‘Connection’: ‘Keep-Alive’,
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘Cookie’: ‘***’,
‘Host’: ‘**.**.***.***’,
‘Referer’: ‘http://**.**.***.***/’} #请求头参数(部分)
data={‘userName’: ‘*****’, ’pwd’: ‘*******’, ’submit’: ’**’} #登录参数
s.post(url, headers=headers, data=data) #在会话中带参数访问仪器
考虑到PET数据的保密性,只展示部分请求参数,重要的参数内容用*号代替。经长期测试发现,该会话方式较稳定,可快速、完整地获取PET实时数据。
2.2.2 实时数据下载与存储在成功访问仪器实时数据URL之后,即可顺利获取其HTML内容。用get()方法访问的仪器,其HTML内容可由get()函数的返回值直接得到:
res_tj= requests.get(url_tj, headers=headers, timeout=(21, 100)) #访问仪器URL
data_tj=res_tj.text #获取HTML内数据
M15的数据获取方式已在上文selenium模块中介绍,不再赘述。ZD8M的数据可以由bs4库beautifulsoup()方法解析或由re正则模块匹配其HTML来获取,这里介绍re模块匹配的方法:
res_zd8m = requests.get(url_zd8m, headers=headers) #访问URL
res_zd8m.encoding = ‘gbk’ #HTML用gbk解码
data_zd8m =pattern2.findall(res_zd8m.text) #匹配获取数据
前兆仪器数据文件格式有dat、sec、epd、sw等,除地电阻率仪外,从HTML获得的数据编码方式均为utf-8(表 1),应用Python自带的I/O模块将其解码后写入文件并存储到本机指定目录下。前兆仪器对数据的完整性、连续性有严格要求,当仪器数据采集器突发故障(如死机或被雷击)时,数据采集器中已有数据无法取出,数据库中也缺少相应数据。此时,程序即可将自动备份的数据上传到数据库,以保证数据的完整性。
2.2.3 仪器数据绘图应用matplotlib模块将下载的当天数据绘制为曲线。若数据为分钟值,则直接绘图;若数据为秒值,则先将其转换为分钟值再进行绘图,以此减少不必要的工作量,提高运行效率。若数据缺测,仪器会产生NULL数据代替实时数据,NULL数据无法转化为浮点数进行绘图,所以,需以re模块匹配出数据中1个所有NULL之前或之后的1个数字(带或不带小数),将NULL统一转换为该固定数值。以GM4为例绘图的代码如下:
pattern=re.compile(“\d+\.?\d*(?=\sNULL)|(?<=NULL\s)\d+\.?\d*”)
fix_data=pattern.findall(data) #匹配出固定值
data=[float(fix_data) if x==’NULL’ else float(x) for x in data[1:: 240]] #提取分钟值
t=np.arange(0, len(data)) #添加时间序列
plt.plot(t, data)
GM4实时数据形式为4个测项秒数据的循环,故提取分钟数据时,秒数据的切片步长参数为240。数据曲线图件绘制完成后,程序将其保存到指定目录中,待值班人员查看曲线形态并进一步判断仪器运行状态(图 5)。在保存当天图件之前,程序会先删除同一目录下前1天的图件,以方便值班人员查看和减少程序对服务器内存的占用。
当程序判断仪器状态为正常的线程时,即结束巡检任务;当判断为仪器故障的线程时,则继续运行,并于10 min(或设置为其他时间间隔)后重新访问仪器,若此时判断为运行状态正常,则结束该线程任务,不启动警报,若仍判断为状态异常,则用Pyautogui模块发起弹窗提醒,同时用pygame模块发送警报声,直到值班人员点击关闭弹窗,程序才会结束警报声线程,解除警报(图 6)。pygame模块的语音播报功能可以对不同的故障仪器进行不同内容的语音警报,以使警报内容清晰准确。考虑到GM4型、M15型地磁仪器在每天8—9时之间未生成文件,故在此时间段内只监测网络通断而不下载实时数据。由于地电仪器(ZD8M型、GEF-Ⅱ型)采用无线传输的方式在0时交互前1日数据,传输数据时会出现网络连接不稳定的现象,故程序的监控时间跳过0时前后15 min,以免造成误报警。故障弹窗和发送警报声的函数如下:
def confirm(name): #弹窗函数
text=name+’仪器故障,请检查!'
pyautogui.confirm(text, title=’仪器故障', buttons=['OK', 'Cancel'])
def mus_play(): #警报声函数
pygame.mixer.music.play() #播放音频
while pygame.mixer.music.get_busy(): #播放为完成之前不退出程序
pass
2.4 监控软件使用说明前兆测震综合监控软件均由Python语言编辑而成,受限于Python运行效率不高的问题,在软件投入使用时将全部代码打包为3部分,每部分均为单一界面软件:第1部分命名为“前兆仪器数据绘图软件”,软件界面如图 3所示,用户点击对应的仪器名称按钮,即可获取该仪器实时数据并将其绘制成曲线图,若有故障即触发弹窗报警(图 6);第2部分命名为“前兆仪器定时数据下载绘图报警软件”,软件界面如图 7所示,用户启动软件后,软件即自动进行每日的定时(03:00、08:30、12:00、15:00、18:00、21:00)数据下载与保存、数据曲线绘图、仪器故障报警等任务,顺利下载的数据和绘制的图件均自动保存到指定文件夹下,用户可自行查看以进一步检查仪器运行状况,发生故障的线程会在10 min后自动重新启动下载数据等任务,若仍发生故障,则触发弹窗报警(图 6);第3部分命名为“前兆测震仪器轮巡监控软件”,软件界面如图 8所示,用户启动软件后,软件即自动开始针对前兆、测震等15套仪器的巡检任务,并且进行不间断的滚动巡检。打包后的软件均为免安装程序包,配置文件均为文本文档(文档内已写入默认参数),用户在简单的参数配置后启动软件即可正常使用。
基于Python语言设计研发的前兆测震综合监控软件实现了巴彦淖尔地震监测中心站前兆、测震15套仪器的实时数据访问、数据备份及曲线绘图、仪器故障警报等功能。解决了测震仪器与前兆仪器、分钟值数据与秒值数据的同时监控,以及特殊的仪器如ZD8M、M15、PET等仪器的实时数据访问的问题。软件界面较简单,运行快速稳定,体型轻量化,在节省观测人工成本的同时保障了仪器数据的完整连续性。监控软件尚有不完善之处,如软件界面虽然较简单,但是可视化程度不高;目前软件对仪器运行状态的判断仅有HTTP状态码1个指标,这使得程序不够智能化。
安凯杰, 郭宝仁, 薛锦明. 地震台站手机平台电源监控系统[J]. 科技资讯, 2020, 18(1): 21. |
程冬焱, 胡玉良, 穆慧敏, 等. 山西地震前兆台网日常运行管理软件[J]. 地震地磁观测与研究, 2016, 37(4): 181-186. |
高东辉, 孟祥龙, 张守国, 等. 基于Nagios的网络监控系统在黑龙江地震监测网络中的应用[J]. 防灾减灾学报, 2013, 29(2): 67-73. |
胡玮, 冯雪东, 石伟, 等. 乌加河地震台形变观测异常与干扰识别[J]. 地震地磁观测与研究, 2022, 43(2): 145-152. DOI:10.3969/j.issn.1003-3246.2022.02.019 |
胡玉良, 程冬焱, 李惠玲, 等. Host Monitor监控软件在山西地震前兆台网的应用[J]. 地震地磁观测与研究, 2016, 37(1): 131-135. |
李刚, 王晓磊, 孙路强, 等. 基于Nagios软件的综合短信联动告警系统在地震行业中的应用研究[J]. 地震研究, 2012, 35(1): 133-138. |
刘春国, 谷元珠, 赵红丽, 等. 地下流体前兆数据库的质量监控系统研制及其开发技术[J]. 地震, 2002, 22(4): 74-80. |
马文娟, 张锦玲, 常明, 等. 区域地震前兆台网管理及运行监控[J]. 地震地磁观测与研究, 2011, 32(4): 74-77. |
王建国, 姚会琴, 高逊, 等. 天津市地震前兆台网的运行监控与维护管理[J]. 大地测量与地球动力学, 2010, 30(Z1): 111-115. |
王莉森, 张云昌, 殷金平, 等. 河北地震前兆台网运行质量监控系统研制[J]. 地震地磁观测与研究, 2016, 37(1): 136-141. |
王秀英, 周振安, 刘爱春. 地震前兆设备动态监控报警功能设计与实现[J]. 地震研究, 2009, 32(4): 431-435. |
殷志刚, 徐锡泉, 张登科, 等. 前兆数据质量监控和水位阶变报警软件[J]. 山西地震, 2012(3): 24-27. |
赵祖虎, 吴利军, 姜佳宁, 等. 地球物理台网仪器监控可视化系统设计与实现[J]. 地震地磁观测与研究, 2022, 43(2): 233-241. |
周振安, 王秀英, 刘爱春. 地震前兆台站环境监控功能的设计[J]. 地震地磁观测与研究, 2006, 27(2): 51-55. |