connectors/ZeroConfListener.py
author Edouard Tisserant <edouard@beremiz.fr>
Thu, 28 Nov 2024 14:27:58 +0100
changeset 4051 8816aee01b07
parent 4039 9ff455817691
permissions -rw-r--r--
merge
4039
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     1
#!/usr/bin/env python
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     3
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     4
# See COPYING file for copyrights details.
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     5
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     6
import weakref
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     7
from zeroconf import ServiceBrowser, Zeroconf, get_all_addresses
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     8
import threading
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     9
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    10
service_type = '_Beremiz._tcp.local.'
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    11
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    12
class ZeroConfListenerClass:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    13
    def __init__(self, dialog):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    14
        self.dialog = weakref.ref(dialog)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    15
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    16
        self.IfacesMonitorState = None
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    17
        self.IfacesMonitorTimer = None
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    18
        self.Browser = None
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    19
        self.ZeroConfInstance = None
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    20
        self.PublishedServices = set()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    21
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    22
        self.start()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    23
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    24
    def __del__(self):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    25
        self.stop()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    26
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    27
    def start(self):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    28
        self.ZeroConfInstance = Zeroconf()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    29
        self.Browser = ServiceBrowser(self.ZeroConfInstance, service_type, self)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    30
        # Start the ifaces_monitor timer thread
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    31
        self.IfacesMonitorTimer = threading.Timer(1.0, self.ifaces_monitor)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    32
        self.IfacesMonitorTimer.start()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    33
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    34
    def stop(self):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    35
        if self.IfacesMonitorTimer is not None:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    36
            self.IfacesMonitorTimer.cancel()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    37
            self.IfacesMonitorTimer = None
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    38
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    39
        if self.Browser is not None:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    40
            self.Browser.cancel()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    41
            self.Browser = None
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    42
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    43
        if  self.ZeroConfInstance is not None:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    44
            self.ZeroConfInstance.close()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    45
            self.ZeroConfInstance = None
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    46
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    47
    def update_service(self, zeroconf, _type, name):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    48
        self.remove_service(zeroconf, _type, name)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    49
        self.add_service(zeroconf, _type, name)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    50
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    51
    def add_service(self, zeroconf, _type, name):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    52
        dialog = self.dialog()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    53
        if not dialog:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    54
            return
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    55
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    56
        info = self.ZeroConfInstance.get_service_info(_type, name)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    57
        if info is None:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    58
            return
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    59
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    60
        typename = info.properties.get(b"protocol", None).decode()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    61
        ip = str(info.parsed_addresses()[0])
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    62
        port = info.port
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    63
        dialog.addService(typename, ip, port, name)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    64
        self.PublishedServices.add(name)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    65
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    66
    def remove_service(self, zeroconf, _type, name):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    67
        dialog = self.dialog()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    68
        if not dialog:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    69
            return
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    70
        
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    71
        if name in self.PublishedServices:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    72
            dialog.removeService(name)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    73
            self.PublishedServices.discard(name)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    74
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    75
    def ifaces_monitor(self):
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    76
        dialog = self.dialog()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    77
        if not dialog:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    78
            return
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    79
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    80
        NewState = get_all_addresses()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    81
        OldState = self.IfacesMonitorState
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    82
        self.IfacesMonitorState = NewState
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    83
        do_restart = False
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    84
        
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    85
        if OldState is not None:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    86
            # detect if a new address appeared
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    87
            for addr in NewState:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    88
                if addr not in OldState:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    89
                    do_restart = True
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    90
                    break
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    91
                else:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    92
                    OldState.remove(addr)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    93
            # detect if an address disappeared
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    94
            if len(OldState) > 0:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    95
                do_restart = True
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    96
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    97
            
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    98
        if do_restart:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    99
            self.stop()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   100
            
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   101
            while self.PublishedServices:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   102
                dialog.removeService(self.PublishedServices.pop())
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   103
        
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   104
            self.start()
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   105
        else:
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   106
            # Restart the ifaces_monitor timer thread
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   107
            self.IfacesMonitorTimer = threading.Timer(1.0, self.ifaces_monitor)
9ff455817691 IDE: refactor discovery panel / zeroconf
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   108
            self.IfacesMonitorTimer.start()