Forum Discussion

Patrick_Rouse's avatar
Patrick_Rouse
Icon for Product Manager rankProduct Manager
2 years ago

Cisco Meraki Environmental Sensor Monitoring

Today, new modules are available in LM Exchange to monitor Cisco Meraki MT-Series Environmental Sensors.  These fully support Resource Explorer and include a new (IoT) Sensor Topology Graphic.  If you are subscribed, these devices count toward the Wireless Access Points SKU.

 

1 Reply

  • If you are getting an "Index 0 out of bounds" error for Meraki water sensors you can update the code to account for empty lists rather than crashing as it does currently.

    /*******************************************************************************
    *  © 2007-2024 - LogicMonitor, Inc. All rights reserved.
     ******************************************************************************/

    import com.santaba.agent.groovy.utils.GroovyScriptHelper as GSH
    import com.logicmonitor.mod.Snippets
    import groovy.json.JsonSlurper

    String organization = hostProps.get("meraki.api.org")
    String serial = hostProps.get("auto.endpoint.serial_number", hostProps.get("meraki.serial")) 
    if (!organization) {
        println "Organization ID missing; device property meraki.api.org must be set."
        return 1
    }
    if (!serial) {
        println "Serial missing; device property auto.endpoint.serial_number or meraki.serial must be set."
        return 1
    }

    def debug = false
    def log = false
    def logCacheContext = "${organization}::cisco-meraki-cloud"

    def modLoader = GSH.getInstance(GroovySystem.version).getScript("Snippets", Snippets.getLoader()).withBinding(getBinding())
    def emit        = modLoader.load("lm.emit", "0")
    def bab         = modLoader.load("lm.bitsandbobs", "0")
    def lmDebugSnip = modLoader.load("lm.debug", "1")
    def lmDebug     = lmDebugSnip.debugSnippetFactory(out, debug, log, logCacheContext)
    def cacheSnip   = modLoader.load("lm.cache", "0")
    def cache       = cacheSnip.cacheSnippetFactory(lmDebug, logCacheContext)

    def cachedOrganizationDeviceStatuses = cache.cacheGet("${organization}::organizationDeviceStatuses")
    if (cachedOrganizationDeviceStatuses) {
        if (debug) println "Fetched cached data using key ${organization}::organizationDeviceStatuses..."
        def organizationDeviceStatuses = new JsonSlurper().parseText(cachedOrganizationDeviceStatuses)
        def organizationDeviceStatus = organizationDeviceStatuses?.values().find { it.serial == serial }
        def statusCodes = ["online": 0, "dormant": 1, "offline": 2]
        def data = statusCodes.get(organizationDeviceStatus?.get("status"), 1)?.toInteger()
        emit.dp("status", data)
    }

    def cachedOrganizationSensors = cache.cacheGet("${organization}::sensors")
    if (cachedOrganizationSensors) {
        if (debug) println "Fetched cached data using key ${organization}::sensors..."
        def organizationSensors = new JsonSlurper().parseText(cachedOrganizationSensors)
        def organizationSensor = organizationSensors?.find { it.serial == serial }
        def sensorReadings = organizationSensor?.get("readings")

        if (sensorReadings?.battery?.percentage && sensorReadings.battery.percentage.size() > 0) {
            emit.dp("battery", sensorReadings.battery.percentage.get(0))
        } else {
            println "Battery percentage data missing or empty"
        }

        if (sensorReadings?.water?.present && sensorReadings.water.present.size() > 0) {
            emit.dp("water", sensorReadings.water.present.get(0).toString() == "false" ? 0 : 1)
        } else {
            println "Water presence data missing or empty"
        }
    }

    bab.keepAlive(hostProps)

    return 0