summaryrefslogtreecommitdiffstats
path: root/src/js/kuksa.js
diff options
context:
space:
mode:
authorRoger Zanoni <rzanoni@igalia.com>2023-12-28 20:07:05 -0300
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2024-01-29 12:07:20 +0000
commitc323ab8fde212120d8d1914d453afeb55b3576e5 (patch)
tree2f3565da1e623d69297b00d2a5e1e2b261692810 /src/js/kuksa.js
parent5f1b6075982b872b5db4e2195e53d19529278d5c (diff)
Update HVAC app to use grpc-web instead of websockets
Adapt the HTML5 applications to use kuksa.val service Bug-AGL: SPEC-4599 Signed-off-by: Roger Zanoni <rzanoni@igalia.com> Change-Id: I3e36a6c08041db8fb59fd7f20497c1c156bbb2f7
Diffstat (limited to 'src/js/kuksa.js')
-rw-r--r--src/js/kuksa.js232
1 files changed, 169 insertions, 63 deletions
diff --git a/src/js/kuksa.js b/src/js/kuksa.js
index 9e9cc22..8542dcb 100644
--- a/src/js/kuksa.js
+++ b/src/js/kuksa.js
@@ -16,108 +16,214 @@
import { v4 as uuidv4 } from 'uuid';
-const DEFAULT_TARGET = "wss://localhost:8090";
+const DEFAULT_TARGET = "https://localhost:8888";
// TODO: use an application token when needed
// currently using https://github.com/eclipse/kuksa.val/blob/master/kuksa_certificates/jwt/super-admin.json.token
const TEST_TOKEN =
- 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJrdWtzYS52YWwiLCJpc3MiOiJFY2xpcHNlIEtVS1NBIERldiIsImFkbWluIjp0cnVlLCJtb2RpZnlUcmVlIjp0cnVlLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTc2NzIyNTU5OSwia3Vrc2EtdnNzIjp7IioiOiJydyJ9fQ.p2cnFGH16QoQ14l6ljPVKggFXZKmD-vrw8G6Vs6DvAokjsUG8FHh-F53cMsE-GDjyZH_1_CrlDCnbGlqjsFbgAylqA7IAJWp9_N6dL5p8DHZTwlZ4IV8L1CtCALs7XVqvcQKHCCzB63Y8PgVDCAqpQSRb79JPVD4pZwkBKpOknfEY5y9wfbswZiRKdgz7o61_oFnd-yywpse-23HD6v0htThVF1SuGL1PuvGJ8p334nt9bpkZO3gaTh1xVD_uJMwHzbuBCF33_f-I5QMZO6bVooXqGfe1zvl3nDrPEjq1aPulvtP8RgREYEqE6b2hB8jouTiC_WpE3qrdMw9sfWGFbm04qC-2Zjoa1yYSXoxmYd0SnliSYHAad9aXoEmFENezQV-of7sc-NX1-2nAXRAEhaqh0IRuJwB4_sG7SvQmnanwkz-sBYxKqkoFpOsZ6hblgPDOPYY2NAsZlYkjvAL2mpiInrsmY_GzGsfwPeAx31iozImX75rao8rm-XucAmCIkRlpBz6MYKCjQgyRz3UtZCJ2DYF4lKqTjphEAgclbYZ7KiCuTn9HualwtEmVzHHFneHMKl7KnRQk-9wjgiyQ5nlsVpCCblg6JKr9of4utuPO3cBvbjhB4_ueQ40cpWVOICcOLS7_w0i3pCq1ZKDEMrYDJfz87r2sU9kw1zeFQk';
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA';
var kuksa_context = {
authToken: TEST_TOKEN,
- socket: undefined,
+ client: undefined,
target: DEFAULT_TARGET,
+ subscribe_entries: [],
+ subscribe_stream: null,
+ locks: new Map()
}
var pathToHandler = null;
-function logReceivedMessage(data) {
- console.log('Received message:', data)
+function updateVehicleInfo(path, dp) {
+ if (!pathToHandler.has(path)) {
+ console.log('Handler not found for', path);
+ return;
+ }
+
+ var handler = pathToHandler.get(path);
+ handler.update(path, dp)
}
-function logConnectionStatus(status, event) {
- console.log('Connection status:', status);
+function send(action, values) {
}
-function kuksaws_onopen(event) {
- logConnectionStatus('Connected.', event);
-
- authorize();
- subscribe(PATHS.leftAirDistribution);
- subscribe(PATHS.leftFanSpeed);
- subscribe(PATHS.leftSeatWarmer);
- subscribe(PATHS.rightSeatWarmer);
- subscribe(PATHS.leftSeatTemperature);
- subscribe(PATHS.rightSeatTemperature);
- subscribe(PATHS.airConditioning);
- subscribe(PATHS.recirculation);
- subscribe(PATHS.frontDefroster);
- subscribe(PATHS.rearDefroster);
+function add_subscribe_entry(path) {
+ console.log('Adding subscribe entry for ' + path + '...')
+ var entry = new VAL.SubscribeEntry();
+ entry.setPath(path);
+ entry.setView(TYPES.View.VIEW_ALL);
+ entry.addFields(TYPES.Field.FIELD_PATH);
+ entry.addFields(TYPES.Field.FIELD_VALUE);
+ kuksa_context.subscribe_entries.push(entry);
}
-function kuksaws_onerror(event) {
- logConnectionStatus('Failed to connect:', event);
+function subscribe() {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var request = new VAL.SubscribeRequest();
+ for (var i in kuksa_context.subscribe_entries) {
+ var entry = kuksa_context.subscribe_entries[i];
+ entry.setView(TYPES.View.VIEW_CURRENT_VALUE);
+ request.addEntries(entry);
+ }
+
+ kuksa_context.subscribe_stream = kuksa_context.client.subscribe(request, metadata);
+
+ kuksa_context.subscribe_stream.on('data', function(response) {
+ var updates = response.getUpdatesList();
+ for (var i in updates) {
+ var update = updates[i];
+ var entry = update.getEntry();
+ var path = entry.getPath();
+ var dp = entry.getValue();
+
+ if (!(entry && path && dp)) {
+ continue;
+ }
+
+ lock(path);
+ updateVehicleInfo(path, dp);
+ unlock(path);
+ }
+ });
+
+ kuksa_context.subscribe_stream.on('error', function(error) {
+ console.log("Error code: " + error.code + " message: " + error.message);
+ // if an error happens here, the databroker will drop the subscriber, so
+ // we need to subscribe again
+ subscribe();
+ });
}
-function kuksaws_onmessage(event) {
- logReceivedMessage(event.data);
+// TODO: investigate why an empty response is always being returned on the
+// response
+export function get(path) {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ if (isLocked(path)) {
+ return;
+ }
- var jsonData = JSON.parse(event.data);
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var request = new VAL.GetRequest();
+ var entry = new VAL.EntryRequest();
+ entry.setPath(path);
+ entry.setView(TYPES.View.VIEW_ALL);
+ entry.addFields(TYPES.Field.FIELD_METADATA);
+ entry.addFields(TYPES.Field.FIELD_VALUE);
+ request.addEntries(entry);
+
+ kuksa_context.client.get(request, metadata, function(error, response) {
+ if (error) {
+ console.log("Get error, code: " + error.code);
+ return;
+ }
+ if (!response) {
+ return;
+ }
+ var entries = response.getEntriesList();
+ for (var i in entries) {
+ var entry = entries[i];
+ var path = entry.getPath();
+ var dp = entry.getValue();
+
+ if (!(entry && path && dp)) {
+ continue;
+ }
+ lock(path);
+ updateVehicleInfo(path, dp);
+ unlock(path);
+ }
+ });
+}
- if (jsonData.action == 'get' ||
- jsonData.action =='subscription') {
- updateVehicleInfo(jsonData);
+export function set(path, dp) {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ if (isLocked(path)) {
+ return;
}
+ lock(path);
+
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var entry = new TYPES.DataEntry();
+ entry.setPath(path);
+ entry.setValue(dp);
+
+ var update = new VAL.EntryUpdate();
+ update.addFields(TYPES.Field.FIELD_PATH);
+ update.addFields(TYPES.Field.FIELD_VALUE);
+ update.setEntry(entry);
+
+ var request = new VAL.SetRequest();
+ request.addUpdates(update);
+
+ kuksa_context.client.set(request, metadata, function(error, response) {
+ // don't unlock updates here, only when we get a value from
+ // the subscription updates
+ });
}
-function updateVehicleInfo(message) {
- var value = message.data.dp.value;
- var path = message.data.path;
+export function init(handlers) {
+ console.log("Initializing kuka-val module...");
+ pathToHandler = new Map(handlers);
+ pathToHandler.forEach(function(handler, path) {
+ add_subscribe_entry(path);
+ });
- if (!pathToHandler.has(path)) {
- console.log('Handler not found for', path);
- return;
+ if (kuksa_context.client == undefined) {
+ console.log("Creating kuksa-val client...");
+ kuksa_context.client = new VAL_WEB.VALClient(kuksa_context.target);
+
+ subscribe();
}
+}
- var handler = pathToHandler.get(path);
- handler.update(path, value)
+export function setInt32(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setInt32(value);
+ set(path, dp);
}
-function send(action, values) {
- var uuid = uuidv4();
- var data = Object.assign({
- action: action,
- tokens: kuksa_context.authToken,
- requestId: uuid,
- }, values);
- var message = JSON.stringify(data);
- console.log('Sent message:', message);
- kuksa_context.socket.send(message);
- return uuid;
+export function setUInt32(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setUint32(value);
+ set(path, dp);
}
-function subscribe(path) {
- return send('subscribe', { path: path });
+export function setBool(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setBool(value);
+ set(path, dp);
}
-function authorize() {
- return send('authorize');
+export function setString(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setString(value);
+ set(path, dp);
}
-export function get(path) {
- return send('get', { path: path });
+export function lock(path) {
+ kuksa_context.locks[path] = true;
}
-export function set(path, value) {
- return send('set', { path: path, value: value });
+export function unlock(path) {
+ kuksa_context.locks[path] = false;
}
-export function init(handlers) {
- pathToHandler = new Map(handlers);
- if (kuksa_context.socket == undefined) {
- kuksa_context.socket = new WebSocket(kuksa_context.target);
- kuksa_context.socket.onopen = kuksaws_onopen;
- kuksa_context.socket.onerror = kuksaws_onerror;
- kuksa_context.socket.onmessage = kuksaws_onmessage;
+export function isLocked(path) {
+ if (!kuksa_context.locks.has(path)) {
+ kuksa_context.locks[path] = false;
}
+ return kuksa_context.locks[path];
}