From f1f6ed5f80a176bd2a70b6d1b409207706d4f68c Mon Sep 17 00:00:00 2001 From: Richard Bowman Date: Thu, 30 Nov 2023 22:51:10 +0000 Subject: [PATCH] Provide centralised readproperty, writeproperty, and action URLs --- webapp/src/main.js | 32 +++++++++++++++++------ webapp/src/wot-client.js | 55 ++++++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/webapp/src/main.js b/webapp/src/main.js index acde7f1d..c1aaaf5a 100644 --- a/webapp/src/main.js +++ b/webapp/src/main.js @@ -34,15 +34,31 @@ Vue.config.productionTip = false; Vue.mixin({ methods: { - async getThingDescription(thing) { - // Get the thing description for the given thing - let origin = this.$store.state.origin; - let uri = `${origin}/${thing}/`; - // We cache TDs in the store, and fetch only if needed. - if (!(uri in store.state.wot.thingDescriptions)) { - await store.dispatch("wot/fetchThingDescription", uri); + thingDescription(thing) { + return this.$store.getters["wot/thingDescription"](thing); + }, + thingAvailable(thing) { + return this.$store.getters["wot/thingAvailable"](thing); + }, + async readThingProperty(thing, property) { + let url = this.$store.getters["wot/thingPropertyUrl"](thing, property, "readproperty"); + try { + let response = await axios.get(url); + return response.data; + } catch (error) { + this.modalError(error); } - return store.state.wot.thingDescriptions[uri]; + }, + async writeThingProperty(thing, property, value) { + let url = this.$store.getters["wot/thingPropertyUrl"](thing, property, "writeproperty"); + try { + let response = await axios.put(url, value); + } catch (error) { + this.modalError(error); + } + }, + thingActionUrl(thing, action) { + return this.$store.getters["wot/thingActionUrl"](thing, action); }, modalConfirm: function(modalText) { var context = this; diff --git a/webapp/src/wot-client.js b/webapp/src/wot-client.js index 036180ad..2a2a69a1 100644 --- a/webapp/src/wot-client.js +++ b/webapp/src/wot-client.js @@ -8,11 +8,11 @@ export const wotStoreModule = { helpers: null }), mutations: { - addThingDescription(state, { thingUri, thingDescription }) { - state.thingDescriptions[thingUri] = thingDescription; + addThingDescription(state, { thingName, thingDescription }) { + state.thingDescriptions[thingName] = thingDescription; }, - removeThingDescription(state, thingUri) { - delete state.thingDescriptions[thingUri]; + removeThingDescription(state, thingName) { + delete state.thingDescriptions[thingName]; }, removeAllThingDescriptions(state) { state.thingDescriptions = {}; @@ -22,16 +22,55 @@ export const wotStoreModule = { async start() { // Set up thing client - not currently used. }, - async fetchThingDescription({ commit }, uri) { + async fetchThingDescription({ commit }, {uri, name=null}) { // Fetch the thing description from the given URI and consume it // NB this should only be called once, or we'll duplicate effort. // Deduplication should be done elsewhere. let response = await axios.get(uri); let td = response.data; - commit("addThingDescription", { thingUri: uri, thingDescription: td }); - } + let thing_name = name | uri.replace(/\/$/, "").split("/").pop(); + commit("addThingDescription", { thingName: thing_name, thingDescription: td }); + }, + async fetchThingDescriptions({ commit }, uri) { + // Fetch thing descriptions from the given URI + let response = await axios.get(uri); + if (response.status != 200) throw "Could not retrieve thing descriptions"; + for (const k in response.data){ + let thing_name = k.replace(/\/$/, "").replace(/^\//, ""); + commit("addThingDescription", {thing_name: thing_name, thing_description: response.data[k]}); + } + }, }, - getters: {} + getters: { + thingDescription: state => thingName => { + return state.thingDescriptions[thingName]; + }, + thingAvailable: state => thingName => { + return thingName in state.thingDescriptions; + }, + thingFormUrl: state => (thing, affordanceType, affordance, op) => { + // Find the URL for a particular operation + let td = state.thingDescriptions[thing]; + if (!td) return null; + let affordances = td[affordanceType]; + return findForm(affordances[affordance], op); + }, + thingPropertyUrl: (_state, getters) => (thing, property, op) => { + // Find the URL for a particular property + return getters.thingFormUrl(thing, "properties", property, op); + }, + thingActionUrl: (_state, getters) => (thing, action, op) => { + // Find the URL for a particular action + return getters.thingFormUrl(thing, "actions", action, op); + }, + } }; +export function findForm(affordance, op){ + // Find the form in the affordance that matches the given operation type + let forms = affordance.forms; + let matchingForm = forms.find(f => f.op == op || f.op.includes(op)); + return matchingForm.href; +} + export default wotStoreModule;