diff --git a/data/internal_config/ssdp.json b/data/internal_config/ssdp.json
new file mode 100644
index 0000000..abe84b2
--- /dev/null
+++ b/data/internal_config/ssdp.json
@@ -0,0 +1,14 @@
+{
+ "ssdp":{
+ "enabled":{
+ "value": true,
+ "config_file": true,
+ "config_web": false
+ },
+ "refresh_frequency":{
+ "value": 1800,
+ "config_file": true,
+ "config_web": false
+ }
+ }
+}
diff --git a/data/www/templates/base.html b/data/www/templates/base.html
index 3465dcc..e00aecf 100644
--- a/data/www/templates/base.html
+++ b/data/www/templates/base.html
@@ -21,7 +21,7 @@
-
+
diff --git a/data/www/templates/cluster.html b/data/www/templates/cluster.html
index caa41ac..c7b156e 100644
--- a/data/www/templates/cluster.html
+++ b/data/www/templates/cluster.html
@@ -2,13 +2,14 @@
{% block content %}
-
Cluster
+ Cluster/SSDP
{% if not fhdhr.config.dict["fhdhr"]["discovery_address"] %}
- Discovery Address must be set for SSDP/Cluster
+ Discovery Address must be set for Cluster/SSDP
{% else %}
+
diff --git a/fHDHR/device/ssdp/__init__.py b/fHDHR/device/ssdp/__init__.py
index e57797f..ed317d8 100644
--- a/fHDHR/device/ssdp/__init__.py
+++ b/fHDHR/device/ssdp/__init__.py
@@ -1,6 +1,7 @@
# Adapted from https://github.com/MoshiBin/ssdpy and https://github.com/ZeWaren/python-upnp-ssdp-example
import socket
import struct
+import time
from .ssdp_detect import fHDHR_Detect
from .rmg_ssdp import RMG_SSDP
@@ -14,7 +15,8 @@ class SSDPServer():
self.detect_method = fHDHR_Detect(fhdhr)
- if fhdhr.config.dict["fhdhr"]["discovery_address"]:
+ if (fhdhr.config.dict["fhdhr"]["discovery_address"] and
+ fhdhr.config.dict["ssdp"]["enabled"]):
self.sock = None
self.proto = "ipv4"
@@ -84,13 +86,51 @@ class SSDPServer():
self.rmg_ssdp = RMG_SSDP(fhdhr, self._broadcast_ip)
self.hdhr_ssdp = HDHR_SSDP(fhdhr, self._broadcast_ip)
+ self.refresh = int(fhdhr.config.dict["ssdp"]["refresh_frequency"])
+ self.refresh_last = None
+
+ self.do_alive()
self.m_search()
+ def do_alive(self, forcealive=False):
+
+ send_alive = False
+ if not self.refresh_last:
+ send_alive = True
+ elif forcealive:
+ send_alive = True
+ elif time.time() >= (self.refresh_last + self.refresh):
+ send_alive = True
+
+ if send_alive:
+ self.fhdhr.logger.info("Sending Alive message to network.")
+ self.do_notify(('239.255.255.250', 1900))
+ self.refresh_last = time.time()
+
+ def do_notify(self, address):
+
+ notify_list = []
+
+ hdhr_notify = self.hdhr_ssdp.get()
+ notify_list.append(hdhr_notify)
+
+ if self.fhdhr.config.dict["rmg"]["enabled"]:
+ rmg_notify = self.rmg_ssdp.get()
+ notify_list.append(rmg_notify)
+
+ for notify in notify_list:
+
+ self.fhdhr.logger.debug("Created {}".format(notify))
+ try:
+ self.sock.sendto(notify, address)
+ except OSError as e:
+ # Most commonly: We received a multicast from an IP not in our subnet
+ self.fhdhr.logger.debug("Unable to send NOTIFY: %s" % e)
+ pass
+
def on_recv(self, data, address):
self.fhdhr.logger.debug("Received packet from {}: {}".format(address, data))
- (host, port) = address
-
try:
header, payload = data.decode().split('\r\n\r\n')[:2]
except ValueError:
@@ -110,24 +150,8 @@ class SSDPServer():
self.fhdhr.logger.debug("Received qualifying M-SEARCH from {}".format(address))
self.fhdhr.logger.debug("M-SEARCH data: {}".format(headers))
- notify_list = []
+ self.do_notify(address)
- hdhr_notify = self.hdhr_ssdp.get()
- notify_list.append(hdhr_notify)
-
- if self.fhdhr.config.dict["rmg"]["enabled"]:
- rmg_notify = self.rmg_ssdp.get()
- notify_list.append(rmg_notify)
-
- for notify in notify_list:
-
- self.fhdhr.logger.debug("Created NOTIFY: {}".format(notify))
- try:
- self.sock.sendto(notify, address)
- except OSError as e:
- # Most commonly: We received a multicast from an IP not in our subnet
- self.fhdhr.logger.debug("Unable to send NOTIFY to {}: {}".format(address, e))
- pass
elif cmd[0] == 'NOTIFY' and cmd[1] == '*':
# SSDP presence
self.fhdhr.logger.debug("NOTIFY data: {}".format(headers))
@@ -169,5 +193,6 @@ class SSDPServer():
while True:
data, address = self.sock.recvfrom(1024)
self.on_recv(data, address)
+ self.do_alive()
except KeyboardInterrupt:
self.sock.close()
diff --git a/fHDHR/http/api/cluster.py b/fHDHR/http/api/cluster.py
index a748319..f14c887 100644
--- a/fHDHR/http/api/cluster.py
+++ b/fHDHR/http/api/cluster.py
@@ -44,6 +44,9 @@ class Cluster():
elif method == 'disconnect':
self.fhdhr.device.cluster.disconnect()
+ elif method == 'alive':
+ self.fhdhr.device.ssdp.do_alive(forcealive=True)
+
else:
return "Invalid Method"