Skip to content

Commit e19c6ee

Browse files
feature: Adds 'read' support
1 parent 66d5f95 commit e19c6ee

File tree

4 files changed

+52
-9
lines changed

4 files changed

+52
-9
lines changed

README.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,25 @@ one by selecting `+ New Dashboard` from the Dashboard menu in the left panel.
2929
Once within the panel editor, select your Haystack data source in the Data Sources menu. Next, select the type of
3030
Haystack query that should be performed. The supported queries are:
3131

32+
- Eval: Evaluate a free-form Axon expression. Grafana variables may be injected into the query, with the supported
33+
variables listed below. *Note: Not all Haystack servers support this functionality*
3234
- HisRead: Display the history of a single point over the selected time range.
33-
- Eval: Evaluate a free-form Axon expression. Grafana variables may be injected into the query, with the supported variables
34-
listed below. *Note: Not all Haystack servers support this functionality*
35-
- `$__timeRange_start`: DateTime start of the selected Grafana time range
36-
- `$__timeRange_end`: DateTime end of the selected Grafana time range
37-
- `$__maxDataPoints`: Number representing the pixel width of Grafana's display panel.
38-
- `$__interval`: Number representing Grafana's recommended data interval. This is the duration of the time range, divided by the number of pixels, delivered in units of minutes.
35+
- Read: Display the records matching a filter. Since this is not timeseries data, it can only be viewed in Grafana's
36+
"Table" view.
37+
38+
#### Variables
39+
40+
Some queries support injecting values from the Grafana UI. The following variables are supported:
41+
42+
- `$__timeRange_start`: DateTime start of the selected Grafana time range
43+
- `$__timeRange_end`: DateTime end of the selected Grafana time range
44+
- `$__maxDataPoints`: Number representing the pixel width of Grafana's display panel.
45+
- `$__interval`: Number representing Grafana's recommended data interval. This is the duration of the time range,
46+
divided by the number of pixels, delivered in units of minutes.
47+
48+
To use them, simply use the value in the input string like this:
49+
50+
```
51+
[{ts: $__timeRange_start, v0: 0}, {ts: $__timeRange_end, v0: 10}].toGrid
52+
```
3953

pkg/plugin/datasource.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ type QueryModel struct {
9999
Type string `json:"type"`
100100
Eval string `json:"eval"`
101101
HisRead string `json:"hisRead"`
102+
Read string `json:"read"`
102103
}
103104

104105
func (datasource *Datasource) query(ctx context.Context, pCtx backend.PluginContext, query backend.DataQuery) backend.DataResponse {
@@ -136,6 +137,13 @@ func (datasource *Datasource) query(ctx context.Context, pCtx backend.PluginCont
136137
return backend.ErrDataResponse(backend.StatusBadRequest, fmt.Sprintf("HisRead failure: %v", err.Error()))
137138
}
138139
grid = hisRead
140+
case "Read":
141+
read, err := datasource.read(model.Read, variables)
142+
if err != nil {
143+
log.DefaultLogger.Error(err.Error())
144+
return backend.ErrDataResponse(backend.StatusBadRequest, fmt.Sprintf("Read failure: %v", err.Error()))
145+
}
146+
grid = read
139147
default:
140148
log.DefaultLogger.Warn("No valid input, returning empty Grid")
141149
grid = haystack.EmptyGrid()
@@ -191,6 +199,13 @@ func (datasource *Datasource) hisRead(id string, timeRange backend.TimeRange) (h
191199
return datasource.client.HisReadAbsDateTime(ref, start, end)
192200
}
193201

202+
func (datasource *Datasource) read(filter string, variables map[string]string) (haystack.Grid, error) {
203+
for name, val := range variables {
204+
filter = strings.ReplaceAll(filter, name, val)
205+
}
206+
return datasource.client.Read(filter)
207+
}
208+
194209
func dataFrameFromGrid(grid haystack.Grid) (*data.Frame, error) {
195210
fields := []*data.Field{}
196211

src/components/QueryEditor.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ export function QueryEditor({ query, onChange, onRunQuery }: Props) {
1717
const onHisReadChange = (event: ChangeEvent<HTMLInputElement>) => {
1818
onChange({ ...query, type: 'HisRead', hisRead: event.target.value });
1919
};
20+
const onReadChange = (event: ChangeEvent<HTMLInputElement>) => {
21+
onChange({ ...query, type: 'Read', read: event.target.value });
22+
};
2023

2124
const queryTypes = [
2225
{ label: 'Eval', value: 0, description: 'Evaluate an Axon expression' },
23-
{ label: 'HisRead', value: 1, description: 'Read the histories of a list of points' }
26+
{ label: 'HisRead', value: 1, description: 'Read the histories of a list of points' },
27+
{ label: 'Read', value: 2, description: 'Read the records matched by a filter' }
2428
];
2529
const queryTypeDefault = queryTypes[0];
2630
function queryTypeFromLabel(label: string) {
@@ -58,7 +62,15 @@ export function QueryEditor({ query, onChange, onRunQuery }: Props) {
5862
return (
5963
<Field>
6064
<InlineField label="Point ID" labelWidth="auto" tooltip="The ID of the point to read">
61-
<Input width={100} prefix={<Icon name="angle-right" />} onChange={onHisReadChange} value={query.hisRead} placeholder={DEFAULT_QUERY.hisRead} />
65+
<Input width={100} prefix={"@"} onChange={onHisReadChange} value={query.hisRead} placeholder={DEFAULT_QUERY.hisRead} />
66+
</InlineField>
67+
</Field>
68+
);
69+
case 2: // Read
70+
return (
71+
<Field>
72+
<InlineField label="Filter" labelWidth="auto" tooltip="A filter for the desired records">
73+
<Input width={100} prefix={<Icon name="filter" />} onChange={onReadChange} value={query.read} placeholder={DEFAULT_QUERY.read} />
6274
</InlineField>
6375
</Field>
6476
);

src/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ export interface MyQuery extends DataQuery {
44
type: string; // Defines the type of query that should be executed
55
eval: string;
66
hisRead: string;
7+
read: string;
78
}
89

910
export const DEFAULT_QUERY: Partial<MyQuery> = {
1011
type: "Eval",
1112
eval: "[{ts: $__timeRange_start, v0: 0}, {ts: $__timeRange_end, v0: 10}].toGrid",
12-
hisRead: "abcdef-123456"
13+
hisRead: "abcdef-123456",
14+
read: "point and temp and air and outside"
1315
};
1416

1517
/**

0 commit comments

Comments
 (0)