diff --git a/docs/agents/meinberg_syncbox_agent.rst b/docs/agents/meinberg_syncbox_agent.rst new file mode 100644 index 000000000..04b5dd7cc --- /dev/null +++ b/docs/agents/meinberg_syncbox_agent.rst @@ -0,0 +1,101 @@ +.. highlight:: rst + +.. _meinberg_syncbox: + +==================== +Meinberg Syncbox Agent +==================== + +The Meinberg Syncbox Agent is an OCS Agent which monitors the Meinberg syncbox, the +Monitoring is performed via SNMP. + +.. argparse:: + :filename: ../socs/agents/meinberg_syncbox/agent.py + :func: add_agent_args + :prog: python3 agent.py + +Configuration File Examples +--------------------------- +Below are configuration examples for the ocs config file and for running the +Agent in a docker container. + +OCS Site Config +``````````````` + +To configure the Meinberg Syncbox Agent we need to add a MeinbergSyncboxAgent +block to our ocs configuration file. Here is an example configuration block +using all of the available arguments:: + + {'agent-class': 'MeinbergSyncboxAgent', + 'instance-id': 'timing-syncbox', + 'arguments': [['--address', '192.168.2.166'], + ['--port', 161], + ['--mode', 'acq'], + ['--snmp-version', 1], + ['--outputs', [1, 2, 3]]]}, + +.. note:: + The ``--address`` argument should be the address of the syncbox on the network. + This is not the main Meinberg M1000 device. + The ``--outputs`` argument can be any of the available 3 outputs. + +Docker Compose +`````````````` + +The Meinberg Syncbox Agent should be configured to run in a Docker container. An +example docker-compose service configuration is shown here:: + + ocs-timing-syncbox: + image: simonsobs/socs:latest + hostname: ocs-docker + network_mode: "host" + volumes: + - ${OCS_CONFIG_DIR}:/config:ro + environment: + - INSTANCE_ID=timing-syncbox + - SITE_HUB=ws://127.0.0.1:8001/ws + - SITE_HTTP=http://127.0.0.1:8001/call + - LOGLEVEL=info + + +The ``LOGLEVEL`` environment variable can be used to set the log level for +debugging. The default level is "info". + +Description +----------- +The Meinberg syncbox synchronizes to the M1000 from PTP and distributes signal +to attached devices in various formats (IRIG, PPS, etc). + +The Meinberg Syncbox Agent actively issues SNMP GET commands to request the +status from several Object Identifiers (OIDs) specified by the syncbox +provided Management Information Base (MIB). +This MIB has been converted from the original .mib format to a .py format that +is consumable via pysnmp and is provided by socs. + +Agent Fields +```````````` +The fields returned by the Agent are built from the SNMP GET responses from the +syncbox. The field names consist of the OID name and the last value of the OID, +which often serves as an index for duplicate pieces of hardware that share a +OID string, i.e. redundant outputs on the OID "mbgSyncboxN2XOutputMode". This +results in field names such as "mbgSyncboxN2XOutputMode_1" and +"mbgSyncboxN2XOutputMode_2". + +These queries mostly return integers which map to some state. These integers +get decoded into their corresponding string representations and stored in the +OCS Agent Process' session.data object. For more details on this structure, see +the Agent API below. For information about the states corresponding to these +values, refer to the MIB file. + +Agent API +--------- + +.. autoclass:: socs.agents.meinberg_syncbox.agent.MeinbergSyncboxAgent + :members: + +Supporting APIs +---------------- + +.. autoclass:: socs.agents.meinberg_syncbox.agent.update_cache + :members: + :noindex: diff --git a/socs/agents/meinberg_syncbox/__init__.py b/socs/agents/meinberg_syncbox/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/socs/agents/meinberg_syncbox/agent.py b/socs/agents/meinberg_syncbox/agent.py new file mode 100644 index 000000000..7be229b4b --- /dev/null +++ b/socs/agents/meinberg_syncbox/agent.py @@ -0,0 +1,499 @@ +import argparse +import os +import time + +import txaio +from autobahn.twisted.util import sleep as dsleep +from ocs import ocs_agent, site_config +from ocs.ocs_twisted import TimeoutLock +from twisted.internet.defer import inlineCallbacks + +from socs.snmp import SNMPTwister + +# For logging +txaio.use_twisted() + + +def _extract_oid_field_and_value(get_result): + """Extract field names and OID values from SNMP GET results. + + The ObjectType objects returned from pysnmp interactions contain the + info we want to use for field names, specifically the OID and associated + integer for uniquely identifying duplicate OIDs, as well as the value of the + OID, which we want to save. + + Here we use the prettyPrint() method to get the OID name, requiring + some string manipulation. We also just grab the hidden ._value + directly, as this seemed the cleanest way to get an actual value of a + normal type. Without doing this we get a pysnmp defined Integer32 or + DisplayString, which were awkward to handle, particularly the + DisplayString. + + Parameters + ---------- + get_result : pysnmp.smi.rfc1902.ObjectType + Result from a pysnmp GET command. + + Returns + ------- + field_name : str + Field name for an OID, i.e. 'outletStatus_1' + oid_value : int or str + Associated value for the OID. Returns None if not an int or str + oid_description : str + String description of the OID value. + """ + # OID from SNMP GET + oid = get_result[0].prettyPrint() + # Makes something like 'IBOOTPDU-MIB::outletStatus.1' + # look like 'outletStatus_1' + field_name = oid.split("::")[1].replace('.', '_') + + # Grab OID value, mostly these are integers + oid_value = get_result[1]._value + oid_description = get_result[1].prettyPrint() + + # Decode string values + if isinstance(oid_value, bytes): + oid_value = oid_value.decode("utf-8") + + # I don't expect any other types at the moment, but just in case. + if not isinstance(oid_value, (int, bytes, str)): + oid_value = None + + return field_name, oid_value, oid_description + + +def _build_message(get_result, time): + """Build the message for publication on an OCS Feed. + + Parameters + ---------- + get_result : pysnmp.smi.rfc1902.ObjectType + Result from a pysnmp GET command. + time : float + Timestamp for when the SNMP GET was issued. + + Returns + ------- + message : dict + OCS Feed formatted message for publishing + """ + message = { + 'block_name': 'syncbox', + 'timestamp': time, + 'data': {} + } + + for item in get_result: + field_name, oid_value, oid_description = _extract_oid_field_and_value(item) + + if oid_value is None: + continue + + message['data'][field_name] = oid_value + message['data'][field_name + "_description"] = oid_description + + return message + + +def update_cache(get_result, timestamp): + """Update the OID Value Cache. + + The OID Value Cache is used to store each unique OID and will be passed to + session.data + + The cache consists of a dictionary, with the unique OIDs as keys, and + another dictionary as the value. Each of these nested dictionaries contains + the OID values, name, and description (decoded string). An example for a + single OID, with connection status and timestamp information:: + + {"mbgSyncboxN2XCurrentRefSource_0": {"status": 'PTP', + "description": 'PTP'}} + + Additionally there is connection status and timestamp information under:: + + "syncbox_connection": {"last_attempt": 1598543359.6326838, + "connected": True}, + "timestamp": 1656085022.680916} + + Parameters + ---------- + get_result : pysnmp.smi.rfc1902.ObjectType + Result from a pysnmp GET command. + timestamp : float + Timestamp for when the SNMP GET was issued. + """ + oid_cache = {} + # Return disconnected if SNMP response is empty + if get_result is None: + oid_cache['syncbox_connection'] = {'last_attempt': time.time(), + 'connected': False} + return oid_cache + + for item in get_result: + field_name, oid_value, oid_description = _extract_oid_field_and_value(item) + if oid_value is None: + continue + + # Update OID Cache for session.data + oid_cache[field_name] = {"status": oid_value} + oid_cache[field_name]["description"] = oid_description + oid_cache['syncbox_connection'] = {'last_attempt': time.time(), + 'connected': True} + oid_cache['timestamp'] = timestamp + + return oid_cache + + +class MeinbergSyncboxAgent: + """Monitor the syncbox system via SNMP. + + Parameters + ---------- + agent : OCSAgent + OCSAgent object which forms this Agent + address : str + Address of the syncbox. + port : int + SNMP port to issue GETs to, default to 161. + version : int + SNMP version for communication (1, 2, or 3), defaults to 1. + outputs : list of ints + List of outputs to monitor. + + Attributes + ---------- + agent : OCSAgent + OCSAgent object which forms this Agent + is_streaming : bool + Tracks whether or not the agent is actively issuing SNMP GET commands + to the syncbox. Setting to false stops sending commands. + log : txaio.tx.Logger + txaio logger object, created by the OCSAgent + """ + + def __init__(self, agent, address, port=161, version=1, outputs=[1, 2, 3]): + self.agent = agent + self.is_streaming = False + self.log = self.agent.log + self.lock = TimeoutLock() + + self.log.info(f'Using SNMP version {version}.') + self.version = version + self.address = address + self.snmp = SNMPTwister(address, port) + self.connected = True + + self.lastGet = 0 + self.sample_period = 60 + + # Create the list of OIDs to send get commands + oids = ['mbgSyncboxN2XSerialNumber', + 'mbgSyncboxN2XFirmwareRevision', + 'mbgSyncboxN2XSystemTime', + 'mbgSyncboxN2XCurrentRefSource', + 'mbgSyncboxN2XPtpProfile', + 'mbgSyncboxN2XPtpNwProt', + 'mbgSyncboxN2XPtpPortState', + 'mbgSyncboxN2XPtpDelayMechanism', + 'mbgSyncboxN2XPtpDelayRequestInterval', + 'mbgSyncboxN2XPtpTimescale', + 'mbgSyncboxN2XPtpUTCOffset', + 'mbgSyncboxN2XPtpLeapSecondAnnounced', + 'mbgSyncboxN2XPtpGrandmasterClockID', + 'mbgSyncboxN2XPtpGrandmasterTimesource', + 'mbgSyncboxN2XPtpGrandmasterPriority1', + 'mbgSyncboxN2XPtpGrandmasterClockClass', + 'mbgSyncboxN2XPtpGrandmasterClockAccuracy', + 'mbgSyncboxN2XPtpGrandmasterClockVariance', + 'mbgSyncboxN2XPtpOffsetToGrandmaster', + 'mbgSyncboxN2XPtpMeanPathDelay'] + output_oids = ['mbgSyncboxN2XOutputMode'] + mib = 'MBG-SYNCBOX-N2X-MIB' + + self.get_list = [] + + # Create the lists of OIDs to send get commands + for oid in oids: + self.get_list.append([(mib, oid, 0)]) + + for out in outputs: + for oid in output_oids: + self.get_list.append([(mib, oid, out - 1)]) + + agg_params = { + 'frame_length': 10 * 60 # [sec] + } + self.agent.register_feed('syncbox', + record=True, + agg_params=agg_params, + buffer_time=0) + + @ocs_agent.param('test_mode', default=False, type=bool) + @inlineCallbacks + def acq(self, session, params=None): + """acq() + + **Process** - Fetch values from the syncbox via SNMP. + + Parameters + ---------- + test_mode : bool, optional + Run the Process loop only once. Meant only for testing. + Default is False. + + Notes + ----- + The most recent data collected is stored in session.data in the + structure:: + + >>> response.session['data'] + {'mbgSyncboxN2XSerialNumber_0': + {'status': '009811006890', + 'description': '009811006890'}, + 'mbgSyncboxN2XFirmwareRevision_0': + {'status': '1.20 ', + 'description': '1.20 '}, + 'mbgSyncboxN2XSystemTime_0': + {'status': '2023-10-28 14:25:54 UTC', + 'description': '2023-10-28 14:25:54 UTC'}, + 'mbgSyncboxN2XCurrentRefSource_0': + {'status': 'PTP', + 'description': 'PTP'}, + 'mbgSyncboxN2XPtpProfile_0': + {'status': 0, + 'description': 'none'}, + 'mbgSyncboxN2XPtpNwProt_0': + {'status': 1, + 'description': 'ipv4'}, + 'mbgSyncboxN2XPtpPortState_0': + {'status': 9, + 'description': 'slave'}, + 'mbgSyncboxN2XPtpDelayMechanism_0': + {'status': 0, + 'description': 'e2e'}, + 'mbgSyncboxN2XPtpDelayRequestInterval_0': + {'status': 1, + 'description': '1'}, + 'mbgSyncboxN2XPtpTimescale_0': + {'status': 0, + 'description': 'tai'}, + 'mbgSyncboxN2XPtpUTCOffset_0': + {'status': '37 sec', + 'description': '37 sec'}, + 'mbgSyncboxN2XPtpLeapSecondAnnounced_0': + {'status': 'no', + 'description': 'no'}, + 'mbgSyncboxN2XPtpGrandmasterClockID_0': + {'status': 'EC:46:70:FF:FE:0A:AB:FE', + 'description': 'EC:46:70:FF:FE:0A:AB:FE'}, + 'mbgSyncboxN2XPtpGrandmasterTimesource_0': + {'status': 32, + 'description': 'gps'}, + 'mbgSyncboxN2XPtpGrandmasterPriority1_0': + {'status': 64, + 'description': '64'}, + 'mbgSyncboxN2XPtpGrandmasterClockClass_0': + {'status': 6, + 'description': '6'}, + 'mbgSyncboxN2XPtpGrandmasterClockAccuracy_0': + {'status': 33, 'description': + 'accurateToWithin100ns'}, + 'mbgSyncboxN2XPtpGrandmasterClockVariance_0': + {'status': 13563, + 'description': '13563'}, + 'mbgSyncboxN2XPtpOffsetToGrandmaster_0': + {'status': '10 ns', + 'description': '10 ns'}, + 'mbgSyncboxN2XPtpMeanPathDelay_0': + {'status': '875 ns', + 'description': '875 ns'}, + 'mbgSyncboxN2XOutputMode_1': + {'status': 4, + 'description': 'pulsePerSecond'}, + 'syncbox_connection': + {'last_attempt': 1656085022.680916, + 'connected': True}, + 'timestamp': 1656085022.680916, + 'address': '10.10.10.50'} + + Some relevant options and units for the above OIDs:: + + mbgSyncboxN2XPtpProfile:: + Options:: none(0), + power(1), + telecom(2) + mbgSyncboxN2XPtpNwProt:: + Options:: unknown(0), + ipv4(1), + ipv6(2), + ieee802-3(3), + deviceNet(4), + controlNet(5), + profiNet(6) + mbgSyncboxN2XPtpPortState:: + Options:: uninitialized(0), + initializing(1), + faulty(2), + disabled(3), + listening(4), + preMaster(5), + master(6), + passive(7), + uncalibrated(8), + slave(9) + mbgSyncboxN2XPtpDelayMechanism:: + Options:: e2e(0), + p2p(1) + mbgSyncboxN2XPtpTimescale:: + Options:: tai(0), + arb(1) + mbgSyncboxN2XPtpGrandmasterTimesource:: + Options:: atomicClock(16), + gps(32), + terrestrialRadio(48), + ptp(64), + ntp(80), + handSet(96), + other(144), + internalOscillator(160) + mbgSyncboxN2XPtpGrandmasterClockAccuracy:: + Options:: accurateToWithin25ns(32), + accurateToWithin100ns(33), + accurateToWithin250ns(34), + accurateToWithin1us(35), + accurateToWithin2Point5us(36), + accurateToWithin10us(37), + accurateToWithin25us(38), + accurateToWithin100us(39), + accurateToWithin250us(40), + accurateToWithin1ms(41), + accurateToWithin2Point5ms(42), + accurateToWithin10ms(43), + accurateToWithin25ms(44), + accurateToWithin100ms(45), + accurateToWithin250ms(46), + accurateToWithin1s(47), + accurateToWithin10s(48), + accurateToGreaterThan10s(49) + """ + + self.is_streaming = True + while self.is_streaming: + yield dsleep(1) + if not self.connected: + self.log.error('No SNMP response. Check your connection!') + self.log.info('Trying to reconnect.') + + read_time = time.time() + + # Check if sample period has passed before getting status + if (read_time - self.lastGet) < self.sample_period: + continue + + # Issue SNMP GET command + # The syncbox has a unique case this requires issuing GET commands + # one by one or else it will return the same data for each OID + get_result = [] + for get in self.get_list: + result = yield self.snmp.get(get, self.version) + if result is None: + self.connected = False + session.data['syncbox_connection'] = {'last_attempt': time.time(), + 'connected': False} + break + get_result.extend(result) + self.connected = True + if not self.connected: + session.degraded = True + continue + session.degraded = False + + # Do not publish if syncbox connection has dropped + try: + # Update session.data + oid_cache = update_cache(get_result, read_time) + oid_cache['address'] = self.address + session.data = oid_cache + self.log.info("{data}", data=session.data) + + self.lastGet = time.time() + # Publish to feed + message = _build_message(get_result, read_time) + self.log.info("{msg}", msg=message) + session.app.publish_to_feed('syncbox', message) + except Exception as e: + self.log.error(f'{e}') + yield dsleep(1) + + if params['test_mode']: + break + + return True, "Finished Recording" + + def _stop_acq(self, session, params=None): + """_stop_acq() + **Task** - Stop task associated with acq process. + """ + if self.is_streaming: + session.set_status('stopping') + self.is_streaming = False + return True, "Stopping Recording" + else: + return False, "Acq is not currently running" + + +def add_agent_args(parser=None): + """ + Build the argument parser for the Agent. Allows sphinx to automatically + build documentation based on this function. + """ + if parser is None: + parser = argparse.ArgumentParser() + + pgroup = parser.add_argument_group("Agent Options") + pgroup.add_argument("--address", help="Address to listen to.") + pgroup.add_argument("--port", default=161, + help="Port to listen on.") + pgroup.add_argument("--snmp-version", default='1', choices=['1', '2', '3'], + help="SNMP version for communication. Must match " + + "configuration on the syncbox.") + pgroup.add_argument("--mode", default='acq', choices=['acq', 'test']) + pgroup.add_argument("--outputs", nargs='+', default=[1, 2, 3], type=int, + help="Syncbox outputs to monitor. Defaults to [1,2,3].") + + return parser + + +def main(args=None): + # Start logging + txaio.start_logging(level=os.environ.get("LOGLEVEL", "info")) + + parser = add_agent_args() + args = site_config.parse_args(agent_class='MeinbergSyncboxAgent', + parser=parser, + args=args) + + if args.mode == 'acq': + init_params = True + elif args.mode == 'test': + init_params = False + + agent, runner = ocs_agent.init_site_agent(args) + p = MeinbergSyncboxAgent(agent, + address=args.address, + port=int(args.port), + version=int(args.snmp_version), + outputs=args.outputs) + + agent.register_process("acq", + p.acq, + p._stop_acq, + startup=init_params, blocking=False) + + runner.run(agent, auto_reconnect=True) + + +if __name__ == "__main__": + main() diff --git a/socs/agents/ocs_plugin_so.py b/socs/agents/ocs_plugin_so.py index 880e91590..977e5fe98 100644 --- a/socs/agents/ocs_plugin_so.py +++ b/socs/agents/ocs_plugin_so.py @@ -34,6 +34,7 @@ ('LATRtXYStageAgent', 'xy_stage/agent.py'), ('MagpieAgent', 'magpie/agent.py'), ('MeinbergM1000Agent', 'meinberg_m1000/agent.py'), + ('MeinbergSyncboxAgent', 'meinberg_syncbox/agent.py'), ('PfeifferAgent', 'pfeiffer_tpg366/agent.py'), ('PfeifferTC400Agent', 'pfeiffer_tc400/agent.py'), ('PysmurfController', 'pysmurf_controller/agent.py'), diff --git a/socs/mibs/MBG-SYNCBOX-N2X-MIB.py b/socs/mibs/MBG-SYNCBOX-N2X-MIB.py new file mode 100644 index 000000000..d062b776f --- /dev/null +++ b/socs/mibs/MBG-SYNCBOX-N2X-MIB.py @@ -0,0 +1,168 @@ +# +# PySNMP MIB module MBG-SYNCBOX-N2X-MIB (https://www.pysnmp.com/pysmi) +# ASN.1 source file://./MBG-SYNCBOX-N2X-MIB.mib +# Produced by pysmi-1.1.13 at Fri Oct 27 11:50:07 2023 +# On host HAWKING platform Linux version 5.15.90.1-microsoft-standard-WSL2 by user davidvng +# Using Python version 3.8.8 (default, Apr 13 2021, 19:58:26) +# +from pysnmp.smi import builder + +mibBuilder = builder.MibBuilder() + +Integer, ObjectIdentifier, OctetString = mibBuilder.importSymbols("ASN1", "Integer", "ObjectIdentifier", "OctetString") +NamedValues, = mibBuilder.importSymbols("ASN1-ENUMERATION", "NamedValues") +ValueSizeConstraint, ConstraintsIntersection, ValueRangeConstraint, SingleValueConstraint, ConstraintsUnion = mibBuilder.importSymbols("ASN1-REFINEMENT", "ValueSizeConstraint", "ConstraintsIntersection", "ValueRangeConstraint", "SingleValueConstraint", "ConstraintsUnion") +mbgSnmpRoot, = mibBuilder.importSymbols("MBG-SNMP-ROOT-MIB", "mbgSnmpRoot") +NotificationGroup, ModuleCompliance, ObjectGroup = mibBuilder.importSymbols("SNMPv2-CONF", "NotificationGroup", "ModuleCompliance", "ObjectGroup") +NotificationType, Integer32, MibScalar, MibTable, MibTableRow, MibTableColumn, TimeTicks, ObjectIdentity, iso, ModuleIdentity, Counter64, Unsigned32, Bits, Gauge32, Counter32, IpAddress, MibIdentifier = mibBuilder.importSymbols("SNMPv2-SMI", "NotificationType", "Integer32", "MibScalar", "MibTable", "MibTableRow", "MibTableColumn", "TimeTicks", "ObjectIdentity", "iso", "ModuleIdentity", "Counter64", "Unsigned32", "Bits", "Gauge32", "Counter32", "IpAddress", "MibIdentifier") +TextualConvention, DisplayString = mibBuilder.importSymbols("SNMPv2-TC", "TextualConvention", "DisplayString") +mbgSyncboxN2X = ModuleIdentity((1, 3, 6, 1, 4, 1, 5597, 40)) +mbgSyncboxN2X.setRevisions(('2013-09-03 00:00',)) +if mibBuilder.loadTexts: + mbgSyncboxN2X.setLastUpdated('201309030000Z') +if mibBuilder.loadTexts: + mbgSyncboxN2X.setOrganization('www.meinberg.de') +mbgSyncboxN2XGeneral = MibIdentifier((1, 3, 6, 1, 4, 1, 5597, 40, 0)) +mbgSyncboxN2XSerialNumber = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 0, 1), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XSerialNumber.setStatus('current') +mbgSyncboxN2XFirmwareRevision = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 0, 2), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XFirmwareRevision.setStatus('current') +mbgSyncboxN2XSystemTime = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 0, 3), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XSystemTime.setStatus('current') +mbgSyncboxN2XCurrentRefSource = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 0, 4), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XCurrentRefSource.setStatus('current') +mbgSyncboxN2XNetworkTimeProtocol = MibIdentifier((1, 3, 6, 1, 4, 1, 5597, 40, 1)) +mbgSyncboxN2XNtpSyncStatus = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 1, 1), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpSyncStatus.setStatus('current') +mbgSyncboxN2XNtpSystemPeer = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 1, 2), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpSystemPeer.setStatus('current') +mbgSyncboxN2XNtpStratum = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 1, 3), Unsigned32()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpStratum.setStatus('current') +mbgSyncboxN2XNtpRefSourceTable = MibTable((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4), ) +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceTable.setStatus('current') +mbgSyncboxN2XNtpRefSourceTableEntry = MibTableRow((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1), ).setIndexNames((0, "MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceIndex")) +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceTableEntry.setStatus('current') +mbgSyncboxN2XNtpRefSourceIndex = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 1), Unsigned32().subtype(subtypeSpec=ValueRangeConstraint(0, 6))) +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceIndex.setStatus('current') +mbgSyncboxN2XNtpRefSourceHostname = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 2), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceHostname.setStatus('current') +mbgSyncboxN2XNtpRefSourceStratum = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 3), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceStratum.setStatus('current') +mbgSyncboxN2XNtpRefSourceReferenceID = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 4), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceReferenceID.setStatus('current') +mbgSyncboxN2XNtpRefSourceReach = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 5), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceReach.setStatus('current') +mbgSyncboxN2XNtpRefSourceCurrPoll = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 6), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceCurrPoll.setStatus('current') +mbgSyncboxN2XNtpRefSourceMinPoll = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 7), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceMinPoll.setStatus('current') +mbgSyncboxN2XNtpRefSourceMaxPoll = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 8), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceMaxPoll.setStatus('current') +mbgSyncboxN2XNtpRefSourceConfigOptions = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 9), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceConfigOptions.setStatus('current') +mbgSyncboxN2XNtpRefSourcePathDelay = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 10), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourcePathDelay.setStatus('current') +mbgSyncboxN2XNtpRefSourceOffset = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 11), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceOffset.setStatus('current') +mbgSyncboxN2XNtpRefSourceJitter = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 1, 4, 1, 12), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XNtpRefSourceJitter.setStatus('current') +mbgSyncboxN2XPrecisionTimeProtocol = MibIdentifier((1, 3, 6, 1, 4, 1, 5597, 40, 2)) +mbgSyncboxN2XPtpProfile = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 1), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 1, 2))).clone(namedValues=NamedValues(("none", 0), ("power", 1), ("telecom", 2)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpProfile.setStatus('current') +mbgSyncboxN2XPtpNwProt = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 2), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 1, 2, 3, 4, 5, 6))).clone(namedValues=NamedValues(("unknown", 0), ("ipv4", 1), ("ipv6", 2), ("ieee802-3", 3), ("deviceNet", 4), ("controlNet", 5), ("profiNet", 6)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpNwProt.setStatus('current') +mbgSyncboxN2XPtpPortState = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 3), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))).clone(namedValues=NamedValues(("uninitialized", 0), ("initializing", 1), ("faulty", 2), ("disabled", 3), ("listening", 4), ("preMaster", 5), ("master", 6), ("passive", 7), ("uncalibrated", 8), ("slave", 9)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpPortState.setStatus('current') +mbgSyncboxN2XPtpDelayMechanism = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 4), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 1))).clone(namedValues=NamedValues(("e2e", 0), ("p2p", 1)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpDelayMechanism.setStatus('current') +mbgSyncboxN2XPtpDelayRequestInterval = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 5), Integer32()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpDelayRequestInterval.setStatus('current') +mbgSyncboxN2XPtpTimescale = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 6), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 1))).clone(namedValues=NamedValues(("tai", 0), ("arb", 1)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpTimescale.setStatus('current') +mbgSyncboxN2XPtpUTCOffset = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 7), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpUTCOffset.setStatus('current') +mbgSyncboxN2XPtpLeapSecondAnnounced = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 8), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpLeapSecondAnnounced.setStatus('current') +mbgSyncboxN2XPtpGrandmasterClockID = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 9), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpGrandmasterClockID.setStatus('current') +mbgSyncboxN2XPtpGrandmasterTimesource = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 10), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(16, 32, 48, 64, 80, 96, 144, 160))).clone(namedValues=NamedValues(("atomicClock", 16), ("gps", 32), ("terrestrialRadio", 48), ("ptp", 64), ("ntp", 80), ("handSet", 96), ("other", 144), ("internalOscillator", 160)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpGrandmasterTimesource.setStatus('current') +mbgSyncboxN2XPtpGrandmasterPriority1 = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 11), Unsigned32()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpGrandmasterPriority1.setStatus('current') +mbgSyncboxN2XPtpGrandmasterClockClass = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 12), Unsigned32()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpGrandmasterClockClass.setStatus('current') +mbgSyncboxN2XPtpGrandmasterClockAccuracy = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 13), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49))).clone(namedValues=NamedValues(("accurateToWithin25ns", 32), ("accurateToWithin100ns", 33), ("accurateToWithin250ns", 34), ("accurateToWithin1us", 35), ("accurateToWithin2Point5us", 36), ("accurateToWithin10us", 37), ("accurateToWithin25us", 38), ("accurateToWithin100us", 39), ("accurateToWithin250us", 40), ("accurateToWithin1ms", 41), ("accurateToWithin2Point5ms", 42), ("accurateToWithin10ms", 43), ("accurateToWithin25ms", 44), ("accurateToWithin100ms", 45), ("accurateToWithin250ms", 46), ("accurateToWithin1s", 47), ("accurateToWithin10s", 48), ("accurateToGreaterThan10s", 49)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpGrandmasterClockAccuracy.setStatus('current') +mbgSyncboxN2XPtpGrandmasterClockVariance = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 14), Unsigned32()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpGrandmasterClockVariance.setStatus('current') +mbgSyncboxN2XPtpGrandmasterPriority2 = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 15), Unsigned32()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpGrandmasterPriority2.setStatus('current') +mbgSyncboxN2XPtpOffsetToGrandmaster = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 16), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpOffsetToGrandmaster.setStatus('current') +mbgSyncboxN2XPtpMeanPathDelay = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 2, 17), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XPtpMeanPathDelay.setStatus('current') +mbgSyncboxN2XOutputs = MibIdentifier((1, 3, 6, 1, 4, 1, 5597, 40, 3)) +mbgSyncboxN2XOutputsTable = MibTable((1, 3, 6, 1, 4, 1, 5597, 40, 3, 1), ) +if mibBuilder.loadTexts: + mbgSyncboxN2XOutputsTable.setStatus('current') +mbgSyncboxN2XOutputsTableEntry = MibTableRow((1, 3, 6, 1, 4, 1, 5597, 40, 3, 1, 1), ).setIndexNames((0, "MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XOutputIndex")) +if mibBuilder.loadTexts: + mbgSyncboxN2XOutputsTableEntry.setStatus('current') +mbgSyncboxN2XOutputIndex = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 3, 1, 1, 1), Unsigned32().subtype(subtypeSpec=ValueRangeConstraint(0, 2))) +if mibBuilder.loadTexts: + mbgSyncboxN2XOutputIndex.setStatus('current') +mbgSyncboxN2XOutputMode = MibTableColumn((1, 3, 6, 1, 4, 1, 5597, 40, 3, 1, 1, 2), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16))).clone(namedValues=NamedValues(("idle", 0), ("timer", 1), ("singleShot", 2), ("cyclicPulse", 3), ("pulsePerSecond", 4), ("pulsePerMinute", 5), ("pulsePerHour", 6), ("emulatedDCF77", 7), ("positionOK", 8), ("timeSync", 9), ("allSync", 10), ("timecode", 11), ("timestring", 12), ("tenMHz", 13), ("emulatedDCF77M59", 14), ("synthesizer", 15), ("timeSlots", 16)))).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XOutputMode.setStatus('current') +mbgSyncboxN2XSerialString = MibScalar((1, 3, 6, 1, 4, 1, 5597, 40, 3, 2), DisplayString()).setMaxAccess("readonly") +if mibBuilder.loadTexts: + mbgSyncboxN2XSerialString.setStatus('current') +mbgSyncboxN2XConformance = MibIdentifier((1, 3, 6, 1, 4, 1, 5597, 40, 10)) +mbgSyncboxN2XCompliances = MibIdentifier((1, 3, 6, 1, 4, 1, 5597, 40, 10, 0)) +mbgSyncboxN2XGroups = MibIdentifier((1, 3, 6, 1, 4, 1, 5597, 40, 10, 1)) +mbgSyncboxN2XCompliance = ModuleCompliance((1, 3, 6, 1, 4, 1, 5597, 40, 10, 0, 0)).setObjects(("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XObjectsGroup")) + +if getattr(mibBuilder, 'version', (0, 0, 0)) > (4, 4, 0): + mbgSyncboxN2XCompliance = mbgSyncboxN2XCompliance.setStatus('current') +mbgSyncboxN2XObjectsGroup = ObjectGroup((1, 3, 6, 1, 4, 1, 5597, 40, 10, 1, 0)).setObjects(("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XSerialNumber"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XFirmwareRevision"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XSystemTime"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XCurrentRefSource"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpSyncStatus"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpSystemPeer"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpStratum"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceHostname"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceStratum"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceReferenceID"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceReach"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceCurrPoll"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceMinPoll"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceMaxPoll"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceConfigOptions"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourcePathDelay"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceOffset"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XNtpRefSourceJitter"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpProfile"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpNwProt"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpPortState"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpDelayMechanism"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpDelayRequestInterval"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpTimescale"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpUTCOffset"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpLeapSecondAnnounced"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpGrandmasterClockID"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpGrandmasterTimesource"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpGrandmasterPriority1"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpGrandmasterClockClass"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpGrandmasterClockAccuracy"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpGrandmasterClockVariance"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpGrandmasterPriority2"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpOffsetToGrandmaster"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XPtpMeanPathDelay"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XOutputMode"), ("MBG-SYNCBOX-N2X-MIB", "mbgSyncboxN2XSerialString")) +if getattr(mibBuilder, 'version', (0, 0, 0)) > (4, 4, 0): + mbgSyncboxN2XObjectsGroup = mbgSyncboxN2XObjectsGroup.setStatus('current') +mibBuilder.exportSymbols("MBG-SYNCBOX-N2X-MIB", mbgSyncboxN2XPtpPortState=mbgSyncboxN2XPtpPortState, mbgSyncboxN2XPtpGrandmasterClockAccuracy=mbgSyncboxN2XPtpGrandmasterClockAccuracy, mbgSyncboxN2XCompliances=mbgSyncboxN2XCompliances, mbgSyncboxN2XNtpSyncStatus=mbgSyncboxN2XNtpSyncStatus, mbgSyncboxN2XNtpRefSourceTable=mbgSyncboxN2XNtpRefSourceTable, mbgSyncboxN2XPtpGrandmasterClockVariance=mbgSyncboxN2XPtpGrandmasterClockVariance, mbgSyncboxN2XNtpRefSourceCurrPoll=mbgSyncboxN2XNtpRefSourceCurrPoll, mbgSyncboxN2XNtpRefSourceReach=mbgSyncboxN2XNtpRefSourceReach, mbgSyncboxN2XNtpRefSourceJitter=mbgSyncboxN2XNtpRefSourceJitter, mbgSyncboxN2XSerialString=mbgSyncboxN2XSerialString, mbgSyncboxN2XNtpRefSourceMinPoll=mbgSyncboxN2XNtpRefSourceMinPoll, PYSNMP_MODULE_ID=mbgSyncboxN2X, mbgSyncboxN2XNtpRefSourceReferenceID=mbgSyncboxN2XNtpRefSourceReferenceID, mbgSyncboxN2XNtpRefSourceTableEntry=mbgSyncboxN2XNtpRefSourceTableEntry, mbgSyncboxN2XPtpOffsetToGrandmaster=mbgSyncboxN2XPtpOffsetToGrandmaster, mbgSyncboxN2XSystemTime=mbgSyncboxN2XSystemTime, mbgSyncboxN2XNtpRefSourceStratum=mbgSyncboxN2XNtpRefSourceStratum, mbgSyncboxN2XOutputsTableEntry=mbgSyncboxN2XOutputsTableEntry, mbgSyncboxN2XOutputMode=mbgSyncboxN2XOutputMode, mbgSyncboxN2XOutputIndex=mbgSyncboxN2XOutputIndex, mbgSyncboxN2XObjectsGroup=mbgSyncboxN2XObjectsGroup, mbgSyncboxN2XNtpRefSourceIndex=mbgSyncboxN2XNtpRefSourceIndex, mbgSyncboxN2XFirmwareRevision=mbgSyncboxN2XFirmwareRevision, mbgSyncboxN2XPtpGrandmasterPriority2=mbgSyncboxN2XPtpGrandmasterPriority2, mbgSyncboxN2XPtpGrandmasterClockClass=mbgSyncboxN2XPtpGrandmasterClockClass, mbgSyncboxN2XNtpRefSourceHostname=mbgSyncboxN2XNtpRefSourceHostname, mbgSyncboxN2XPrecisionTimeProtocol=mbgSyncboxN2XPrecisionTimeProtocol, mbgSyncboxN2XNtpSystemPeer=mbgSyncboxN2XNtpSystemPeer, mbgSyncboxN2X=mbgSyncboxN2X, mbgSyncboxN2XPtpMeanPathDelay=mbgSyncboxN2XPtpMeanPathDelay, mbgSyncboxN2XGroups=mbgSyncboxN2XGroups, mbgSyncboxN2XConformance=mbgSyncboxN2XConformance, mbgSyncboxN2XNtpRefSourceConfigOptions=mbgSyncboxN2XNtpRefSourceConfigOptions, mbgSyncboxN2XNtpRefSourceMaxPoll=mbgSyncboxN2XNtpRefSourceMaxPoll, mbgSyncboxN2XPtpGrandmasterClockID=mbgSyncboxN2XPtpGrandmasterClockID, mbgSyncboxN2XOutputs=mbgSyncboxN2XOutputs, mbgSyncboxN2XPtpDelayRequestInterval=mbgSyncboxN2XPtpDelayRequestInterval, mbgSyncboxN2XNtpRefSourcePathDelay=mbgSyncboxN2XNtpRefSourcePathDelay, mbgSyncboxN2XGeneral=mbgSyncboxN2XGeneral, mbgSyncboxN2XNtpRefSourceOffset=mbgSyncboxN2XNtpRefSourceOffset, mbgSyncboxN2XPtpGrandmasterTimesource=mbgSyncboxN2XPtpGrandmasterTimesource, mbgSyncboxN2XPtpGrandmasterPriority1=mbgSyncboxN2XPtpGrandmasterPriority1, mbgSyncboxN2XPtpDelayMechanism=mbgSyncboxN2XPtpDelayMechanism, mbgSyncboxN2XNetworkTimeProtocol=mbgSyncboxN2XNetworkTimeProtocol, mbgSyncboxN2XSerialNumber=mbgSyncboxN2XSerialNumber, mbgSyncboxN2XCompliance=mbgSyncboxN2XCompliance, mbgSyncboxN2XOutputsTable=mbgSyncboxN2XOutputsTable, mbgSyncboxN2XPtpNwProt=mbgSyncboxN2XPtpNwProt, mbgSyncboxN2XPtpUTCOffset=mbgSyncboxN2XPtpUTCOffset, mbgSyncboxN2XNtpStratum=mbgSyncboxN2XNtpStratum, mbgSyncboxN2XPtpLeapSecondAnnounced=mbgSyncboxN2XPtpLeapSecondAnnounced, mbgSyncboxN2XPtpTimescale=mbgSyncboxN2XPtpTimescale, mbgSyncboxN2XPtpProfile=mbgSyncboxN2XPtpProfile, mbgSyncboxN2XCurrentRefSource=mbgSyncboxN2XCurrentRefSource) diff --git a/socs/plugin.py b/socs/plugin.py index 91b5296d1..f98fa864e 100644 --- a/socs/plugin.py +++ b/socs/plugin.py @@ -27,6 +27,7 @@ 'LATRtXYStageAgent': {'module': 'socs.agents.xy_stage.agent', 'entry_point': 'main'}, 'MagpieAgent': {'module': 'socs.agents.magpie.agent', 'entry_point': 'main'}, 'MeinbergM1000Agent': {'module': 'socs.agents.meinberg_m1000.agent', 'entry_point': 'main'}, + 'MeinbergSyncboxAgent': {'module': 'socs.agents.meinberg_syncbox.agent', 'entry_point': 'main'}, 'PfeifferAgent': {'module': 'socs.agents.pfeiffer_tpg366.agent', 'entry_point': 'main'}, 'PfeifferTC400Agent': {'module': 'socs.agents.pfeiffer_tc400.agent', 'entry_point': 'main'}, 'PysmurfController': {'module': 'socs.agents.pysmurf_controller.agent', 'entry_point': 'main'},