Здравствуйте.
Совсем недавно я узнал что существует один простой но полезный проект «Народный мониторинг» Смысл его в том, если вкратце, чтоб объединить множество разрозненных датчиков мониторинга окружающей среды в одном месте. Ведь одно дело например посмотреть прогноз погоды в инете и совсем другое дело увидеть реально где какие температура, влажность, давление и их изменение с течением времени.
Или например если банально лень встать и посмотреть на градусник за окном)
Проект этот позволяет «складировать», отображать и смотреть историю изменения данных. В общем все что для счастья надо — там есть. Также можно датчики делать публичными или приватными.
Для желающих приобщится существуют готовые устройства и как их заполучить можно узнать на сайте. Вот ссылка на пост с которого все начиналось и пример устройства там же.
Кроме этого существует множество датчиков в составе SCADA систем и многие из них могут отражать параметры окружающей среды в самых различных географических местах. Вот об этом я и хочу рассказать — как любой датчик OPC сервера любой SCADA системы прикрутить к вышеописанному сервису.
Итак нам понадобится:
1. Python 2.7
2. Open OPC for Python
3. Python for Windows extensions
Все это устанавливается на машины или туда же где крутится OPC сервер, или удаленно. Я устанавливал локально.
Далее просто запускается мой скрипт поражающий своей сложностью:
import OpenOPC
import time
import socket
while True:
try:
opc = OpenOPC.client()
opc.connect("OWEN.RS485")
s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) # UDP
addr = ('map.net13.info',8283)
val = opc['Com1/TRM138(8bit adr=24)/ChannelData3/rEAd']
buf = "#123456789ABCDEn#123456789ABCDE10#" +"%.1f#"%val + "n##"
s.sendto(buf,addr)
opc.close()
s.close()
except :
pass
time.sleep(180)
Как видно я подключаюсь к ОРС серверу «OWEN.RS485» и считываю значение «итема» 'Com1/TRM138(8bit adr=24)/ChannelData3/rEAd'. Таким образом можно читать значение любого «итема» ОРС сервера.
Кстати если изучить документацию к OpenOPC то вы там найдете много полезных функций которых вполне достаточно для создания небольшой визуализации например.
Пакет для отправки формируется из уникального ID устройства 123456789ABCDE (можно придумать и свой, но лучьше использовать серийник датчика или модуля ввода) и уникального ID датчика. Последний я получил добавив к ID устройства 0x10, что означает что это температурный датчик. Подробнее можно почитать на сайте проекта в разделе для разработчиков.
Само подключение к сервису происходит очень просто. Нужно просто зарегистрироваться на сайте и начинать отсылать туда пакеты. Когда система получит несколько пакетов можно будет создать новое устройство и добавить в него датчик. Для отладки есть мониторинг пакетов с вашего IP в разделе для разработчиков. Со всеми вопросами, благодарностями и предложениями по поводу сервиса можете обращаться к создателю сервиса SSar
Для тех кто не ищет легких путей добавлю листинг службы windows которая делает тоже самое:
# -*- coding: utf-8 -*-
import win32serviceutil
import win32service
import win32event
import servicemanager
import OpenOPC
import socket
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "ServiceForNarodmon"
_svc_display_name_ = "ServiceForNarodmon"
_svc_description_ = "Service For Narodmon.ru"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
self.hWaitResume = win32event.CreateEvent(None, 0, 0, None)
self.timeout = 60000 #Пауза между выполнением основного цикла службы в миллисекундах
self.resumeTimeout = 1000
self._paused = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
#servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
#servicemanager.PYS_SERVICE_STOPPED,
#(self._svc_name_, ''))
def SvcPause(self):
self.ReportServiceStatus(win32service.SERVICE_PAUSE_PENDING)
self._paused = True
self.ReportServiceStatus(win32service.SERVICE_PAUSED)
#servicemanager.LogInfoMsg("The %s service has paused." % (self._svc_name_, ))
def SvcContinue(self):
self.ReportServiceStatus(win32service.SERVICE_CONTINUE_PENDING)
win32event.SetEvent(self.hWaitResume)
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
#servicemanager.LogInfoMsg("The %s service has resumed." % (self._svc_name_, ))
def SvcDoRun(self):
#servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
# servicemanager.PYS_SERVICE_STARTED,
# (self._svc_name_,""))
self.main()
#В этом методе реализовываем нашу службу
def main(self):
#Здесь выполняем необходимые действия при старте службы
#servicemanager.LogInfoMsg("Hello! Im a Narodmon.ru Service.")
while 1:
#Здесь должен находиться основной код сервиса
#servicemanager.LogInfoMsg("I'm still here.")
try:
opc = OpenOPC.client()
opc.connect("OWEN.RS485")
s = socket.socket( socket.AF_INET, socket.SOCK_DGRAM ) # UDP
addr = ('map.net13.info',8283)
val = opc['Com1/TRM138(8bit adr=24)/ChannelData3/rEAd']
buf = "#123456789ABCDEn#123456789ABCDE10#" +"%.1f#"%val + "n##"
s.sendto(buf,addr)
opc.close()
s.close()
except :
pass
#Проверяем не поступила ли команда завершения работы службы
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
if rc == win32event.WAIT_OBJECT_0:
#Здесь выполняем необходимые действия при остановке службы
#servicemanager.LogInfoMsg("Bye!")
break
#Здесь выполняем необходимые действия при приостановке службы
if self._paused:
pass
#servicemanager.LogInfoMsg("I'm paused... Keep waiting...")
#Приостановка работы службы
while self._paused:
#Проверям не поступила ли команда возобновления работы службы
rc = win32event.WaitForSingleObject(self.hWaitResume, self.resumeTimeout)
if rc == win32event.WAIT_OBJECT_0:
self._paused = False
#Здесь выполняем необходимые действия при возобновлении работы службы
#servicemanager.LogInfoMsg("Yeah! Let's continue!")
break
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
Все попытки писать сообщения с системный журнал закомментированный потому что в WinXP они не работают. Разбираться не стал дольше потому что на Win7 все нормально. Можете «запились» себе свою службу с «блэкджеком и женщинами легкого провидения».
Удачи!
Автор: svavan