From 981680cd5342cd29537a764747ef4bffce24bde6 Mon Sep 17 00:00:00 2001 From: Wiebe Date: Mon, 5 Sep 2016 01:31:32 +0200 Subject: [PATCH 1/9] Added ethernet driver - Receiving works with some minor bugs. - Sending not working yet. --- MySensors-config-schema.coffee | 6 +- MySensors.coffee | 490 ++++++++++----------------------- ethernet.coffee | 45 +++ 3 files changed, 192 insertions(+), 349 deletions(-) create mode 100755 ethernet.coffee diff --git a/MySensors-config-schema.coffee b/MySensors-config-schema.coffee index 06af6bb..639c01d 100644 --- a/MySensors-config-schema.coffee +++ b/MySensors-config-schema.coffee @@ -12,7 +12,7 @@ module.exports = { driver: description: "The diver to connect to the PiGateway" type: "string" - enum: ["serialport"] + enum: ["serialport", "ethernet"] default: "serialport" driverOptions: description: "Options for the driver" @@ -20,6 +20,8 @@ module.exports = { default: { "serialDevice": '/dev/ttyUSB0', #"/dev/ttyUSB0", "baudrate": 115200 + "host": "192.168.1.100" + "port": 5003 } protocols: description: "MySensors protrocol version" @@ -33,4 +35,4 @@ module.exports = { description: "Mysensors starting node id" type: "number" default: 1 -} +} \ No newline at end of file diff --git a/MySensors.coffee b/MySensors.coffee index 6923954..c5148af 100644 --- a/MySensors.coffee +++ b/MySensors.coffee @@ -161,12 +161,15 @@ module.exports = (env) -> constructor: (framework,config) -> @config = config @framework = framework - assert @config.driver in ["serialport", "gpio"] + assert @config.driver in ["serialport", "gpio","ethernet"] # setup a new driver switch @config.driver when "serialport" SerialPortDriver = require './serialport' @driver = new SerialPortDriver(@config.driverOptions) + when "ethernet" + EthernetDriver = require './ethernet' + @driver = new EthernetDriver(@config.driverOptions) @driver.on('error', (error) => @emit('error', error) ) @driver.on('reconnect', (error) => @emit('reconnect', error) ) @@ -195,7 +198,6 @@ module.exports = (env) -> # decoding message datas = data.toString().split(";") sender = parseInt datas[0] - sensor = parseInt datas[1] command = parseInt datas[2] ack = parseInt datas[3] @@ -285,14 +287,14 @@ module.exports = (env) -> nextnodeid = @config.startingNodeId if nextnodeid is null nextnodeid = 1 - else + else nextnodeid +=1 while newid is false newid = not @framework.deviceManager.devicesConfig.some (device, iterator) => device.nodeid is nextnodeid if newid is false nextnodeid +=1 - + if newid is true and nextnodeid < 255 datas = { @@ -424,7 +426,7 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Motion Sensor #{nodeid}.#{sensorid}", config ) - # Smoke sensor found + # Smoke sensor found if sensortype is S_SMOKE config = { class: 'MySensorsPIR', @@ -434,8 +436,8 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Smoke Sensor #{nodeid}.#{sensorid}", config ) - - # Moisture sensor found + + # Moisture sensor found if sensortype is S_MOISTURE config = { class: 'MySensorsPIR', @@ -445,7 +447,7 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Moisture Sensor #{nodeid}.#{sensorid}", config ) - + # Leak sensor found if sensortype is S_WATER_LEAK config = { @@ -522,7 +524,7 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Water Sensor #{nodeid}.#{sensorid}", config ) - + # pH sensor found if sensortype is S_WATER_QUALITY config = { @@ -590,7 +592,6 @@ module.exports = (env) -> MySensorsSwitch MySensorsDimmer MySensorsPulseMeter - MySensorsEnergyMeter MySensorsWaterMeter MySensorsPH MySensorsButton @@ -632,14 +633,14 @@ module.exports = (env) -> @attributes = {} @attributes.temperature = { - description: "the measured temperature" + description: "the messured temperature" type: "number" unit: '°C' acronym: 'T' } @attributes.humidity = { - description: "the measured humidity" + description: "the messured humidity" type: "number" unit: '%' acronym: 'RH' @@ -664,8 +665,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -675,7 +676,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid for sensorid in @config.sensorid if result.sensor is sensorid @@ -690,13 +691,9 @@ module.exports = (env) -> @_humidity = Math.round(parseFloat(result.value)) @emit "humidity", @_humidity ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getTemperature: -> Promise.resolve @_temperatue @@ -716,7 +713,7 @@ module.exports = (env) -> @attributes = {} @attributes.temperature = { - description: "the measured temperature" + description: "the messured temperature" type: "number" unit: '°C' acronym: 'T' @@ -741,8 +738,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -752,20 +749,16 @@ module.exports = (env) -> @emit "battery", @_battery ) - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.type is V_TEMP and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorDST ", result @_temperatue = parseFloat(result.value) @emit "temperature", @_temperatue ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getTemperature: -> Promise.resolve @_temperatue @@ -786,14 +779,14 @@ module.exports = (env) -> @attributes = {} @attributes.temperature = { - description: "the measured temperature" + description: "the messured temperature" type: "number" unit: '°C' acronym: 'T' } @attributes.pressure = { - description: "the measured pressure" + description: "the messured pressure" type: "number" unit: 'hPa' acronym: 'mbar' @@ -824,8 +817,8 @@ module.exports = (env) -> } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -835,7 +828,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid for sensorid in @config.sensorid if result.sensor is sensorid @@ -855,13 +848,9 @@ module.exports = (env) -> @emit "forecast", @_forecast ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getTemperature: -> Promise.resolve @_temperatue @@ -888,7 +877,7 @@ module.exports = (env) -> @attributes = {} @attributes.watt = { - description: "the measured Wattage" + description: "the messured Wattage" type: "number" unit: 'W' acronym: 'Watt' @@ -902,12 +891,23 @@ module.exports = (env) -> } @attributes.kWh = { - description: "the measured kWh" + description: "the messured kWh" type: "number" unit: 'kWh' acronym: 'kWh' } + calculatekwh = ( => + @_avgkw = @_totalkw / @_tickcount + @_kwh = (@_avgkw * (@_tickcount * 10)) / 3600 + @_tickcount = 0 + @_totalkw = 0 + if mySensors.config.debug + env.logger.debug "calculatekwh..", @kwh + @emit "kWh", @_kwh + ) + + @attributes.battery = { description: "Display the battery level of sensor" type: "number" @@ -928,13 +928,13 @@ module.exports = (env) -> } @attributes.ampere = { - description: "the measured Ampere" + description: "the messured Ampere" type: "number", unit: "A" acronym: 'Ampere' } - @rfRequestEventHandler = ( (result) => + @board.on("rfRequest", (result) => if result.sender is @config.nodeid datas = { @@ -947,8 +947,8 @@ module.exports = (env) -> @board._rfWrite(datas) ) - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -958,7 +958,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsPulseMeter", result @@ -979,16 +979,11 @@ module.exports = (env) -> env.logger.debug "<- MySensorsPulseMeter V_KWH" @_kwh = parseFloat(result.value) @emit "kWh", @_kwh + ) - @board.on("rfRequest", @rfRequestEventHandler) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfRequest", @rfRequestEventHandler - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getWatt: -> Promise.resolve @_watt @@ -997,155 +992,6 @@ module.exports = (env) -> getBattery: -> Promise.resolve @_battery getAmpere: -> Promise.resolve @_ampere - class MySensorsEnergyMeter extends env.devices.Device - - constructor: (@config,lastState, @board) -> - @id = @config.id - @name = @config.name - if mySensors.config.debug - env.logger.debug "MySensorsEnergyMeter ", @id, @name - - @kWhlastTime = {} - @attributes = {} - @_watt = {} - for sensorid in @config.sensorid - do(sensorid) => - attr = "Phase_" + sensorid - - @attributes[attr] = { - description: "this measure wattage" - type: "number" - displaySparkline: false - unit: "W" - acronym: attr - } - @kWhlastTime[sensorid] = Date.now() - getter = ( => Promise.resolve @_watt[sensorid] ) - @_createGetter( attr, getter) - @_watt[sensorid] = lastState?[attr]?.value - - @_kwh = lastState?.kWh?.value or 0 - @_totalPower = lastState?.totalPower?.value or 0 - @_rate = lastState?.rate?.value or 0 - @_battery = lastState?.battery?.value - - @attributes.totalPower = { - description: "Total Watt" - type: "number" - unit: 'W' - displaySparkline: false - acronym: 'Total' - } - - @attributes.kWh = { - description: "this measure kWh" - type: "number" - unit: 'kWh' - acronym: 'kWh' - } - - @attributes.rate = { - description: "Electricity Cost" - type: "number" - unit: "" - displaySparkline: false - acronym: @config.currency - } - - @attributes.battery = { - description: "Display the battery level of sensor" - type: "number" - displaySparkline: false - unit: "%" - icon: - noText: true - mapping: { - 'icon-battery-empty': 0 - 'icon-battery-fuel-1': [0, 20] - 'icon-battery-fuel-2': [20, 40] - 'icon-battery-fuel-3': [40, 60] - 'icon-battery-fuel-4': [60, 80] - 'icon-battery-fuel-5': [80, 100] - 'icon-battery-filled': 100 - } - hidden: !@config.batterySensor - } - - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid - unless result.value is null or undefined - # When the battery is to low, battery percentages higher then 100 could be send - if result.value > 100 - result.value = 0 - - @_battery = parseInt(result.value) - @emit "battery", @_battery - ) - - @rfValueEventHandler = ( (result) => - if result.sender is @config.nodeid - if result.sensor in @config.sensorid and result.type is V_WATT - if mySensors.config.debug - env.logger.debug "<- MySensorsEnergyMeter", result - @calculatePower(result) - ) - - @_resetWattage = setInterval(( => - env.logger.debug "<- MySensorsEnergyMeter setinterval" - for sensorid in @config.sensorid - if (new Date()) - @kWhlastTime[sensorid] > @config.resetTime - result = {} - result = - { - sender: @config.nodeid, - sensor: sensorid, - type : V_WATT, - value : 0 - } - @calculatePower(result) - ), 30000) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) - super() - - calculatePower:(result) -> - currdate = new Date() - - if currdate > new Date(currdate.getFullYear(), currdate.getMonth() + 1, 1) - @_kwh = 0 - @_rate = 0 - - diffTime = currdate - @kWhlastTime[result.sensor] - - @_watt[result.sensor] = Math.floor(parseInt(result.value)) - calibratedWattage = (@_watt[result.sensor] * (100 - @config.correction)/100) - intKwh = ((calibratedWattage / 1000 ) * ( diffTime ) / 3600000) - @_totalPower = 0 - for sensorid in @config.sensorid - @_totalPower += @_watt[sensorid] - - @_kwh = @_kwh + intKwh - @kWhlastTime[result.sensor] = currdate - @_rate = @_rate + intKwh * @config.rate - if mySensors.config.debug - env.logger.debug "<- MySensorsEnergyMeter V_KWH", @_kwh , @_rate - - @emit "Phase_" + result.sensor, @_watt[result.sensor] - @emit "totalPower" , @_totalPower - @emit "kWh", @_kwh - @emit "rate", @_rate - - destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler - clearInterval(@_resetWattage) - super() - - getKWh: -> Promise.resolve @_kwh - getRate: -> Promise.resolve @_rate - getTotalPower: -> Promise.resolve @_totalPower - getBattery: -> Promise.resolve @_battery - class MySensorsWaterMeter extends env.devices.Device constructor: (@config,lastState, @board) -> @@ -1163,7 +1009,7 @@ module.exports = (env) -> @attributes = {} @attributes.flow = { - description: "the measured water in liter per minute" + description: "the meassured water in liter per minute" type: "number" unit: 'l/min' acronym: 'Flow' @@ -1177,7 +1023,7 @@ module.exports = (env) -> } @attributes.volume = { - description: "the measured water in m3" + description: "the meassured water in m3" type: "number" unit: 'm3' acronym: 'Total' @@ -1202,7 +1048,7 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfRequestEventHandler = ( (result) => + @board.on("rfRequest", (result) => if result.sender is @config.nodeid datas = { @@ -1215,8 +1061,8 @@ module.exports = (env) -> @board._rfWrite(datas) ) - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1226,7 +1072,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsWaterMeter", result @@ -1247,22 +1093,16 @@ module.exports = (env) -> @emit "volume", @_volume ) - @board.on("rfRequest", @rfRequestEventHandler) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfRequest", @rfRequestEventHandler - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getFlow: -> Promise.resolve @_flow getPulsecount: -> Promise.resolve @_pulsecount getVolume: -> Promise.resolve @_volume getBattery: -> Promise.resolve @_battery - + class MySensorsPH extends env.devices.Device constructor: (@config,lastState, @board) -> @@ -1294,8 +1134,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1306,12 +1146,12 @@ module.exports = (env) -> ) @attributes.ph = { - description: "the measured pH value" + description: "the meassured pH value" type: "number" unit: 'pH' } - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsPH", result @@ -1319,13 +1159,9 @@ module.exports = (env) -> @_ph = parseFloat(result.value) @emit "ph", @_ph ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getPh: -> Promise.resolve @_ph @@ -1338,10 +1174,10 @@ module.exports = (env) -> @name = @config.name @_presence = lastState?.presence?.value or false @_battery = lastState?.battery?.value - + if mySensors.config.debug env.logger.debug "MySensorsPIR ", @id, @name, @_presence - + @addAttribute('battery', { description: "Battery", type: "number" @@ -1361,9 +1197,9 @@ module.exports = (env) -> hidden: !@config.batterySensor }) @['battery'] = ()-> Promise.resolve(@_battery) - - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1372,12 +1208,12 @@ module.exports = (env) -> @_battery = parseInt(result.value) @emit "battery", @_battery ) - + resetPresence = ( => @_setPresence(no) ) - @rfValueEventHandler = ( (result) => + @board.on('rfValue', (result) => if result.sender is @config.nodeid and result.type is V_TRIPPED and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorPIR ", result @@ -1392,15 +1228,11 @@ module.exports = (env) -> @_setPresence(no) ), @config.resetTime) ) - - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) + super() - + destroy: -> clearTimeout(@_resetPresenceTimeout) - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getPresence: -> Promise.resolve @_presence @@ -1436,8 +1268,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1447,7 +1279,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @rfValueEventHandler = ( (result) => + @board.on('rfValue', (result) => if result.sender is @config.nodeid and result.type is ( V_TRIPPED or V_STATUS ) and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsButton ", result @@ -1456,13 +1288,9 @@ module.exports = (env) -> else @_setContact(no) ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getBattery: -> Promise.resolve @_battery @@ -1476,15 +1304,15 @@ module.exports = (env) -> if mySensors.config.debug env.logger.debug "MySensorsSwitch ", @id, @name, @_state - @rfValueEventHandler = ( (result) => + @board.on('rfValue', (result) => if result.sender is @config.nodeid and result.type is V_STATUS and result.sensor is @config.sensorid state = (if parseInt(result.value) is 1 then on else off) if mySensors.config.debug env.logger.debug "<- MySensorSwitch ", result @_setState(state) ) - - @rfRequestEventHandler = ( (result) => + + @board.on("rfRequest", (result) => if result.sender is @config.nodeid and result.type is V_STATUS datas = { @@ -1496,8 +1324,6 @@ module.exports = (env) -> } @board._rfWrite(datas) ) - @board.on("rfValue", @rfValueEventHandler) - @board.on("rfRequest", @rfRequestEventHandler) super() changeStateTo: (state) -> @@ -1514,10 +1340,8 @@ module.exports = (env) -> @board._rfWrite(datas).then ( () => @_setState(state) ) - + destroy: -> - @board.removeListener "rfValue", @rfValueEventHandler - @board.removeListener "rfRequest", @rfRequestEventHandler super() class MySensorsDimmer extends env.devices.DimmerActuator @@ -1529,8 +1353,8 @@ module.exports = (env) -> @_dimlevel = lastState?.dimlevel?.value or 0 @_lastdimlevel = lastState?.lastdimlevel?.value or 100 @_state = lastState?.state?.value or off - - @rfRequestEventHandler = ( (result) => + + @board.on("rfRequest", (result) => if result.sender is @config.nodeid and result.type is V_PERCENTAGE datas = { @@ -1542,8 +1366,8 @@ module.exports = (env) -> } @board._rfWrite(datas) ) - - @rfValueEventHandler = ( (result) => + + @board.on('rfValue', (result) => if result.sender is @config.nodeid and result.type is V_PERCENTAGE and result.sensor is @config.sensorid state = (if parseInt(result.value) is 0 then off else on) dimlevel = (result.value) @@ -1552,8 +1376,6 @@ module.exports = (env) -> @_setState(state) @_setDimlevel(dimlevel) ) - @board.on("rfRequest", @rfRequestEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() turnOn: -> @changeDimlevelTo(@_lastdimlevel) @@ -1576,10 +1398,8 @@ module.exports = (env) -> @board._rfWrite(datas).then ( () => @_setDimlevel(level) ) - + destroy: -> - @board.removeListener "rfRequest", @rfRequestEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() class MySensorsLight extends env.devices.Device @@ -1613,8 +1433,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1625,12 +1445,12 @@ module.exports = (env) -> ) @attributes.light = { - description: "the measured light" + description: "the messured light" type: "number" unit: '%' } - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsLight", result @@ -1638,13 +1458,9 @@ module.exports = (env) -> @_light = parseInt(result.value) @emit "light", @_light ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getLight: -> Promise.resolve @_light @@ -1681,8 +1497,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined @_battery = parseInt(result.value) @emit "battery", @_battery @@ -1690,12 +1506,12 @@ module.exports = (env) -> @attributes.lux = { - description: "the measured light in lux" + description: "the messured light in lux" type: "number" unit: 'lux' } - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsLux", result @@ -1703,13 +1519,9 @@ module.exports = (env) -> @_lux = parseInt(result.value) @emit "lux", @_lux ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getLux: -> Promise.resolve @_lux @@ -1745,7 +1557,7 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => + @board.on("rfbattery", (result) => if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send @@ -1757,12 +1569,12 @@ module.exports = (env) -> ) @attributes.distance = { - description: "the measured distance" + description: "the messured distance" type: "number" unit: 'cm' } - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsDistance", result @@ -1770,13 +1582,9 @@ module.exports = (env) -> @_distance = parseInt(result.value) @emit "distance", @_distance ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getDistance: -> Promise.resolve @_distance @@ -1812,8 +1620,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @rfbatteryEventHandler = ( (result) => - if result.sender is @config.nodeid + @board.on("rfbattery", (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1824,12 +1632,12 @@ module.exports = (env) -> ) @attributes.gas = { - description: "the measured gas presence in ppm" + description: "the messured gas presence in ppm" type: "number" unit: 'ppm' } - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsGas", result @@ -1837,13 +1645,9 @@ module.exports = (env) -> @_gas = parseInt(result.value) @emit "gas", @_gas ) - @board.on("rfbattery", @rfbatteryEventHandler) - @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler - @board.removeListener "rfValue", @rfValueEventHandler super() getGas: -> Promise.resolve @_gas @@ -1858,14 +1662,13 @@ module.exports = (env) -> if mySensors.config.debug env.logger.debug "MySensorsShutter ", @id, @name, @_position - @rfValueEventHandler = ( (result) => + @board.on('rfValue', (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid and result.type is V_UP or result.type is V_DOWN or result.type is V_STOP position = (if result.type is V_UP then 'up' else if result.type is V_DOWN then 'down' else 'stopped') if mySensors.config.debug env.logger.debug "<- MySensorsShutter ", result @_setPosition(position) - ) - @board.on("rfValue", @rfValueEventHandler) + ) super() moveToPosition: (position) -> @@ -1895,9 +1698,8 @@ module.exports = (env) -> @board._rfWrite(datas).then ( () => @_setPosition('stopped') ) - + destroy: -> - @board.removeListener "rfValue", @rfValueEventHandler super() class MySensorsMulti extends env.devices.Device @@ -1954,7 +1756,7 @@ module.exports = (env) -> @_createGetter name, ( => Promise.resolve @attributeValue[name] ) # when a mysensors value has been received - @rfValueEventHandler = ( (result) => + @board.on("rfValue", (result) => # loop trough all attributes in the config for attr, i in @config.attributes do (attr) => @@ -1994,11 +1796,12 @@ module.exports = (env) -> else throw new Error("Illegal unit for attribute type: #{name} in MySensorsMulti.") + # If the received value is different then the current value, it should be emitted @_setAttribute name, value ) # when a battery percentage has been received - @rfbatteryEventHandler = ( (result) => + @board.on("rfbattery", (result) => # loop trough all attributes in the config for attr, i in @config.attributes do (attr) => @@ -2009,25 +1812,22 @@ module.exports = (env) -> unless result.value is null or undefined if mySensors.config.debug env.logger.debug "<- MySensorsMulti", result - # When the battery is too low, battery percentages higher then 100 could be sent + # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 result.value = 0 value = parseInt(result.value) # If the received value is different then the current value, it should be emitted @_setAttribute name, value ) - @board.on("rfValue", @rfValueEventHandler) - @board.on("rfbattery", @rfbatteryEventHandler) super() - + destroy: -> - @board.removeListener "rfValue", @rfValueEventHandler - @board.removeListener "rfbattery", @rfbatteryEventHandler super() - + _setAttribute: (attributeName, value) -> - @attributeValue[attributeName] = value - @emit attributeName, value + unless @attributeValue[attributeName] is value + @attributeValue[attributeName] = value + @emit attributeName, value class MySensorsBattery extends env.devices.Device @@ -2039,39 +1839,37 @@ module.exports = (env) -> @attributes = {} @_battery = {} - for nodes in @config.nodes - if not nodes.name - for device in @framework.deviceManager.devicesConfig - if device?.nodeid and device?.nodeid is nodes.nodeid + for nodeid in @config.nodeid + do (nodeid) => + for device in @framework.deviceManager.devicesConfig + if device?.nodeid and device?.nodeid is nodeid attrname = device?.name break - else - attrname = nodes.name - attr = "batteryLevel_" + nodes.nodeid - @attributes[attr] = { - description: "the measured Battery Stat of Sensor" - type: "number" - displaySparkline: false - unit: "%" - acronym: attrname - icon: - noText: true - mapping: { - 'icon-battery-empty': 0 - 'icon-battery-fuel-1': [0, 20] - 'icon-battery-fuel-2': [20, 40] - 'icon-battery-fuel-3': [40, 60] - 'icon-battery-fuel-4': [60, 80] - 'icon-battery-fuel-5': [80, 100] - 'icon-battery-filled': 100 - } - } - getter = ( => Promise.resolve @_battery[nodes.nodeid] ) - @_createGetter( attr, getter) - @_battery[nodes.nodeid] = lastState?[attr]?.value + attr = "batteryLevel_" + nodeid + @attributes[attr] = { + description: "the measured Battery Stat of Sensor" + type: "number" + displaySparkline: false + unit: "%" + acronym: attrname + icon: + noText: true + mapping: { + 'icon-battery-empty': 0 + 'icon-battery-fuel-1': [0, 20] + 'icon-battery-fuel-2': [20, 40] + 'icon-battery-fuel-3': [40, 60] + 'icon-battery-fuel-4': [60, 80] + 'icon-battery-fuel-5': [80, 100] + 'icon-battery-filled': 100 + } + } + getter = ( => Promise.resolve @_battery[nodeid] ) + @_createGetter( attr, getter) + @_battery[nodeid] = lastState?[attr]?.value - @rfbatteryEventHandler = ( (result) => + @board.on("rfbattery", (result) => unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -2080,11 +1878,9 @@ module.exports = (env) -> @_battery[result.sender] = parseInt(result.value) @emit "batteryLevel_" + result.sender, @_battery[result.sender] ) - @board.on("rfbattery", @rfbatteryEventHandler) super() - + destroy: -> - @board.removeListener "rfbattery", @rfbatteryEventHandler super() class MySensorsActionHandler extends env.actions.ActionHandler @@ -2186,4 +1982,4 @@ module.exports = (env) -> # Create a instance of my plugin mySensors = new MySensors # and return it to the framework. - return mySensors + return mySensors \ No newline at end of file diff --git a/ethernet.coffee b/ethernet.coffee new file mode 100755 index 0000000..f2815a2 --- /dev/null +++ b/ethernet.coffee @@ -0,0 +1,45 @@ +events = require 'events' +net = require 'net' +Promise = require 'bluebird' + +class EthernetDriver extends events.EventEmitter + + constructor: (protocolOptions)-> + port = protocolOptions.port + host = protocolOptions.host + @connection = net.createConnection port, host + connect: (timeout, retries) -> + # cleanup + @ready = no + + # reject promise on error + @connection.on('error', (error) => @emit('error', error) ) + @connection.on('close', => @emit 'close' ) + + # setup data listner + @connection.on 'data', (data) => + # Sanitize data + + line = data.slice(0, data.length - 1) + + @emit('line', line) + + #resolve promise on connect + @connection.on 'connect', () => + @ready = yes + @emit 'ready' + return + + return new Promise( (resolve, reject) => + @once("ready", resolve) + @once("error", reject) + ) + + disconnect: -> + @connection.end() + return Promise.resolve() + + write: (data) -> + @connection.write(data, 'utf-8') + +module.exports = EthernetDriver From 0e1c6d99f4c002fcd38db2cf3e7af0457df93670 Mon Sep 17 00:00:00 2001 From: Wiebe Date: Mon, 5 Sep 2016 01:34:00 +0200 Subject: [PATCH 2/9] Revert "Added ethernet driver" This reverts commit 981680cd5342cd29537a764747ef4bffce24bde6. --- MySensors-config-schema.coffee | 6 +- MySensors.coffee | 490 +++++++++++++++++++++++---------- ethernet.coffee | 45 --- 3 files changed, 349 insertions(+), 192 deletions(-) delete mode 100755 ethernet.coffee diff --git a/MySensors-config-schema.coffee b/MySensors-config-schema.coffee index 639c01d..06af6bb 100644 --- a/MySensors-config-schema.coffee +++ b/MySensors-config-schema.coffee @@ -12,7 +12,7 @@ module.exports = { driver: description: "The diver to connect to the PiGateway" type: "string" - enum: ["serialport", "ethernet"] + enum: ["serialport"] default: "serialport" driverOptions: description: "Options for the driver" @@ -20,8 +20,6 @@ module.exports = { default: { "serialDevice": '/dev/ttyUSB0', #"/dev/ttyUSB0", "baudrate": 115200 - "host": "192.168.1.100" - "port": 5003 } protocols: description: "MySensors protrocol version" @@ -35,4 +33,4 @@ module.exports = { description: "Mysensors starting node id" type: "number" default: 1 -} \ No newline at end of file +} diff --git a/MySensors.coffee b/MySensors.coffee index c5148af..6923954 100644 --- a/MySensors.coffee +++ b/MySensors.coffee @@ -161,15 +161,12 @@ module.exports = (env) -> constructor: (framework,config) -> @config = config @framework = framework - assert @config.driver in ["serialport", "gpio","ethernet"] + assert @config.driver in ["serialport", "gpio"] # setup a new driver switch @config.driver when "serialport" SerialPortDriver = require './serialport' @driver = new SerialPortDriver(@config.driverOptions) - when "ethernet" - EthernetDriver = require './ethernet' - @driver = new EthernetDriver(@config.driverOptions) @driver.on('error', (error) => @emit('error', error) ) @driver.on('reconnect', (error) => @emit('reconnect', error) ) @@ -198,6 +195,7 @@ module.exports = (env) -> # decoding message datas = data.toString().split(";") sender = parseInt datas[0] + sensor = parseInt datas[1] command = parseInt datas[2] ack = parseInt datas[3] @@ -287,14 +285,14 @@ module.exports = (env) -> nextnodeid = @config.startingNodeId if nextnodeid is null nextnodeid = 1 - else + else nextnodeid +=1 while newid is false newid = not @framework.deviceManager.devicesConfig.some (device, iterator) => device.nodeid is nextnodeid if newid is false nextnodeid +=1 - + if newid is true and nextnodeid < 255 datas = { @@ -426,7 +424,7 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Motion Sensor #{nodeid}.#{sensorid}", config ) - # Smoke sensor found + # Smoke sensor found if sensortype is S_SMOKE config = { class: 'MySensorsPIR', @@ -436,8 +434,8 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Smoke Sensor #{nodeid}.#{sensorid}", config ) - - # Moisture sensor found + + # Moisture sensor found if sensortype is S_MOISTURE config = { class: 'MySensorsPIR', @@ -447,7 +445,7 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Moisture Sensor #{nodeid}.#{sensorid}", config ) - + # Leak sensor found if sensortype is S_WATER_LEAK config = { @@ -524,7 +522,7 @@ module.exports = (env) -> @framework.deviceManager.discoveredDevice( 'pimatic-mysensors', "Water Sensor #{nodeid}.#{sensorid}", config ) - + # pH sensor found if sensortype is S_WATER_QUALITY config = { @@ -592,6 +590,7 @@ module.exports = (env) -> MySensorsSwitch MySensorsDimmer MySensorsPulseMeter + MySensorsEnergyMeter MySensorsWaterMeter MySensorsPH MySensorsButton @@ -633,14 +632,14 @@ module.exports = (env) -> @attributes = {} @attributes.temperature = { - description: "the messured temperature" + description: "the measured temperature" type: "number" unit: '°C' acronym: 'T' } @attributes.humidity = { - description: "the messured humidity" + description: "the measured humidity" type: "number" unit: '%' acronym: 'RH' @@ -665,8 +664,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -676,7 +675,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid for sensorid in @config.sensorid if result.sensor is sensorid @@ -691,9 +690,13 @@ module.exports = (env) -> @_humidity = Math.round(parseFloat(result.value)) @emit "humidity", @_humidity ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getTemperature: -> Promise.resolve @_temperatue @@ -713,7 +716,7 @@ module.exports = (env) -> @attributes = {} @attributes.temperature = { - description: "the messured temperature" + description: "the measured temperature" type: "number" unit: '°C' acronym: 'T' @@ -738,8 +741,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -749,16 +752,20 @@ module.exports = (env) -> @emit "battery", @_battery ) - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.type is V_TEMP and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorDST ", result @_temperatue = parseFloat(result.value) @emit "temperature", @_temperatue ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getTemperature: -> Promise.resolve @_temperatue @@ -779,14 +786,14 @@ module.exports = (env) -> @attributes = {} @attributes.temperature = { - description: "the messured temperature" + description: "the measured temperature" type: "number" unit: '°C' acronym: 'T' } @attributes.pressure = { - description: "the messured pressure" + description: "the measured pressure" type: "number" unit: 'hPa' acronym: 'mbar' @@ -817,8 +824,8 @@ module.exports = (env) -> } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -828,7 +835,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid for sensorid in @config.sensorid if result.sensor is sensorid @@ -848,9 +855,13 @@ module.exports = (env) -> @emit "forecast", @_forecast ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getTemperature: -> Promise.resolve @_temperatue @@ -877,7 +888,7 @@ module.exports = (env) -> @attributes = {} @attributes.watt = { - description: "the messured Wattage" + description: "the measured Wattage" type: "number" unit: 'W' acronym: 'Watt' @@ -891,23 +902,12 @@ module.exports = (env) -> } @attributes.kWh = { - description: "the messured kWh" + description: "the measured kWh" type: "number" unit: 'kWh' acronym: 'kWh' } - calculatekwh = ( => - @_avgkw = @_totalkw / @_tickcount - @_kwh = (@_avgkw * (@_tickcount * 10)) / 3600 - @_tickcount = 0 - @_totalkw = 0 - if mySensors.config.debug - env.logger.debug "calculatekwh..", @kwh - @emit "kWh", @_kwh - ) - - @attributes.battery = { description: "Display the battery level of sensor" type: "number" @@ -928,13 +928,13 @@ module.exports = (env) -> } @attributes.ampere = { - description: "the messured Ampere" + description: "the measured Ampere" type: "number", unit: "A" acronym: 'Ampere' } - @board.on("rfRequest", (result) => + @rfRequestEventHandler = ( (result) => if result.sender is @config.nodeid datas = { @@ -947,8 +947,8 @@ module.exports = (env) -> @board._rfWrite(datas) ) - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -958,7 +958,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsPulseMeter", result @@ -979,11 +979,16 @@ module.exports = (env) -> env.logger.debug "<- MySensorsPulseMeter V_KWH" @_kwh = parseFloat(result.value) @emit "kWh", @_kwh - ) + @board.on("rfRequest", @rfRequestEventHandler) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfRequest", @rfRequestEventHandler + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getWatt: -> Promise.resolve @_watt @@ -992,6 +997,155 @@ module.exports = (env) -> getBattery: -> Promise.resolve @_battery getAmpere: -> Promise.resolve @_ampere + class MySensorsEnergyMeter extends env.devices.Device + + constructor: (@config,lastState, @board) -> + @id = @config.id + @name = @config.name + if mySensors.config.debug + env.logger.debug "MySensorsEnergyMeter ", @id, @name + + @kWhlastTime = {} + @attributes = {} + @_watt = {} + for sensorid in @config.sensorid + do(sensorid) => + attr = "Phase_" + sensorid + + @attributes[attr] = { + description: "this measure wattage" + type: "number" + displaySparkline: false + unit: "W" + acronym: attr + } + @kWhlastTime[sensorid] = Date.now() + getter = ( => Promise.resolve @_watt[sensorid] ) + @_createGetter( attr, getter) + @_watt[sensorid] = lastState?[attr]?.value + + @_kwh = lastState?.kWh?.value or 0 + @_totalPower = lastState?.totalPower?.value or 0 + @_rate = lastState?.rate?.value or 0 + @_battery = lastState?.battery?.value + + @attributes.totalPower = { + description: "Total Watt" + type: "number" + unit: 'W' + displaySparkline: false + acronym: 'Total' + } + + @attributes.kWh = { + description: "this measure kWh" + type: "number" + unit: 'kWh' + acronym: 'kWh' + } + + @attributes.rate = { + description: "Electricity Cost" + type: "number" + unit: "" + displaySparkline: false + acronym: @config.currency + } + + @attributes.battery = { + description: "Display the battery level of sensor" + type: "number" + displaySparkline: false + unit: "%" + icon: + noText: true + mapping: { + 'icon-battery-empty': 0 + 'icon-battery-fuel-1': [0, 20] + 'icon-battery-fuel-2': [20, 40] + 'icon-battery-fuel-3': [40, 60] + 'icon-battery-fuel-4': [60, 80] + 'icon-battery-fuel-5': [80, 100] + 'icon-battery-filled': 100 + } + hidden: !@config.batterySensor + } + + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid + unless result.value is null or undefined + # When the battery is to low, battery percentages higher then 100 could be send + if result.value > 100 + result.value = 0 + + @_battery = parseInt(result.value) + @emit "battery", @_battery + ) + + @rfValueEventHandler = ( (result) => + if result.sender is @config.nodeid + if result.sensor in @config.sensorid and result.type is V_WATT + if mySensors.config.debug + env.logger.debug "<- MySensorsEnergyMeter", result + @calculatePower(result) + ) + + @_resetWattage = setInterval(( => + env.logger.debug "<- MySensorsEnergyMeter setinterval" + for sensorid in @config.sensorid + if (new Date()) - @kWhlastTime[sensorid] > @config.resetTime + result = {} + result = + { + sender: @config.nodeid, + sensor: sensorid, + type : V_WATT, + value : 0 + } + @calculatePower(result) + ), 30000) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) + super() + + calculatePower:(result) -> + currdate = new Date() + + if currdate > new Date(currdate.getFullYear(), currdate.getMonth() + 1, 1) + @_kwh = 0 + @_rate = 0 + + diffTime = currdate - @kWhlastTime[result.sensor] + + @_watt[result.sensor] = Math.floor(parseInt(result.value)) + calibratedWattage = (@_watt[result.sensor] * (100 - @config.correction)/100) + intKwh = ((calibratedWattage / 1000 ) * ( diffTime ) / 3600000) + @_totalPower = 0 + for sensorid in @config.sensorid + @_totalPower += @_watt[sensorid] + + @_kwh = @_kwh + intKwh + @kWhlastTime[result.sensor] = currdate + @_rate = @_rate + intKwh * @config.rate + if mySensors.config.debug + env.logger.debug "<- MySensorsEnergyMeter V_KWH", @_kwh , @_rate + + @emit "Phase_" + result.sensor, @_watt[result.sensor] + @emit "totalPower" , @_totalPower + @emit "kWh", @_kwh + @emit "rate", @_rate + + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler + clearInterval(@_resetWattage) + super() + + getKWh: -> Promise.resolve @_kwh + getRate: -> Promise.resolve @_rate + getTotalPower: -> Promise.resolve @_totalPower + getBattery: -> Promise.resolve @_battery + class MySensorsWaterMeter extends env.devices.Device constructor: (@config,lastState, @board) -> @@ -1009,7 +1163,7 @@ module.exports = (env) -> @attributes = {} @attributes.flow = { - description: "the meassured water in liter per minute" + description: "the measured water in liter per minute" type: "number" unit: 'l/min' acronym: 'Flow' @@ -1023,7 +1177,7 @@ module.exports = (env) -> } @attributes.volume = { - description: "the meassured water in m3" + description: "the measured water in m3" type: "number" unit: 'm3' acronym: 'Total' @@ -1048,7 +1202,7 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfRequest", (result) => + @rfRequestEventHandler = ( (result) => if result.sender is @config.nodeid datas = { @@ -1061,8 +1215,8 @@ module.exports = (env) -> @board._rfWrite(datas) ) - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1072,7 +1226,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsWaterMeter", result @@ -1093,16 +1247,22 @@ module.exports = (env) -> @emit "volume", @_volume ) + @board.on("rfRequest", @rfRequestEventHandler) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfRequest", @rfRequestEventHandler + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getFlow: -> Promise.resolve @_flow getPulsecount: -> Promise.resolve @_pulsecount getVolume: -> Promise.resolve @_volume getBattery: -> Promise.resolve @_battery - + class MySensorsPH extends env.devices.Device constructor: (@config,lastState, @board) -> @@ -1134,8 +1294,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1146,12 +1306,12 @@ module.exports = (env) -> ) @attributes.ph = { - description: "the meassured pH value" + description: "the measured pH value" type: "number" unit: 'pH' } - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsPH", result @@ -1159,9 +1319,13 @@ module.exports = (env) -> @_ph = parseFloat(result.value) @emit "ph", @_ph ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getPh: -> Promise.resolve @_ph @@ -1174,10 +1338,10 @@ module.exports = (env) -> @name = @config.name @_presence = lastState?.presence?.value or false @_battery = lastState?.battery?.value - + if mySensors.config.debug env.logger.debug "MySensorsPIR ", @id, @name, @_presence - + @addAttribute('battery', { description: "Battery", type: "number" @@ -1197,9 +1361,9 @@ module.exports = (env) -> hidden: !@config.batterySensor }) @['battery'] = ()-> Promise.resolve(@_battery) - - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1208,12 +1372,12 @@ module.exports = (env) -> @_battery = parseInt(result.value) @emit "battery", @_battery ) - + resetPresence = ( => @_setPresence(no) ) - @board.on('rfValue', (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.type is V_TRIPPED and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorPIR ", result @@ -1228,11 +1392,15 @@ module.exports = (env) -> @_setPresence(no) ), @config.resetTime) ) - + + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> clearTimeout(@_resetPresenceTimeout) + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getPresence: -> Promise.resolve @_presence @@ -1268,8 +1436,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1279,7 +1447,7 @@ module.exports = (env) -> @emit "battery", @_battery ) - @board.on('rfValue', (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.type is ( V_TRIPPED or V_STATUS ) and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsButton ", result @@ -1288,9 +1456,13 @@ module.exports = (env) -> else @_setContact(no) ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getBattery: -> Promise.resolve @_battery @@ -1304,15 +1476,15 @@ module.exports = (env) -> if mySensors.config.debug env.logger.debug "MySensorsSwitch ", @id, @name, @_state - @board.on('rfValue', (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.type is V_STATUS and result.sensor is @config.sensorid state = (if parseInt(result.value) is 1 then on else off) if mySensors.config.debug env.logger.debug "<- MySensorSwitch ", result @_setState(state) ) - - @board.on("rfRequest", (result) => + + @rfRequestEventHandler = ( (result) => if result.sender is @config.nodeid and result.type is V_STATUS datas = { @@ -1324,6 +1496,8 @@ module.exports = (env) -> } @board._rfWrite(datas) ) + @board.on("rfValue", @rfValueEventHandler) + @board.on("rfRequest", @rfRequestEventHandler) super() changeStateTo: (state) -> @@ -1340,8 +1514,10 @@ module.exports = (env) -> @board._rfWrite(datas).then ( () => @_setState(state) ) - + destroy: -> + @board.removeListener "rfValue", @rfValueEventHandler + @board.removeListener "rfRequest", @rfRequestEventHandler super() class MySensorsDimmer extends env.devices.DimmerActuator @@ -1353,8 +1529,8 @@ module.exports = (env) -> @_dimlevel = lastState?.dimlevel?.value or 0 @_lastdimlevel = lastState?.lastdimlevel?.value or 100 @_state = lastState?.state?.value or off - - @board.on("rfRequest", (result) => + + @rfRequestEventHandler = ( (result) => if result.sender is @config.nodeid and result.type is V_PERCENTAGE datas = { @@ -1366,8 +1542,8 @@ module.exports = (env) -> } @board._rfWrite(datas) ) - - @board.on('rfValue', (result) => + + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.type is V_PERCENTAGE and result.sensor is @config.sensorid state = (if parseInt(result.value) is 0 then off else on) dimlevel = (result.value) @@ -1376,6 +1552,8 @@ module.exports = (env) -> @_setState(state) @_setDimlevel(dimlevel) ) + @board.on("rfRequest", @rfRequestEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() turnOn: -> @changeDimlevelTo(@_lastdimlevel) @@ -1398,8 +1576,10 @@ module.exports = (env) -> @board._rfWrite(datas).then ( () => @_setDimlevel(level) ) - + destroy: -> + @board.removeListener "rfRequest", @rfRequestEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() class MySensorsLight extends env.devices.Device @@ -1433,8 +1613,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1445,12 +1625,12 @@ module.exports = (env) -> ) @attributes.light = { - description: "the messured light" + description: "the measured light" type: "number" unit: '%' } - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsLight", result @@ -1458,9 +1638,13 @@ module.exports = (env) -> @_light = parseInt(result.value) @emit "light", @_light ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getLight: -> Promise.resolve @_light @@ -1497,8 +1681,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined @_battery = parseInt(result.value) @emit "battery", @_battery @@ -1506,12 +1690,12 @@ module.exports = (env) -> @attributes.lux = { - description: "the messured light in lux" + description: "the measured light in lux" type: "number" unit: 'lux' } - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsLux", result @@ -1519,9 +1703,13 @@ module.exports = (env) -> @_lux = parseInt(result.value) @emit "lux", @_lux ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getLux: -> Promise.resolve @_lux @@ -1557,7 +1745,7 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => + @rfbatteryEventHandler = ( (result) => if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send @@ -1569,12 +1757,12 @@ module.exports = (env) -> ) @attributes.distance = { - description: "the messured distance" + description: "the measured distance" type: "number" unit: 'cm' } - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsDistance", result @@ -1582,9 +1770,13 @@ module.exports = (env) -> @_distance = parseInt(result.value) @emit "distance", @_distance ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getDistance: -> Promise.resolve @_distance @@ -1620,8 +1812,8 @@ module.exports = (env) -> hidden: !@config.batterySensor } - @board.on("rfbattery", (result) => - if result.sender is @config.nodeid + @rfbatteryEventHandler = ( (result) => + if result.sender is @config.nodeid unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1632,12 +1824,12 @@ module.exports = (env) -> ) @attributes.gas = { - description: "the messured gas presence in ppm" + description: "the measured gas presence in ppm" type: "number" unit: 'ppm' } - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid if mySensors.config.debug env.logger.debug "<- MySensorsGas", result @@ -1645,9 +1837,13 @@ module.exports = (env) -> @_gas = parseInt(result.value) @emit "gas", @_gas ) + @board.on("rfbattery", @rfbatteryEventHandler) + @board.on("rfValue", @rfValueEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler + @board.removeListener "rfValue", @rfValueEventHandler super() getGas: -> Promise.resolve @_gas @@ -1662,13 +1858,14 @@ module.exports = (env) -> if mySensors.config.debug env.logger.debug "MySensorsShutter ", @id, @name, @_position - @board.on('rfValue', (result) => + @rfValueEventHandler = ( (result) => if result.sender is @config.nodeid and result.sensor is @config.sensorid and result.type is V_UP or result.type is V_DOWN or result.type is V_STOP position = (if result.type is V_UP then 'up' else if result.type is V_DOWN then 'down' else 'stopped') if mySensors.config.debug env.logger.debug "<- MySensorsShutter ", result @_setPosition(position) - ) + ) + @board.on("rfValue", @rfValueEventHandler) super() moveToPosition: (position) -> @@ -1698,8 +1895,9 @@ module.exports = (env) -> @board._rfWrite(datas).then ( () => @_setPosition('stopped') ) - + destroy: -> + @board.removeListener "rfValue", @rfValueEventHandler super() class MySensorsMulti extends env.devices.Device @@ -1756,7 +1954,7 @@ module.exports = (env) -> @_createGetter name, ( => Promise.resolve @attributeValue[name] ) # when a mysensors value has been received - @board.on("rfValue", (result) => + @rfValueEventHandler = ( (result) => # loop trough all attributes in the config for attr, i in @config.attributes do (attr) => @@ -1796,12 +1994,11 @@ module.exports = (env) -> else throw new Error("Illegal unit for attribute type: #{name} in MySensorsMulti.") - # If the received value is different then the current value, it should be emitted @_setAttribute name, value ) # when a battery percentage has been received - @board.on("rfbattery", (result) => + @rfbatteryEventHandler = ( (result) => # loop trough all attributes in the config for attr, i in @config.attributes do (attr) => @@ -1812,22 +2009,25 @@ module.exports = (env) -> unless result.value is null or undefined if mySensors.config.debug env.logger.debug "<- MySensorsMulti", result - # When the battery is to low, battery percentages higher then 100 could be send + # When the battery is too low, battery percentages higher then 100 could be sent if result.value > 100 result.value = 0 value = parseInt(result.value) # If the received value is different then the current value, it should be emitted @_setAttribute name, value ) + @board.on("rfValue", @rfValueEventHandler) + @board.on("rfbattery", @rfbatteryEventHandler) super() - + destroy: -> + @board.removeListener "rfValue", @rfValueEventHandler + @board.removeListener "rfbattery", @rfbatteryEventHandler super() - + _setAttribute: (attributeName, value) -> - unless @attributeValue[attributeName] is value - @attributeValue[attributeName] = value - @emit attributeName, value + @attributeValue[attributeName] = value + @emit attributeName, value class MySensorsBattery extends env.devices.Device @@ -1839,37 +2039,39 @@ module.exports = (env) -> @attributes = {} @_battery = {} - for nodeid in @config.nodeid - do (nodeid) => - for device in @framework.deviceManager.devicesConfig - if device?.nodeid and device?.nodeid is nodeid + for nodes in @config.nodes + if not nodes.name + for device in @framework.deviceManager.devicesConfig + if device?.nodeid and device?.nodeid is nodes.nodeid attrname = device?.name break + else + attrname = nodes.name - attr = "batteryLevel_" + nodeid - @attributes[attr] = { - description: "the measured Battery Stat of Sensor" - type: "number" - displaySparkline: false - unit: "%" - acronym: attrname - icon: - noText: true - mapping: { - 'icon-battery-empty': 0 - 'icon-battery-fuel-1': [0, 20] - 'icon-battery-fuel-2': [20, 40] - 'icon-battery-fuel-3': [40, 60] - 'icon-battery-fuel-4': [60, 80] - 'icon-battery-fuel-5': [80, 100] - 'icon-battery-filled': 100 - } - } - getter = ( => Promise.resolve @_battery[nodeid] ) - @_createGetter( attr, getter) - @_battery[nodeid] = lastState?[attr]?.value + attr = "batteryLevel_" + nodes.nodeid + @attributes[attr] = { + description: "the measured Battery Stat of Sensor" + type: "number" + displaySparkline: false + unit: "%" + acronym: attrname + icon: + noText: true + mapping: { + 'icon-battery-empty': 0 + 'icon-battery-fuel-1': [0, 20] + 'icon-battery-fuel-2': [20, 40] + 'icon-battery-fuel-3': [40, 60] + 'icon-battery-fuel-4': [60, 80] + 'icon-battery-fuel-5': [80, 100] + 'icon-battery-filled': 100 + } + } + getter = ( => Promise.resolve @_battery[nodes.nodeid] ) + @_createGetter( attr, getter) + @_battery[nodes.nodeid] = lastState?[attr]?.value - @board.on("rfbattery", (result) => + @rfbatteryEventHandler = ( (result) => unless result.value is null or undefined # When the battery is to low, battery percentages higher then 100 could be send if result.value > 100 @@ -1878,9 +2080,11 @@ module.exports = (env) -> @_battery[result.sender] = parseInt(result.value) @emit "batteryLevel_" + result.sender, @_battery[result.sender] ) + @board.on("rfbattery", @rfbatteryEventHandler) super() - + destroy: -> + @board.removeListener "rfbattery", @rfbatteryEventHandler super() class MySensorsActionHandler extends env.actions.ActionHandler @@ -1982,4 +2186,4 @@ module.exports = (env) -> # Create a instance of my plugin mySensors = new MySensors # and return it to the framework. - return mySensors \ No newline at end of file + return mySensors diff --git a/ethernet.coffee b/ethernet.coffee deleted file mode 100755 index f2815a2..0000000 --- a/ethernet.coffee +++ /dev/null @@ -1,45 +0,0 @@ -events = require 'events' -net = require 'net' -Promise = require 'bluebird' - -class EthernetDriver extends events.EventEmitter - - constructor: (protocolOptions)-> - port = protocolOptions.port - host = protocolOptions.host - @connection = net.createConnection port, host - connect: (timeout, retries) -> - # cleanup - @ready = no - - # reject promise on error - @connection.on('error', (error) => @emit('error', error) ) - @connection.on('close', => @emit 'close' ) - - # setup data listner - @connection.on 'data', (data) => - # Sanitize data - - line = data.slice(0, data.length - 1) - - @emit('line', line) - - #resolve promise on connect - @connection.on 'connect', () => - @ready = yes - @emit 'ready' - return - - return new Promise( (resolve, reject) => - @once("ready", resolve) - @once("error", reject) - ) - - disconnect: -> - @connection.end() - return Promise.resolve() - - write: (data) -> - @connection.write(data, 'utf-8') - -module.exports = EthernetDriver From 1392de8ecf8b1bdca8f473ac7ce1ecad358ce02d Mon Sep 17 00:00:00 2001 From: Wiebe Date: Mon, 5 Sep 2016 01:35:52 +0200 Subject: [PATCH 3/9] added ethernet driver still some bugs to fix like sending data --- MySensors-config-schema.coffee | 4 ++- MySensors.coffee | 3 +++ ethernet.coffee | 45 ++++++++++++++++++++++++++++++++++ package.json | 1 + 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100755 ethernet.coffee diff --git a/MySensors-config-schema.coffee b/MySensors-config-schema.coffee index 06af6bb..fb4408d 100644 --- a/MySensors-config-schema.coffee +++ b/MySensors-config-schema.coffee @@ -12,7 +12,7 @@ module.exports = { driver: description: "The diver to connect to the PiGateway" type: "string" - enum: ["serialport"] + enum: ["serialport", "ethernet"] default: "serialport" driverOptions: description: "Options for the driver" @@ -20,6 +20,8 @@ module.exports = { default: { "serialDevice": '/dev/ttyUSB0', #"/dev/ttyUSB0", "baudrate": 115200 + "host": "192.168.1.100" + "port": 5003 } protocols: description: "MySensors protrocol version" diff --git a/MySensors.coffee b/MySensors.coffee index 6923954..2316acd 100644 --- a/MySensors.coffee +++ b/MySensors.coffee @@ -167,6 +167,9 @@ module.exports = (env) -> when "serialport" SerialPortDriver = require './serialport' @driver = new SerialPortDriver(@config.driverOptions) + when "ethernet" + EthernetDriver = require './ethernet' + @driver = new EthernetDriver(@config.driverOptions) @driver.on('error', (error) => @emit('error', error) ) @driver.on('reconnect', (error) => @emit('reconnect', error) ) diff --git a/ethernet.coffee b/ethernet.coffee new file mode 100755 index 0000000..f2815a2 --- /dev/null +++ b/ethernet.coffee @@ -0,0 +1,45 @@ +events = require 'events' +net = require 'net' +Promise = require 'bluebird' + +class EthernetDriver extends events.EventEmitter + + constructor: (protocolOptions)-> + port = protocolOptions.port + host = protocolOptions.host + @connection = net.createConnection port, host + connect: (timeout, retries) -> + # cleanup + @ready = no + + # reject promise on error + @connection.on('error', (error) => @emit('error', error) ) + @connection.on('close', => @emit 'close' ) + + # setup data listner + @connection.on 'data', (data) => + # Sanitize data + + line = data.slice(0, data.length - 1) + + @emit('line', line) + + #resolve promise on connect + @connection.on 'connect', () => + @ready = yes + @emit 'ready' + return + + return new Promise( (resolve, reject) => + @once("ready", resolve) + @once("error", reject) + ) + + disconnect: -> + @connection.end() + return Promise.resolve() + + write: (data) -> + @connection.write(data, 'utf-8') + +module.exports = EthernetDriver diff --git a/package.json b/package.json index 0dff038..07da055 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "files": [ "MySensors.coffee", "serialport.coffee", + "ethernet.coffee", "README.md", "device-config-schema.coffee", "MySensors-config-schema.coffee", From f3d84ba0ddda30a757c5c8b086218ce08634771b Mon Sep 17 00:00:00 2001 From: Wiebe Date: Mon, 5 Sep 2016 19:23:16 +0200 Subject: [PATCH 4/9] fix error when transmitting --- ethernet.coffee | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ethernet.coffee b/ethernet.coffee index f2815a2..dd926ec 100755 --- a/ethernet.coffee +++ b/ethernet.coffee @@ -40,6 +40,14 @@ class EthernetDriver extends events.EventEmitter return Promise.resolve() write: (data) -> - @connection.write(data, 'utf-8') + if not @connection.write(data, 'utf-8', () => + @emit "done" + ) + @emit "error" + + return new Promise( (resolve, reject) => + @once("done", resolve) + @once("error", reject) + ) module.exports = EthernetDriver From 46d36d316bbd5e27b32066365c6e169f76dde889 Mon Sep 17 00:00:00 2001 From: Wiebe Date: Mon, 5 Sep 2016 19:45:03 +0200 Subject: [PATCH 5/9] alow ethernet driver --- MySensors.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MySensors.coffee b/MySensors.coffee index 2316acd..5100925 100644 --- a/MySensors.coffee +++ b/MySensors.coffee @@ -161,7 +161,7 @@ module.exports = (env) -> constructor: (framework,config) -> @config = config @framework = framework - assert @config.driver in ["serialport", "gpio"] + assert @config.driver in ["serialport", "gpio", "ethernet"] # setup a new driver switch @config.driver when "serialport" From 39a5df3f66054cfa0eb8557910c548b779c4209e Mon Sep 17 00:00:00 2001 From: Wiebe Date: Mon, 5 Sep 2016 19:57:58 +0200 Subject: [PATCH 6/9] better config handling for editing in gui --- MySensors-config-schema.coffee | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/MySensors-config-schema.coffee b/MySensors-config-schema.coffee index fb4408d..bfeda3b 100644 --- a/MySensors-config-schema.coffee +++ b/MySensors-config-schema.coffee @@ -10,18 +10,43 @@ module.exports = { type: "boolean" default: true driver: - description: "The diver to connect to the PiGateway" + description: "The driver to connect to the gateway" type: "string" enum: ["serialport", "ethernet"] default: "serialport" + defines: + property: "driverOptions" + options: + serialport: + title: "serialport driver options" + type: "object" + properties: + serialDevice: + description: "The name of the serial device to use" + type: "string" + default: "/dev/ttyUSB0" + baudrate: + description: "The baudrate to use for serial communication" + type: "integer" + default: 115200 + ethernet: + title: "ethernet driver options" + type: "object" + properties: + host: + description: "The IP address of the gateway" + type: "string" + default: "192.168.1.100" + port: + description: "The port of the gateway" + type: "integer" + default: 5003 driverOptions: description: "Options for the driver" type: "object" default: { - "serialDevice": '/dev/ttyUSB0', #"/dev/ttyUSB0", + "serialDevice": "/dev/ttyUSB0", "baudrate": 115200 - "host": "192.168.1.100" - "port": 5003 } protocols: description: "MySensors protrocol version" From c407e8485aa4f5e55988ad6856562e0368f70749 Mon Sep 17 00:00:00 2001 From: Wiebe Date: Wed, 7 Sep 2016 19:26:53 +0200 Subject: [PATCH 7/9] prevent pimatic from crashing on error connecting --- MySensors.coffee | 13 ++++++++----- ethernet.coffee | 26 ++++++++++++++++---------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/MySensors.coffee b/MySensors.coffee index 5100925..3e1b3f7 100644 --- a/MySensors.coffee +++ b/MySensors.coffee @@ -161,7 +161,7 @@ module.exports = (env) -> constructor: (framework,config) -> @config = config @framework = framework - assert @config.driver in ["serialport", "gpio", "ethernet"] + assert @config.driver in ["serialport", "ethernet"] # setup a new driver switch @config.driver when "serialport" @@ -171,10 +171,13 @@ module.exports = (env) -> EthernetDriver = require './ethernet' @driver = new EthernetDriver(@config.driverOptions) - @driver.on('error', (error) => @emit('error', error) ) - @driver.on('reconnect', (error) => @emit('reconnect', error) ) + @driver.on('error', (error) => + env.logger.error error + ) + @driver.on('reconnect', (error) => + @emit('reconnect', error) + ) @driver.on('close', => - @emit('close') ) @driver.on("data", (data) => @@ -186,7 +189,7 @@ module.exports = (env) -> ) - connect: (timeout = 20000, retries = 3) -> + connect: (timeout = 2500, retries = 3) -> return @pendingConnect = @driver.connect(timeout, retries) diff --git a/ethernet.coffee b/ethernet.coffee index dd926ec..0bf34e2 100755 --- a/ethernet.coffee +++ b/ethernet.coffee @@ -5,25 +5,31 @@ Promise = require 'bluebird' class EthernetDriver extends events.EventEmitter constructor: (protocolOptions)-> - port = protocolOptions.port - host = protocolOptions.host - @connection = net.createConnection port, host + @port = protocolOptions.port + @host = protocolOptions.host + connect: (timeout, retries) -> + + # Create connection + @connection = net.createConnection @port, @host + # cleanup @ready = no - # reject promise on error - @connection.on('error', (error) => @emit('error', error) ) - @connection.on('close', => @emit 'close' ) + # reject promise on close + @connection.on 'close', () => + @emit('close') - # setup data listner + # setup data listener @connection.on 'data', (data) => # Sanitize data - - line = data.slice(0, data.length - 1) - + line = data.slice(0, data.length - 1) @emit('line', line) + # reject promise on error + @connection.on 'error', (error) => + @emit('error', error) + #resolve promise on connect @connection.on 'connect', () => @ready = yes From debfb3376d0444b9feb262c69a3779b34c1c0e81 Mon Sep 17 00:00:00 2001 From: Oitzu Date: Mon, 12 Sep 2016 16:17:25 +0200 Subject: [PATCH 8/9] Convert incoming data to string and replace line breaks. --- ethernet.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ethernet.coffee b/ethernet.coffee index 0bf34e2..a9cf78a 100755 --- a/ethernet.coffee +++ b/ethernet.coffee @@ -23,6 +23,8 @@ class EthernetDriver extends events.EventEmitter # setup data listener @connection.on 'data', (data) => # Sanitize data + data = data.toString() + data = data.replace(/(\r\n|\n|\r)/gm,"") line = data.slice(0, data.length - 1) @emit('line', line) From 33a725736dfd689b49d64a4a0273247ff26a17c3 Mon Sep 17 00:00:00 2001 From: Oitzu Date: Mon, 12 Sep 2016 20:12:21 +0200 Subject: [PATCH 9/9] Removed slice function call. --- ethernet.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ethernet.coffee b/ethernet.coffee index a9cf78a..c93053c 100755 --- a/ethernet.coffee +++ b/ethernet.coffee @@ -24,8 +24,7 @@ class EthernetDriver extends events.EventEmitter @connection.on 'data', (data) => # Sanitize data data = data.toString() - data = data.replace(/(\r\n|\n|\r)/gm,"") - line = data.slice(0, data.length - 1) + line = data.replace(/(\r\n|\n|\r)/gm,"") @emit('line', line) # reject promise on error