Hi!
I made a little api that is meant to speak with an OSIsoft PI AFSDK, so I’m not using the Grafana OSIsoft module, but a custom API.
Here is the error I get in the explore (same error in a dashboard)
{
"state": "Error",
"series": [],
"timeRange": {
"from": "2023-04-09T21:09:22.045Z",
"to": "2023-04-10T03:09:22.045Z",
"raw": {
"from": "now-6h",
"to": "now"
}
},
"graphFrames": [],
"logsFrames": [],
"traceFrames": [],
"nodeGraphFrames": [],
"flameGraphFrames": [],
"tableFrames": [],
"rawPrometheusFrames": [],
"rawPrometheusResult": null,
"graphResult": null,
"logsResult": null,
"tableResult": null,
"request": {
"app": "explore",
"dashboardId": 0,
"timezone": "browser",
"startTime": 1681096162268,
"interval": "2s",
"intervalMs": 2000,
"panelId": "Q-c9c004f2-5fa0-485a-b514-b8b129804055-0",
"targets": [
{
"target": "TAG123.VAL",
"refId": "A",
"type": "timeserie"
}
],
"range": {
"from": "2023-04-10T02:09:22.184Z",
"to": "2023-04-10T03:09:22.184Z",
"raw": {
"from": "now-1h",
"to": "now"
}
},
"requestId": "explore_left",
"rangeRaw": {
"from": "now-1h",
"to": "now"
},
"scopedVars": {
"__interval": {
"text": "2s",
"value": "2s"
},
"__interval_ms": {
"text": 2000,
"value": 2000
}
},
"maxDataPoints": 1835,
"liveStreaming": false,
"adhocFilters": [],
"endTime": 1681096162576
}
}
PI is supposed to receive TAG123.VAL and return an array like this :
"target": "TAG123.VAL",
"dataPoints": [
{
"value": 404.8739929199219,
"timestamp": 1681092366864
},
{
"value": 404.773681640625,
"timestamp": 1681092370930
},
{
"value": 404.8453063964844,
"timestamp": 1681092372907
},
… and so on …
I think part of the problem I that the amount of information I have to give is lower than what grafana is expecting, but right now I don’t know where to look.
Here is my query endpoint:
[HttpPost("/query")]
public async Task<IActionResult> Query([FromBody] QueryRequestBody query)
{
try
{
var queryResponseList = new List<QueryResponse>();
if (query.Targets != null)
{
foreach (var queryTarget in query.Targets)
{
var tagName = queryTarget.Target;
var startTime = query.Range.From.UtcDateTime;
var endTime = query.Range.To.UtcDateTime;
if (tagName != null)
{
var piValues = await _piWrapperService.GetPlotValuesAsync(tagName, startTime, endTime);
_logger.LogInformation("Retrieved {Count} data points for target {Target} between {StartTime} and {EndTime}", piValues.Count, tagName, startTime, endTime);
var dataPoints = piValues.Select(piValue => new DataPoint
{
Value = piValue.Value,
Timestamp = new DateTimeOffset(piValue.Timestamp).ToUnixTimeMilliseconds()
}).ToList();
queryResponseList.Add(item: new QueryResponse
{
Target = tagName,
DataPoints = dataPoints
}); ;
}
}
}
return Ok(queryResponseList);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in /query endpoint");
return StatusCode(StatusCodes.Status500InternalServerError, "Internal server error");
}
}
And finally the wrapper method GetPlotValuesAsync:
public async Task<List<PIValue>> GetPlotValuesAsync(string? tagName, DateTime startTime, DateTime endTime, int intervals = 100)
{
var plotRequest = new
{
TagName = tagName,
StartTime = startTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
EndTime = endTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
Intervals = intervals
};
var content = new StringContent(JsonConvert.SerializeObject(plotRequest), System.Text.Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync("/plots", content);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<List<PIValue>>(responseBody) ?? new List<PIValue>();
}
I’m really sorry for the long post, but I felt that I needed to put as much information as possible to better understand to problem.
Thanks for you help and I will be pleased to provide further information!