diff --git a/agent_based/checkpoint_vsx.ps b/agent_based/checkpoint_vsx.ps
new file mode 100644
index 0000000000000000000000000000000000000000..8d4953756c495e7b5dde1a3ad045c7ce5dc25614
--- /dev/null
+++ b/agent_based/checkpoint_vsx.ps
@@ -0,0 +1,249 @@
+#!/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  : 2017-17-05
+#
+# Check Point vsx Cluster status
+#
+# Monitor status of virtual systems in Check Point vsx/vsls cluster
+#
+# 2018-08-03: changed snmp scan function
+# 2018-08-13: code cleanup, add metrics
+# 2020-06-08: changed snmp-scan function
+# 2021-09-06: rewritten for CMK 2.0
+#
+# snmpwalk sample
+#
+# .1.3.6.1.4.1.2620.1.16.22.1.1.1.3.0 = Gauge32: 2
+# .1.3.6.1.4.1.2620.1.16.22.1.1.2.3.0 = Gauge32: 2
+# .1.3.6.1.4.1.2620.1.16.22.1.1.3.3.0 = STRING: "HRI"
+# .1.3.6.1.4.1.2620.1.16.22.1.1.4.3.0 = STRING: "Virtual System"
+# .1.3.6.1.4.1.2620.1.16.22.1.1.5.3.0 = STRING: "10.140.1.3"
+# .1.3.6.1.4.1.2620.1.16.22.1.1.6.3.0 = STRING: "Standard"
+# .1.3.6.1.4.1.2620.1.16.22.1.1.7.3.0 = STRING: "Active"
+# .1.3.6.1.4.1.2620.1.16.22.1.1.8.3.0 = STRING: "Trust established"
+# .1.3.6.1.4.1.2620.1.16.22.1.1.9.3.0 = STRING: "Standby"
+# .1.3.6.1.4.1.2620.1.16.22.1.1.10.3.0 = Gauge32: 0
+#
+# .1.3.6.1.4.1.2620.1.16.23.1.1.2.3.0 = Gauge32: 40
+# .1.3.6.1.4.1.2620.1.16.23.1.1.3.3.0 = Gauge32: 864
+# .1.3.6.1.4.1.2620.1.16.23.1.1.4.3.0 = Gauge32: 14900
+# .1.3.6.1.4.1.2620.1.16.23.1.1.5.3.0 = STRING: "69459"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.6.3.0 = STRING: "2405"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.7.3.0 = STRING: "67054"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.8.3.0 = STRING: "0"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.9.3.0 = STRING: "4228862"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.10.3.0 = STRING: "72445"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.11.3.0 = STRING: "0"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.12.3.0 = STRING: "7074"
+# .1.3.6.1.4.1.2620.1.16.23.1.1.13.3.0 = INTEGER: 0
+#
+import time
+from dataclasses import dataclass
+from typing import List, Dict, Optional, Tuple
+
+from cmk.base.plugins.agent_based.agent_based_api.v1 import (
+    register,
+    Service,
+    Result,
+    State,
+    SNMPTree,
+    all_of,
+    startswith,
+    any_of,
+    equals,
+    Metric,
+    get_value_store,
+    get_rate,
+    GetRateError,
+)
+from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import (
+    DiscoveryResult,
+    CheckResult,
+    StringTable,
+)
+
+
+@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
+    vsxCountersIsDataValid: str
+    metrics_rate: List[Tuple[str, int]]
+
+
+def parse_checkpoint_vsx(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, vsxCountersIsDataValid = entry
+        except ValueError:
+            return
+        if vsxStatusVsType.lower in ['virtual system']:  # , 'vsx gateway', 'virtual switch', 'virtual router'
+            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),
+                vsxCountersIsDataValid=vsxCountersIsDataValid,
+                metrics_rate=[
+                    ('vsxCountersPackets', int(vsxCountersPackets)),
+                    ('vsxCountersDroppedTotal', int(vsxCountersDroppedTotal)),
+                    ('vsxCountersAcceptedTotal', int(vsxCountersAcceptedTotal)),
+                    ('vsxCountersRejectedTotal', int(vsxCountersRejectedTotal)),
+                    ('vsxCountersBytesAcceptedTotal', int(vsxCountersBytesAcceptedTotal)),
+                    ('vsxCountersBytesDroppedTotal', int(vsxCountersBytesDroppedTotal)),
+                    ('vsxCountersBytesRejectedTotal', int(vsxCountersBytesRejectedTotal)),
+                    ('vsxCountersLoggedTotal', int(vsxCountersLoggedTotal)),
+                ],
+            )
+    return vsx_systems
+
+
+def discovery_checkpoint_vsx(section: Dict[str, CheckpointVsx]) -> DiscoveryResult:
+    for key in section.keys():
+        yield Service(
+            item=key,
+            parameters={'policyname': section[key].vsxStatusPolicyName, 'ha_state': section[key].vsxStatusHAState}
+        )
+
+
+def check_checkpoint_vsx(item, params, section: Dict[str, CheckpointVsx]) -> CheckResult:
+    try:
+        vsx = section[item]
+    except KeyError:
+        yield Result(state=State.UNKNOWN, notice='Item not found in SNMP data')
+        return
+
+    now_time = time.time()
+    value_store = get_value_store()
+    raise_ingore_res = False
+
+    for key, value in vsx.metrics_rate:
+        try:
+            value = get_rate(value_store, f'checkpoint_vsx_{key}', now_time, int(value), raise_overflow=True)
+        except GetRateError:
+            raise_ingore_res = True
+            value = 0
+        yield Metric(name=f'checkpoint_vsx_{key}', value=value, boundaries=(0, None))
+
+    # system information
+    yield Result(state=State.OK, summary=f'IP: {vsx.vsxStatusMainIP}, VS ID: {vsx.vsxStatusVSId}')
+    # Counters
+    # infotext = f'Connections: {vsx.vsxCountersConnNum:.0f}, ' \
+    #            f'Packets prosessed: {vsx.vsxCountersPackets:.0f}/s, ' \
+    #            f'Logs send: {vsx.vsxCountersLoggedTotal:0.2f}/s')
+
+    yield Result(state=State.OK, notice=f'System name: {item}')
+    yield Result(state=State.OK, notice=f'H/A status: {vsx.vsxStatusHAState}')
+    yield Result(state=State.OK, notice=f'Virtual system ID {vsx.vsxStatusVSId}')
+    yield Result(state=State.OK, notice=f'Type {vsx.vsxStatusVsType}')
+    yield Result(state=State.OK, notice=f'Weight {vsx.vsxStatusVSWeight}')
+    yield Result(state=State.OK, notice=f'Main IP {vsx.vsxStatusMainIP}')
+    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.vsxStatusSicTrustState}')
+
+    yield Result(state=State.OK, notice=f'Conn table limit {vsx.vsxCountersConnTableLimit}')
+    yield Result(state=State.OK, notice=f'Is data valid {vsx.vsxCountersIsDataValid}')
+
+    if vsx.vsxCountersConnTableLimit > 0:
+        yield Metric(value=vsx.vsxCountersConnNum, name='connections', boundaries=(0, vsx.vsxCountersConnTableLimit))
+    else:
+        yield Metric(value=vsx.vsxCountersConnNum, name='connections')
+    yield Metric(value=vsx.vsxCountersConnPeakNum, name='connections_peak')
+
+    if not vsx.vsxStatusHAState.lower() in ['active', 'standby']:
+        yield Result(state=State.WARN, notice=f'Status: {vsx.vsxStatusHAState}')
+    else:
+        yield Result(state=State.OK, summary=f'Status: {vsx.vsxStatusHAState}')
+    if not vsx.vsxStatusSicTrustState.lower() in ['trust established']:
+        yield Result(state=State.WARN, notice='SIC not established')
+    if not vsx.vsxStatusVsPolicyType.lower() in ['active']:
+        yield Result(state=State.CRIT, notice='No policy installed')
+    if params.get('policyname', 'unknown') != vsx.vsxStatusPolicyName:
+        yield Result(
+            state=State.WARN,
+            notice=f'Policy name changed: expected {params["policyname"]}, found {vsx.vsxStatusPolicyName}'
+        )
+    if params.get('ha_state', 'unknown') != vsx.vsxStatusHAState:
+        yield Result(
+            state=State.WARN,
+            notice=f'State changed: expected/found {params["ha_state"]}/{vsx.vsxStatusHAState}'
+        )
+
+
+register.snmp_section(
+    name='checkpoint_vsx',
+    parse_function=parse_checkpoint_vsx,
+    fetch=SNMPTree(
+        base='.1.3.6.1.4.1.2620.1.16',  # CHECKPOINT-MIB::vsxStatusVSId
+        oids=[
+            '22.1.1.3',  # vsxStatusVsName
+            '22.1.1.4',  # vsxStatusVsType
+            '22.1.1.5',  # vsxStatusMainIP
+            '22.1.1.6',  # vsxStatusPolicyName
+            '22.1.1.7',  # vsxStatusVsPolicyType
+            '22.1.1.8',  # vsxStatusSicTrustState
+            '22.1.1.9',  # vsxStatusHAState
+            '22.1.1.10',  # vsxStatusVSWeight
+            '23.1.1.2',  # vsxCountersConnNum
+            '23.1.1.3',  # vsxCountersConnPeakNum
+            '23.1.1.4',  # vsxCountersConnTableLimit
+            '23.1.1.5',  # vsxCountersPackets
+            '23.1.1.6',  # vsxCountersDroppedTotal
+            '23.1.1.7',  # vsxCountersAcceptedTotal
+            '23.1.1.8',  # vsxCountersRejectedTotal
+            '23.1.1.9',  # vsxCountersBytesAcceptedTotal
+            '23.1.1.10',  # vsxCountersBytesDroppedTotal
+            '23.1.1.11',  # vsxCountersBytesRejectedTotal
+            '23.1.1.12',  # vsxCountersLoggedTotal
+            '23.1.1.13',  # vsxCountersIsDataValid
+        ]),
+
+    detect=  # all_of(
+    any_of(
+        startswith('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.2620'),
+        all_of(
+            equals('.1.3.6.1.2.1.1.2.0', '.1.3.6.1.4.1.8072.3.2.10'),
+            equals('.1.3.6.1.4.1.2620.1.6.1.0', 'SVN Foundation'),
+        )
+    ),
+    # startswith('.1.3.6.1.4.1.2620.1.2.1.0', 'IPSec VPN')
+    # )
+)
+
+register.check_plugin(
+    name='checkpoint_vsx',
+    service_name='VSX System %s',
+    discovery_function=discovery_checkpoint_vsx,
+    check_function=check_checkpoint_vsx,
+    check_ruleset_name='checkpoint_vsx',
+    check_default_parameters={
+        'vsType': ['virtual system', 'vsx gateway', 'virtual switch', 'virtual router']
+    },
+)
diff --git a/checkpoint_vsx.mkp b/checkpoint_vsx.mkp
index 672988dba878c54172c89c07e3c596a955fb4a3a..b37c81fcaa6dccf918ba631d8ae0553f07af8a6f 100644
Binary files a/checkpoint_vsx.mkp and b/checkpoint_vsx.mkp differ
diff --git a/packages/checkpoint_vsx b/packages/checkpoint_vsx
index 81903a14bb89d2a00cad496f45bb87c3dcd5d613..cd48699ef83e9edc5d0aa557dc56ebb7aba6a6ec 100644
--- a/packages/checkpoint_vsx
+++ b/packages/checkpoint_vsx
@@ -1,11 +1,20 @@
-{'author': u'Th.L. (thl-cmk[at]outlook[dot]com)',
- 'description': u"Monitor status of virtual systems in Check Point vsx/vsls cluster.\n\n - creates one check for every virtual system. \n - check goes critical if virtual system status is not 'Active' or 'Standby'\n - longoutput gives details for each virtual system.\n - monitors VSX virtual system counters (connections/packets/bytes/logs).\n",
+{'author': 'Th.L. (thl-cmk[at]outlook[dot]com)',
+ 'description': 'Monitor status of virtual systems in Check Point vsx/vsls '
+                'cluster.\n'
+                '\n'
+                ' - creates one check for every virtual system. \n'
+                ' - check goes critical if virtual system status is not '
+                "'Active' or 'Standby'\n"
+                ' - longoutput gives details for each virtual system.\n'
+                ' - monitors VSX virtual system counters '
+                '(connections/packets/bytes/logs).\n',
  'download_url': 'https://thl-cmk.hopto.org',
- 'files': {'checks': ['checkpoint_vsx'],
+ 'files': {'agent_based': ['checkpoint_vsx.ps'],
            'web': ['plugins/metrics/checkpoint_vsx.py']},
  'name': 'checkpoint_vsx',
  'num_files': 2,
- 'title': u'Check Point VSX system status and counter',
- 'version': '20200608.v.0.2',
- 'version.min_required': '1.2.8b8',
- 'version.packaged': '1.4.0p38'}
\ No newline at end of file
+ 'title': 'Check Point VSX system status and counter',
+ 'version': '20210906.v.0.3',
+ 'version.min_required': '2.0.0',
+ 'version.packaged': '2021.07.14',
+ 'version.usable_until': None}
\ No newline at end of file
diff --git a/web/plugins/metrics/checkpoint_vsx.py b/web/plugins/metrics/checkpoint_vsx.py
index 11d39c5c3ba87d157f3dda155396343e30702f49..a4700f234b74cdafe138e328c9a719ea0b516747 100644
--- a/web/plugins/metrics/checkpoint_vsx.py
+++ b/web/plugins/metrics/checkpoint_vsx.py
@@ -1,5 +1,5 @@
-#!/usr/bin/python
-# -*- encoding: utf-8; py-indent-offset: 4 -*-
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
 #
 # License: GNU General Public License v2
 #
@@ -10,6 +10,13 @@
 # Check Point VSX status metrics plugin
 # checkpoint_vsx
 #
+from cmk.gui.i18n import _
+
+from cmk.gui.plugins.metrics import (
+    metric_info,
+    graph_info,
+    perfometer_info,
+)
 metric_info['checkpoint_vsx_connections'] = {
     'title': _('Connections active'),
     'unit': 'count',
@@ -83,15 +90,15 @@ check_metrics['check_mk-checkpoint_vsx'] = {
     'logges_send': {'name': 'checkpoint_vsx_logges_send', },
 }
 
-graph_info.append({
+graph_info['checkpoint_vsx_connections']={
     'title': _('Check Point VSX: Connections'),
     'metrics': [
         ('checkpoint_vsx_connections_peak', 'line'),
         ('checkpoint_vsx_connections', 'area'),
     ]
-})
+}
 
-graph_info.append({
+graph_info['checkpoint_vsx_packets']={
     'title': _('Check Point VSX: Packets'),
     'metrics': [
         ('checkpoint_vsx_packets_rejected', 'line'),
@@ -99,24 +106,23 @@ graph_info.append({
         ('checkpoint_vsx_packets_accepted', 'line'),
         ('checkpoint_vsx_packets_processed', 'line'),
     ]
-})
+}
 
-graph_info.append({
+graph_info['checkpoint_vsx_bytes']={
     'title': _('Check Point VSX: Bytes'),
     'metrics': [
         ('checkpoint_vsx_bytes_rejected', 'line'),
         ('checkpoint_vsx_bytes_dropped', 'line'),
         ('checkpoint_vsx_bytes_accepted', 'line'),
     ]
-})
+}
 
-graph_info.append({
+graph_info['checkpoint_vsx_logges_send']={
     'title': _('Check Point VSX: Logs'),
     'metrics': [
         ('checkpoint_vsx_logges_send', 'line'),
     ]
-})
-
+}
 
 perfometer_info.append(('stacked', [
     {
@@ -132,3 +138,4 @@ perfometer_info.append(('stacked', [
         'exponent': 2,
     },
 ]))
+