UNPKG

iobroker.omron-fins

Version:
325 lines (275 loc) 11.1 kB
"use strict"; /* * Created with @iobroker/create-adapter v1.29.1 */ // The adapter-core module gives you access to the core ioBroker functions // you need to create an adapter const utils = require("@iobroker/adapter-core"); const fins = require("omron-fins/lib/index.js"); const thisval = []; const thisName = []; const all = []; let time; let time2; let plc_poll; let plc_ip; let plc_port; let client; let devicesin; // Load your modules here, e.g.: // const fs = require("fs"); class OmronFins extends utils.Adapter { /** * @param {Partial<utils.AdapterOptions>} [options={}] */ constructor(options) { super({ ...options, name: "omron-fins", }); this.on("ready", this.onReady.bind(this)); this.on("stateChange", this.onStateChange.bind(this)); // this.on("objectChange", this.onObjectChange.bind(this)); // this.on("message", this.onMessage.bind(this)); this.on("unload", this.onUnload.bind(this)); } /** * Is called when databases are connected and adapter received configuration. */ async onReady() { // Initialize your adapter here // Reset the connection indicator during startup this.setState("info.connection", false, true); // The adapters config (in the instance object everything under the attribute "native") is accessible via // this.config: //this.log.debug("Value1: " + JSON.stringify(this.config.devices[0].value)); //this.log.debug("config.devices: " + JSON.stringify(this.config.devices)); if (this.config.devices !== "") { devicesin=true; plc_poll = this.config.plc_poll; //werte von index als Daten übergeben plc_ip = this.config.plc_ip; plc_port = Number(this.config.plc_port); client = new fins.FinsClient(plc_port, plc_ip); for (const device in this.config.devices) { //for schleife für Array Bilden der werte try { thisval.push(this.config.devices[device].value); thisName.push(this.config.devices[device].name); all.push( this.stateValues = { name: nameFilter(this.config.devices[device].name), variable: this.config.devices[device].value } ); } catch (error) { this.log.info("Error Arry "); } } } else { devicesin=false; } //this.log.debug("thisval wert: " + JSON.stringify(thisval)); //log ob Array Bilden geklappt hat //this.log.debug("thisval Name: " + JSON.stringify(thisName)); //this.log.debug("ALL: " + JSON.stringify(all)); /*const client = new fins.FinsClient(plc_port,plc_ip); //Client deglariern const _this = this; client.on("reply",async ()=> { //info.connection Abfrage ob es verbindung steht await _this.setStateAsync("info.connection", true); clearTimeout(time); time=setTimeout(async function(){ await _this.setStateAsync("info.connection", false); }, plc_poll + 2000); //console.log("Reply from: ", msg.remotehost); }); client.readMultiple(...thisval);*/ /* For every state in the system there has to be also an object of type state Here a simple template for a boolean variable named "testVariable" Because every adapter instance uses its own unique namespace variable names can't collide with other adapters variables */ for (const datapoint in this.config.devices) { let data; switch (this.config.devices[datapoint].type) { //Von Index abrufen was für ein Datentyp und Umwandeln case "BOOL": data = "boolean"; break; case "CHANNEL": data = "number"; break; case "NUMBER": data = "number"; break; case "COUNTER": data = "number"; break; case "TIMER": data = "number"; break; default: // code block } //objekte Bilden // @ts-ignore await this.setObjectNotExistsAsync(nameFilter(this.config.devices[datapoint].name), { type: "state", common: { name: this.config.devices[datapoint].name, type: data, role: "state", read: true, write: true, }, native: { adress: this.config.devices[datapoint].value, }, }); this.subscribeStates(nameFilter(this.config.devices[datapoint].name)); } // In order to get state updates, you need to subscribe to them. The following line adds a subscription for our variable we have created above. //this.subscribeStates("testVariable"); // You can also add a subscription for multiple states. The following line watches all states starting with "lights." // this.subscribeStates("lights.*"); // Or, if you really must, you can also watch all states. Don't do this if you don't need to. Otherwise this will cause a lot of unnecessary load on the system: // this.subscribeStates("*"); /* setState examples you will notice that each setState will cause the stateChange event to fire (because of above subscribeStates cmd) */ // the variable testVariable is set to true as command (ack=false) //await this.setStateAsync("testVariable", true); // same thing, but the value is flagged "ack" // ack should be always set to true if the value is received from or acknowledged from the target system //await this.setStateAsync("testVariable", { val: true, ack: true }); // same thing, but the state is deleted after 30s (getState will return null afterwards) //await this.setStateAsync("testVariable", { val: true, ack: true, expire: 30 }); // examples for the checkPassword/checkGroup functions //let result = await this.checkPasswordAsync("admin", "iobroker"); //this.log.info("check user admin pw iobroker: " + result); //result = await this.checkGroupAsync("admin", "admin"); //this.log.info("check group user admin group admin: " + result); if (devicesin === true) { this.readStates(); } } readStates() { //Abrufen der der Werte von der Steuerung mit Zeit interval const _this = this; //Abrufen der Werte //const client = new fins.FinsClient(plc_port,plc_ip); //this.log.debug("port: " + JSON.stringify(plc_port)); //this.log.debug("IP: " + JSON.stringify(plc_ip)); client.once("reply", function (msg) { //console.log("Reply from: ", msg.remotehost); //_this.log.debug("Replying to issued command of: "+ msg.command); //_this.log.debug("Response code of: " + msg.code); //_this.log.debug("Data returned: "+ msg.values); for (const x in msg.values) { //_this.log.info(`${thisName[x]}: ${Boolean(msg.values[x])}`); //_this.log.debug(`${thisName[x]}: ${msg.values[x]}`); //_this.setStateAsync(nameFilter(thisName[x]), { val: Boolean(msg.values[x]), ack: true }); _this.setStateAsync(nameFilter(thisName[x]), { val: msg.values[x], ack: true }); } _this.setStateAsync("info.connection", true); clearTimeout(time); time = setTimeout(() => { _this.setStateAsync("info.connection", false); }, Number(plc_poll) + 4000); }); client.readMultiple(...thisval); //this.log.info("Time wert: " + time); time2 = setTimeout( function () { _this.readStates(); //Am ende der funktion erneut aufrufen }, plc_poll); } /** * Is called when adapter shuts down - callback has to be called under any circumstances! * @param {() => void} callback */ onUnload(callback) { //Beim Beenden des Adapters noch Timeouts löschen try { // Here you must clear all timeouts or intervals that may still be active clearTimeout(time); clearTimeout(time2); // ... // clearInterval(interval1); callback(); } catch (e) { callback(); } } // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor. // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`. // /** // * Is called if a subscribed object changes // * @param {string} id // * @param {ioBroker.Object | null | undefined} obj // */ // onObjectChange(id, obj) { // if (obj) { // // The object was changed // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`); // } else { // // The object was deleted // this.log.info(`object ${id} deleted`); // } // } /** * Is called if a subscribed state changes * @param {string} id * @param {ioBroker.State | null | undefined} state */ onStateChange(id, state) { if (state && state.ack === false) { let aktuell; // The state was changed and is not (yet) acknowledged this.log.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`); //ALL: [{"name":"Test","variable":"CB0:00"},{"name":"Test2","variable":"CB0:01"},{"name":"test3","variable":"W31:00"},{"name":"Testd","variable":"D12"}] const idarry = id.split("."); aktuell = all.find(x => x.name === idarry[idarry.length - 1]).variable; //this.log.debug(`idarry ${idarry} `); //this.log.debug(`Variable ${aktuell} `); //this.log.debug(`Wert ${state.val} `); client.write(aktuell, Number(state.val)); } else { //this.log.info(`state ${id} deleted`); // Send command 1 - level nesting } } // If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor. // /** // * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ... // * Using this method requires "common.message" property to be set to true in io-package.json // * @param {ioBroker.Message} obj // */ // onMessage(obj) { // if (typeof obj === "object" && obj.message) { // if (obj.command === "send") { // // e.g. send email or pushover or whatever // this.log.info("send command"); // // Send response in callback if required // if (obj.callback) this.sendTo(obj.from, obj.command, "Message received", obj.callback); // } // } // } } function nameFilter(name) { const signs = [String.fromCharCode(46), String.fromCharCode(44), String.fromCharCode(92), String.fromCharCode(47), String.fromCharCode(91), String.fromCharCode(93), String.fromCharCode(123), String.fromCharCode(125), String.fromCharCode(32), String.fromCharCode(129), String.fromCharCode(154), String.fromCharCode(132), String.fromCharCode(142), String.fromCharCode(148), String.fromCharCode(153)]; //46=. 44=, 92=\ 47=/ 91=[ 93=] 123={ 125=} 32=Space 129=ü 154=Ü 132=ä 142=Ä 148=ö 153=Ö signs.forEach((item, index) => { const count = name.split(item).length - 1; for (let i = 0; i < count; i++) { name = name.replace(item, ""); } const result = name.search(/$/); if (result !== -1) { name = name.replace(/_$/, ""); } }); return name; } // @ts-ignore parent is a valid property on module if (module.parent) { // Export the constructor in compact mode /** * @param {Partial<utils.AdapterOptions>} [options={}] */ module.exports = (options) => new OmronFins(options); } else { // otherwise start the instance directly new OmronFins(); }