📜 ⬆️ ⬇️

How easy it is to connect any OPC server sensor to the narodmon.ru project

Hello.

More recently, I learned that there is one simple but useful project “People's Monitoring”. Its meaning is, if in brief, to combine many disparate environmental monitoring sensors in one place. Indeed, it is one thing, for example, to see the weather forecast on the Internet, and it’s quite another thing to really see where the temperature, humidity, pressure and their change over time.

Or, for example, if it is commonplace to be too lazy to get up and look at the thermometer outside the window)


')
This project allows you to "store", display and watch the data change history. In general, all that is necessary for happiness is there. You can make the sensors public or private.

For those who want to join there are ready-made devices and how to get them can be found on the website. Here is a link to the post from which it all began and an example of the device in the same place.

In addition, there are many sensors in the composition of SCADA systems and many of them may reflect environmental parameters in a variety of geographic locations. That's what I want to tell you about - like to fasten any SCADA system of any OPC server sensor to the above described service.

So we need:

1. Python 2.7
2. Open OPC for Python
3. Python for Windows extensions

All this is installed on the machine where the OPC server is spinning, or remotely. I installed locally.

Next, just run my script, striking in its complexity:

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 = ('narodmon.ru',1234) # ip:port    " " val = opc['Com1/TRM138(8bit adr=24)/ChannelData3/rEAd'] buf = "#123456789ABCDE\n#123456789ABCDE10#" +"%.1f#"%val + "\n##" s.sendto(buf,addr) opc.close() s.close() except : pass time.sleep(180) 


As you can see, I connect to the OWEN server “OWEN.RS485” and read the value of the item 'Com1 / TRM138 (8bit adr = 24) / ChannelData3 / rEAd'. Thus, you can read the value of any "item" OPC server.

By the way, if you study the documentation for OpenOPC, then you will find there many useful functions which are quite sufficient for creating for example a small visualization.

The package for sending is formed from the unique device ID 123456789ABCDE (you can think of your own, but it is better to use the serial number of the sensor or the input module) and the unique sensor ID. The last one I got was adding 0x10 to the device ID, which means that it is a temperature sensor. You can read more on the project website in the section for developers.

The very connection to the service is very simple. You need to register on the site and start sending packages. When the system receives several packages, it will be possible to create a new device and add a sensor to it. For debugging there is monitoring of packets from your IP in the section for developers. With all questions, thanks and suggestions about the service you can contact the creator of the service SSar

For those who are not looking for easy ways, I’ll add a listing of the windows service that does the same thing:

 # -*- 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 = ('narodmon.ru',1234) # ip:port    " " val = opc['Com1/TRM138(8bit adr=24)/ChannelData3/rEAd'] buf = "#123456789ABCDE\n#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) 


All attempts to write messages to the system log are commented out because they do not work in WinXP. I didn’t understand further because everything is fine on Win7. You can “grind” your service with “blackjack and women of light providence”.

Good luck!

Source: https://habr.com/ru/post/156277/


All Articles