{"id":3948,"date":"2023-10-25T19:42:46","date_gmt":"2023-10-25T19:42:46","guid":{"rendered":"https:\/\/wiki.thomasandsofia.com\/?p=3948"},"modified":"2024-08-08T22:16:52","modified_gmt":"2024-08-08T22:16:52","slug":"zenpack-development-snmp","status":"publish","type":"post","link":"https:\/\/wiki.thomasandsofia.com\/?p=3948","title":{"rendered":"ZenPack Development &#8211; SNMP"},"content":{"rendered":"<h3>Training Docs<\/h3>\n<p><a href=\"https:\/\/zenpacks.zenoss.io\/zdk\/dev-env\/\">https:\/\/zenpacks.zenoss.io\/zdk\/dev-env\/<\/a><\/p>\n<h3>2:36<\/h3>\n<h3>NetBotz Device:<\/h3>\n<ul>\n<li>IP: 10.90.34.172<\/li>\n<li>Port: 1024<\/li>\n<li>Version: 2c<\/li>\n<li>Community: netbotz<\/li>\n<\/ul>\n<h3>Day 1 &#8211; 5 hrs<\/h3>\n<p>No sound for 1st 7 minutes<\/p>\n<ul>\n<li><a href=\"https:\/\/zenoss.zoom.us\/rec\/share\/l7v_OVc3rU_hA7cJ9FLP3L4bwn6xOBMpwT2EM6bMxcGkFCk-2_fKbXcRe20T8xmp.zhRWWxTt7SQZJXVd?startTime=1679489620000\" target=\"_blank\" rel=\"noopener\">Video Link<\/a>\n<ul>\n<li>#y*26Psp<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Times:<\/p>\n<ul>\n<li>0:28:00 Creating ZenPack (CLI)<\/li>\n<li>X:XX:00 Creating a Monitoring Template (UI)\n<ul>\n<li>1:06:00 Create Data Point (UI)\n<ul>\n<li>Includes how to translate a MIB Definition to an OID (CLI)<\/li>\n<\/ul>\n<\/li>\n<li>1:12:00 Create Thresholds (UI)<\/li>\n<li>1:17:00 Graphs (UI)\n<ul>\n<li>1:25:00 Data Point formatting<\/li>\n<\/ul>\n<\/li>\n<li>1:28:00 Testing the template (CLI)\n<ul>\n<li>There are issues&#8230;.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Export The ZenPack 1:40:00<\/li>\n<li>Break: 1:45:00 &#8211; 2:01:00<\/li>\n<li>Create ZenPack via CLI\n<ul>\n<li>2:10:00 edit zenpacks.yaml<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Notes:<\/p>\n<ul>\n<li>Use zenjobs instead of zenhub for testing `\/z` mount point.<\/li>\n<li>Could not get netsnmp to work. Use the target device posted above.<\/li>\n<li><\/li>\n<\/ul>\n<pre><span data-sheets-formula-bar-text-style=\"font-size:13px;color:#000000;font-weight:normal;text-decoration:none;font-family:'Arial';font-style:normal;text-decoration-skip-ink:none;\">#Nexus 5k v3\r\nsnmpwalk -v3 -u V3User -l authPriv -a MD5 -A AuthPassword -x DES -X PrivPassword 10.171.100.94 system\r\n\r\n#Linux Public\r\n<\/span>snmpwalk -v2c -c public 10.90.35.84 system<\/pre>\n<p>NetSNMP: 0:26:00<\/p>\n<ul>\n<li>Unable to install Netbots, so will use the devices above and hope they work for the class.<\/li>\n<\/ul>\n<h1>Creating a ZenPack<\/h1>\n<ul>\n<li>Video: 0:28:00<\/li>\n<li>Documentation: https:\/\/zenpacks.zenoss.io\/zdk\/get-started\/\n<ul>\n<li>Documentation is incorrect. You cannot view the YAML file yet.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre># ~ 60 seconds each command\r\nzenpacklib --create ZenPacks.training.NetBotz\r\n#install in link mode.  Only for creating zenpacks.\r\n# this uses the source instead of egg files\r\nzenpack --link --install ZenPacks.training.NetBotz\r\n#\r\nserviced service restart zope<\/pre>\n<p>Note: Normally for ZenPack changes we would restart everything, but for the class will do the minimal to save time.<\/p>\n<pre>serviced service restart zenoss.cse\/zenoss\r\n# You should never need to restart infrastructure services!<\/pre>\n<h3>Create the .egg file<\/h3>\n<pre>cd \/z\/ZenPacks.training.NetBotz\r\npython setup.py bdist_egg\r\n\r\n# The resulting .egg file will be found:\r\n# \/z\/ZenPacks.training.NetBotz\/dist<\/pre>\n<h3>Add a Device Class to a ZenPack (UI)<\/h3>\n<ol>\n<li>Create the Device Class<\/li>\n<li>Highlight the Device Class via the Infrastructure tab<\/li>\n<li>Click the lower left gear icon and select &#8220;Add to ZenPack&#8230;&#8221;<\/li>\n<li>Select your ZenPack and click [ Submit ]<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3>Add a monitoring template and Bind to device class<\/h3>\n<p><strong>Add the Template<\/strong><\/p>\n<p>Advanced &gt; Monitoring Templates &gt; [+] Add a monitoring template<\/p>\n<ul>\n<li>Give it a name (NetBotzDevice)<\/li>\n<li>Create at the \/NetBotz device class level<\/li>\n<\/ul>\n<p><strong>Bind it to the Device Class<\/strong><\/p>\n<ul>\n<li>Method 1:\n<ul>\n<li>Refresh browser to make sure new template is there<\/li>\n<li>Select the NetBotz device class under the \/NetBotzDevice template.<\/li>\n<li>Click the gear icon in the bottom left corner and select &#8220;Toggle Template Binding&#8221;<\/li>\n<li>Refresh browser again<\/li>\n<li>Upon success, you&#8217;ll see a green checkmark next to the \/Netbotz device class<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4005\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-1.png\" alt=\"\" width=\"530\" height=\"372\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-1.png 530w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-1-300x211.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-1-150x105.png 150w\" sizes=\"auto, (max-width: 530px) 100vw, 530px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4006\" src=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-2.png\" alt=\"\" width=\"518\" height=\"379\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-2.png 518w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-2-300x219.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2023\/10\/Bind-to-device-class-2-150x110.png 150w\" sizes=\"auto, (max-width: 518px) 100vw, 518px\" \/><\/a><\/p>\n<ul>\n<li>Method 2:\n<ul>\n<li>Click Infrastructure\n<ul>\n<li>Select the NetBotz device class &gt; Details<\/li>\n<li>Click the gear icon in the botton left corner and select &#8220;Bind Templates&#8221;<\/li>\n<li>Select the NetBotzDevice template<\/li>\n<li>[ Save ]<\/li>\n<\/ul>\n<\/li>\n<li>Return to Advanced &gt; Monitoring Templates and click the \/Netbotz device class under the NetBotzDevice template.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3><strong>Finding SNMP Values to add<\/strong><\/h3>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/understanding-snmp-walks\/\" target=\"_blank\" rel=\"noopener\">Understanding SNMP Walks<\/a><\/p>\n<h3>Export the ZenPack (UI)<\/h3>\n<ul>\n<li>Advanced &gt; Click ZenPack link<\/li>\n<li>Verify Device Class and correct templates applied\n<ul>\n<li>Vague. You&#8217;ll need to look at the files.<\/li>\n<\/ul>\n<\/li>\n<li>Lower left gear icon &gt; Export ZenPack &gt; Export\n<ul>\n<li>No need to download at this time. The file is on the system<\/li>\n<\/ul>\n<\/li>\n<li>.egg File is located in \/z\/ZenPacks.COMPANY.ZENPACK_NAME\/dist\/<\/li>\n<\/ul>\n<h1>Create ZenPack via CLI<\/h1>\n<p>02:01:20 &#8211; Starting with the ZenPack created via the UI.<\/p>\n<p>&nbsp;<\/p>\n<p>EZ Environmental Variables (Optional)<\/p>\n<pre>export ZP_TOP_DIR=\/z\/ZenPacks.COMPANY.ZENPACK_NAME\r\nexport ZP_DIR=$ZP_TOP_DIR\/ZenPacks\/COMPANY\/ZENPACK_NAME<\/pre>\n<p><em>For my lab: I&#8217;ll need to copy\/paste this every time I log back in.<\/em><\/p>\n<pre>export ZP_TOP_DIR=\/z\/ZenPacks.training.NetBotz\r\nexport ZP_DIR=$ZP_TOP_DIR\/ZenPacks\/training\/NetBotz<\/pre>\n<p>Notes:<\/p>\n<ul>\n<li>Only files in the ZenPacks.COMPANY.ZENPACK_NAME\/ZenPacks folder will be included in the ZenPack.egg. Anything above that will be ignored.\n<ul>\n<li>This is set in the MANIFEST.in file<\/li>\n<\/ul>\n<\/li>\n<li>ZenPack names can go as many layers deep at required but not recommended to go past 4.\n<ul>\n<li>Extra typing and not much to gain beyond that.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>Directory and File Descriptions<\/h3>\n<p>$ZP_TOP_DIR\/ZenPacks\/COMPANY\/ZENPACK_NAME\/<\/p>\n<ul>\n<li>zenpack.yaml\n<ul>\n<li>Currently only has ZP name. Most work will be done here<\/li>\n<\/ul>\n<\/li>\n<li>\/datasources:<\/li>\n<li>\/lib: list additional libraries<\/li>\n<li>\/libexec: scripts that the ZP needs to run<\/li>\n<li>\/migrate: Advanced. No need for this now<\/li>\n<li>\/modeler\n<ul>\n<li>\/plugins<\/li>\n<\/ul>\n<\/li>\n<li>\/objects: Should contain an .xml file with what we did via the UI, but I don&#8217;t have it \ud83d\ude41<\/li>\n<li>\/parsers: Custom parsing scripts<\/li>\n<li>\/resources: Mostly Javascript<\/li>\n<li>\/skins: Obsolete<\/li>\n<li>\/tests:<\/li>\n<li>\/thresholds:<\/li>\n<li>zenpack.yaml<\/li>\n<\/ul>\n<h3>Edit zenpack.yaml<\/h3>\n<p><a href=\"https:\/\/zenpacks.zenoss.io\/zdk\/start\/snmp\/device-modeling\/\" target=\"_blank\" rel=\"noopener\">https:\/\/zenpacks.zenoss.io\/zdk\/start\/snmp\/device-modeling\/<\/a><\/p>\n<pre id=\"__code_1\"><code><span class=\"nt\">name<\/span><span class=\"p\">:<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">ZenPacks.training.NetBotz<\/span>\r\n\r\n<span class=\"nt\">classes<\/span><span class=\"p\">:<\/span>\r\n  <span class=\"nt\">NetBotzDevice<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"nt\">base<\/span><span class=\"p\">:<\/span> <span class=\"p p-Indicator\">[<\/span><span class=\"nv\">zenpacklib.Device<\/span><span class=\"p p-Indicator\">]<\/span>\r\n    <span class=\"nt\">label<\/span><span class=\"p\">:<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">NetBotz<\/span>\r\n    <span class=\"nt\">properties<\/span><span class=\"p\">:<\/span>\r\n      <span class=\"nt\">temp_sensor_count<\/span><span class=\"p\">:<\/span>\r\n        <span class=\"nt\">type<\/span><span class=\"p\">:<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">int<\/span>\r\n\r\n<span class=\"nt\">device_classes<\/span><span class=\"p\">:<\/span>\r\n  <span class=\"nt\">\/NetBotz<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"nt\">zProperties<\/span><span class=\"p\">:<\/span>\r\n      <span class=\"nt\">zPythonClass<\/span><span class=\"p\">:<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">ZenPacks.training.NetBotz.NetBotzDevice<\/span>\r\n      <span class=\"nt\">zSnmpMonitorIgnore<\/span><span class=\"p\">:<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">false<\/span>\r\n      <span class=\"nt\">zCollectorPlugins<\/span><span class=\"p\">:<\/span>\r\n        <span class=\"p p-Indicator\">-<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">training.snmp.NetBotz<\/span>\r\n        <span class=\"p p-Indicator\">-<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">zenoss.snmp.NewDeviceMap<\/span>\r\n        <span class=\"p p-Indicator\">-<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">zenoss.snmp.DeviceMap<\/span>\r\n        <span class=\"p p-Indicator\">-<\/span> <span class=\"l l-Scalar l-Scalar-Plain\">zenoss.snmp.InterfaceMap<\/span><\/code><\/pre>\n<h4>Save the file and reinstall the ZenPack<\/h4>\n<pre>zenpack --link --install $ZP_TOP_DIR\r\nserviced service restart zope\r\n# or restart everything!\r\nserviced service restart zenoss.resmgr\/zenoss<\/pre>\n<p>Note: If you installed the ZenPack using &#8211;link, you should continue to do so.<\/p>\n<h4>Update the device&#8217;s properties<\/h4>\n<p><em>Note: Ignore the video and documentation here&#8230; does not work, but keep following along until you use the UI.<\/em><\/p>\n<p>Because the device and device class existed before the new zenpack properties were installed, it will not automatically obtain these values.<\/p>\n<ol>\n<li>Move the device to a new device class \/Ping, \/Http, etc.)<\/li>\n<li>Delete the NetBotz device class<\/li>\n<li>Reinstall the ZenPack as shown above<\/li>\n<li>Restart Zope<\/li>\n<li>Move the device back to the recreated device class.<\/li>\n<\/ol>\n<h1>Create a Modeler Plugin<\/h1>\n<h3>Create the Modeler plugin path<\/h3>\n<pre>mkdir -p $ZP_DIR\/modeler\/plugins\/training\/snmp<\/pre>\n<h3>Touch each file with the dunder-init files<\/h3>\n<p>These empty files are required for the folders to be picked up by the build system.<\/p>\n<pre>touch $ZP_DIR\/modeler\/__init__.py\r\ntouch $ZP_DIR\/modeler\/plugins\/__init__.py\r\ntouch $ZP_DIR\/modeler\/plugins\/training\/__init__.py\r\ntouch $ZP_DIR\/modeler\/plugins\/training\/snmp\/__init__.py<\/pre>\n<h3>Create the Modeler file and add the content<\/h3>\n<p>Note: The name of the class must match the name of the file!<\/p>\n<pre>nano $ZP_DIR\/modeler\/plugins\/training\/snmp\/NetBotz.py\r\n...\r\nfrom Products.DataCollector.plugins.CollectorPlugin import (\r\n    SnmpPlugin, GetTableMap,\r\n    )\r\n\r\nclass NetBotz(SnmpPlugin):\r\n    snmpGetTableMaps = (\r\n        GetTableMap(\r\n            'tempSensorTable', '1.3.6.1.4.1.5528.100.4.1.1.1', {\r\n                '.1': 'tempSensorId',\r\n                }\r\n            ),\r\n        )\r\n\r\n    def process(self, device, results, log):\r\n        temp_sensors = results[1].get('tempSensorTable', {})\r\n\r\n        return self.objectMap({\r\n            'temp_sensor_count': len(temp_sensors.keys()),\r\n            })\r\n<\/pre>\n<p>After adding the new modeler plugin to the device class and remodeling the device, you&#8217;ll be able to view the new property in zendmd. Next, we&#8217;ll add the property to the device overview page.<\/p>\n<h3>Update the device overview to show the new property<\/h3>\n<h4>Create the directory to store the Javascript:<\/h4>\n<p>This should already exist&#8230;<\/p>\n<pre>mkdir -p $ZP_DIR\/resources<\/pre>\n<h4>Create a file with the javascript<\/h4>\n<pre>nano $ZP_DIR\/resources\/device.js<\/pre>\n<p><strong>and add the following content<\/strong><\/p>\n<pre>Ext.onReady(function() {\r\n    var DEVICE_OVERVIEW_ID = 'deviceoverviewpanel_summary';\r\n    Ext.ComponentMgr.onAvailable(DEVICE_OVERVIEW_ID, function(){\r\n        var overview = Ext.getCmp(DEVICE_OVERVIEW_ID);\r\n        overview.removeField('memory');\r\n\r\n        overview.addField({\r\n            name: 'temp_sensor_count',\r\n            fieldLabel: _t('# Temperature Sensors')\r\n        });\r\n    });\r\n});<\/pre>\n<h1>Component Modeling<\/h1>\n<p>3:03:00 <a href=\"https:\/\/zenpacks.zenoss.io\/zdk\/start\/snmp\/component-modeling\/\">Component Modeling Documentation<\/a><\/p>\n<h3>Search the MIB for things that might be important to you<\/h3>\n<pre>smidump -f identifiers \/usr\/share\/snmp\/mibs\/NETBOTZV2-MIB.mib | grep -Ei temp<\/pre>\n<h3>Walk the row looking for these component attributes<\/h3>\n<pre>snmpwalk -v2c -c netbotz -m all 10.90.34.172:1024 1.3.6.1.4.1.5528.100.4.1.1.1<\/pre>\n<h4>Filter this down to just one component<\/h4>\n<pre>snmpwalk -v2c -c netbotz -m all 10.90.34.172:1024 1.3.6.1.4.1.5528.100.4.1.1.1 | grep 21604919<\/pre>\n<p>Results:<\/p>\n<pre>NETBOTZV2-MIB::tempSensorId.21604919 = STRING: nbHawkEnc_1_TEMP\r\nNETBOTZV2-MIB::tempSensorValue.21604919 = INTEGER: 265\r\nNETBOTZV2-MIB::tempSensorErrorStatus.21604919 = INTEGER: normal(0)\r\nNETBOTZV2-MIB::tempSensorLabel.21604919 = STRING: Temperature\r\nNETBOTZV2-MIB::tempSensorEncId.21604919 = STRING: nbHawkEnc_1\r\nNETBOTZV2-MIB::tempSensorPortId.21604919 = STRING: \r\nNETBOTZV2-MIB::tempSensorValueStr.21604919 = STRING: 26.500000\r\nNETBOTZV2-MIB::tempSensorValueInt.21604919 = INTEGER: 26\r\nNETBOTZV2-MIB::tempSensorValueIntF.21604919 = INTEGER: 79\r\nNETBOTZV2-MIB::tempSensorEntry.10.21604919 = Counter32: 21604919<\/pre>\n<h3>Identify items to include in the Model<\/h3>\n<p>These are items that rarely change<\/p>\n<ul>\n<li>tempSensorId<\/li>\n<li>tempSensorEncId<\/li>\n<li>tempSensorPortId<\/li>\n<\/ul>\n<p>Note: Coincidence that these are all strings?<\/p>\n<h3>Update the YAML file to add the component<\/h3>\n<pre>nano $ZP_DIR\/zenpack.yaml<\/pre>\n<p>add the following:<\/p>\n<pre>NetBotzTemperatureSensor:\r\n    base: [zenpacklib.Component]\r\n    label: Temperature Sensor\r\n    properties:\r\n      enclosure:\r\n        label: Enclosure\r\n\r\n      port:\r\n        label: Port\r\n\r\nclass_relationships:\r\n  - NetBotzDevice 1:MC NetBotzTemperatureSensor\r\n<\/pre>\n<p>Note:<\/p>\n<ul>\n<li>1:MC says &#8220;A single NetBotzDevice may have many NetBotzTemperatureSensor components&#8221;<\/li>\n<li>The properties &#8220;enclosure&#8221; and &#8220;port&#8221; do not need to be &#8216;typed&#8217; as strings. Strings are the default type.\n<ul>\n<li>Look at our previous &#8220;temp_sensor_count&#8221; which was &#8216;typed&#8217; as &#8216;int&#8217;<\/li>\n<\/ul>\n<\/li>\n<li>There is no need to create properties for &#8216;id&#8217; nor &#8216;title&#8217; since these are included with the zenpacklib.component<\/li>\n<\/ul>\n<h3>Reinstall the ZenPack and restart Zope<\/h3>\n<p>This is always required to pick up yaml file changes.<\/p>\n<pre># Reinstall the ZenPack\r\nzenpack --link --install $ZP_TOP_DIR\r\n# OR (sweet trick here)\r\nhistory | grep install\r\n!HISTORY_NUMBER_YOU_WANT_TO_RUN\r\n\r\n# restart Zope\r\nserviced service restart zope\r\n<\/pre>\n<h4>Test if the component class exists with zendmd<\/h4>\n<pre>from ZenPacks.training.NetBotz.NetBotzTemperatureSensor import NetBotzTemperatureSensor\r\nsensor = NetBotzTemperatureSensor('test_sensor_01')\r\ndevice = find(\"Netbotz01\")\r\ndevice.netBotzTemperatureSensors._setObject(sensor.id, sensor)\r\nsensor = device.netBotzTemperatureSensors._getOb(sensor.id)\r\nprint sensor\r\nprint sensor.device()<\/pre>\n<p>This will error. We need to run the following:<\/p>\n<pre>device.buildRelations()\r\ncommit()<\/pre>\n<p>Now rerun the above code and it will work<\/p>\n<h3>Update (Replace) the Modeler Plugin<\/h3>\n<pre>nano $ZP_DIR\/modeler\/plugins\/training\/snmp\/NetBotz.py<\/pre>\n<p>Replace everything with the following contents:<\/p>\n<pre>from Products.DataCollector.plugins.CollectorPlugin import (\r\n    SnmpPlugin, GetTableMap,\r\n    )\r\n\r\n\r\nclass NetBotz(SnmpPlugin):\r\n    relname = 'netBotzTemperatureSensors'\r\n    modname = 'ZenPacks.training.NetBotz.NetBotzTemperatureSensor'\r\n\r\n    snmpGetTableMaps = (\r\n        GetTableMap(\r\n            'tempSensorTable', '1.3.6.1.4.1.5528.100.4.1.1.1', {\r\n                '.1': 'tempSensorId',\r\n                '.5': 'tempSensorEncId',\r\n                '.6': 'tempSensorPortId',\r\n                }\r\n            ),\r\n        )\r\n\r\n    def process(self, device, results, log):\r\n        temp_sensors = results[1].get('tempSensorTable', {})\r\n\r\n        rm = self.relMap()\r\n        for snmpindex, row in temp_sensors.items():\r\n            name = row.get('tempSensorId')\r\n            if not name:\r\n                log.warn('Skipping temperature sensor with no name')\r\n                continue\r\n\r\n            rm.append(self.objectMap({\r\n                'id': self.prepId(name),\r\n                'title': name,\r\n                'snmpindex': snmpindex.strip('.'),\r\n                'enclosure': row.get('tempSensorEncId'),\r\n                'port': row.get('tempSensorPortId'),\r\n                }))\r\n\r\n        return rm<\/pre>\n<p>Notes:<\/p>\n<ul>\n<li>prepId turns a string into something URL friendly\n<ul>\n<li>These should also be strings so they remain unique<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>Restart Zope and zenhub to push the changes<\/h4>\n<h4>Remodel the device<\/h4>\n<p>You should now see the temperature sensors as components of the device.<\/p>\n<ul>\n<li>If not, make sure the modeler plugin didn&#8217;t fall off the device class somehow.<\/li>\n<\/ul>\n<h3>Add a Monitoring Template<\/h3>\n<p>Note: Recommended to do this via the YAML file, but will do this in the UI instead.<\/p>\n<p>Create the template as outlined in the doc.<\/p>\n<h1>Traps<\/h1>\n<p>3:51:15 <a href=\"https:\/\/zenpacks.zenoss.io\/zdk\/start\/snmp\/traps\/\" target=\"_blank\" rel=\"noopener\">Traps Documentation<\/a><\/p>\n<p>This isn&#8217;t really part of the ZenPack, but good to know.<\/p>\n<h3>Push the MIB file to the collectors<\/h3>\n<p><a href=\"https:\/\/zenoss.atlassian.net\/wiki\/spaces\/~124743625\/pages\/1062961222\/Install+MIBs#Instructions\" target=\"_blank\" rel=\"noopener\">https:\/\/zenoss.atlassian.net\/wiki\/spaces\/~124743625\/pages\/1062961222\/Install+MIBs#Instructions<\/a><\/p>\n<p>Note: Recall the MIB file is <code>\/usr\/share\/snmp\/mibs\/NETBOTZV2-MIB.mib<\/code><\/p>\n<h3>Simulate a trap<\/h3>\n<h4>Get the collector pool&#8217;s trap vip<\/h4>\n<pre>sudo iptables -L FORWARD -n | grep 162\r\n# ACCEPT udp -- 0.0.0.0\/0 172.17.0.55 udp dpt:162 \/* serviced: DO_NOT_REMOVE *\/<\/pre>\n<h4>Send the trap using the MIB Friendly description<\/h4>\n<p>Note: You can get the Friendly OID names from Advanced &gt; MIBs &gt; SELECT_MIB &gt; Dropdown = &#8216;Traps&#8217;<\/p>\n<pre>sudo snmptrap 172.17.0.55 0 NETBOTZV2-MIB::netBotzTempTooHigh<\/pre>\n<p>&nbsp;<\/p>\n<h1>Commands<\/h1>\n<p><strong>Create ZenPack .egg file<\/strong><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>file will be in .\/dist folder<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<pre>cd \/z\/ZENPACK_NAME\r\npython setup.py bdist_egg<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Add a device<\/strong><\/p>\n<pre>z zendisc run --deviceclass=\/DEVICECLASS --device=IP.ADD.RE.SS<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>SNMP Walk<\/strong><\/p>\n<pre>snmpwalk -v2c -c public 10.90.35.84 1.3.6.1.2.1.1.3.0<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Training Docs https:\/\/zenpacks.zenoss.io\/zdk\/dev-env\/ 2:36 NetBotz Device: IP: 10.90.34.172 Port: 1024 Version: 2c Community: netbotz Day 1 &#8211; 5 hrs No sound for 1st 7 minutes Video Link #y*26Psp Times: 0:28:00 Creating ZenPack (CLI) X:XX:00 Creating a Monitoring Template (UI) 1:06:00 Create Data Point (UI) Includes how to translate a MIB Definition to an OID (CLI) ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/?p=3948\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3948","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3948","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3948"}],"version-history":[{"count":19,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3948\/revisions"}],"predecessor-version":[{"id":4023,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/3948\/revisions\/4023"}],"wp:attachment":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3948"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3948"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3948"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}