summaryrefslogtreecommitdiffstats
path: root/lib/vehicle-signals/vss_client.dart
blob: e416d87b5f4f2cbeb1a60db2f96c100754a592b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// SPDX-License-Identifier: Apache-2.0
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:grpc/grpc.dart';
import 'package:flutter_cluster_dashboard/generated/kuksa/val/v1/val.pbgrpc.dart';
import 'package:flutter_cluster_dashboard/generated/kuksa/val/v1/types.pb.dart';
import 'package:flutter_cluster_dashboard/config.dart';

abstract class VssClient {
  final KuksaConfig config;
  final ClientChannel channel;
  final VALClient stub;
  final Ref ref;

  // Extenders will likely override this
  final List<String> signals = [];

  VssClient({required this.config, required this.channel, required this.stub, required this.ref});

  // Abstract method extenders must implement
  void handleSignalUpdates(EntryUpdate update);

  void run() async {
    if (signals.isEmpty)
      return;

    var request = SubscribeRequest();
    for (var i = 0; i < signals.length; i++) {
      var entry = SubscribeEntry();
      entry.path = signals[i];
      entry.fields.add(Field.FIELD_PATH);
      entry.fields.add(Field.FIELD_VALUE);
      request.entries.add(entry);
    }

    try {
      Map<String, String> metadata = {};
      if (config.authorization.isNotEmpty) {
        metadata = {'authorization': "Bearer ${config.authorization}" };
      }
      var responseStream = stub.subscribe(request, options: CallOptions(metadata: metadata));
      await for (var response in responseStream) {
        for (var update in response.updates) {
          if (!(update.hasEntry() && update.entry.hasPath()))
            continue;
          handleSignalUpdates(update);
        }
      }
    } catch (e) {
      print(e);
    }
  }

  void setUint32(String path, int value, [bool actuator = true]) async {
    var dp = Datapoint()
      ..uint32 = value;
    set(path, dp, actuator);
  }

  void setInt32(String path, int value, [bool actuator = true]) async {
    var dp = Datapoint()
      ..int32 = value;
    set(path, dp, actuator);
  }

  void setBool(String path, bool value, [bool actuator = true]) async {
    var dp = Datapoint()
      ..bool_12 = value;
    set(path, dp, actuator);
  }

  void setString(String path, String value, [bool actuator = true]) async {
    var dp = Datapoint()
      ..string = value;
    set(path, dp, actuator);
  }

  void setFloat(String path, double value, [bool actuator = true]) async {
    var dp = Datapoint()
      ..float = value;
    set(path, dp, actuator);
  }

  void setDouble(String path, double value, [bool actuator = true]) async {
    var dp = Datapoint()
      ..double_18 = value;
    set(path, dp, actuator);
  }

  void set(String path, Datapoint dp, bool actuator) async {
    var entry = DataEntry()
      ..path = path;
    var update = EntryUpdate();
    if (actuator) {
      entry.actuatorTarget = dp;
      update.fields.add(Field.FIELD_ACTUATOR_TARGET);
    } else {
      entry.value = dp;
      update.fields.add(Field.FIELD_VALUE);
    }
    update.entry = entry;
    var request = SetRequest();
    request.updates.add(update);
    Map<String, String> metadata = {};
    if (config.authorization.isNotEmpty) {
      metadata = {'authorization': "Bearer ${config.authorization}" };
    }
    await stub.set(request, options: CallOptions(metadata: metadata));
  }

}