NEWS
eigene Visualisierung mit vue.js per socket
-
Hallo ioBrokers,
ich versuche gerade meine ioBroker Instanz mit einer Vue.js App zu verbinden.
Ein einfacher Test per HTML (https://github.com/ioBroker/ioBroker.socketio/tree/master/example) hat mit meiner Instanz funktioniert.
2021-04-09T11:12:20.701Z Connected => authenticate conn.js:317 2021-04-09T11:12:20.840Z Authenticated: true index.html:26 connected ============================== index.html:32 Received 4360 states.
Die Verbindung wird auch im socket.io Objekt im ioBroker gelistet:
Aber nun stehe ich vor dem Problem das Ganze in Vue einzubinden.
Die conn.js von Bluefox einfach in Vue importieren und dort wie in der index.html aufzurufen klappt leider nicht:Test.vue:
<template> ... </template> <script> import { servConn } from '../js/conn.js'; servConn.namespace = 'vue.0'; servConn._useStorage = false; var states = []; servConn.init({ ... }); <style> ... </style>
Die onConnChange Funktion wird nicht durch die init Funktion getriggert:
onConnChange: function (isConnected) { if (isConnected) { console.log('connected =============================='); servConn.getStates(function (err, _states) { var count = 0; for (var id in _states) { count++; } console.log('Received ' + count + ' states.'); states = _states; }); servConn.subscribe('0_userdata.0.Entwicklung.Test.sampleState'); servConn.subscribe('alias.0.sensor.temperatur.garten'); } else { console.log('disconnected =============================='); } }, console.log(servConn);
Die Ausgabe aus Zeile 20 oben zeigt
console.log(servConn);
zeigt
das keine Verbindung hergestellt wurde (alles null- oder Initialwerte), der Namespace aber korrekt auf "vue.0" gesetzt wurde.
Hoffentlich hat jemand einen Tipp, wo das Problem liegt.
Gruß
Darth -
@darth2010 Ich kenne vue nicht, habe aber dasselbe mit Angular 10 gemacht. Allerdings habe ich nicht sie Datei von Bluefox verwendet sondern einfach selber einen wrapper für socket.io geschrieben. Ausser getState und subscribe habe ich bis heute nichts anderes benötigt.
Leider hat dein Code oben so viele Lücken, dass ich nicht sagen kann, was das Problem ist.
Vielleicht kannst du ja mal den ganzen Code hier oder sonst wo posten.
Ansonsten versuche es mit einem Tutorial für vue + socket.io und schreibe dann deinem eigenen Code für getState und subscribe.
-
Ja das ist natürlich eine Lösung .
Mir geht auch primar nur darum die Änderungen in den Datenpunkten mitzubekommen ohne den Server alle 5 sek mit Simple API gets zu fluten ;-).
Ich dachte mit der schon fertigen js lib könnte ich mir das sparen
Dann werde ich mir das Tutorial für socket.io ansehen.
-
@darth2010 Der Beitrag ist zwar schon etwas älter, aber vielleicht steht die Lösung ja noch aus. Ich habe mich auch mit dem Thema Vue.js auseinander gesetzt und die Verbindung zwischen ioBroker und Vue.js via socket.io zum Laufen bekommen. Meine Vue.js Visualisierung ist aktuell noch im Versuchs- und Aufbaustadium...
Zunächst habe ich eine JS Datei mit dem Namen "ioBroker.js" erstellt in der ich die conn.js initialisiere.
import servConn from "@/services/conn.js"; import store from "@/store/index.js"; export default { connect: function(baseURL) { servConn.namespace = "vis.0"; servConn._useStorage = false; servConn.init( { name: "vis.0", // optional - default 'vis.0' connLink: baseURL, // optional URL of the socket.io adapter socketSession: "" // optional - used by authentication }, { onConnChange: function(isConnected) { if (isConnected) { console.log("connected"); servConn.getStates(function(err, _states) { if (!err) { store.dispatch("ioBrokerInit", _states); console.log("ioBroker Initalisierung erfolgreich!"); } else { console.log("ioBroker Initalisierung fehlgeschlagen!"); } }); } else { console.log("disconnected"); } }, onUpdate: function(id, state) { setTimeout(function() { var ioBrokerID = ""; var ioBrokerState = {}; ioBrokerID = id; ioBrokerState = state; store.dispatch("ioBrokerUpdate", { ioBrokerID, ioBrokerState }); }, 0); } } ); }, setState: function(id, val) { servConn.setState(id, val); } };
Bei der Initialisierung werden zunächst alle Objekte aus ioBroker als State im Store (vuex) angelegt (onConnChange). Im anschließenden Verlauf werden die States dann immer bei Änderung aktualisiert (onUpdate).
Die Initialisierung an sich stoße ich in der app.vue an:
<script> import ioBroker from "@/services/ioBroker.js"; const baseURL = "http://192.168.xxx.yyy:8084"; export default { data() { return { }; }, methods: { ioBrokerConnect: function() { this.$loadScript(baseURL + "/socket.io/socket.io.js") .then(() => { console.log("Verbunden"); ioBroker.connect(baseURL); }) .catch(() => { console.log("Nicht Verbunden"); }); } }, created() { this.ioBrokerConnect(); }, beforeDestroy() { this.$unloadScript(this.baseURL + "/socket.io/socket.io.js"); } }; </script>
Um die Verbindung herzustellen habe ich das "LoadScript-Plugin" installiert.
Hier noch mein Store:
import Vue from "vue"; import Vuex from "vuex"; // modules import * as homematic from "./modules/homematic.js"; //import ioBroker from "@/services/ioBroker.js"; Vue.use(Vuex); export default new Vuex.Store({ // ------------------------------------------------------------------------------------------------------ // MODULES // ------------------------------------------------------------------------------------------------------ modules: { homematic }, // ------------------------------------------------------------------------------------------------------ // STATE // ------------------------------------------------------------------------------------------------------ state: { ioBroker: { states: [], Heizung: { out: { PumpeEin: false, VentilAuf: false, VentilZu: false } }, config: { isDataFetched: false } } }, // ------------------------------------------------------------------------------------------------------ // ACTIONS // ------------------------------------------------------------------------------------------------------ actions: { // States von ioBroker im Store aktualisieren ioBrokerUpdate({ commit }, { ioBrokerID, ioBrokerState }) { commit("IOBROKER_UPDATE", { ioBrokerID, ioBrokerState }); commit("IOBROKER_MOD"); }, // Beim Laden alle States einmal einlesen ioBrokerInit({ commit }, ioBrokerStates) { commit("IOBROKER_INIT", ioBrokerStates); commit("IOBROKER_MOD"); }, // States an ioBroker senden ioBrokerSetState({ commit }, { ioBrokerID, ioBrokerState }) { commit("IOBROKER_SETSTATE", { ioBrokerID, ioBrokerState }); } }, // ------------------------------------------------------------------------------------------------------ // MUTATIONS // ------------------------------------------------------------------------------------------------------ mutations: { // States von ioBroker im Store aktualisieren IOBROKER_UPDATE(state, { ioBrokerID, ioBrokerState }) { state.ioBroker.states[ioBrokerID] = ioBrokerState; }, // States von ioBroker im Store aktualisieren IOBROKER_INIT(state, ioBrokerStates) { state.ioBroker.states = ioBrokerStates; state.ioBroker.config.isDataFetched = true; }, // Spezifische ioBroker State-Modifikationen IOBROKER_MOD(state) { var TempState = state.ioBroker.states["modbus.0.inputRegisters.3998_Heizung_Ausgaenge"]; state.ioBroker.Heizung.out.VentilAuf = (TempState.val & 1) == 1; state.ioBroker.Heizung.out.VentilZu = (TempState.val & 2) == 2; state.ioBroker.Heizung.out.PumpeEin = (TempState.val & 64) == 64; } }, // ------------------------------------------------------------------------------------------------------ // GETTERS // ------------------------------------------------------------------------------------------------------ getters: { GETioBroker: state => ioBrokerID => { return state.ioBroker.states[ioBrokerID]; }, HomematicDevice: state => HMdevice => { for (var i = 0; i <= state.homematic.devices.length; i++) { if (state.homematic.devices[i].name == HMdevice) { return state.homematic.devices[i]; } } } } });
Meine conn.js Datei. Diese musste auch noch etwas angepasst werden.
Ich hoffe die Beschreibung hilft etwas beim Anbinden deiner Vue.js Instanz. Bei mir läuft das ganze bisher ohne Probleme. Leider bin ich kein Profi und habe mir das ganze per Selbststudium versucht beizubringen. Bitte geht bei Fehlern nicht zu hart mit mir ins Gericht
Gruß Florian
-
@bombel Sorry, dass ich das hier nie geschrieben habe, aber es gibt inzwischen eine offizielle Lösung dafür:
https://www.npmjs.com/package/@iobroker/socket-clientDiese npm Library kannst du einfach bei dir einbinden und hast mit
Connection
eine Klasse, die du konfigurieren und dann benutzen kannst. Einfacher geht es kaum noch.Falls du deine Vuex Integration auch als npm Library zur Verfügung stellen würdest, wäre sicherlich allen Vue(x) Programmierern geholfen.
-
@bombel ich hole diesen Thread mal aus der Versenkung. Mich würde mal interessieren, ob jemand eine Anbindung mit VueJS 3 und Vuex umgesetzt hat. Ich bekomme es zwar hin, dass meine Aktualisierungen im Store landen aber die Initialisierung klappt nicht. Hat da wer einen Ansatz, wie die onConnChange aussehen muss und wo ich sie aufrufen soll? Hab's bisher bei beforeMount() eingebunden. Aber irgendwie gehts nicht ...
Danke für eure Hilfe.
Peter