diff --git a/brian_dashboard_manager/templating/eumetsat.py b/brian_dashboard_manager/templating/eumetsat.py
new file mode 100644
index 0000000000000000000000000000000000000000..fd11bfbd20f27121f3d20ce8dab94859213b404e
--- /dev/null
+++ b/brian_dashboard_manager/templating/eumetsat.py
@@ -0,0 +1,95 @@
+import operator
+from brian_dashboard_manager.templating.helpers \
+    import get_dashboard_data, letter_generator, create_panel
+
+
+def get_panel_data(all_subscriptions):
+
+    result = dict()
+
+    def _panel(s):
+        return {
+            'measurement': 'multicast_subscriptions',
+            'title': f'{s["subscription"]} on {s["router"]}',
+            'subscription': s['subscription'],
+            'router': s['router']
+        }
+
+    for subscription in all_subscriptions:
+        dashboard_name = f'{subscription["router"]} subscriptions'
+        result.setdefault(dashboard_name, []).append(_panel(subscription))
+
+    # make the panels sorted deterministically
+    for name in result.keys():
+        result[name] = sorted(result[name], key=operator.itemgetter('subscription'))
+
+    return result
+
+
+
+def get_panel_fields(panel, panel_type, datasource):
+    """
+    Helper for generating a single panel,
+    with ingress/egress and percentile targets
+    """
+    letters = letter_generator()
+
+    def get_target_data(alias, field):
+        return {
+            # panel includes identifying information
+            # such as hostname, subscription, etc.
+            **panel,
+            'alias': alias,
+            'refId': next(letters),
+            'select_field': field
+            # 'percentile': 'percentile' in alias.lower(),
+        }
+
+    targets = [('Multicast Traffic', 'octets')]
+
+    return create_panel({
+        **panel,
+        'datasource': datasource,
+        'linewidth': 1,
+        'title': panel['title'].format(panel_type),
+        'panel_targets': [get_target_data(*target) for target in targets],
+        'y_axis_type': 'bits',
+    })
+
+def subscription_panel_generator(gridPos):
+    """
+    Shared wrapper for shorter calls without
+    gridPos to generate panels.
+
+    Generates panels used in a normal dashboard
+    for all traffic + (conditionally) IPv6 + Errors
+    """
+    def get_panel_definitions(panels, datasource, errors=False):
+        result = []
+
+        for panel in panels:
+            result.append(get_panel_fields({
+                **panel,
+                **next(gridPos)
+            }, 'traffic', datasource))
+            if panel.get('has_v6', False):
+                result.append(get_panel_fields({
+                    **panel,
+                    **next(gridPos)
+                }, 'IPv6', datasource))
+            if errors:
+                result.append(get_panel_fields({
+                    **panel,
+                    **next(gridPos)
+                }, 'errors', datasource))
+
+        return result
+
+    return get_panel_definitions
+
+
+def generate_eumetsat_multicast(subscriptions, datasource):
+    panel_data = get_panel_data(subscriptions)
+    for dash in get_dashboard_data(panel_data, datasource, 'EUMET_MULTICAST'):
+        yield dash
+
diff --git a/brian_dashboard_manager/templating/helpers.py b/brian_dashboard_manager/templating/helpers.py
index b7c9e0e87bc89ae28be0f7a7e71a1f30bd40b204..a5cb297b0bb9ed587420ecb9164cbbe2993271c4 100644
--- a/brian_dashboard_manager/templating/helpers.py
+++ b/brian_dashboard_manager/templating/helpers.py
@@ -275,7 +275,7 @@ def get_panel_fields(panel, panel_type, datasource):
     })
 
 
-def panel_generator(gridPos):
+def default_interface_panel_generator(gridPos):
     """
     Shared wrapper for shorter calls without
     gridPos to generate panels.
@@ -318,7 +318,7 @@ def get_nren_dashboard_data(data, datasource, tag):
 
         gridPos = gridPos_generator(id_gen, start=1)
 
-        panel_gen = panel_generator(gridPos)
+        panel_gen = default_interface_panel_generator(gridPos)
 
         if len(dash['AGGREGATES']) > 0:
             agg_panels = create_aggregate_panel(
@@ -358,7 +358,10 @@ def get_nren_dashboard_data(data, datasource, tag):
         yield result
 
 
-def get_dashboard_data(data, datasource, tag, errors=False):
+def get_dashboard_data(
+        data, datasource, tag,
+        panel_generator=default_interface_panel_generator,
+        errors=False):
     """
     Generates all panels used in a normal dashboard without aggregate panels
     """
diff --git a/brian_dashboard_manager/templating/templates/shared/panel_target.json.j2 b/brian_dashboard_manager/templating/templates/shared/panel_target.json.j2
index 0bcd9f694d3153a187f63012bb032a8bbc796cb4..7247e1723a84bbca4e9ad1de260f6101d3ef6958 100644
--- a/brian_dashboard_manager/templating/templates/shared/panel_target.json.j2
+++ b/brian_dashboard_manager/templating/templates/shared/panel_target.json.j2
@@ -45,37 +45,50 @@
         ]
     ],
     "tags": [
-        {% if not isp %}
+        {% if isp %}
         {
             "condition": null,
-            "key": "hostname",
+            "key": "tag",
             "operator": "=",
-            "value": "{{ hostname }}"
+            "value": "{{ interface_tag }}"
         },
         {
             "condition": "AND",
-            "key": "interface_name",
+            "key": "isp",
             "operator": "=",
-            "value": "{{ interface }}"
+            "value": "{{ isp }}"
+        },
+        {
+            "condition": "AND",
+            "key": "nren",
+            "operator": "=",
+            "value": "{{ nren }}"
         }
-        {% else %}
+        {% elif subscription %}
         {
             "condition": null,
-            "key": "tag",
+            "key": "hostname",
             "operator": "=",
-            "value": "{{ interface_tag }}"
+            "value": "{{ hostname }}"
         },
         {
             "condition": "AND",
-            "key": "isp",
+            "key": "subscription",
             "operator": "=",
-            "value": "{{ isp }}"
+            "value": "{{ subscription }}"
+        }
+        {% else %}
+        {
+            "condition": null,
+            "key": "hostname",
+            "operator": "=",
+            "value": "{{ hostname }}"
         },
         {
             "condition": "AND",
-            "key": "nren",
+            "key": "interface_name",
             "operator": "=",
-            "value": "{{ nren }}"
+            "value": "{{ interface }}"
         }
         {% endif %}
     ]