diff --git a/agent_based/checkpoint_vsx_system.py b/agent_based/checkpoint_vsx_system.py
index d9069908a0f13ef9cf511e07c885bb988153c7b3..8dfb77ab58adc3e72ae5a0b8990ece6f391b5735 100644
--- a/agent_based/checkpoint_vsx_system.py
+++ b/agent_based/checkpoint_vsx_system.py
@@ -23,6 +23,11 @@
 #             moved Main IP to details, if it is not an IPv4 address
 # 2022-10-23: fixed warning on upgrade "non-empty params vanished" for policyname and ha_state
 # 2023-05-29: moved gui files to ~/local/lib/check_mk/gui/plugins/...
+# 2023-06-17: added support for predicted levels for connection active
+#             changed bytes/packets metrics to check_levels/check_levels_predictive
+# 2023-06-18: cleanup variable names to better meet python standards
+#
+
 #
 # snmpwalk sample
 #
@@ -92,7 +97,7 @@
 import ipaddress
 import time
 from dataclasses import dataclass
-from typing import List, Dict, Optional, Tuple
+from typing import List, Dict, Optional, Any
 
 from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     register,
@@ -109,6 +114,8 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import (
     get_rate,
     GetRateError,
     check_levels,
+    check_levels_predictive,
+    render,
 )
 from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
     DiscoveryResult,
@@ -117,55 +124,114 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
 )
 
 
+@dataclass
+class VsxMetric:
+    name: str
+    value: float
+    label: str
+    levels: str
+    render_func: Any
+
+
 @dataclass
 class CheckpointVsx:
-    vsxStatusVSId: str
-    vsxStatusVsType: str
-    vsxStatusMainIP: str
-    vsxStatusPolicyName: str
-    vsxStatusVsPolicyType: str
-    vsxStatusSicTrustState: str
-    vsxStatusHAState: str
-    vsxStatusVSWeight: str
-    vsxCountersConnNum: int
-    vsxCountersConnPeakNum: int
-    vsxCountersConnTableLimit: int
-    metrics_rate: List[Tuple[str, int]]
+    vs_id: str
+    vs_type: str
+    main_ip: str
+    policy_name: str
+    policy_type: str
+    sic_trust_state: str
+    ha_state: str
+    vs_weight: str
+    connections_active: int
+    connections_peak: int
+    connections_limit: int
+    metrics_rate: List[VsxMetric]
+
+
+def _render_per_second(value: float) -> str:
+    return f'{value:.2}/s'
 
 
 def parse_checkpoint_vsx_system(string_table: StringTable) -> Optional[Dict[str, CheckpointVsx]]:
     vsx_systems = {}
     for entry in string_table:
         try:
-            vsxStatusVSId, vsxStatusVsName, vsxStatusVsType, vsxStatusMainIP, vsxStatusPolicyName, \
-            vsxStatusVsPolicyType, vsxStatusSicTrustState, vsxStatusHAState, vsxStatusVSWeight, vsxCountersConnNum, \
-            vsxCountersConnPeakNum, vsxCountersConnTableLimit, vsxCountersPackets, vsxCountersDroppedTotal, \
-            vsxCountersAcceptedTotal, vsxCountersRejectedTotal, vsxCountersBytesAcceptedTotal, \
-            vsxCountersBytesDroppedTotal, vsxCountersBytesRejectedTotal, vsxCountersLoggedTotal = entry
+            vs_id, vs_name, vs_type, main_ip, policy_name, policy_type, sic_trust_state, ha_state, vs_weight, \
+                connections_active, connections_peak, connections_limit, packets_processed, packets_dropped, \
+                packets_accepted, packets_rejected, bytes_accepted, bytes_dropped, bytes_rejected, loggs_send = entry
         except ValueError:
             return
 
-        vsx_systems[vsxStatusVsName] = CheckpointVsx(
-            vsxStatusVSId=vsxStatusVSId,
-            vsxStatusVsType=vsxStatusVsType,
-            vsxStatusMainIP=vsxStatusMainIP,
-            vsxStatusPolicyName=vsxStatusPolicyName,
-            vsxStatusVsPolicyType=vsxStatusVsPolicyType,
-            vsxStatusSicTrustState=vsxStatusSicTrustState,
-            vsxStatusHAState=vsxStatusHAState,
-            vsxStatusVSWeight=vsxStatusVSWeight,
-            vsxCountersConnNum=int(vsxCountersConnNum),
-            vsxCountersConnPeakNum=int(vsxCountersConnPeakNum),
-            vsxCountersConnTableLimit=int(vsxCountersConnTableLimit),
+        vsx_systems[vs_name] = CheckpointVsx(
+            vs_id=vs_id,
+            vs_type=vs_type,
+            main_ip=main_ip,
+            policy_name=policy_name,
+            policy_type=policy_type,
+            sic_trust_state=sic_trust_state,
+            ha_state=ha_state,
+            vs_weight=vs_weight,
+            connections_active=int(connections_active),
+            connections_peak=int(connections_peak),
+            connections_limit=int(connections_limit),
             metrics_rate=[
-                ('packets_processed', int(vsxCountersPackets)),
-                ('packets_dropped', int(vsxCountersDroppedTotal)),
-                ('packets_accepted', int(vsxCountersAcceptedTotal)),
-                ('packets_rejected', int(vsxCountersRejectedTotal)),
-                ('bytes_accepted', int(vsxCountersBytesAcceptedTotal)),
-                ('bytes_dropped', int(vsxCountersBytesDroppedTotal)),
-                ('bytes_rejected', int(vsxCountersBytesRejectedTotal)),
-                ('loggs_send', int(vsxCountersLoggedTotal)),
+                VsxMetric(
+                    name='bytes_accepted',
+                    value=float(bytes_accepted),
+                    label='Bytes accepted',
+                    levels='levels_bytes_accepted',
+                    render_func=render.iobandwidth,
+                ),
+                VsxMetric(
+                    name='bytes_dropped',
+                    value=float(bytes_dropped),
+                    label='Bytes dropped',
+                    levels='levels_bytes_dropped',
+                    render_func=render.iobandwidth,
+                ),
+                VsxMetric(
+                    name='bytes_rejected',
+                    value=float(bytes_rejected),
+                    label='Bytes rejected',
+                    levels='levels_bytes_rejected',
+                    render_func=render.iobandwidth,
+                ),
+                VsxMetric(
+                    name='packets_accepted',
+                    value=float(packets_accepted),
+                    label='Packets accepted',
+                    levels='levels_packets_accepted',
+                    render_func=_render_per_second,
+                ),
+                VsxMetric(
+                    name='packets_dropped',
+                    value=float(packets_dropped),
+                    label='Packets dropped',
+                    levels='levels_packets_dropped',
+                    render_func=_render_per_second,
+                ),
+                VsxMetric(
+                    name='packets_rejected',
+                    value=float(packets_rejected),
+                    label='Packets rejected',
+                    levels='levels_packets_rejected',
+                    render_func=_render_per_second,
+                ),
+                VsxMetric(
+                    name='packets_processed',
+                    value=float(packets_processed),
+                    label='Packets processed',
+                    levels='levels_packets_processed',
+                    render_func=_render_per_second,
+                ),
+                VsxMetric(
+                    name='loggs_send',
+                    value=float(loggs_send),
+                    label='Logs send',
+                    levels='levels_logs_send',
+                    render_func=_render_per_second,
+                ),
             ],
         )
     return vsx_systems
@@ -173,90 +239,131 @@ def parse_checkpoint_vsx_system(string_table: StringTable) -> Optional[Dict[str,
 
 def discovery_checkpoint_vsx_system(params, section: Dict[str, CheckpointVsx]) -> DiscoveryResult:
     for key in section.keys():
-        if section[key].vsxStatusVsType.lower() in params['vs_type']:
+        if section[key].vs_type.lower() in params['vs_type']:
             yield Service(
                 item=key,
-                parameters={'policyname': section[key].vsxStatusPolicyName, 'ha_state': section[key].vsxStatusHAState}
+                parameters={'policyname': section[key].policy_name, 'ha_state': section[key].ha_state}
             )
 
 
 def check_checkpoint_vsx_system(item, params, section: Dict[str, CheckpointVsx]) -> CheckResult:
+    # warn on old params
+    if params.get('levels_lower_absolute') or params.get('levels_upper_absolute'):
+        yield Result(
+            state=State.WARN,
+            summary='Reconfigure your "Check Point VSX System" WATO rule(s) please. '
+                    'You are using deprecated settings (Maximum/Minimum number of firewall connections)'
+        )
+
     try:
         vsx = section[item]
     except KeyError:
         yield Result(state=State.UNKNOWN, notice='Item not found in SNMP data')
         return
 
-    if not vsx.vsxStatusSicTrustState.lower() in ['trust established']:
+    if not vsx.sic_trust_state.lower() in ['trust established']:
         yield Result(state=State(params['state_sic_not_established']), notice='SIC not established')
 
-    if vsx.vsxStatusVsType.lower() in ['virtual system', 'vsx gateway']:
+    if vsx.vs_type.lower() in ['virtual system', 'vsx gateway']:
         yield Result(state=State.OK, notice=f'System name: {item}')
         try:
-            yield Result(state=State.OK, summary=f'Main IP: {ipaddress.ip_address(vsx.vsxStatusMainIP)}')
+            yield Result(state=State.OK, summary=f'Main IP: {ipaddress.ip_address(vsx.main_ip)}')
         except ValueError:
-            yield Result(state=State.OK, notice=f'Main IP: {vsx.vsxStatusMainIP}')
+            yield Result(state=State.OK, notice=f'Main IP: {vsx.main_ip}')
 
-        yield Result(state=State.OK, summary=f'VS ID: {vsx.vsxStatusVSId}',
-                     details=f'Virtual system ID: {vsx.vsxStatusVSId}')
-        yield Result(state=State.OK, notice=f'System type: {vsx.vsxStatusVsType}')
+        yield Result(state=State.OK, summary=f'VS ID: {vsx.vs_id}', details=f'Virtual system ID: {vsx.vs_id}')
+        yield Result(state=State.OK, notice=f'System type: {vsx.vs_type}')
 
-        if not vsx.vsxStatusHAState.lower() in ['active', 'standby']:
-            yield Result(state=State(params['state_ha_not_act_stb']), summary=f'H/A Status: {vsx.vsxStatusHAState}')
+        if not vsx.ha_state.lower() in ['active', 'standby']:
+            yield Result(state=State(params['state_ha_not_act_stb']), summary=f'H/A Status: {vsx.ha_state}')
         else:
-            yield Result(state=State.OK, summary=f'H/A Status: {vsx.vsxStatusHAState}')
+            yield Result(state=State.OK, summary=f'H/A Status: {vsx.ha_state}')
 
-        if not vsx.vsxStatusVsPolicyType.lower() in ['active']:
+        if not vsx.policy_type.lower() in ['active']:
             yield Result(state=State(params['state_policy_not_installed']), notice='No policy installed')
 
-        if params['policyname'] != vsx.vsxStatusPolicyName:  # policy changed
+        if params['policyname'] != vsx.policy_name:  # policy changed
             yield Result(
                 state=State(params['state_policy_changed']),
-                notice=f'Policy name changed: expected {params["policyname"]}, found {vsx.vsxStatusPolicyName}'
+                notice=f'Policy name changed: expected {params["policyname"]}, found {vsx.policy_name}'
             )
 
-        if params['ha_state'] != vsx.vsxStatusHAState:  # H/A state changed
+        if params['ha_state'] != vsx.ha_state:  # H/A state changed
             yield Result(
                 state=State(params['state_ha_changed']),
-                notice=f'State changed: expected/found {params["ha_state"]}/{vsx.vsxStatusHAState}'
+                notice=f'State changed: expected/found {params["ha_state"]}/{vsx.ha_state}'
             )
 
-        yield Result(state=State.OK, notice=f'SIC status: {vsx.vsxStatusSicTrustState}')
-        yield Result(state=State.OK, notice=f'Weight: {vsx.vsxStatusVSWeight}')
-        yield Result(state=State.OK, notice=f'Policy name: {vsx.vsxStatusPolicyName}')
-        yield Result(state=State.OK, notice=f'Policy type: {vsx.vsxStatusVsPolicyType}')
+        yield Result(state=State.OK, notice=f'SIC status: {vsx.sic_trust_state}')
+        yield Result(state=State.OK, notice=f'Weight: {vsx.vs_weight}')
+        yield Result(state=State.OK, notice=f'Policy name: {vsx.policy_name}')
+        yield Result(state=State.OK, notice=f'Policy type: {vsx.policy_type}')
 
-        # metrics rate
-        now_time = time.time()
-        value_store = get_value_store()
         metrics_prefix = 'checkpoint_vsx_'
 
-        for key, value in vsx.metrics_rate:
-            try:
-                value = get_rate(value_store, f'{metrics_prefix}{key}', now_time, int(value), raise_overflow=True)
-            except GetRateError:
-                value = 0
-            yield Metric(name=f'checkpoint_vsx_{key}', value=value, boundaries=(0, None))
-
         # metrics count
-        yield from check_levels(
-            value=vsx.vsxCountersConnNum,
+        yield from check_levels_predictive(
+            value=vsx.connections_active,
             metric_name=f'{metrics_prefix}connections',
-            levels_upper=params.get('levels_upper_absolute'),
-            levels_lower=params.get('levels_lower_absolute'),
+            levels=params.get('levels_connections'),
+            label='Connections',
+            render_func=lambda v: f'{v:.0f}',
+            boundaries=(0, None),
+        ) if isinstance(params.get('levels_connections'), dict) else check_levels(
+            value=vsx.connections_active,
+            metric_name=f'{metrics_prefix}connections',
+            levels_upper=params.get('levels_connections'),
+            # levels_lower=params.get('levels_lower_absolute'),
             label='Connections',
             render_func=lambda v: f'{v:.0f}',
             boundaries=(0, None),
         )
 
-        yield Metric(value=vsx.vsxCountersConnPeakNum, name=f'{metrics_prefix}connections_peak')
-        if vsx.vsxCountersConnTableLimit > 0:
-            yield Metric(value=vsx.vsxCountersConnTableLimit, name=f'{metrics_prefix}connections_limit')
+        # metrics rate
+        now_time = time.time()
+        value_store = get_value_store()
+
+        for metric in vsx.metrics_rate:
+            try:
+                value = get_rate(
+                    value_store,
+                    f'{metrics_prefix}{metric.name}',
+                    now_time,
+                    metric.value,
+                    raise_overflow=True,
+                )
+            except GetRateError:
+                continue
+            # yield Metric(name=f'checkpoint_vsx_{key}', value=value, boundaries=(0, None))
+            yield from check_levels_predictive(
+                value=value,
+                metric_name=f'checkpoint_vsx_{metric.name}',
+                levels=params.get(metric.levels),
+                label=metric.label,
+                render_func=metric.render_func,
+                boundaries=(0, None),
+                # needs patched lib/check_mk/base/api/agent_based/utils.py
+                # see PR https://github.com/Checkmk/checkmk/pull/598
+                # notice_only=True,
+            ) if isinstance(params.get(metric.levels), dict) else check_levels(
+                value=value,
+                metric_name=f'checkpoint_vsx_{metric.name}',
+                levels_upper=params.get(metric.levels),
+                # levels_lower=params.get('levels_lower_absolute'),
+                label=metric.label,
+                render_func=metric.render_func,
+                boundaries=(0, None),
+                notice_only=True
+            )
+
+        yield Metric(value=vsx.connections_peak, name=f'{metrics_prefix}connections_peak')
+        if vsx.connections_limit > 0:
+            yield Metric(value=vsx.connections_limit, name=f'{metrics_prefix}connections_limit')
     else:
         yield Result(state=State.OK, notice=f'System name: {item}')
-        yield Result(state=State.OK, summary=f'Virtual system ID: {vsx.vsxStatusVSId}')
-        yield Result(state=State.OK, summary=f'System Type: {vsx.vsxStatusVsType}')
-        yield Result(state=State.OK, summary=f'SIC status: {vsx.vsxStatusSicTrustState}')
+        yield Result(state=State.OK, summary=f'Virtual system ID: {vsx.vs_id}')
+        yield Result(state=State.OK, summary=f'System Type: {vsx.vs_type}')
+        yield Result(state=State.OK, summary=f'SIC status: {vsx.sic_trust_state}')
 
 
 register.snmp_section(
@@ -317,6 +424,7 @@ register.check_plugin(
         'state_policy_not_installed': 2,
         'state_policy_changed': 1,
         'state_ha_changed': 1,
+
         # 'levels_upper_absolute': (None, None),
         # 'levels_lower_absolute': (None, None),
         # 'policyname': '',
diff --git a/checkpoint_vsx_system-0.5.0-20230619.mkp b/checkpoint_vsx_system-0.5.0-20230619.mkp
new file mode 100644
index 0000000000000000000000000000000000000000..61e7c3a9f908950b4e7fc319972fcf51e61d9dcb
Binary files /dev/null and b/checkpoint_vsx_system-0.5.0-20230619.mkp differ
diff --git a/checkpoint_vsx_system.mkp b/checkpoint_vsx_system.mkp
index 88eba84ef0a8f77eefa78bfdca353b8e0963ffa1..61e7c3a9f908950b4e7fc319972fcf51e61d9dcb 100644
Binary files a/checkpoint_vsx_system.mkp and b/checkpoint_vsx_system.mkp differ
diff --git a/gui/wato/check_parameters/checkpoint_vsx_system.py b/gui/wato/check_parameters/checkpoint_vsx_system.py
new file mode 100644
index 0000000000000000000000000000000000000000..f9ad001ff1d8ac0335161c5b16d51afc8d5a8424
--- /dev/null
+++ b/gui/wato/check_parameters/checkpoint_vsx_system.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# License: GNU General Public License v2
+#
+# Author: thl-cmk[at]outlook[dot]com
+# URL   : https://thl-cmk.hopto.org
+# Date  : 2021-09-07
+#
+
+# 2023-06-17: changed upper/lower levels for active connections to levels (predictive)
+#             added wato levels option for bytes/packets perf counters
+# 2023-06-18: moved wato file to check_parameters sub directory
+
+from cmk.gui.i18n import _
+from cmk.gui.valuespec import (
+    Dictionary,
+    TextAscii,
+    Tuple,
+    Integer,
+    MonitoringState,
+    ListChoice,
+    TextUnicode,
+)
+
+from cmk.gui.plugins.wato.utils import (
+    CheckParameterRulespecWithItem,
+    rulespec_registry,
+    RulespecGroupCheckParametersNetworking,
+    RulespecGroupCheckParametersDiscovery,
+    HostRulespec,
+    Levels,
+)
+
+
+def _parameter_valuespec_checkpoint_vsx_system():
+    return Dictionary(
+        elements=[
+            ('state_ha_not_act_stb',
+             MonitoringState(
+                 title=_('State if H/A state is not active/standby'),
+                 help=_('Monitoring state if H/A state is not active or standby. Defaulr is "CRIT"'),
+                 default_value=2,
+             )),
+            ('state_ha_changed',
+             MonitoringState(
+                 title=_('State if H/A state has changed'),
+                 help=_('Monitoring state if H/A state has changed. Default is "WARN".'),
+                 default_value=1,
+             )),
+            ('state_policy_not_installed',
+             MonitoringState(
+                 title=_('State if no policy is installed'),
+                 help=_('Monitoring state if no policy is installed. Default is "CRIT"'),
+                 default_value=2,
+             )),
+            ('state_policy_changed',
+             MonitoringState(
+                 title=_('State if policy name has changed'),
+                 help=_('Monitoring status on policy name change. Default is "WARN".'),
+                 default_value=1,
+             )),
+            ('state_sic_not_established',
+             MonitoringState(
+                 title=_('State if SIC is not established'),
+                 help=_('Monitoring state if SIC (Secure Internal Communication) is not established. Default is "CRIT"'),
+                 default_value=2,
+             )),
+            ('levels_bytes_accepted', Levels(title=_('Levels for Bytes Accepted'), unit=_('Bytes/s'), )),
+            ('levels_bytes_dropped', Levels(title=_('Levels for Bytes Dropped'), unit=_('Bytes/s'), )),
+            ('levels_bytes_rejected', Levels(title=_('Levels for Bytes Rejected'), unit=_('Bytes/s'), )),
+            ('levels_connections', Levels(title=_('Levels for Connections'), unit=_('Connections'), )),
+            ('levels_logs_send', Levels(title=_('Levels for Logs Send'), unit=_('Logs/s'), )),
+            ('levels_packets_accepted', Levels(title=_('Levels for Packets Accepted'), unit=_('Packets/s'), )),
+            ('levels_packets_dropped', Levels(title=_('Levels for Packets Dropped'), unit=_('Packets/s'), )),
+            ('levels_packets_rejected', Levels(title=_('Levels for Packets Rejected'), unit=_('Packets/s'), )),
+            ('levels_packets_processed', Levels(title=_('Levels for Packets Processed'), unit=_('Packets/s'), )),
+            # added by plugin discovery function -> hidden key
+            ('policyname', TextUnicode()),
+            # added by plugin discovery function -> hidden key
+            ('ha_state', TextUnicode()),
+        ],
+        hidden_keys=['policyname', 'ha_state'],
+        ignored_keys=['levels_upper_absolute', 'levels_lower_absolute'],
+        # shows help before an item is activated, nur bei render "normal"
+        # columns=2,
+        # space saver -> Title to the Right -> item starts on same line. Adds collapsed properties
+        # form_part like form, only more space between label and checkbox
+        # render='form',
+        # item on same hight as label, is multiline item label moves to the middle of item -> saves space
+        # render form looks better
+        # form_narrow=True,
+        # same as form_narrow=True (?)
+        # form_isopen=False,
+    )
+
+
+rulespec_registry.register(
+    CheckParameterRulespecWithItem(
+        check_group_name='checkpoint_vsx_system',
+        group=RulespecGroupCheckParametersNetworking,
+        match_type='dict',
+        parameter_valuespec=_parameter_valuespec_checkpoint_vsx_system,
+        title=lambda: _('Check Point VSX system'),
+        item_spec=lambda: TextAscii(title=_('VSX System name'), ),
+    ))
+
+
+def _valuespec_discovery_checkpoint_vsx_system():
+    _vs_types = [
+        ('virtual system', 'Virtual System'),
+        ('vsx gateway', 'VSX Gateway'),
+        ('virtual switch', 'Virtual Switch'),
+        ('virtual router', 'Virtual Router'),
+    ]
+    return Dictionary(
+            title=_('Check Point VSX system'),
+            elements=[
+                ('vs_type',
+                 ListChoice(
+                     title=_('VS types to discover'),
+                     help=_('Virtual system types to discover. Note: if you select "VSX Gateway", '
+                            'this will also discover ClusterXL systems.'),
+                     choices=_vs_types,
+                     default_value=[
+                         'virtual system',
+                     ],
+                 )),
+            ],
+        )
+
+
+rulespec_registry.register(
+    HostRulespec(
+        group=RulespecGroupCheckParametersDiscovery,
+        match_type='dict',
+        name='discovery_checkpoint_vsx_system',
+        valuespec=_valuespec_discovery_checkpoint_vsx_system,
+    ))
diff --git a/packages/checkpoint_vsx_system b/packages/checkpoint_vsx_system
index ee4de64a5fa57ed921fe5d0ed11345996671e18d..65f7d43a73e15016576b3113c3084c3cfa66d751 100644
--- a/packages/checkpoint_vsx_system
+++ b/packages/checkpoint_vsx_system
@@ -15,10 +15,10 @@
  'files': {'agent_based': ['checkpoint_vsx_system.py'],
            'checkman': ['checkpoint_vsx_system'],
            'gui': ['metrics/checkpoint_vsx_system.py',
-                   'wato/checkpoint_vsx_system.py']},
+                   'wato/check_parameters/checkpoint_vsx_system.py']},
  'name': 'checkpoint_vsx_system',
  'title': 'Check Point VSX system status and counter',
- 'version': '0.4.0-20230529',
+ 'version': '0.5.0-20230619',
  'version.min_required': '2.1.0b1',
- 'version.packaged': '2.1.0p21',
- 'version.usable_until': None}
\ No newline at end of file
+ 'version.packaged': '2.2.0p2',
+ 'version.usable_until': None}