Edouard@647: #!/usr/bin/env python Edouard@647: # -*- coding: utf-8 -*- Edouard@647: andrej@1667: # This file is part of Beremiz runtime. Edouard@647: # andrej@1571: # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD Edouard@647: # andrej@1667: # See COPYING.Runtime file for copyrights details. Edouard@647: # andrej@1667: # This library is free software; you can redistribute it and/or andrej@1667: # modify it under the terms of the GNU Lesser General Public andrej@1667: # License as published by the Free Software Foundation; either andrej@1667: # version 2.1 of the License, or (at your option) any later version. andrej@1667: andrej@1667: # This library is distributed in the hope that it will be useful, andrej@1571: # but WITHOUT ANY WARRANTY; without even the implied warranty of andrej@1667: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU andrej@1667: # Lesser General Public License for more details. andrej@1667: andrej@1667: # You should have received a copy of the GNU Lesser General Public andrej@1667: # License along with this library; if not, write to the Free Software andrej@1667: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Edouard@647: andrej@1826: andrej@1881: from __future__ import absolute_import andrej@1826: from __future__ import print_function andrej@1732: import socket andrej@1732: import threading andrej@1830: import zeroconf Edouard@647: Edouard@763: service_type = '_PYRO._tcp.local.' Edouard@763: andrej@1736: andrej@1831: class ServicePublisher(object): Edouard@647: def __init__(self): Edouard@647: # type: fully qualified service type name andrej@1740: self.serviceproperties = {'description': 'Beremiz remote PLC'} andrej@1730: Edouard@647: self.name = None Edouard@647: self.ip_32b = None Edouard@647: self.port = None Edouard@647: self.server = None Edouard@647: self.service_name = None Edouard@647: self.retrytimer = None andrej@1730: Edouard@647: def RegisterService(self, name, ip, port): Edouard@647: try: Edouard@647: self._RegisterService(name, ip, port) andrej@1846: except Exception: andrej@1740: self.retrytimer = threading.Timer(2, self.RegisterService, [name, ip, port]) andrej@1730: self.retrytimer.start() Edouard@647: Edouard@647: def _RegisterService(self, name, ip, port): Edouard@647: # name: fully qualified service name andrej@1740: self.service_name = 'Beremiz_%s.%s' % (name, service_type) Edouard@647: self.name = name Edouard@647: self.port = port Edouard@647: andrej@1830: self.server = zeroconf.Zeroconf() andrej@1826: print("MDNS brodcasting on :" + ip) Edouard@647: Edouard@648: if ip == "0.0.0.0": Edouard@648: ip = self.gethostaddr() andrej@1826: print("MDNS brodcasted service address :" + ip) Edouard@647: self.ip_32b = socket.inet_aton(ip) Edouard@647: andrej@1830: self.server.register_service( andrej@1878: zeroconf.ServiceInfo(service_type, andrej@1878: self.service_name, andrej@1878: self.ip_32b, andrej@1878: self.port, andrej@1878: properties=self.serviceproperties)) andrej@1742: self.retrytimer = None andrej@1730: Edouard@647: def UnRegisterService(self): Edouard@647: if self.retrytimer is not None: Edouard@647: self.retrytimer.cancel() Edouard@647: andrej@1830: if self.server is not None: andrej@1830: self.server.unregister_service( andrej@1830: zeroconf.ServiceInfo(service_type, andrej@1830: self.service_name, andrej@1830: self.ip_32b, andrej@1830: self.port, andrej@1830: properties=self.serviceproperties)) andrej@1830: self.server.close() andrej@1830: self.server = None andrej@1730: andrej@1744: def gethostaddr(self, dst='224.0.1.41'): Edouard@647: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) Edouard@647: try: Edouard@647: s.connect((dst, 7)) andrej@1847: (host, _port) = s.getsockname() Edouard@647: s.close() Edouard@647: if host != '0.0.0.0': Edouard@647: return host andrej@1846: except Exception: Edouard@647: pass Edouard@647: return socket.gethostbyname(socket.gethostname())