Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  version bump + history update
  added wind-sensor
  • Loading branch information
Sebastian Kroll committed Jul 3, 2018
2 parents 94de5c4 + 9c87baf commit b9da646
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 2 deletions.
3 changes: 3 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## version history

### 0.4.0
- added wind-sensor (still testing)

### 0.3.7
- changed polling mechanism to prevent deadlocks on netatmo API errors

Expand Down
114 changes: 114 additions & 0 deletions accessory/eveatmo-wind-accessory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
'use strict';

var homebridge;
var Characteristic;
var NetatmoAccessory;
var path = require('path');

module.exports = function(pHomebridge) {
if (pHomebridge && !homebridge) {
homebridge = pHomebridge;
NetatmoAccessory = require("../lib/netatmo-accessory")(homebridge);
Characteristic = homebridge.hap.Characteristic;
}

class EveatmoWindAccessory extends NetatmoAccessory {
constructor(deviceData, netatmoDevice) {
var accessoryConfig = {
"id": deviceData._id,
"model": "Eve Wind",
"netatmoType": deviceData.type,
"firmware": deviceData.firmware,
"name": deviceData._name || "Eveatmo " + netatmoDevice.deviceType + " " + deviceData._id,
"hasBattery": (deviceData.battery_vp) ? true : false,
};

super(homebridge, accessoryConfig, netatmoDevice);
this.buildServices(accessoryConfig);

this.windStrength = 0.0;
this.windAngle = 0;

this.refreshData(function(err, data) {});
}

buildServices(accessoryConfig) {
var serviceDir = path.dirname(__dirname) + '/service';
try {
var EveatmoWindService = require(serviceDir + '/eveatmo-wind')(homebridge);
var serviceWind = new EveatmoWindService(this);
serviceWind.isPrimaryService = true;
this.addService(serviceWind);

if (accessoryConfig.hasBattery) {
var EveatmoBatteryService = require(serviceDir + '/eveatmo-battery')(homebridge);
var serviceBattery = new EveatmoBatteryService(this);
this.addService(serviceBattery);
}

} catch (err) {
this.log.warn("Could not process service files for " + accessoryConfig.name);
this.log.warn(err);
this.log.warn(err.stack);
}
}

notifyUpdate(deviceData) {
var accessoryData = this.extractAccessoryData(deviceData);
var weatherData = this.mapAccessoryDataToWeatherData(accessoryData);
this.applyWeatherData(weatherData);
}

mapAccessoryDataToWeatherData(accessoryData) {
var result = {};
var dashboardData = accessoryData.dashboard_data;
if (dashboardData) {
if (dashboardData.hasOwnProperty("WindStrength")) {
result.windStrength = dashboardData.WindStrength;
}
if (dashboardData.hasOwnProperty("WindAngle")) {
result.windAngle = dashboardData.WindAngle;
}
}

result.batteryPercent = accessoryData.battery_percent;
if (!result.batteryPercent) {
result.batteryPercent = 100;
}
result.lowBattery = (result.batteryPercent <= 20) ? true : false;

return result;
}

applyWeatherData(weatherData) {
var dataChanged = false;

if (weatherData.hasOwnProperty("windStrength") && this.windStrength != weatherData.windStrength) {
this.windStrength = weatherData.windStrength;
dataChanged = true;
}
if (weatherData.hasOwnProperty("windAngle") && this.windAngle != weatherData.windAngle) {
this.windAngle = weatherData.windAngle;
dataChanged = true;
}

if (weatherData.batteryPercent && this.batteryPercent != weatherData.batteryPercent) {
this.batteryPercent = weatherData.batteryPercent;
dataChanged = true;
}
if (weatherData.lowBattery && this.lowBattery != weatherData.lowBattery) {
this.lowBattery = weatherData.lowBattery;
dataChanged = true;
}

if (dataChanged) {
this.getServices().forEach(
function(svc) {
var call = svc.updateCharacteristics && svc.updateCharacteristics();
}
);
}
}
}
return EveatmoWindAccessory;
};
6 changes: 5 additions & 1 deletion device/weatherstation-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ var homebridge;
var EveatmoRoomAccessory;
var EveatmoWeatherAccessory;
var EveatmoRainAccessory;
var EveatmoWindAccessory;

module.exports = function(pHomebridge) {
if (pHomebridge && !homebridge) {
homebridge = pHomebridge;
EveatmoRoomAccessory = require("../accessory/eveatmo-room-accessory")(homebridge);
EveatmoWeatherAccessory = require("../accessory/eveatmo-weather-accessory")(homebridge);
EveatmoRainAccessory = require("../accessory/eveatmo-rain-accessory")(homebridge);
EveatmoWindAccessory = require("../accessory/eveatmo-wind-accessory")(homebridge);
}

class WeatherstationDeviceType extends NetatmoDevice {
Expand Down Expand Up @@ -59,7 +61,9 @@ module.exports = function(pHomebridge) {
return new EveatmoWeatherAccessory(deviceData, this);
} else if(deviceData.type == 'NAModule3') { // Rain
return new EveatmoRainAccessory(deviceData, this);
}
} else if(deviceData.type == 'NAModule2') { // Wind
return new EveatmoWindAccessory(deviceData, this);
}
return false;
}
}
Expand Down
91 changes: 91 additions & 0 deletions mockapi_calls/getstationsdata-eveatmo.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,97 @@
"rf_status": 67,
"firmware": 43
},
{
"_id": "10:00:00:00:00:05",
"type": "NAModule2",
"last_message": 1469639523,
"last_seen": 1469639502,
"dashboard_data": {
"WindAngle": 188,
"WindStrength": 6,
"GustAngle": 143,
"GustStrength": 15,
"time_utc": 1469905065
},
"WindHistoric": [
{
"WindStrength": "6",
"WindAngle": 200,
"time_utc": 1469901739
},
{
"WindStrength": "6",
"WindAngle": 217,
"time_utc": 1469902040
},
{
"WindStrength": "6",
"WindAngle": 200,
"time_utc": 1469902342
},
{
"WindStrength": "4",
"WindAngle": 178,
"time_utc": 1469902643
},
{
"WindStrength": "7",
"WindAngle": 197,
"time_utc": 1469902944
},
{
"WindStrength": "9",
"WindAngle": 182,
"time_utc": 1469903245
},
{
"WindStrength": "10",
"WindAngle": 191,
"time_utc": 1469903546
},
{
"WindStrength": "8",
"WindAngle": 193,
"time_utc": 1469903848
},
{
"WindStrength": "6",
"WindAngle": 194,
"time_utc": 1469904155
},
{
"WindStrength": "7",
"WindAngle": 213,
"time_utc": 1469904457
},
{
"WindStrength": "6",
"WindAngle": 192,
"time_utc": 1469904764
},
{
"WindStrength": "6",
"WindAngle": 188,
"time_utc": 1469905065
}
],
"date_max_wind_str": 1469903245,
"date_max_temp": 1469851393,
"date_min_temp": 1469881855,
"min_temp": -0.8,
"max_temp": 0,
"max_wind_angle": 225,
"max_wind_str": 22,
"data_type": [
"Wind"
],
"module_name": "Wind Gauge",
"last_setup": 1464467149,
"battery_vp": 5940,
"battery_percent": 97,
"rf_status": 75,
"firmware": 17
},
{
"_id": "03:00:00:01:23:45",
"type": "NAModule4",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "homebridge-eveatmo",
"version": "0.3.7",
"version": "0.4.0",
"description": "Homebridge plugin which adds a Netatmo weatherstation as HomeKit device and tries to act like Elgato Eve Room/Weather",
"license": "ISC",
"keywords": [
Expand Down
121 changes: 121 additions & 0 deletions service/eveatmo-wind.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
'use strict';

var homebridge;
var Characteristic;

const WIND_MEASURE_STYPE_ID = "2AFB775E-79E5-4399-B3CD-398474CAE86C";
const WIND_STRENGTH_CTYPE_ID = "49C8AE5A-A3A5-41AB-BF1F-12D5654F9F41";
const WIND_ANGLE_CTYPE_ID = "46F1284C-1912-421B-82F5-EB75008B167E";

module.exports = function(pHomebridge) {
if (pHomebridge && !homebridge) {
homebridge = pHomebridge;
Characteristic = homebridge.hap.Characteristic;
}

class WindStrengthCharacteristic extends Characteristic {
constructor(accessory) {
super('Wind Strength', WIND_STRENGTH_CTYPE_ID);
this.setProps({
format: Characteristic.Formats.FLOAT,
unit: "km/h",
minValue: 0,
maxValue: 100,
minStep: 0.1,
perms: [
Characteristic.Perms.READ,
Characteristic.Perms.NOTIFY
]
});
this.value = this.getDefaultValue();
}
}

class WindAngleCharacteristic extends Characteristic {
constructor(accessory) {
super('Wind Angle', WIND_ANGLE_CTYPE_ID);
this.setProps({
format: Characteristic.Formats.STRING,
perms: [
Characteristic.Perms.READ,
Characteristic.Perms.NOTIFY
]
});
this.value = this.getDefaultValue();
}
}

class WindService extends homebridge.hap.Service {
constructor(accessory) {
super(accessory.name + " Wind Sensor", WIND_MEASURE_STYPE_ID);
this.accessory = accessory;

this.addCharacteristic(WindStrengthCharacteristic)
.on('get', this.getWindStrength.bind(this))
.eventEnabled = true;
this.addCharacteristic(WindAngleCharacteristic)
.on('get', this.getWindAngle.bind(this))
.eventEnabled = true;

this.addOptionalCharacteristic(Characteristic.Name);
}

updateCharacteristics() {
this.getCharacteristic(WindStrengthCharacteristic)
.updateValue(this.accessory.windStrength);
this.getCharacteristic(WindAngleCharacteristic)
.updateValue(this.transformDirectionDegToString());
}

getWindStrength(callback) {
this.accessory.refreshData(function(err,data) {
callback(err, this.accessory.windStrength);
}.bind(this));
}

getWindAngle(callback) {
this.accessory.refreshData(function(err,data) {
callback(err, this.transformDirectionDegToString());
}.bind(this));
}

transformDirectionDegToString() {
var a = this.accessory.windAngle;
if (a >= 348.75 || a < 11.25) {
return 'N';
} else if (a >= 11.25 && a < 33.75) {
return 'NNE';
} else if (a >= 33.75 && a < 56.25) {
return 'NE';
} else if (a >= 56.25 && a < 78.75) {
return 'ENE';
} else if (a >= 78.75 && a < 101.25) {
return 'E';
} else if (a >= 101.25 && a < 123.75) {
return 'ESE';
} else if (a >= 123.75 && a < 146.25) {
return 'SE';
} else if (a >= 146.25 && a < 168.75) {
return 'SSE';
} else if (a >= 168.75 && a < 191.25) {
return 'S';
} else if (a >= 191.25 && a < 213.75) {
return 'SSW';
} else if (a >= 213.75 && a < 236.25) {
return 'SW';
} else if (a >= 236.25 && a < 258.75) {
return 'WSW';
} else if (a >= 258.75 && a < 281.25) {
return 'W';
} else if (a >= 281.25 && a < 303.75) {
return 'WNW';
} else if (a >= 303.75 && a < 326.25) {
return 'NW';
} else if (a >= 326.25 && a < 348.75) {
return 'NNW';
}
}
}

return WindService;
};

0 comments on commit b9da646

Please sign in to comment.