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: kinsamanka@3750: kinsamanka@3750: andrej@1732: import socket andrej@1732: import threading andrej@1830: import zeroconf Edouard@647: Edouard@763: Edouard@2477: service_type = '_Beremiz._tcp.local.' andrej@1736: edouard@2492: andrej@1831: class ServicePublisher(object): Edouard@2477: def __init__(self, protocol): Edouard@2477: self.serviceproperties = { Edouard@2477: 'description': 'Beremiz remote PLC', Edouard@2477: 'protocol': protocol Edouard@2477: } 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) edouard@4037: except Exception as e: edouard@4037: print(f"Failed to register service ({str(e)}), retrying in 2 seconds") 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@2477: self.service_name = '%s.%s' % (name, service_type) Edouard@647: self.name = name Edouard@647: self.port = port Edouard@647: Edouard@2320: if ip == "0.0.0.0": Edouard@2320: print("MDNS brodcasted on all interfaces") edouard@2492: interfaces = zeroconf.InterfaceChoice.All Edouard@2320: ip = self.gethostaddr() Edouard@2320: else: edouard@2492: interfaces = [ip] Edouard@647: Edouard@2320: self.server = zeroconf.Zeroconf(interfaces=interfaces) edouard@2492: andrej@1826: print("MDNS brodcasted service address :" + ip) Edouard@647: self.ip_32b = socket.inet_aton(ip) Edouard@647: edouard@4040: self.service_info = zeroconf.ServiceInfo( edouard@4040: service_type, edouard@4040: self.service_name, edouard@4040: self.port, edouard@4040: addresses=[self.ip_32b], edouard@4040: properties=self.serviceproperties) edouard@4040: edouard@4040: self.server.register_service(self.service_info) 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: edouard@4040: self.server.unregister_service(self.service_info) 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())