Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
This script finds all the data items both current and historical on all the assets of a model and outputs them as XML.
Parameters:
import com.axeda.drm.sdk.Context
import com.axeda.drm.sdk.device.ModelFinder
import com.axeda.drm.sdk.device.Model
import com.axeda.drm.sdk.device.DeviceFinder
import com.axeda.drm.sdk.data.CurrentDataFinder
import com.axeda.drm.sdk.device.Device
import com.axeda.drm.sdk.data.HistoricalDataFinder
import groovy.xml.MarkupBuilder
/*
* AllDataItems2XML.groovy
*
* Find all the historical and current data items for all assets in a given model.
*
* @param model_name - (REQ):Str name of the model.
* @param from_time - (REQ):Long millisecond timestamp to begin query from.
* @param to_time - (REQ):Long millisecond timestamp to end query at.
*
* @note from_time and to_time should be provided because it limits the query size.
*
* @author Sara Streeter <sstreeter@axeda.com>
*/
def response = [:]
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
// measure the script run time
def timeProfiles = [:]
def scriptStartTime = new Date()
try {
// getUserContext is supported as of release 6.1.5 and higher
final def CONTEXT = Context.getUserContext()
// confirm that required parameters have been provided
validateParameters(actual: parameters, expected: ["model_name", "from_time", "to_time"])
// find the model
def modelFinder = new ModelFinder(CONTEXT)
modelFinder.setName(parameters.model_name)
Model model = modelFinder.findOne()
// throw exception if no model found
if (!model) {
throw new Exception("No model found for ${parameters.model_name}.")
}
// find all assets of that model
def assetFinder = new DeviceFinder(CONTEXT)
assetFinder.setModel(model)
def assets = assetFinder.findAll()
// find the current and historical data values for each asset
//note: since device will be set on the datafinders going forward, a dummy device is set on instantiation which is not actually stored
def currentDataFinder = new CurrentDataFinder(CONTEXT, new Device(CONTEXT, "placeholder", model))
def historicalDataFinder = new HistoricalDataFinder(CONTEXT, new Device(CONTEXT, "placeholder", model))
historicalDataFinder.startDate = new Date(parameters.from_time as Long)
historicalDataFinder.endDate = new Date(parameters.to_time as Long)
// assemble the response
xml.Response(){
assets.each { Device asset ->
currentDataFinder.device = asset
def currentValueList = currentDataFinder.find()
historicalDataFinder.device = asset
def valueList = historicalDataFinder.find()
Asset(){
id(asset.id.value)
name( asset.name)
serial_number(asset.serialNumber)
model_id( asset.model.id.value)
model_name(asset.model.name)
current_data(){
currentValueList.each{ data ->
timestamp( data?.getTimestamp()?.format("yyyyMMdd HH:mm"))
name(data?.dataItem?.name)
value( data?.asString())
}}
historical_data(){
valueList.each { data ->
timestamp( data?.getTimestamp()?.format("yyyyMMdd HH:mm"))
name(data?.dataItem?.name)
value( data?.asString())
}}
}
}
}
} catch (def ex) {
xml.Response() {
Fault {
Code('Groovy Exception')
Message(ex.getMessage())
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
Detail(sw.toString())
}
}
}
return ['Content-Type': 'text/xml', 'Content': writer.toString()]
private Map createTimeProfile(String label, Date startTime, Date endTime) {
[
(label): [
startTime: [timestamp: startTime.time, readable: startTime.toString()],
endTime: [timestamp: endTime.time, readable: endTime.toString()],
profile: [
elapsed_millis: endTime.time - startTime.time,
elapsed_secs: (endTime.time - startTime.time) / 1000
]
]
]
}
private validateParameters(Map args) {
if (!args.containsKey("actual")) {
throw new Exception("validateParameters(args) requires 'actual' key.")
}
if (!args.containsKey("expected")) {
throw new Exception("validateParameters(args) requires 'expected' key.")
}
def config = [
require_username: false
]
Map actualParameters = args.actual.clone() as Map
List expectedParameters = args.expected
config.each { key, value ->
if (args.options?.containsKey(key)) {
config[key] = args.options[key]
}
}
if (!config.require_username) { actualParameters.remove("username") }
expectedParameters.each { paramName ->
if (!actualParameters.containsKey(paramName) || !actualParameters[paramName]) {
throw new IllegalArgumentException(
"Parameter '${paramName}' was not found in the query; '${paramName}' is a reqd. parameter.")
}
}
}
Sample Output:
<Response>
<Asset>
<id>2864</id>
<name>keg24</name>
<serial_number>keg24</serial_number>
<model_id>1081</model_id>
<model_name>Kegerator</model_name>
<current_data>
<timestamp>20111103 14:44</timestamp>
<name>currKegPercentage</name>
<value>34.0</value>
<timestamp>20111103 14:38</timestamp>
<name>currTempF</name>
<value>43.0</value>
</current_data>
<historical_data />
</Asset>
<Asset>
<id>2861</id>
<name>keg28</name>
<serial_number>keg28</serial_number>
<model_id>1081</model_id>
<model_name>Kegerator</model_name>
<current_data>
<timestamp />
<name>currKegPercentage</name>
<value>?</value>
<timestamp>20111103 14:21</timestamp>
<name>currTempF</name>
<value>43.0</value>
</current_data>
<historical_data />
</Asset>
<Asset>
<id>2863</id>
<name>keg21</name>
<serial_number>keg21</serial_number>
<model_id>1081</model_id>
<model_name>Kegerator</model_name>
<current_data>
<timestamp />
<name>currKegPercentage</name>
<value>?</value>
<timestamp>20111103 14:39</timestamp>
<name>currTempF</name>
<value>42.0</value>
</current_data>
<historical_data />
</Asset>
<Asset>
<id>2862</id>
<name>keg25</name>
<serial_number>keg25</serial_number>
<model_id>1081</model_id>
<model_name>Kegerator</model_name>
<current_data>
<timestamp>20111103 14:36</timestamp>
<name>currKegPercentage</name>
<value>34.0</value>
<timestamp />
<name>currTempF</name>
<value>?</value>
</current_data>
<historical_data />
</Asset>
<Asset>
<id>2867</id>
<name>keg29</name>
<serial_number>keg29</serial_number>
<model_id>1081</model_id>
<model_name>Kegerator</model_name>
<current_data>
<timestamp>20111103 14:48</timestamp>
<name>currKegPercentage</name>
<value>35.0</value>
<timestamp />
<name>currTempF</name>
<value>?</value>
</current_data>
<historical_data />
</Asset>
<Asset>
<id>2865</id>
<name>keg27</name>
<serial_number>keg27</serial_number>
<model_id>1081</model_id>
<model_name>Kegerator</model_name>
<current_data>
<timestamp>20111103 14:39</timestamp>
<name>currKegPercentage</name>
<value>34.0</value>
<timestamp>20111103 14:44</timestamp>
<name>currTempF</name>
<value>42.0</value>
</current_data>
<historical_data />
</Asset>
<Asset>
<id>2866</id>
<name>keg23</name>
<serial_number>keg23</serial_number>
<model_id>1081</model_id>
<model_name>Kegerator</model_name>
<current_data>
<timestamp>20111103 14:46</timestamp>
<name>currKegPercentage</name>
<value>34.0</value>
<timestamp />
<name>currTempF</name>
<value>?</value>
</current_data>
<historical_data />
</Asset>
</Response>