From 14d5e8d05c7171687a4e1457f4bbeeae0d9919a5 Mon Sep 17 00:00:00 2001
From: "th.l" <thl-cmk@outlook.com>
Date: Tue, 17 Dec 2024 11:44:43 +0100
Subject: [PATCH] added support for Network Visualization  -
 wireless_ethernet_statuses.py    - incompatible: changed service from Port to
 Interface    - added interface inventory  - switch_ports_statuses.py    -
 incompatible: changed service from Port to Interface    - incompatible:
 reworked service discovery rule (Cisco Meraki Switch Ports)    - added
 interface inventory    - added host label nvdct/has_lldp_neighbours

---
 README.md                                     |   2 +-
 mkp/cisco_meraki-1.4.1-20241217.mkp           | Bin 0 -> 44015 bytes
 .../cisco_meraki_org_device_status.py         |   2 +-
 .../meraki/agent_based/appliance_uplinks.py   |  22 +-
 .../meraki/agent_based/appliance_vpns.py      |   4 +-
 .../meraki/agent_based/cellular_uplinks.py    |  54 +--
 .../agent_based/switch_ports_statuses.py      | 370 ++++++++++++------
 .../wireless_device_ssid_status.py            |   4 +-
 .../agent_based/wireless_ethernet_statuses.py |  34 +-
 source/cmk_addons_plugins/meraki/lib/agent.py | 297 +++++++++-----
 source/cmk_addons_plugins/meraki/lib/utils.py |  56 +--
 .../meraki/rulesets/switch_ports_statuses.py  |  71 ++--
 source/packages/cisco_meraki                  |   2 +-
 13 files changed, 587 insertions(+), 331 deletions(-)
 create mode 100644 mkp/cisco_meraki-1.4.1-20241217.mkp

diff --git a/README.md b/README.md
index 0cc147b..20dce74 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[PACKAGE]: ../../raw/master/mkp/cisco_meraki-1.3.7-20241116.mkp "cisco_meraki-1.3.7-20241116.mkp"
+[PACKAGE]: ../../raw/master/mkp/cisco_meraki-1.4.1-20241217.mkp "cisco_meraki-1.4.1-20241217.mkp"
 [SDK]: ../../raw/master/mkp/MerakiSDK-1.52.0-20241116.mkp "MerakiSDK-1.52.0-20241116.mkp"
 # Cisco Meraki special agent
 
diff --git a/mkp/cisco_meraki-1.4.1-20241217.mkp b/mkp/cisco_meraki-1.4.1-20241217.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..517e79d7a5a922b5e93427c2db53138760c470c4
GIT binary patch
literal 44015
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
b{6E9n|M7zO4=UELdI!!y<F$iTLxKH2=37)W

literal 0
HcmV?d00001

diff --git a/source/agent_based/cisco_meraki_org_device_status.py b/source/agent_based/cisco_meraki_org_device_status.py
index 56b1c6f..5a0d4ac 100644
--- a/source/agent_based/cisco_meraki_org_device_status.py
+++ b/source/agent_based/cisco_meraki_org_device_status.py
@@ -3,7 +3,7 @@
 # Copyright (C) 2022 Checkmk GmbH - License: GNU General Public License v2
 # This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
 # conditions defined in the file COPYING, which is part of this source code package.
-
+from cmk.gui.forms import section
 # enhancements by thl-cmk[at]outlook[dot]com, https://thl-cmk.hopto.org
 # - made device status configurable via WATO
 # - added last_reported as check_levels, levels_upper can be configured via WATO
diff --git a/source/cmk_addons_plugins/meraki/agent_based/appliance_uplinks.py b/source/cmk_addons_plugins/meraki/agent_based/appliance_uplinks.py
index 7a093bf..4fb45ed 100644
--- a/source/cmk_addons_plugins/meraki/agent_based/appliance_uplinks.py
+++ b/source/cmk_addons_plugins/meraki/agent_based/appliance_uplinks.py
@@ -14,11 +14,12 @@
 # 2024-05-15: fixed typo in output of uplink.received (in -> In) (ThX to Rickard Eriksson)
 #             moved parse function to the dataclasses
 # 2024-05-19: reworked appliance uplinks usage
-# 2024-04-24: fixed, we can have no traffic if uplinc is not connected
+# 2024-04-24: fixed, we can have no traffic if uplink is not connected
 # 2024-06-29: refactored for CMK 2.3
-#             changed service name from "Appliance Uplink" to "Uplink"
+#             changed service name from 'Appliance Uplink' to 'Uplink'
 #             fixed render function for bandwidth -> uses now render.networkbandwidth
 # 2024-06-30: renamed from cisco_meraki_org_appliance_uplinks.py in to appliance_uplinks.py
+# 2024-12-13: added connecting to _STATUS_MAP
 
 from collections.abc import Mapping
 from dataclasses import dataclass
@@ -61,8 +62,8 @@ __appliance_uplinks = [
                 'publicIp': '20.197.135.251',
                 'secondaryDns': '9.9.9.9',
                 'status': 'active',
-                "received": 52320006,  # bytes
-                "sent": 52928038,  # bytes
+                'received': 52320006,  # bytes
+                'sent': 52928038,  # bytes
             },
             {
                 'gateway': '192.168.5.100',
@@ -78,7 +79,7 @@ __appliance_uplinks = [
     }
 ]
 
-_LAST_REPORTED_AT = "%Y-%m-%dT%H:%M:%SZ"
+_LAST_REPORTED_AT = '%Y-%m-%dT%H:%M:%SZ'
 
 
 @dataclass(frozen=True)
@@ -152,7 +153,7 @@ def parse_appliance_uplinks(string_table: StringTable) -> Appliance | None:
 
 
 agent_section_cisco_meraki_org_appliance_uplinks = AgentSection(
-    name="cisco_meraki_org_appliance_uplinks",
+    name='cisco_meraki_org_appliance_uplinks',
     parse_function=parse_appliance_uplinks,
 )
 
@@ -163,10 +164,11 @@ def discover_appliance_uplinks(section: Appliance) -> DiscoveryResult:
 
 
 _STATUS_MAP = {
-    "active": 0,
-    "failed": 2,
-    "not_connected": 1,
-    "ready": 0,
+    'active': 0,
+    'failed': 2,
+    'not_connected': 1,
+    'ready': 0,
+    'connecting': 1,
 }
 _TIMESPAN = 60
 
diff --git a/source/cmk_addons_plugins/meraki/agent_based/appliance_vpns.py b/source/cmk_addons_plugins/meraki/agent_based/appliance_vpns.py
index b163e2e..38632f8 100644
--- a/source/cmk_addons_plugins/meraki/agent_based/appliance_vpns.py
+++ b/source/cmk_addons_plugins/meraki/agent_based/appliance_vpns.py
@@ -180,11 +180,11 @@ def check_appliance_vpns(item: str, params: Mapping[str, any], section: Mapping[
         return None
 
     if peer.reachability is not None and peer.reachability.lower() in ['reachable']:
-        yield Result(state=State.OK, summary=f'{peer.reachability}')
+        yield Result(state=State.OK, summary=f'Status: {peer.reachability}')
     else:
         yield Result(
             state=State(params.get('status_not_reachable', 1)),
-            summary=f'{peer.reachability}',
+            summary=f'Status: {peer.reachability}',
         )
 
     yield Result(state=State.OK, summary=f'Type: {peer.type}')
diff --git a/source/cmk_addons_plugins/meraki/agent_based/cellular_uplinks.py b/source/cmk_addons_plugins/meraki/agent_based/cellular_uplinks.py
index 2c9df38..c502b48 100644
--- a/source/cmk_addons_plugins/meraki/agent_based/cellular_uplinks.py
+++ b/source/cmk_addons_plugins/meraki/agent_based/cellular_uplinks.py
@@ -11,7 +11,7 @@
 # 2024-04-27: made data parsing more robust
 # 2024-06-29: refactored for CMK 2.3
 #             moved parse functions to class methods
-#             changed service name from "Cellular uplink" to "Uplink"
+#             changed service name from 'Cellular uplink' to 'Uplink'
 # 2024-06-30: renamed from cisco_meraki_org_cellular_uplinks.py in to cellular_uplinks.py
 
 from collections.abc import Mapping
@@ -35,39 +35,39 @@ from cmk_addons.plugins.meraki.lib.utils import get_int, load_json
 
 __cellular_uplinks = [
     {
-        "highAvailability": {
-            "enabled": False,
-            "role": "primary"
+        'highAvailability': {
+            'enabled': False,
+            'role': 'primary'
         },
-        "lastReportedAt": "2023-11-13T19:52:06Z",
-        "model": "MG41",
-        "networkId": "L_575897802350012343",
-        "serial": "QQQQ-XXXX-ZZZZ",
-        "uplinks": [
+        'lastReportedAt': '2023-11-13T19:52:06Z',
+        'model': 'MG41',
+        'networkId': 'L_575897802350012343',
+        'serial': 'QQQQ-XXXX-ZZZZ',
+        'uplinks': [
             {
-                "apn": "apn.name",
-                "connectionType": "lte",
-                "dns1": None,
-                "dns2": None,
-                "gateway": None,
-                "iccid": "89492027206012345518",
-                "interface": "cellular",
-                "ip": None,
-                "model": "integrated",
-                "provider": "provider.name",
-                "publicIp": "2.3.4.5",
-                "signalStat": {
-                    "rsrp": "-111",
-                    "rsrq": "-8"
+                'apn': 'apn.name',
+                'connectionType': 'lte',
+                'dns1': None,
+                'dns2': None,
+                'gateway': None,
+                'iccid': '89492027206012345518',
+                'interface': 'cellular',
+                'ip': None,
+                'model': 'integrated',
+                'provider': 'provider.name',
+                'publicIp': '2.3.4.5',
+                'signalStat': {
+                    'rsrp': '-111',
+                    'rsrq': '-8'
                 },
-                "signalType": None,
-                "status": "active"
+                'signalType': None,
+                'status': 'active'
             }
         ]
     }
 ]
 
-_LAST_REPORTED_AT = "%Y-%m-%dT%H:%M:%SZ"
+_LAST_REPORTED_AT = '%Y-%m-%dT%H:%M:%SZ'
 
 
 @dataclass(frozen=True)
@@ -159,7 +159,7 @@ def parse_cellular_uplinks(string_table: StringTable) -> CellularGateway | None:
 
 
 agent_section_cisco_meraki_org_cellular_uplinks = AgentSection(
-    name="cisco_meraki_org_cellular_uplinks",
+    name='cisco_meraki_org_cellular_uplinks',
     parse_function=parse_cellular_uplinks,
 )
 
diff --git a/source/cmk_addons_plugins/meraki/agent_based/switch_ports_statuses.py b/source/cmk_addons_plugins/meraki/agent_based/switch_ports_statuses.py
index 7ec77bf..f210421 100644
--- a/source/cmk_addons_plugins/meraki/agent_based/switch_ports_statuses.py
+++ b/source/cmk_addons_plugins/meraki/agent_based/switch_ports_statuses.py
@@ -7,7 +7,7 @@
 # URL   : https://thl-cmk.hopto.org
 # Date  : 2023-11-11
 # File  : switch_ports_statuses.py (check plugin)
-
+from Cython.Shadow import returns
 # 2024-04-08: moved neighbour_name and neighbour_port to key columns
 # 2024-04-27: made data parsing more robust
 # 2024-05-12: added support for MerakiGetOrganizationSwitchPortsStatusesBySwitch (Early Access)
@@ -19,6 +19,14 @@
 #             try to match the output of a "normal" cmk interface service
 # 2024-06-30: renamed from cisco_meraki_switch_ports_statuses.py in to switch_ports_statuses.py
 # 2024-06-30: fixed discovery of (admin disabled) ports
+# 2024-11-17: changed operational/admin status to up/down from connected/disconnected, enabled/disabled
+#             incompatible change item from "Port %s" to "Interface %s" -> (Port is moved to %s)
+#               -> rediscover your devices (tabularasa)
+#             added interface inventory
+#             added hostlabel function for nvdct/has_lldp_neighbours
+# 2024-11-23  fixed crash on missing traffic data
+#             incompatible removed "Port" from item -> use only interface index
+# 2024-12-14: reworked output of port status
 
 # ToDo: create service label cmk/meraki/uplink:yes/no
 
@@ -39,6 +47,8 @@ from cmk.agent_based.v2 import (
     TableRow,
     check_levels,
     render,
+    HostLabelGenerator,
+    HostLabel,
 )
 
 from cmk_addons.plugins.meraki.lib.utils import get_float, get_int, load_json
@@ -51,6 +61,13 @@ class SwitchSecurePort:
     configOverrides: Mapping[any] | None
     enabled: bool | None
 
+    __secure_port =  {
+        "active": False,
+        "authenticationStatus": "Disabled",
+        "configOverrides": {},
+        "enabled": False,
+    }
+
     @classmethod
     def parse(cls, secure_port: Mapping[str, any] | None):
         return cls(
@@ -70,14 +87,26 @@ class SwitchPortCDP:
     device_port: str | None
     platform: str | None
     version: str | None
+    native_vlan: str | None
+
+    __cdp = {
+        "address": "172.24.10.1",
+        "capabilities": "Switch",
+        "deviceId": "149f43b14530",
+        "nativeVlan": 10,
+        "platform": "MS250-48FP",
+        "portId": "Port 49",
+        "version": "1",
+    }
 
     @classmethod
     def parse(cls, cdp: Mapping[str, str] | None):
         return cls(
-            device_id=str(cdp['deviceId']) if cdp.get('deviceId') is not None else None,
-            device_port=str(cdp['portId']) if cdp.get('portId') is not None else None,
             address=str(cdp['address']) if cdp.get('address') is not None else None,
             capabilities=str(cdp['capabilities']) if cdp.get('capabilities') is not None else None,
+            device_id=str(cdp['deviceId']) if cdp.get('deviceId') is not None else None,
+            device_port=str(cdp['portId']) if cdp.get('portId') is not None else None,
+            native_vlan=str(cdp['nativeVlan']) if cdp.get('nativeVlan') is not None else None,
             platform=str(cdp['platform']) if cdp.get('platform') is not None else None,
             version=str(cdp['version']) if cdp.get('version') is not None else None,
         ) if cdp else None
@@ -93,24 +122,36 @@ class SwitchPortLLDP:
     system_description: str | None
     system_name: str | None
 
+    __lldp = {
+        "chassisId": "14:9f:43:b1:45:30",
+        "managementAddress": "172.24.10.1",
+        "managementVlan": 10,
+        "portDescription": "Port 49",
+        "portId": "49",
+        "portVlan": 10,
+        "systemCapabilities": "S-VLAN Component of a VLAN Bridge",
+        "systemDescription": "Meraki MS250-48FP Cloud Managed PoE Switch",
+        "systemName": "Meraki MS250-48FP - DV1-R005",
+    }
+
     @classmethod
     def parse(cls, lldp: Mapping[str, str] | None):
         return cls(
+            cache_capabilities=str(lldp['systemCapabilities']) if lldp.get('systemCapabilities') is not None else None,
             chassis_id=str(lldp['chassisId']) if lldp.get('chassisId') is not None else None,
+            management_address=str(lldp['managementAddress']) if lldp.get('managementAddress') is not None else None,
+            port_description=str(lldp['portDescription']) if lldp.get('portDescription') is not None else None,
             port_id=str(lldp['portId']) if lldp.get('portId') is not None else None,
-            system_name=str(lldp['systemName']) if lldp.get('systemName') is not None else None,
             system_description=str(lldp['systemDescription']) if lldp.get('systemDescription') is not None else None,
-            port_description=str(lldp['portDescription']) if lldp.get('portDescription') is not None else None,
-            cache_capabilities=str(lldp['systemCapabilities']) if lldp.get('systemCapabilities') is not None else None,
-            management_address=str(lldp['managementAddress']) if lldp.get('managementAddress') is not None else None,
+            system_name=str(lldp['systemName']) if lldp.get('systemName') is not None else None,
         ) if lldp else None
 
 
 @dataclass(frozen=True)
 class SwitchPortUsage:
-    total: float
-    sent: float
     recv: float
+    sent: float
+    total: float
 
     @classmethod
     def parse(cls, usage: Mapping[str, float] | None):
@@ -124,9 +165,9 @@ class SwitchPortUsage:
 
         """
         return cls(
-            total=get_float(usage.get('total')) * 1000,
-            sent=get_float(usage.get('sent')) * 1000,
             recv=get_float(usage.get('recv')) * 1000,
+            sent=get_float(usage.get('sent')) * 1000,
+            total=get_float(usage.get('total')) * 1000,
         ) if usage else None
 
 
@@ -148,10 +189,11 @@ class SwitchPortTraffic:
 
         Returns:
         """
+
         return cls(
-            total=get_float(traffic.get('total')) * 1000,
-            sent=get_float(traffic.get('sent')) * 1000,
             recv=get_float(traffic.get('recv')) * 1000,
+            sent=get_float(traffic.get('sent')) * 1000,
+            total=get_float(traffic.get('total')) * 1000,
         ) if traffic else None
 
 
@@ -170,62 +212,92 @@ class SwitchPortSpanningTree:
         Returns:
 
         """
+
         if isinstance(spanning_tree, dict):
             return cls(
                 status=[str(status) for status in spanning_tree.get('statuses', [])]
             )
 
 
+def parse_admin_state(admin_state: bool | None) -> str | None:
+    state_map = {
+        True: 1,
+        False: 2,
+    }
+    return state_map.get(admin_state)
+
+
+def parse_operational_state(operational_state: str | None) -> str | None:
+    state_map = {
+        'connected': 1,
+        'disconnected': 2,
+    }
+    if isinstance(operational_state, str):
+        return state_map.get(operational_state.lower())
+
+
 @dataclass(frozen=True)
 class SwitchPort:
+    port_id: int  # needs to bee always there
+    admin_state: int | None
     cdp: SwitchPortCDP | None
     client_count: int | None
     duplex: str | None
-    enabled: bool | None
     errors: Sequence[str] | None
     is_up_link: bool | None
     lldp: SwitchPortLLDP | None
-    port_id: str | None
+    operational_state: int | None
     power_usage_in_wh: float | None
     secure_port: SwitchSecurePort | None
+    spanning_tree: SwitchPortSpanningTree | None
     speed: str | None
-    status: str | None
     traffic: SwitchPortTraffic | None
     usage: SwitchPortUsage | None
     warnings: Sequence[str]
-    spanning_tree: SwitchPortSpanningTree | None
+    # syntetic settings
+    alias: str | None
+    description: str | None
+    if_port_type: str | None
+    name: str | None
 
     @classmethod
     def parse(cls, port: Mapping[str, object]):
         return cls(
-            port_id=str(port['portId']) if port.get('portId') is not None else None,
+            port_id=int(port['portId']),  # needs to be always there
+            admin_state=parse_admin_state(port.get('enabled')),
+            cdp=SwitchPortCDP.parse(port.get('cdp')),
             client_count=get_int(port.get('clientCount')),
             duplex=str(port['duplex']) if port.get('duplex') is not None else None,
-            enabled=bool(port['enabled']) if port.get('enabled') is not None else None,
             errors=port['errors'] if port.get('errors') is not None else None,
             is_up_link=bool(port['isUplink']) if port.get('isUplink') is not None else None,
-            power_usage_in_wh=get_float(port.get('powerUsageInWh')),
-            speed=str(port['speed']) if port.get('speed') is not None else None,
-            status=str(port['status']) if port.get('status') is not None else None,
-            warnings=port['warnings'] if port.get('warnings') is not None else None,
             lldp=SwitchPortLLDP.parse(port.get('lldp')),
-            cdp=SwitchPortCDP.parse(port.get('cdp')),
+            operational_state=parse_operational_state(port.get('status')),
+            power_usage_in_wh=get_float(port.get('powerUsageInWh')),
             secure_port=SwitchSecurePort.parse(port.get('securePort')),
-            usage=SwitchPortUsage.parse(port.get('usageInKb')),
+            spanning_tree=SwitchPortSpanningTree.parse(port.get('spanningTree')),
+            speed=str(port['speed']) if port.get('speed') is not None else None,
             traffic=SwitchPortTraffic.parse((port.get('trafficInKbps'))),
-            spanning_tree=SwitchPortSpanningTree.parse(port.get('spanningTree'))
+            usage=SwitchPortUsage.parse(port.get('usageInKb')),
+            warnings=port['warnings'] if port.get('warnings') is not None else None,
+            # synthetic settings
+            alias=f'Port {port["portId"]}' if port.get('portId') is not None else None,
+            description=f'Port {port["portId"]}' if port.get('portId') is not None else None,
+            if_port_type='6 - ethernetCsmacd',
+            name=f'Port {port["portId"]}' if port.get('portId') is not None else None,
         )
 
 
-_admin_status = {
-    True: 'enabled',
-    False: 'disabled',
-}
-
-_is_up_link = {
-    True: 'yes',
-    False: 'no',
-}
+def host_label_meraki_switch_ports_statuses(section: Mapping[str, SwitchPort]) -> HostLabelGenerator:
+    """Host label function
+    Labels:
+        "nvdct/has_lldp_neighbours":
+            This label is set to "yes" for all hosts with LLDP neighbours
+    """
+    for port in section.values():
+        if port.lldp:
+            yield HostLabel(name="nvdct/has_lldp_neighbours", value="yes")
+            break
+    # only set LLDP label, Merkai CDP data are not usefully for NVDCT
 
 
 def parse_switch_ports_statuses(string_table: StringTable) -> Mapping[str, SwitchPort] | None:
@@ -235,33 +307,32 @@ def parse_switch_ports_statuses(string_table: StringTable) -> Mapping[str, Switc
     if isinstance(json_data, dict) and 'ports' in json_data.keys():
         json_data = json_data['ports']
 
-    return {port['portId']: SwitchPort.parse(port) for port in json_data}
+    return {port["portId"]: SwitchPort.parse(port) for port in json_data if port.get('portId', '').isdigit()}
 
 
 agent_section_cisco_meraki_org_switch_ports_statuses = AgentSection(
     name="cisco_meraki_org_switch_ports_statuses",
     parse_function=parse_switch_ports_statuses,
+    host_label_function=host_label_meraki_switch_ports_statuses,
 )
 
 
 def discover_switch_ports_statuses(params: Mapping[str, object], section: Mapping[str, SwitchPort]) -> DiscoveryResult:
-    discovered_port_states = params['discovered_port_states']
-    # adjust params, as we can not use True/False as keys anymore in rule sets :-(
-    if 'admin_enabled' in discovered_port_states:
-        discovered_port_states.append(True)
-        discovered_port_states.remove('admin_enabled')
-    if 'admin_disabled' in discovered_port_states:
-        discovered_port_states.append(False)
-        discovered_port_states.append('disabled')
-        discovered_port_states.remove('admin_disabled')
+    state_map = {
+        1: 'up',
+        2: 'down',
+    }
+    admin_port_states = params['admin_port_states']
+    operational_port_states = params['operational_port_states']
 
-    for port in section.values():
-        if port.enabled in discovered_port_states and port.status.lower() in discovered_port_states:
+    for item, port in section.items():
+        if state_map.get(port.admin_state) in admin_port_states and \
+                state_map.get(port.operational_state) in operational_port_states:
             yield Service(
-                item=port.port_id,
+                item=item,
                 parameters={
-                    'enabled': port.enabled,
-                    'status': port.status,
+                    'admin_state': port.admin_state,
+                    'operational_state': port.operational_state,
                     'speed': port.speed,
                 }
             )
@@ -272,82 +343,98 @@ def render_network_bandwidth_bits(value: int) -> str:
 
 
 def check_switch_ports_statuses(item: str, params: Mapping[str, any], section: Mapping[str, SwitchPort]) -> CheckResult:
-    def _status_changed(is_state: str, was_state: str, state: int, message: str):
-        if is_state != was_state:
-            is_state = is_state if is_state else 'N/A'
-            was_state = was_state if was_state else 'N/A'
-            yield Result(state=State(state), notice=f'{message}: from {was_state}, to {is_state}')
+    state_map = {
+        1: 'up',
+        2: 'down',
+    }
+
+    is_up_link = {
+        True: 'yes',
+        False: 'no',
+    }
+
+    def has_changed (is_state: int | str | None, was_state: int | str | None) -> bool:
+        if not is_state or not was_state:
+            # ignore if state is None -> meaning this change is expected. OP state down -> op -> speed None -> xxx
+            return False
+
+        if is_state == was_state:
+            return False
+
+        return True
 
     if (port := section.get(item)) is None:
         return
 
-    # check admin state changed
-    yield from _status_changed(
-        is_state=_admin_status[port.enabled],
-        was_state=_admin_status[params['enabled']],
-        message='Admin status changed',
-        state=params['state_admin_change'],
-    )
-
-    if port.enabled:  # check admin sate
-        yield Result(state=State.OK, notice=f'Admin status: {_admin_status[port.enabled]}')
-        # check operational status changed
-        yield from _status_changed(
-            is_state=port.status.lower(),
-            was_state=params['status'].lower(),
-            message='Operational status changed',
-            state=params['state_op_change']
+    if port.admin_state == 2:
+        yield Result(
+            state=State(params['state_disabled']),
+            summary=f'(admin {state_map.get(port.admin_state)})',
+            details=f'Admin status: {state_map.get(port.admin_state)}',
         )
-        if port.status.lower() == 'connected':  # check operational state
-            yield Result(state=State.OK, summary=f'({port.status})', details=f'Operational status: {port.status}')
-            # check speed changed
-            yield from _status_changed(
-                is_state=port.speed,
-                was_state=params['speed'],
-                message='Speed changed',
-                state=params['state_speed_change']
-            )
-            if params['speed'] == port.speed:  # only if speed unchanged
-                yield Result(state=State.OK, summary=f'Speed: {port.speed}')
-
-            if params.get('show_traffic'):
-                yield from check_levels(
-                    value=port.traffic.recv,  # Bits
-                    label='In',
-                    metric_name='if_in_bps',
-                    render_func=render_network_bandwidth_bits,  # Bytes
-                    # notice_only=True,
-                )
-                yield from check_levels(
-                    value=port.traffic.sent,  # Bits
-                    label='Out',
-                    metric_name='if_out_bps',
-                    render_func=render_network_bandwidth_bits,  # Bytes
-                    # notice_only=True,
-                )
-
-            if port.duplex.lower() == 'full':  # check duplex state
-                yield Result(state=State.OK, notice=f'Duplex: {port.duplex}')
-            else:
-                yield Result(state=State(params['state_not_full_duplex']), notice=f'Duplex: {port.duplex}')
-            yield Result(state=State.OK, notice=f'Clients: {port.client_count}')
-        else:
-            yield Result(
-                state=State(params['state_not_connected']),
-                summary=f'({port.status})',
-                details=f'Operational status: {port.status}'
-            )
     else:
+        yield Result(state=State.OK, notice=f'Admin status: {state_map.get(port.admin_state)}')
+
+    if has_changed(port.admin_state, params['admin_state']):
+        message = f'changed admin {state_map.get(params["admin_state"])} -> {state_map.get(port.admin_state)}'
+        yield Result(state=State(params['state_admin_change']), notice=message)
+
+    if port.admin_state == 2:  # down
+        return
+
+    if port.operational_state == 2:
         yield Result(
-            state=State(params['state_disabled']),
-            summary=f'({_admin_status[port.enabled].title()})',
-            details=f'Admin status: {_admin_status[port.enabled].title()}',
+            state=State(params['state_not_connected']),
+            summary=f'({state_map.get(port.operational_state)})',
+            details=f'Operational status: {state_map.get(port.operational_state)}'
+        )
+    else:
+        yield Result(
+            state=State.OK,
+            summary=f'({state_map.get(port.operational_state)})',
+            details=f'Operational status: {state_map.get(port.operational_state)}'
         )
 
+    if has_changed(port.operational_state, params['operational_state']):
+        message = f'changed {state_map.get(params["operational_state"])} -> {state_map.get(port.operational_state)}'
+        yield Result(state=State(params['state_op_change']), summary=message)
+
+    if port.operational_state == 2:
+        return
+
+    yield Result(state=State.OK, summary=f'Speed: {port.speed}')
+
+    if has_changed(port.speed, params['speed']):
+        message = f'changed {params["speed"]} -> {port.speed}'
+        yield Result(state=State(params['state_speed_change']), summary=message)
+
+
+    if params.get('show_traffic') and port.traffic:
+        yield from check_levels(
+            value=port.traffic.recv,  # Bits
+            label='In',
+            metric_name='if_in_bps',
+            render_func=render_network_bandwidth_bits,  # Bytes
+            # notice_only=True,
+        )
+        yield from check_levels(
+            value=port.traffic.sent,  # Bits
+            label='Out',
+            metric_name='if_out_bps',
+            render_func=render_network_bandwidth_bits,  # Bytes
+            # notice_only=True,
+        )
+
+        if port.duplex.lower() == 'full':  # check duplex state
+            yield Result(state=State.OK, notice=f'Duplex: {port.duplex}')
+        else:
+            yield Result(state=State(params['state_not_full_duplex']), notice=f'Duplex: {port.duplex}')
+        yield Result(state=State.OK, notice=f'Clients: {port.client_count}')
+
     if port.is_up_link:
-        yield Result(state=State.OK, summary='UP-Link', details=f'UP-Link: {_is_up_link[port.is_up_link]}')
+        yield Result(state=State.OK, summary='UP-Link', details=f'UP-Link: {is_up_link[port.is_up_link]}')
     else:
-        yield Result(state=State.OK, notice=f'UP-Link: {_is_up_link[port.is_up_link]}')
+        yield Result(state=State.OK, notice=f'UP-Link: {is_up_link[port.is_up_link]}')
 
     if port.power_usage_in_wh:
         yield Result(state=State.OK, summary=f'Power usage: {port.power_usage_in_wh} Wh')
@@ -368,7 +455,7 @@ def check_switch_ports_statuses(item: str, params: Mapping[str, any], section: M
 
 check_plugin_cisco_meraki_org_switch_ports_statuses = CheckPlugin(
     name='cisco_meraki_org_switch_ports_statuses',
-    service_name='Port %s',
+    service_name='Interface %s',
     discovery_function=discover_switch_ports_statuses,
     check_function=check_switch_ports_statuses,
     check_default_parameters={
@@ -382,11 +469,38 @@ check_plugin_cisco_meraki_org_switch_ports_statuses = CheckPlugin(
     check_ruleset_name='cisco_meraki_switch_ports_statuses',
     discovery_ruleset_name='discovery_cisco_meraki_switch_ports_statuses',
     discovery_default_parameters={
-        'discovered_port_states': ['admin_enabled', 'admin_disabled', 'connected', 'disconnected']
+        'admin_port_states': ['up', 'down'],
+        'operational_port_states': ['up', 'down'],
     }
 )
 
 
+def inventory_meraki_interfaces(section: Mapping[str, SwitchPort]) -> InventoryResult:
+    for port in section.values():
+        yield TableRow(
+            path=['networking', 'interfaces'],
+            key_columns={
+                "index": port.port_id,
+            },
+            inventory_columns={
+                **({'alias': port.alias} if port.alias else {}),
+                **({'description': port.description} if port.description else {}),
+                **({'name': port.name} if port.name else {}),
+                **({'admin_status': port.admin_state} if port.admin_state else {}),
+                **({'oper_status': port.operational_state} if port.operational_state else {}),
+                **({'speed': port.speed} if port.speed else {}),
+                **({'if_port_type': port.if_port_type} if port.if_port_type else {}),
+            },
+        )
+
+
+inventory_plugin_inv_meraki_interfaces = InventoryPlugin(
+    name='inv_meraki_interfaces',
+    sections=['cisco_meraki_org_switch_ports_statuses'],
+    inventory_function=inventory_meraki_interfaces,
+)
+
+
 def inventory_meraki_cdp_cache(section: Mapping[str, SwitchPort]) -> InventoryResult:
     path = ['networking', 'cdp_cache', 'neighbours']
 
@@ -394,14 +508,16 @@ def inventory_meraki_cdp_cache(section: Mapping[str, SwitchPort]) -> InventoryRe
         if cdp := port.cdp:
             key_columns = {
                 'local_port': port.port_id,
-                'neighbour_name': cdp.device_id,
+                'neighbour_name': '',
                 'neighbour_port': cdp.device_port,
             }
             neighbour = {
-                'neighbour_address': cdp.address,
-                'platform_details': cdp.version,
-                'platform': cdp.platform,
-                'capabilities': cdp.capabilities
+                **({'capabilities': cdp.capabilities} if cdp.capabilities else {}),
+                **({'native_vlan': cdp.native_vlan} if cdp.native_vlan else {}),
+                **({'neighbour_address': cdp.address} if cdp.address else {}),
+                **({'neighbour_id': cdp.device_id} if cdp.device_id else {}),
+                **({'platform': cdp.platform} if cdp.platform else {}),
+                **({'version': cdp.version} if cdp.version else {}),
             }
             yield TableRow(
                 path=path,
@@ -428,11 +544,11 @@ def inventory_meraki_lldp_cache(section: Mapping[str, SwitchPort]) -> InventoryR
                 'neighbour_port': lldp.port_id,
             }
             neighbour = {
-                'neighbour_id': lldp.chassis_id,
-                'system_description': lldp.system_description,
-                'port_description': lldp.port_description,
-                'capabilities': lldp.cache_capabilities,
-                'neighbour_address': lldp.management_address,
+                **({'capabilities': lldp.cache_capabilities} if lldp.cache_capabilities else {}),
+                **({'neighbour_address': lldp.management_address} if lldp.management_address else {}),
+                **({'neighbour_id': lldp.chassis_id} if lldp.chassis_id else {}),
+                **({'port_description': lldp.port_description} if lldp.port_description else {}),
+                **({'system_description': lldp.system_description} if lldp.system_description else {}),
             }
             yield TableRow(
                 path=path,
diff --git a/source/cmk_addons_plugins/meraki/agent_based/wireless_device_ssid_status.py b/source/cmk_addons_plugins/meraki/agent_based/wireless_device_ssid_status.py
index 5b65d48..2710ccc 100644
--- a/source/cmk_addons_plugins/meraki/agent_based/wireless_device_ssid_status.py
+++ b/source/cmk_addons_plugins/meraki/agent_based/wireless_device_ssid_status.py
@@ -15,6 +15,7 @@
 # 2024-07-13: fixed crash on missing metrics (device dormant) ThX to Leon Buhleier
 # 2024-08-07: fixed crash on missing power value (unit only) ThX to Leon Buhleier
 # 2024-09-12: fixed missing SSID 0 ThX to Andreas Doehler
+# 2024-12-13: fixed crash if no valid data received (json_data = [[]])
 
 from collections.abc import Mapping
 from dataclasses import dataclass
@@ -64,7 +65,7 @@ class SSID:
 
 def parse_wireless_device_status(string_table: StringTable) -> Mapping[str, SSID] | None:
     json_data = load_json(string_table)
-    if (json_data := json_data[0]) is None:
+    if not (json_data := json_data[0]):
         return
 
     ssids = {}
@@ -78,7 +79,6 @@ def parse_wireless_device_status(string_table: StringTable) -> Mapping[str, SSID
         item = str(ssid_number) + ' on band ' + row.get('band')
 
         ssids[item] = SSID.parse(row)
-
     return ssids
 
 
diff --git a/source/cmk_addons_plugins/meraki/agent_based/wireless_ethernet_statuses.py b/source/cmk_addons_plugins/meraki/agent_based/wireless_ethernet_statuses.py
index 8ad1aa7..88cc8fe 100644
--- a/source/cmk_addons_plugins/meraki/agent_based/wireless_ethernet_statuses.py
+++ b/source/cmk_addons_plugins/meraki/agent_based/wireless_ethernet_statuses.py
@@ -12,6 +12,9 @@
 # 2024-06-29: refactored for CMK 2.3
 #             moved parse functions to class methods
 # 2024-06-30: renamed from cisco_meraki_org_wireless_ethernet_statuses.py in to wireless_ethernet_statuses.py
+# 2024-11-17: incompatible change item from "Port %s" to "Interface %s" -> rediscover your devices
+#             added interface inventory
+# 2024-12-12: fixed crash if speed is None
 
 # ToDo: create ruleset cisco_meraki_wireless_ethernet_statuses
 
@@ -28,6 +31,9 @@ from cmk.agent_based.v2 import (
     State,
     StringTable,
     render,
+    InventoryPlugin,
+    InventoryResult,
+    TableRow,
 )
 from cmk_addons.plugins.meraki.lib.utils import get_int, load_json
 
@@ -176,7 +182,7 @@ def check_wireless_ethernet_statuses(
 
 check_plugin_cisco_meraki_org_wireless_ethernet_statuses = CheckPlugin(
     name='cisco_meraki_org_wireless_ethernet_statuses',
-    service_name='Port %s',
+    service_name='Interface %s',
     discovery_function=discover_wireless_ethernet_statuses,
     check_function=check_wireless_ethernet_statuses,
     check_default_parameters={
@@ -187,3 +193,29 @@ check_plugin_cisco_meraki_org_wireless_ethernet_statuses = CheckPlugin(
     },
     # check_ruleset_name='cisco_meraki_wireless_ethernet_statuses',
 )
+
+
+def inventory_meraki_wireless_ethernet(section: Mapping[str, WirelessEthernetPort]) -> InventoryResult:
+    for port in section.values():
+        yield TableRow(
+            path=['networking', 'interfaces'],
+            key_columns={
+                "index": port.name.split(' ')[-1],
+            },
+            inventory_columns={
+                'alias': port.name,
+                'description': port.name,
+                'name': port.name,
+                'admin_status': 1,
+                'oper_status': 1,
+                **({'speed': render.nicspeed(port.speed)} if port.speed is not None else {}),
+                'if_port_type': '6 - ethernetCsmacd',
+            },
+        )
+
+
+inventory_plugin_inv_meraki_wireless_ethernet = InventoryPlugin(
+    name='inv_meraki_wireless_ethernet',
+    sections=['cisco_meraki_org_wireless_ethernet_statuses'],
+    inventory_function=inventory_meraki_wireless_ethernet,
+)
diff --git a/source/cmk_addons_plugins/meraki/lib/agent.py b/source/cmk_addons_plugins/meraki/lib/agent.py
index ef80ffe..50516ca 100644
--- a/source/cmk_addons_plugins/meraki/lib/agent.py
+++ b/source/cmk_addons_plugins/meraki/lib/agent.py
@@ -40,14 +40,17 @@
 # 2024-09-12: added version check for min. Meraki SDK version
 # 2024-09-15: fixed MerakiGetOrganizationSwitchPortsStatusesBySwitch -> return only list of switches
 # 2024-11-16: fixed crash on missing items in MerakiGetOrganizationSwitchPortsStatusesBySwitch (ThX to Stephan Bergfeld)
+# 2024-11-23: added appliance port api call -> not yet active
+# 2024-12-13: fixed crash in SwitchPortStatus if response has no data (>Response [503}>)
 
 # ToDo: create inventory from Networks, is per organisation, not sure where/how to put this in the inventory
 # ToDo: list Connected Datacenters like Umbrella https://developer.cisco.com/meraki/api-v1/list-data-centers/
 # ToDo: https://developer.cisco.com/meraki/api-v1/list-tunnels/
+# ToDo: https://developer.cisco.com/meraki/api-v1/get-organization-wireless-clients-overview-by-device/
 
 # if the following is available (right now only with early access enabled)
-# ToDO: https://developer.cisco.com/meraki/api-v1/get-organization-switch-ports-statuses-by-switch/
-# ToDo: https://developer.cisco.com/meraki/api-v1/get-organization-switch-ports-overview/  # (done)
+# ToDO: https://developer.cisco.com/meraki/api-v1/get-organization-switch-ports-statuses-by-switch/ # (done)
+# ToDo: https://developer.cisco.com/meraki/api-v1/get-organization-switch-ports-overview/
 # TODo: https://developer.cisco.com/meraki/api-v1/get-organization-certificates/
 # ToDo: https://developer.cisco.com/meraki/api-v1/api-reference-early-access-api-platform-configure-firmwareupgrades-get-network-firmware-upgrades/
 
@@ -62,6 +65,7 @@ from argparse import Namespace
 from collections.abc import Iterable, Iterator, Mapping, Sequence
 from dataclasses import dataclass
 from enum import auto, Enum
+from json import JSONDecodeError
 from logging import getLogger
 from os import environ
 from pathlib import Path
@@ -89,6 +93,7 @@ from cmk_addons.plugins.meraki.lib.utils import (
 
     # parameter names
     _SEC_NAME_APPLIANCE_UPLINKS,
+    _SEC_NAME_APPLIANCE_PORTS,
     _SEC_NAME_APPLIANCE_UPLINKS_USAGE,
     _SEC_NAME_APPLIANCE_VPNS,
     _SEC_NAME_APPLIANCE_PERFORMANCE,
@@ -125,53 +130,55 @@ from cmk_addons.plugins.meraki.lib.utils import (
     _SEC_CACHE_SWITCH_PORTS_STATUSES,
     _SEC_CACHE_WIRELESS_DEVICE_STATUS,
     _SEC_CACHE_WIRELESS_ETHERNET_STATUSES,
+    _SEC_CACHE_APPLIANCE_PORTS,
 )
 
 _MERAKI_SDK_MIN_VERSION: Final = '1.46.0'
 
-_LOGGER = getLogger("agent_cisco_meraki")
+_LOGGER = getLogger('agent_cisco_meraki')
 
-_API_NAME_API: Final = "api"
-_API_NAME_DEVICE_NAME: Final = "name"
+_API_NAME_API: Final = 'api'
+_API_NAME_DEVICE_NAME: Final = 'name'
 _API_NAME_DEVICE_PRODUCT_TYPE: Final = 'productType'
-_API_NAME_DEVICE_SERIAL: Final = "serial"
+_API_NAME_DEVICE_SERIAL: Final = 'serial'
 _API_NAME_DEVICE_TYPE_APPLIANCE: Final = 'appliance'
 _API_NAME_DEVICE_TYPE_CAMERA: Final = 'camera'
 _API_NAME_DEVICE_TYPE_CELLULAR: Final = 'cellularGateway'
 _API_NAME_DEVICE_TYPE_SENSOR: Final = 'sensor'
 _API_NAME_DEVICE_TYPE_SWITCH: Final = 'switch'
 _API_NAME_DEVICE_TYPE_WIRELESS: Final = 'wireless'
-_API_NAME_ENABLED: Final = "enabled"
+_API_NAME_ENABLED: Final = 'enabled'
 _API_NAME_NETWORK_ID: Final = 'networkId'
-_API_NAME_ORGANISATION_ID: Final = "id"
-_API_NAME_ORGANISATION_NAME: Final = "name"
+_API_NAME_ORGANISATION_ID: Final = 'id'
+_API_NAME_ORGANISATION_NAME: Final = 'name'
 
-# map section parameter name to python name (do we really need this, why not use the name ("-" -> "_")?
+# map section parameter name to python name (do we really need this, why not use the name ('-' -> '_')?
 _SECTION_NAME_MAP = {
-    _SEC_NAME_APPLIANCE_UPLINKS: "appliance_uplinks",
-    _SEC_NAME_APPLIANCE_UPLINKS_USAGE: "appliance_uplinks_usage",
-    _SEC_NAME_APPLIANCE_VPNS: "appliance_vpns",
-    _SEC_NAME_APPLIANCE_PERFORMANCE: "appliance_performance",
-    _SEC_NAME_CELLULAR_UPLINKS: "cellular_uplinks",
-    _SEC_NAME_DEVICE_INFO: "device_info",
-    _SEC_NAME_DEVICE_STATUSES: "device_status",
-    _SEC_NAME_DEVICE_UPLINKS_INFO: "device_uplinks_info",
-    _SEC_NAME_LICENSES_OVERVIEW: "licenses_overview",
-    _SEC_NAME_NETWORKS: "networks",
-    _SEC_NAME_ORGANISATIONS: "organisations",
-    _SEC_NAME_ORG_API_REQUESTS: "api_requests_by_organization",
-    _SEC_NAME_SENSOR_READINGS: "sensor_readings",
-    _SEC_NAME_SWITCH_PORTS_STATUSES: "switch_ports_statuses",
-    _SEC_NAME_WIRELESS_DEVICE_STATUS: "wireless_device_status",
-    _SEC_NAME_WIRELESS_ETHERNET_STATUSES: "wireless_ethernet_statuses",
+    _SEC_NAME_APPLIANCE_UPLINKS: 'appliance_uplinks',
+    _SEC_NAME_APPLIANCE_UPLINKS_USAGE: 'appliance_uplinks_usage',
+    _SEC_NAME_APPLIANCE_PORTS: 'appliance_ports',
+    _SEC_NAME_APPLIANCE_VPNS: 'appliance_vpns',
+    _SEC_NAME_APPLIANCE_PERFORMANCE: 'appliance_performance',
+    _SEC_NAME_CELLULAR_UPLINKS: 'cellular_uplinks',
+    _SEC_NAME_DEVICE_INFO: 'device_info',
+    _SEC_NAME_DEVICE_STATUSES: 'device_status',
+    _SEC_NAME_DEVICE_UPLINKS_INFO: 'device_uplinks_info',
+    _SEC_NAME_LICENSES_OVERVIEW: 'licenses_overview',
+    _SEC_NAME_NETWORKS: 'networks',
+    _SEC_NAME_ORGANISATIONS: 'organisations',
+    _SEC_NAME_ORG_API_REQUESTS: 'api_requests_by_organization',
+    _SEC_NAME_SENSOR_READINGS: 'sensor_readings',
+    _SEC_NAME_SWITCH_PORTS_STATUSES: 'switch_ports_statuses',
+    _SEC_NAME_WIRELESS_DEVICE_STATUS: 'wireless_device_status',
+    _SEC_NAME_WIRELESS_ETHERNET_STATUSES: 'wireless_ethernet_statuses',
     # Early Access
-    _SEC_NAME_ORG_SWITCH_PORTS_STATUSES: "org_switch_ports_statuses",
+    _SEC_NAME_ORG_SWITCH_PORTS_STATUSES: 'org_switch_ports_statuses',
 }
 
 # _MIN_CACHE_INTERVAL = 300
 # _RANDOM_CACHE_INTERVAL = 300
 
-MerakiCacheFilePath = Path(tmp_dir) / "agents" / "agent_cisco_meraki"
+MerakiCacheFilePath = Path(tmp_dir) / 'agents' / 'agent_cisco_meraki'
 MerakiAPIData = Mapping[str, object]
 
 
@@ -235,7 +242,7 @@ class Section:
     piggyback: str | None = None
 
     def get_name(self) -> str:
-        return "_".join(["cisco_meraki", self.api_data_source.name, self.name])
+        return '_'.join(['cisco_meraki', self.api_data_source.name, self.name])
 
 
 class _Organisation(TypedDict):
@@ -258,13 +265,13 @@ class _Organisation(TypedDict):
 #
 # --\ DataCache
 #   |
-#   |--\ MerakiSection
+#   +--\ MerakiSection
 #      |  - adds cache_interval = 86400
 #      |  - adds get_validity_from_args = True
 #      |
-#      |--> MerakiGetOrganizations                          		           -> default 86400
+#      +--> MerakiGetOrganizations                          		           -> default 86400
 #      |
-#      |--\ MerakiSectionOrg
+#      +--\ MerakiSectionOrg
 #      |  |  - adds org_id parameter
 #      |  |
 #      |  |--> MerakiGetOrganization				                           -> default 86400
@@ -282,13 +289,20 @@ class _Organisation(TypedDict):
 #      |  |--> MerakiGetOrganizationCellularGatewayUplinkStatuses              -> ex. 60.
 #      |  |--> MerakiGetOrganizationSwitchPortsStatusesBySwitch                -> ex. 60+
 #      |
-#      |--\ MerakiSectionSerial
-#         |  - adds serial as parameter
-#         |  - sets cache_interval = 60 + randrange(300)
+#      +--\ MerakiSectionSerial
+#      |  |  - adds serial as parameter
+#      |  |  - sets cache_interval = 60
+#      |  |
+#      |  |--> MerakiGetDeviceSwitchPortsStatuses 	                           -> default 60+
+#      |  |--> MerakiGetDeviceWirelessStatus	                               -> default 60+
+#      |  |--> MerakiGetDeviceAppliancePerformance
+#      |
+#      +--\ MerakiSectionNetwork
+#         | - adds network id as parameter
+#         | - sets cache_interval = 60
 #         |
-#         |--> MerakiGetDeviceSwitchPortsStatuses 	                           -> default 60+
-#         |--> MerakiGetDeviceWirelessStatus	                               -> default 60+
-#         |--> MerakiGetDeviceAppliancePerformance
+#         |--> MerakiGetNetworkAppliancePorts
+#
 
 class MerakiSection(DataCache):
     def __init__(
@@ -305,7 +319,7 @@ class MerakiSection(DataCache):
 
     @property
     def name(self):
-        return "meraki_section"
+        return 'meraki_section'
 
     @property
     def cache_interval(self):
@@ -338,18 +352,29 @@ class MerakiSectionSerial(MerakiSection):
         super().__init__(config=config, cache_interval=cache_interval)
 
 
+class MerakiSectionNetwork(MerakiSection):
+    def __init__(
+            self,
+            config: MerakiConfig,
+            network_id: str,
+            cache_interval: int = 1,
+    ):
+        self._network_id = network_id
+        super().__init__(config=config, cache_interval=cache_interval)
+
+
 class MerakiGetOrganizations(MerakiSection):
     @property
     def name(self):
-        return "getOrganizations"
+        return 'getOrganizations'
 
     def get_live_data(self):
         try:
             return self._config.dashboard.organizations.getOrganizations(
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Get organisations: %r", e)
+            _LOGGER.debug('Get organisations: %r', e)
             return []
 
 
@@ -379,9 +404,9 @@ class MerakiGetOrganizationApiRequestsOverviewResponseCodesByInterval(MerakiSect
             # )
             return self._config.dashboard.organizations.getOrganizationApiRequestsOverviewResponseCodesByInterval(
                 self._org_id,
-                total_pages="all",
-                t0=strftime("%Y-%m-%dT%H:%M:%MZ", gmtime(now_time()-120)),
-                t1=strftime("%Y-%m-%dT%H:%M:%MZ", gmtime())
+                total_pages='all',
+                t0=strftime('%Y-%m-%dT%H:%M:%MZ', gmtime(now_time()-120)),
+                t1=strftime('%Y-%m-%dT%H:%M:%MZ', gmtime())
             )
 
         except meraki.APIError as e:
@@ -400,7 +425,7 @@ class MerakiGetOrganizationLicensesOverview(MerakiSectionOrg):
                 self._org_id,
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get license overview: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get license overview: %r', self._org_id, e)
             return []
 
 
@@ -413,10 +438,10 @@ class MerakiGetOrganizationDevices(MerakiSectionOrg):
         try:
             return self._config.dashboard.organizations.getOrganizationDevices(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get devices: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get devices: %r', self._org_id, e)
             return {}
 
 
@@ -429,10 +454,10 @@ class MerakiGetOrganizationNetworks(MerakiSectionOrg):
         try:
             return self._config.dashboard.organizations.getOrganizationNetworks(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get networks: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get networks: %r', self._org_id, e)
             return []
 
 
@@ -445,10 +470,10 @@ class MerakiGetOrganizationDevicesStatuses(MerakiSectionOrg):
         try:
             return self._config.dashboard.organizations.getOrganizationDevicesStatuses(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get device statuses: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get device statuses: %r', self._org_id, e)
             return []
 
 
@@ -461,10 +486,10 @@ class MerakiGetOrganizationDevicesUplinksAddressesByDevice(MerakiSectionOrg):
         try:
             return self._config.dashboard.organizations.getOrganizationDevicesUplinksAddressesByDevice(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get device statuses: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get device statuses: %r', self._org_id, e)
             return []
 
 
@@ -477,10 +502,10 @@ class MerakiGetOrganizationApplianceUplinkStatuses(MerakiSectionOrg):
         try:
             return self._config.dashboard.appliance.getOrganizationApplianceUplinkStatuses(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get Appliance uplink status by network: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get Appliance uplink status by network: %r', self._org_id, e)
             return []
 
 
@@ -490,17 +515,17 @@ class MerakiGetOrganizationApplianceUplinksUsageByNetwork(MerakiSectionOrg):
         return f'getOrganizationApplianceUplinksUsageByNetwork_{self._org_id}'
 
     def get_live_data(self):
-        if meraki.__version__ < "1.39.0":
+        if meraki.__version__ < '1.39.0':
             _LOGGER.debug(f'Meraki SDK is to old. Installed: {meraki.__version__}, excepted: 1.39.0')
             return []
         try:
             return self._config.dashboard.appliance.getOrganizationApplianceUplinksUsageByNetwork(
                 organizationId=self._org_id,
-                total_pages="all",
+                total_pages='all',
                 timespan=60  # default=86400 (one day), maximum=1209600 (14 days), needs to match value in check
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get Appliance uplink usage by network: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get Appliance uplink usage by network: %r', self._org_id, e)
             return []
 
 
@@ -513,11 +538,11 @@ class MerakiGetOrganizationApplianceVpnStatuses(MerakiSectionOrg):
         try:
             return self._config.dashboard.appliance.getOrganizationApplianceVpnStatuses(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
 
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get Appliance VPN status by network: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get Appliance VPN status by network: %r', self._org_id, e)
             return []
 
 
@@ -532,7 +557,7 @@ class MerakiGetDeviceAppliancePerformance(MerakiSectionSerial):
             return self._config.dashboard.appliance.getDeviceAppliancePerformance(
                 self._serial)
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Serial: %r: Get appliance device performance: %r",
+            _LOGGER.debug('Serial: %r: Get appliance device performance: %r',
                           self._serial, e)
             return []
 
@@ -546,10 +571,10 @@ class MerakiGetOrganizationSensorReadingsLatest(MerakiSectionOrg):
         try:
             return self._config.dashboard.sensor.getOrganizationSensorReadingsLatest(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get sensor readings: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get sensor readings: %r', self._org_id, e)
             return []
 
 
@@ -562,11 +587,11 @@ class MerakiGetDeviceSwitchPortsStatuses(MerakiSectionSerial):
         try:
             return self._config.dashboard.switch.getDeviceSwitchPortsStatuses(
                 self._serial,
-                # total_pages="all",
+                # total_pages='all',
                 timespan=max(self._config.timespan, 900),
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Serial: %r: Get Switch Port Statuses: %r", self._serial, e)
+            _LOGGER.debug('Serial: %r: Get Switch Port Statuses: %r', self._serial, e)
             return []
 
 
@@ -576,16 +601,16 @@ class MerakiGetOrganizationWirelessDevicesEthernetStatuses(MerakiSectionOrg):
         return f'getOrganizationWirelessDevicesEthernetStatuses_{self._org_id}'
 
     def get_live_data(self):
-        if meraki.__version__ < "1.39.0":
+        if meraki.__version__ < '1.39.0':
             _LOGGER.debug(f'Meraki SDK is to old. Installed: {meraki.__version__}, expceted: 1.39.0')
             return []
         try:
             return self._config.dashboard.wireless.getOrganizationWirelessDevicesEthernetStatuses(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Organisation ID: %r: Get wireless devices ethernet statuses: %r", self._org_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get wireless devices ethernet statuses: %r', self._org_id, e)
             return []
 
 
@@ -598,7 +623,7 @@ class MerakiGetDeviceWirelessStatus(MerakiSectionSerial):
         try:
             return self._config.dashboard.wireless.getDeviceWirelessStatus(self._serial)
         except meraki.exceptions.APIError as e:
-            _LOGGER.debug("Serial: %r: Get wireless device status: %r", self._serial, e)
+            _LOGGER.debug('Serial: %r: Get wireless device status: %r', self._serial, e)
             return []
 
 
@@ -611,7 +636,7 @@ class MerakiGetOrganizationCellularGatewayUplinkStatuses(MerakiSectionOrg):
         try:
             return self._config.dashboard.cellularGateway.getOrganizationCellularGatewayUplinkStatuses(
                 self._org_id,
-                total_pages="all",
+                total_pages='all',
             )
         except meraki.exceptions.APIError as e:
             _LOGGER.debug('Organisation ID: %r: Get cellular gateways uplink statuses: %r', self._org_id, e)
@@ -652,12 +677,32 @@ class MerakiGetOrganizationSwitchPortsStatusesBySwitch(MerakiSectionOrg):
         except RequestException as e:
             _LOGGER.debug('Organisation ID: %r: Get Ports statuses by switch: %r', self._org_id, e)
             return []
-        _response = response.json()
+        try:
+            _response = response.json()
+        except JSONDecodeError:
+            _LOGGER.debug('Organisation ID: %r: Get Ports statuses by switch: %r', self._org_id, response)
+            return []
         if _response:
             return _response.get('items', [])
         return []
 
 
+class MerakiGetNetworkAppliancePorts(MerakiSectionNetwork):
+    @property
+    def name(self):
+        return f'getNetworkAppliancePorts_{self._network_id}'
+
+    def get_live_data(self):
+        try:
+            return self._config.dashboard.appliance.getNetworkAppliancePorts(
+                self._network_id,
+                # total_pages='all',
+            )
+        except meraki.exceptions.APIError as e:
+            _LOGGER.debug('Network ID: %r: Get appliance ports: %r', self._network_id, e)
+            return []
+
+
 #
 # Main run
 #
@@ -737,7 +782,7 @@ class MerakiOrganisation:
                 device_piggyback = device[_API_NAME_DEVICE_NAME]
             except KeyError as e:
                 _LOGGER.debug(
-                    "Organisation ID: %r: Get device piggyback: %r", self.organisation_id, e
+                    'Organisation ID: %r: Get device piggyback: %r', self.organisation_id, e
                 )
                 continue
 
@@ -872,6 +917,60 @@ class MerakiOrganisation:
                             piggyback=self._adjust_piggyback(host=piggyback),
                             )
 
+            # if _SEC_NAME_APPLIANCE_PORTS not in self.config.excluded_sections and networks:
+            #     for network in networks:
+            #         appliance_ports_by_network = MerakiGetNetworkAppliancePorts(
+            #             config=self.config,
+            #             network_id=network.get('id'),
+            #             cache_interval=30,
+            #         ).get_data(use_cache=self.config.use_cache)
+            #         __ports = [
+            #             {
+            #                 'number': 5,
+            #                 'enabled': True,
+            #                 'type': 'trunk',
+            #                 'dropUntaggedTraffic': True,
+            #                 'allowedVlans': 'all'
+            #             },
+            #             {
+            #                 'number': 6,
+            #                 'enabled': True,
+            #                 'type': 'trunk',
+            #                 'dropUntaggedTraffic': True,
+            #                 'allowedVlans': 'all'
+            #             },
+            #             {
+            #                 'number': 7,
+            #                 'enabled': True,
+            #                 'type': 'trunk',
+            #                 'dropUntaggedTraffic': False,
+            #                 'vlan': 1,
+            #                 'allowedVlans': 'all'},
+            #             {
+            #                 'number': 8,
+            #                 'enabled': True,
+            #                 'type': 'trunk',
+            #                 'dropUntaggedTraffic': True,
+            #                 'allowedVlans': 'all'
+            #             },
+            #             {
+            #                 'number': 9,
+            #                 'enabled': True,
+            #                 'type': 'trunk',
+            #                 'dropUntaggedTraffic': False,
+            #                 'vlan': 10,
+            #                 'allowedVlans': 'all'
+            #             },
+            #             {
+            #                 'number': 10,
+            #                 'enabled': True,
+            #                 'type': 'trunk',
+            #                 'dropUntaggedTraffic': False,
+            #                 'vlan': 10,
+            #                 'allowedVlans': 'all'
+            #             }
+            #         ]
+
         if devices_by_type.get(_API_NAME_DEVICE_TYPE_SWITCH):
             if _SEC_NAME_SWITCH_PORTS_STATUSES not in self.config.excluded_sections:
                 for switch in devices_by_type[_API_NAME_DEVICE_TYPE_SWITCH]:
@@ -982,8 +1081,8 @@ class MerakiOrganisation:
                 return None
             licenses_overview.update(
                 {
-                    "organisation_id": self.organisation_id,
-                    "organisation_name": self.organisation_name,
+                    'organisation_id': self.organisation_id,
+                    'organisation_name': self.organisation_name,
                 }
             )
             return licenses_overview
@@ -1000,8 +1099,8 @@ class MerakiOrganisation:
         def _update_device(device: dict[str, object]) -> MerakiAPIData:
             device.update(
                 {
-                    "organisation_id": self.organisation_id,
-                    "organisation_name": self.organisation_name,
+                    'organisation_id': self.organisation_id,
+                    'organisation_name': self.organisation_name,
                     'network_name': self._networks.get(device.get(_API_NAME_NETWORK_ID)).name,
                 }
             )
@@ -1027,7 +1126,7 @@ class MerakiOrganisation:
                 _LOGGER.debug(f'Host without name _get_device_piggyback serial: {serial}')
                 return None
         except KeyError as e:
-            _LOGGER.debug("Organisation ID: %r: Get device piggyback: %r", self.organisation_id, e)
+            _LOGGER.debug('Organisation ID: %r: Get device piggyback: %r', self.organisation_id, e)
             return None
 
     @staticmethod
@@ -1076,8 +1175,9 @@ def _write_sections(sections: Iterable[Section]) -> None:
 @dataclass(frozen=True)
 class CachePerSection:
     appliance_performance: int
-    appliance_uplinks_usage: int
+    appliance_ports: int
     appliance_uplinks: int
+    appliance_uplinks_usage: int
     appliance_vpns: int
     cellular_uplinks: int
     device_info: int
@@ -1110,39 +1210,39 @@ class Args(Namespace):
 def parse_arguments(argv: Sequence[str] | None) -> Args:
     parser = create_default_argument_parser(description=__doc__)
 
-    parser.add_argument("hostname")
+    parser.add_argument('hostname')
     parser.add_argument(
-        "apikey",
-        help="API key for the Meraki API dashboard access.",
+        'apikey',
+        help='API key for the Meraki API dashboard access.',
     )
 
-    parser.add_argument("--proxy", type=str)
+    parser.add_argument('--proxy', type=str)
 
     # parser.add_argument(
-    #     "--sections",
-    #     nargs="+",
+    #     '--sections',
+    #     nargs='+',
     #     choices=list(_SECTION_NAME_MAP),
     #     default=list(_SECTION_NAME_MAP),
-    #     help="Explicit sections that are collected.",
+    #     help='Explicit sections that are collected.',
     # )
 
     parser.add_argument(
-        "--excluded-sections",
-        nargs="*",
+        '--excluded-sections',
+        nargs='*',
         choices=list(_SECTION_NAME_MAP),
         default=[],
-        help="Sections that are excluded form data collected.",
+        help='Sections that are excluded form data collected.',
     )
 
     parser.add_argument(
-        "--orgs",
-        nargs="+",
+        '--orgs',
+        nargs='+',
         default=[],
-        help="Explicit organisation IDs that are checked.",
+        help='Explicit organisation IDs that are checked.',
     )
 
     # parser.add_argument(
-    #     "--prefix-suffix",
+    #     '--prefix-suffix',
     #     nargs=5,
     #     action='append',
     #     default=[],
@@ -1168,13 +1268,14 @@ def parse_arguments(argv: Sequence[str] | None) -> Args:
 
     parser.add_argument(
         '--cache-per-section',
-        nargs="+",
+        nargs='+',
         type=int,
-        help="List of cache time per section in minutes",
+        help='List of cache time per section in minutes',
         default=[
             _SEC_CACHE_APPLIANCE_PERFORMANCE,
-            _SEC_CACHE_APPLIANCE_UPLINKS_USAGE,
+            _SEC_CACHE_APPLIANCE_PORTS,
             _SEC_CACHE_APPLIANCE_UPLINKS,
+            _SEC_CACHE_APPLIANCE_UPLINKS_USAGE,
             _SEC_CACHE_APPLIANCE_VPNS,
             _SEC_CACHE_CELLULAR_UPLINKS,
             _SEC_CACHE_DEVICE_INFO,
@@ -1182,13 +1283,13 @@ def parse_arguments(argv: Sequence[str] | None) -> Args:
             _SEC_CACHE_DEVICE_UPLINKS_INFO,
             _SEC_CACHE_LICENSES_OVERVIEW,
             _SEC_CACHE_NETWORKS,
+            _SEC_CACHE_ORGANISATIONS,
             _SEC_CACHE_ORG_API_REQUESTS,
             _SEC_CACHE_ORG_SWITCH_PORTS_STATUSES,
-            _SEC_CACHE_ORGANISATIONS,
             _SEC_CACHE_SENSOR_READINGS,
             _SEC_CACHE_SWITCH_PORTS_STATUSES,
             _SEC_CACHE_WIRELESS_DEVICE_STATUS,
-            _SEC_CACHE_WIRELESS_ETHERNET_STATUSES
+            _SEC_CACHE_WIRELESS_ETHERNET_STATUSES,
         ]
     )
 
diff --git a/source/cmk_addons_plugins/meraki/lib/utils.py b/source/cmk_addons_plugins/meraki/lib/utils.py
index 810af86..2301c95 100644
--- a/source/cmk_addons_plugins/meraki/lib/utils.py
+++ b/source/cmk_addons_plugins/meraki/lib/utils.py
@@ -23,23 +23,24 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import CheckResul
 MerakiAPIData = Mapping[str, object]
 
 # parameter names for agent options
-_SEC_NAME_ORGANISATIONS: Final = "_organisations"  # internal use runs always
-_SEC_NAME_DEVICE_INFO: Final = "_device_info"  # Not configurable, needed for piggyback
-_SEC_NAME_NETWORKS: Final = "_networks"  # internal use, runs always, needed for network names
-_SEC_NAME_ORG_API_REQUESTS: Final = "api-requests-by-organization"  # internal use, runs always
-
-_SEC_NAME_APPLIANCE_UPLINKS: Final = "appliance-uplinks"
-_SEC_NAME_APPLIANCE_UPLINKS_USAGE: Final = "appliance-uplinks-usage"
-_SEC_NAME_APPLIANCE_VPNS: Final = "appliance-vpns"
-_SEC_NAME_APPLIANCE_PERFORMANCE: Final = "appliance-performance"
-_SEC_NAME_CELLULAR_UPLINKS: Final = "cellular-uplinks"
-_SEC_NAME_DEVICE_STATUSES: Final = "device-status"
-_SEC_NAME_DEVICE_UPLINKS_INFO: Final = "device-uplinks-info"
-_SEC_NAME_LICENSES_OVERVIEW: Final = "licenses-overview"
-_SEC_NAME_SENSOR_READINGS: Final = "sensor-readings"
-_SEC_NAME_SWITCH_PORTS_STATUSES: Final = "switch-ports-statuses"
-_SEC_NAME_WIRELESS_DEVICE_STATUS: Final = "wireless-device-status"
-_SEC_NAME_WIRELESS_ETHERNET_STATUSES: Final = "wireless-ethernet-statuses"
+_SEC_NAME_ORGANISATIONS: Final = '_organisations'  # internal use runs always
+_SEC_NAME_DEVICE_INFO: Final = '_device_info'  # Not configurable, needed for piggyback
+_SEC_NAME_NETWORKS: Final = '_networks'  # internal use, runs always, needed for network names
+_SEC_NAME_ORG_API_REQUESTS: Final = 'api-requests-by-organization'  # internal use, runs always
+
+_SEC_NAME_APPLIANCE_UPLINKS: Final = 'appliance-uplinks'
+_SEC_NAME_APPLIANCE_PORTS: Final = 'appliance-ports'
+_SEC_NAME_APPLIANCE_UPLINKS_USAGE: Final = 'appliance-uplinks-usage'
+_SEC_NAME_APPLIANCE_VPNS: Final = 'appliance-vpns'
+_SEC_NAME_APPLIANCE_PERFORMANCE: Final = 'appliance-performance'
+_SEC_NAME_CELLULAR_UPLINKS: Final = 'cellular-uplinks'
+_SEC_NAME_DEVICE_STATUSES: Final = 'device-status'
+_SEC_NAME_DEVICE_UPLINKS_INFO: Final = 'device-uplinks-info'
+_SEC_NAME_LICENSES_OVERVIEW: Final = 'licenses-overview'
+_SEC_NAME_SENSOR_READINGS: Final = 'sensor-readings'
+_SEC_NAME_SWITCH_PORTS_STATUSES: Final = 'switch-ports-statuses'
+_SEC_NAME_WIRELESS_DEVICE_STATUS: Final = 'wireless-device-status'
+_SEC_NAME_WIRELESS_ETHERNET_STATUSES: Final = 'wireless-ethernet-statuses'
 
 
 # api cache defaults per section
@@ -60,22 +61,21 @@ _SEC_CACHE_SENSOR_READINGS = 0
 _SEC_CACHE_SWITCH_PORTS_STATUSES = 0
 _SEC_CACHE_WIRELESS_DEVICE_STATUS = 30
 _SEC_CACHE_WIRELESS_ETHERNET_STATUSES = 30
-
-
+_SEC_CACHE_APPLIANCE_PORTS = 30
 
 # Early Access
-_SEC_NAME_ORG_SWITCH_PORTS_STATUSES: Final = "org-switch-ports-statuses"
+_SEC_NAME_ORG_SWITCH_PORTS_STATUSES: Final = 'org-switch-ports-statuses'
 
 
 @dataclass(frozen=True)
 class MerakiNetwork:
-    id: str  # "N_24329156",
-    name: str  # "Main Office",
-    product_types: Sequence[str]  # ["appliance", "switch", "wireless"]
-    time_zone: str  # "America/Los_Angeles",
-    tags: Sequence[str]  # [ "tag1", "tag2" ],
-    enrollment_string: str | None  # "my-enrollment-string",
-    notes: str  # "Additional description of the network",
+    id: str  # 'N_24329156',
+    name: str  # 'Main Office',
+    product_types: Sequence[str]  # ['appliance', 'switch', 'wireless']
+    time_zone: str  # 'America/Los_Angeles',
+    tags: Sequence[str]  # [ 'tag1', 'tag2' ],
+    enrollment_string: str | None  # 'my-enrollment-string',
+    notes: str  # 'Additional description of the network',
     is_bound_to_config_template: bool  # false
     organisation_id: str
     organisation_name: str
@@ -97,7 +97,7 @@ def check_last_reported_ts(
     if (age := time.time() - last_reported_ts) < 0:
         yield Result(
             state=State.OK,
-            summary="Negative timespan since last report time.",
+            summary='Negative timespan since last report time.',
         )
         return
     if levels_upper:
diff --git a/source/cmk_addons_plugins/meraki/rulesets/switch_ports_statuses.py b/source/cmk_addons_plugins/meraki/rulesets/switch_ports_statuses.py
index 3cea6f7..5c2f580 100644
--- a/source/cmk_addons_plugins/meraki/rulesets/switch_ports_statuses.py
+++ b/source/cmk_addons_plugins/meraki/rulesets/switch_ports_statuses.py
@@ -15,6 +15,10 @@
 # 2024-06-27: refactored for CMK 2.3
 # 2024-06-30: renamed from cisco_meraki_switch_ports_statuses.py in to switch_ports_statuses.py
 #             added params from discovery as render only
+# 2024-11-17: incompatible change to match changed port status check -> recreate your discovery rule
+# 2024-11-23: added missing discovery parameters admin_state and operational_state
+#             removed discovery parameters 'enabled' and 'status'
+#             reference to section organization_switch_ports removed, missing traffic, lldp, cdp, stp, ...
 
 from cmk.rulesets.v1 import Label, Title, Help
 from cmk.rulesets.v1.form_specs import (
@@ -29,11 +33,6 @@ from cmk.rulesets.v1.form_specs import (
 )
 from cmk.rulesets.v1.rule_specs import CheckParameters, DiscoveryParameters, HostAndItemCondition, Topic
 
-from cmk_addons.plugins.meraki.lib.utils import (
-    _SEC_NAME_ORG_SWITCH_PORTS_STATUSES,
-    _SEC_NAME_SWITCH_PORTS_STATUSES,
-)
-
 
 def _parameter_form():
     return Dictionary(
@@ -55,17 +54,17 @@ def _parameter_form():
                 )),
             'state_speed_change': DictElement(
                 parameter_form=ServiceState(
-                    title=Title('Monitoring state if speed is changed'),
+                    title=Title('Monitoring state if speed has changed'),
                     prefill=DefaultValue(ServiceState.WARN),
                 )),
             'state_admin_change': DictElement(
                 parameter_form=ServiceState(
-                    title=Title('Monitoring state if admin state is changed'),
+                    title=Title('Monitoring state if admin state has changed'),
                     prefill=DefaultValue(ServiceState.WARN),
                 )),
             'state_op_change': DictElement(
                 parameter_form=ServiceState(
-                    title=Title('Monitoring state if operational state is changed'),
+                    title=Title('Monitoring state if operational state has changed'),
                     prefill=DefaultValue(ServiceState.WARN),
                 )),
             'show_traffic': DictElement(
@@ -76,23 +75,20 @@ def _parameter_form():
                     help_text=Help(
                         'Use only with cache disabled in the Meraki special agent settings. '
                         'Depending on your Meraki organization size (in terms of number of switches) '
-                        'this will exceeds the limits of the allowed API requests per second. You can try to '
-                        'enable "Early Access" in the Meraki dashboard. In the Meraki special agent settings '
-                        f'switch from "{_SEC_NAME_SWITCH_PORTS_STATUSES}" to "{_SEC_NAME_ORG_SWITCH_PORTS_STATUSES}". '
-                        'This will fetch all the switch data with one API request instead of one request for each '
-                        'switch.'
+                        'this will exceeds the limits of the allowed API requests per second.'
                     ),
                 )),
             # params from discovery
-            'enabled': DictElement(
+            'admin_state': DictElement(
                 render_only=True,
                 parameter_form=String(
                     title=Title('Discovered admin state')
-                )),
-            'status': DictElement(
+                )
+            ),
+            'operational_state': DictElement(
                 render_only=True,
                 parameter_form=String(
-                    title=Title('Discovered status')
+                    title=Title('Discovered operational state')
                 )
             ),
             'speed': DictElement(
@@ -100,7 +96,7 @@ def _parameter_form():
                 parameter_form=String(
                     title=Title('Discovered speed')
                 )
-            )
+            ),
         },
     )
 
@@ -117,33 +113,42 @@ rule_spec_cisco_meraki_switch_ports_statuses = CheckParameters(
 def _discovery_form():
     return Dictionary(
         elements={
-            'discovered_port_states': DictElement(
+            'operational_port_states': DictElement(
                 parameter_form=MultipleChoice(
-                    title=Title('Select Ports to discover'),
+                    title=Title('Match port states'),
                     elements=[
                         MultipleChoiceElement(
-                            title=Title('Admin enabled'),
-                            name='admin_enabled',
+                            title=Title('1 - up'),
+                            name='up',
                         ),
                         MultipleChoiceElement(
-                            title=Title('Admin disabled'),
-                            name='admin_disabled',
+                            title=Title('2 - down'),
+                            name='down',
                         ),
+                    ],
+                    help_text=Help('Apply this rule only to interfaces whose port state is listed below.'),
+                    prefill=DefaultValue([
+                        'up',
+                        'down',
+                    ])
+                )),
+            'admin_port_states': DictElement(
+                parameter_form=MultipleChoice(
+                    title=Title('Match admin states'),
+                    elements=[
                         MultipleChoiceElement(
-                            title=Title('Connected'),
-                            name='connected',
+                            title=Title('1 - up'),
+                            name='up',
                         ),
                         MultipleChoiceElement(
-                            title=Title('Disconnected'),
-                            name='disconnected',
+                            title=Title('2 - down'),
+                            name='down',
                         ),
                     ],
-                    help_text=Help('Select the port states for discovery'),
+                    help_text=Help('Apply this rule only to interfaces whose admin state is listed below'),
                     prefill=DefaultValue([
-                        'admin_enabled',
-                        'admin_disabled',
-                        'connected',
-                        'disconnected',
+                        'up',
+                        'down',
                     ])
                 )),
         },
diff --git a/source/packages/cisco_meraki b/source/packages/cisco_meraki
index 21fb4c5..0687aaf 100644
--- a/source/packages/cisco_meraki
+++ b/source/packages/cisco_meraki
@@ -63,7 +63,7 @@
            'web': ['plugins/views/cisco_meraki.py']},
  'name': 'cisco_meraki',
  'title': 'Cisco Meraki special agent',
- 'version': '1.3.7-20241116',
+ 'version': '1.4.1-20241217',
  'version.min_required': '2.3.0b1',
  'version.packaged': 'cmk-mkp-tool 0.2.0',
  'version.usable_until': '2.4.0b1'}
-- 
GitLab