Axeda: Get Model Or Asset Alarms and Details

    This script dumps all the alarms for a model or asset to JSON.

     

    Parameters (one or the other must be provided):

    1. modelName - (OPTIONAL) String - name of the model
    2. assetId - (OPTIONAL) String - id of the asset

     

    import com.axeda.common.sdk.id.Identifier
    import com.axeda.drm.sdk.Context
    import com.axeda.drm.sdk.audit.AuditCategory
    import com.axeda.drm.sdk.audit.AuditMessage
    import com.axeda.drm.sdk.scripto.Request
    import groovy.json.*
    import net.sf.json.JSONObject
    import java.net.URLDecoder
    import static com.axeda.sdk.v2.dsl.Bridges.*
    import com.axeda.services.v2.CustomObjectCriteria
    import com.axeda.services.v2.CustomObjectType
    import com.axeda.services.v2.CustomObject
    import com.axeda.services.v2.ExecutionResult
    import com.axeda.services.v2.ExtendedMap
    import com.axeda.drm.sdk.device.Model
    import com.axeda.drm.sdk.device.ModelFinder
    import com.axeda.drm.sdk.device.DeviceFinder
    import com.axeda.drm.sdk.device.Device
    import com.axeda.services.v2.ModelCriteria
    import com.axeda.services.v2.ModelType
    import com.axeda.services.v2.FindModelResult
    import com.axeda.services.v2.AssetCriteria
    import com.axeda.services.v2.FindAssetResult
    import com.axeda.services.v2.AlarmCriteria
    import com.axeda.sdk.v2.bridge.MobileLocationBridge
    import com.axeda.drm.sdk.mobilelocation.MobileLocationFinder
    import com.axeda.drm.sdk.mobilelocation.CurrentMobileLocationFinder
    import com.axeda.drm.sdk.mobilelocation.MobileLocation
    import com.axeda.drm.sdk.data.AlarmState
    import com.axeda.drm.sdk.data.AlarmFinder
    import com.axeda.drm.sdk.data.Alarm
    import com.axeda.platform.sdk.v1.services.ServiceFactory
    import com.axeda.drm.sdk.data.CurrentDataFinder
    import com.axeda.drm.sdk.device.DataItem
    import com.axeda.drm.sdk.data.HistoricalDataFinder
    import com.axeda.drm.sdk.data.DataValue
    import com.axeda.drm.sdk.data.DataValueList
    import com.axeda.platform.sdk.v1.services.extobject.ExtendedObjectSearchCriteria
    import com.axeda.common.date.DateRange
    import com.axeda.common.date.ExplicitDateRange
    
    /**
    * GetModel_Or_Asset_Alarms.groovy
    * -----------------------
    *
    * Returns assets with organizations, alarms, and current mobile location.
    *
    * @params
    * modelName (OPTIONAL) Str - the name of the model to retrieve assets
    * assetId (OPTIONAL) Long - the id of the asset - one of the two is REQUIRED
    *
    *
    * @author sara streeter <sstreeter@axeda.com>
    *
    */
    
    /**
    * initialize our global variables
    * json = the contents of our response
    * infoString = a stringBuilder used to collect debug information during the script
    * contentType = the content type we will return
    * scriptname = The name of this Script, used in multiple places
    */
    def json = new groovy.json.JsonBuilder()
    def infoString = new StringBuilder()
    def contentType = "application/json"
    def scriptName = "GetModel_Or_Asset_Alarms.groovy"
    def root = [:]
    
    def timings = [:]
    timings.dataItemList = 0
    timings.currentdata = 0
    timings.histdata = 0
    timings.wholescript = 0
    timings.alarms = 0
    timings.loop = 0
    timings.filter = 0
    timings.devices = 0
    timings.geocode = 0
    
    
    wholestart = System.currentTimeMillis()
    
    final def Context CONTEXT = Context.getSDKContext()
    
    def deviceList
    List<Device> devices
    
    try {
    
        /* BUSINESS LOGIC GOES HERE */
       
        def modelName = Request.parameters.modelName
        def assetId
        def alarms
        AlarmFinder alarmFinder = new AlarmFinder(CONTEXT)
       
        if (Request.parameters.assetId != null && Request.parameters.assetId != ""){
            assetId = Request.parameters.assetId
            DeviceFinder deviceFinder = new DeviceFinder(CONTEXT, new Identifier(assetId as Long));
            def device = deviceFinder.find()
            if (device){
                alarmFinder.setDevice(device)
                modelName = device.model.name
            }
        }
        else if (modelName){
           
            try{
            modelName = new URLDecoder().decode(modelName)
            }
            catch(e){ logger.info(e.localizedMessage) }
    
            if (modelName != null && modelName !=""){
                ModelFinder modelFinder = new ModelFinder(CONTEXT)
                modelFinder.setName(modelName)
                Model model = modelFinder.find()
              
                if (model){
                    modelName = model?.name
                    alarmFinder.setModel(model)
                }
            }   
        }
       
        alarms = alarmFinder.findAll()
    
        // build the json from the models
             root = [
                 "result": [
                 "model": modelName,
                 "assetId": assetId,
                 "alarms":alarms?.inject([]){ aList, alarm ->
                       aList << [
                            "deviceId": alarm.device?.id?.value,
                           "deviceName": alarm.device.name,
                           "deviceSerial": alarm.device.serialNumber,
                            "name": alarm.name,
                            "id": alarm.id.value,
                            "state": alarm.state.name,
                            "description": alarm.description,
                            "severity": alarm.severity,
                            "timestamp": alarm.date.time
    
                       ]
                        
                      aList
                  }
                ]
             ]
    
        /* BUSINESS LOGIC ENDS HERE */
    
    } catch (Exception e) {
        def errorCode = "123456"
        processException(scriptName,json,e,errorCode)
    }
    finally {
        timings.wholescript = System.currentTimeMillis() - wholestart
        root += [params: Request.parameters]
        root += [timings: timings]
    
    }
    
    return ['Content-Type': 'application/json', 'Content': JSONObject.fromObject(root).toString(2)]
    
    /*
    *
    * ACTIVE CODE ENDS HERE
    *
    */
    
    //---------------------------------------------------------------//
    
    /*
    *
    * HELPER METHODS START BELOW
    *
    */
    
    /**
    * Wrap-up the response in our standard return map
    * @param contentType The global contentType variable
    * @param response The contents of the response (String ONLY)
    */
    private def createReturnMap(String contentType, String response) {
        return ["Content-Type": contentType,"Content":response]
    }
    
    /*
        Processes the contents of an Exception and add it to the Errors collection
        @param json The markup builder
    */
    private def processException(String scriptName, JsonBuilder json, Exception e, String code) {
        // catch the exception output
        def logStringWriter = new StringWriter()
        e.printStackTrace(new PrintWriter(logStringWriter))
        logger.error("Exception occurred in ${scriptName}: ${logStringWriter.toString()}")
    
        /*
            Construct the error response
            - errorCode Will be an element from an agreed upon enum
            - errorMessage The text of the exception
         */
        json.errors  {
            error {
                errorCode   "${code}"
                message     "[${scriptName}]: " + e.getMessage()
                timestamp   "${System.currentTimeMillis()}"
            }
        }
    
        return json
    }
    
    /*
        Log a message. This will log a message and add it to info String
        @param logger The injected logger
        @param scriptName The name of the script being executed
        @param info The infoString to append to
        @param message The actual message to log
    */
    private def logMessage(def logger, String scriptName, StringBuilder info, String message) {
        logger.info(message)
        info.append(message+"\n")
    }
    
    /*
        Audit a message. This will store a message in the Audit log, based on the supplied category.
        @param category The category for this audit message. One of: "scripting", "network", "device" or "data". Anything not recognized will be treated as "data".
        @param message The actual message to audit
        @param assetId If supplied, will associate the audit message with the asset at this ID
    */
    private def auditMessage(String category, String message, String assetId) {
        AuditCategory auditCategory = null
        switch (category) {
            case "scripting":
                auditCategory = AuditCategory.SCRIPTING;
                break;
            case "network":
                auditCategory = AuditCategory.NETWORK;
                break;
            case "device":
                auditCategory = AuditCategory.DEVICE_COMMUNICATION;
                break;
            default:
                auditCategory = AuditCategory.DATA_MANAGEMENT;
                break;
        }
    
        if (assetId == null) {
            new AuditMessage(Context.create(),"com.axeda.drm.rules.functions.AuditLogAction",auditCategory,[message]).store()
        } else {
            new AuditMessage(Context.create(),"com.axeda.drm.rules.functions.AuditLogAction",auditCategory,[message],new Identifier(Long.valueOf(assetId))).store()
        }
    }
    
    
    def findOrCreateExtendedMap(String name){
           // should take a name of Extended Map and output an object of type Extended Map, if it outputs null we throw an Exception
           def outcome = [:]
           outcome.extendedMap
    
           ExtendedMap extendedMap = extendedMapBridge.find(name)
    
           if (!extendedMap){
                extendedMap = new ExtendedMap(name: name)
               extendedMapBridge.create(extendedMap)
           }
    
           if (extendedMap) {
            ExecutionResult result = new ExecutionResult()
            result.setSuccessful(true)
            result.setTotalCount(1)
            outcome.result = result
            outcome.extendedMap = extendedMap
           }
           else {
               ExecutionResult result = new ExecutionResult()
               result.setSuccessful(false)
               result.setTotalCount(1)
               outcome.result = result
           }
            return outcome
       }
    
       def retrieveModels(){
          // retrieves the list populated by a separate script
           def outcome = [:]
           outcome.modelList
    
           ModelCriteria modelCriteria = new ModelCriteria()
           modelCriteria.type = ModelType.STANDALONE
    
           FindModelResult modelResult = modelBridge.find(modelCriteria)
    
           if (modelResult.models.size() > 0){
            ExecutionResult result = new ExecutionResult()
            result.setSuccessful(true)
            result.setTotalCount(1)
            outcome.result = result
            outcome.modelList = modelResult.models
           }
           else {
               ExecutionResult result = new ExecutionResult()
               result.setSuccessful(false)
               result.setTotalCount(1)
               outcome.result = result
           }
            return outcome
       }
    
       def returnModelsWithAssets(List<com.axeda.services.v2.Model> modelList){
           def outcome = [:]
           outcome.modelList
           outcome.message
    
           if (!modelList || modelList?.size() ==0){
               ExecutionResult result = new ExecutionResult()
              result.setSuccessful(false)
              result.setTotalCount(1)
              outcome.result = result
              outcome.message = "returnModelsWithAssets: Model list was not supplied or was of size zero."
              return outcome
           }
    
           DeviceFinder deviceFinder = new DeviceFinder(CONTEXT)
           ModelFinder modelFinder = new ModelFinder(CONTEXT)
           List<com.axeda.drm.sdk.device.Model> sortedList = modelList.inject([]){ target, amodel ->
                modelFinder.setName(amodel.modelNumber)
               com.axeda.drm.sdk.device.Model bmodel = modelFinder.find()
               deviceFinder.setModel(bmodel)
               def numAssets = deviceFinder.findAll().size()
               if (numAssets > 0 ){
                      target << bmodel
                }
                target
           }.sort{ amodel, bmodel ->  amodel.name <=> bmodel.name}
    
           if (sortedList.size() > 0){
            ExecutionResult result = new ExecutionResult()
            result.setSuccessful(true)
            result.setTotalCount(1)
            outcome.result = result
            outcome.modelList = sortedList
           }
           else {
              ExecutionResult result = new ExecutionResult()
              result.setSuccessful(false)
              result.setTotalCount(1)
              outcome.result = result
          }
            return outcome
    
       }
    
        def addMapEntry(String mapName, String key, String value){
           def outcome = [:]
            outcome.key
            outcome.value
    
            ExecutionResult result = extendedMapBridge.append(mapName, key, value)
            outcome.result = result
    
            if (result.successful){
                outcome.key = key
                outcome.value = value
            }
            return outcome
    
       }