Skip to content

Commit

Permalink
checkpoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
chasenicholl committed Nov 1, 2023
1 parent ccff5c1 commit 9632777
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig,
import { PLATFORM_NAME, PLUGIN_NAME } from './settings';
import { WeatherFlowTempestPlatformAccessory } from './platformAccessory';

import { TempestApi, Observation } from './tempestApi';
import { TempestApi, Observation } from './tempest';

interface TempestSensor {
name: string;
Expand Down
115 changes: 115 additions & 0 deletions src/tempestApi.ts → src/tempest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Logger } from 'homebridge';
import axios, { AxiosResponse } from 'axios';
import * as dgram from 'dgram';

export interface Observation {
// temperature sensors
Expand All @@ -26,6 +27,120 @@ export interface Observation {
brightness: number; // Lux
}

export interface SocketObservation {

timestamp: number;
windLull: number;
windSpeed: number;
windGust: number;
windDirection: number;
pressure: number;
temperature: number;
humidity: number;
illumination: number;
uvIndex: number;
solarRadiation: number;
rain: number;
strikes: number;
lightningDistance: number;
reportingInterval: number;

}


export class TempestSocket {

private log: Logger;
private s: dgram.Socket;

constructor(log: Logger, address = '0.0.0.0', port = 50222) {

this.log = log;
this.s = dgram.createSocket('udp4');
this.setupSocket(address, port);
this.setupSignalHandlers();
}

private setupSocket(address: string, port: number) {

// this.s.setsockopt(dgram.SOL_SOCKET, dgram.SO_REUSEADDR, 1);
// this.s.setsockopt(dgram.SOL_SOCKET, dgram.SO_REUSEPORT, 1);
this.s.bind({ address: address, port: port });
this.s.on('message', (msg) => {
try {
const message_string = msg.toString('utf-8');
const data = JSON.parse(message_string);
this.processReceivedData(data);
} catch (error) {
this.log.warn('JSON processing of data failed');
this.log.error(error as string);
}
});

this.s.on('error', (err) => {
this.log.error('Socket error:', err);
});

}

private processReceivedData(data: any) {
// if (data.type === 'obs_air') {
// console.log(data);
// // air_tm = this.air_data(data, air_tm);
// }

if (data.type === 'obs_st') {
// console.log(data);
this.parseTempestData(data);
// st_tm = this.tempest_data(data, st_tm);
}

// if (data.type === 'obs_sky') {
// console.log(data);
// // sky_tm = this.sky_data(data, sky_tm);
// }
}

private parseTempestData(data: any): SocketObservation {
const obs = data.obs[0];
const windLull = (obs[1] !== null) ? obs[1] * 2.2369 : 0;
const windSpeed = (obs[2] !== null) ? obs[2] * 2.2369 : 0;
const windGust = (obs[3] !== null) ? obs[3] * 2.2369 : 0;
return {
timestamp: obs[0],
windLull: windLull,
windSpeed: windSpeed,
windGust: windGust,
windDirection: obs[4],
pressure: obs[6],
temperature: obs[7],
humidity: obs[8],
illumination: obs[9],
uvIndex: obs[10],
solarRadiation: obs[11],
rain: parseFloat(obs[12]),
strikes: obs[14],
lightningDistance: obs[15],
reportingInterval: obs[17],
} as SocketObservation;

}

private setupSignalHandlers() {

process.on('SIGTERM', () => {
this.log.info('Got SIGTERM, shutting down Tempest Homebridge...');
});

process.on('SIGINT', () => {
this.log.info('Got SIGINT, shutting down Tempest Homebridge...');
this.s.close();
});

}

}

export class TempestApi {

private log: Logger;
Expand Down
119 changes: 119 additions & 0 deletions src/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import * as dgram from 'dgram';

export interface SocketObservation {

timestamp: number;
windLull: number;
windSpeed: number;
windGust: number;
windDirection: number;
pressure: number;
temperature: number;
humidity: number;
illumination: number;
uvIndex: number;
solarRadiation: number;
rain: number;
strikes: number;
lightningDistance: number;
reportingInterval: number;

}


export class TempestSocket {

// private log: Logger;
private s: dgram.Socket;

constructor(address = '0.0.0.0', port = 50222) {

// this.log = log;
this.s = dgram.createSocket('udp4');
this.setupSocket(address, port);
this.setupSignalHandlers();
}

private setupSocket(address: string, port: number) {

// this.s.setsockopt(dgram.SOL_SOCKET, dgram.SO_REUSEADDR, 1);
// this.s.setsockopt(dgram.SOL_SOCKET, dgram.SO_REUSEPORT, 1);
this.s.bind({ address: address, port: port });
this.s.on('message', (msg) => {
try {
const message_string = msg.toString('utf-8');
const data = JSON.parse(message_string);
console.log(data);
this.processReceivedData(data);
} catch (error) {
console.log('JSON processing of data failed');
console.log(error as string);
}
});

this.s.on('error', (err) => {
console.log('Socket error:', err);
});

}

private processReceivedData(data: any) {
// if (data.type === 'obs_air') {
// console.log(data);
// // air_tm = this.air_data(data, air_tm);
// }

if (data.type === 'obs_st') {
// console.log(data);
const parsed_data = this.parseTempestData(data);
console.log(parsed_data);
// st_tm = this.tempest_data(data, st_tm);
}

// if (data.type === 'obs_sky') {
// console.log(data);
// // sky_tm = this.sky_data(data, sky_tm);
// }
}

private parseTempestData(data: any): SocketObservation {
const obs = data.obs[0];
const windLull = (obs[1] !== null) ? obs[1] * 2.2369 : 0;
const windSpeed = (obs[2] !== null) ? obs[2] * 2.2369 : 0;
const windGust = (obs[3] !== null) ? obs[3] * 2.2369 : 0;
return {
timestamp: obs[0],
windLull: windLull,
windSpeed: windSpeed,
windGust: windGust,
windDirection: obs[4],
pressure: obs[6],
temperature: obs[7],
humidity: obs[8],
illumination: obs[9],
uvIndex: obs[10],
solarRadiation: obs[11],
rain: parseFloat(obs[12]),
strikes: obs[14],
lightningDistance: obs[15],
reportingInterval: obs[17],
} as SocketObservation;

}

private setupSignalHandlers() {

process.on('SIGTERM', () => {
console.log('Got SIGTERM, shutting down Tempest Homebridge...');
});

process.on('SIGINT', () => {
console.log('Got SIGINT, shutting down Tempest Homebridge...');
this.s.close();
});

}

}

new TempestSocket();
30 changes: 30 additions & 0 deletions src/tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(("0.0.0.0", 50222))

stopped = False
try:
while not stopped:
try:
hub = s.recvfrom(1024)
data = json.loads(hub[0].decode("utf-8")) # hub is a truple (json, ip, port)
except json.JSONDecodeError:
print("JSON processing of data failed")
continue

if (data["type"] == "obs_air"):
print(data)
# air_tm = self.air_data(data, air_tm)

if (data["type"] == "obs_st"):
print(data)
parse_tempest_data(data)
# st_tm = self.tempest_data(data, st_tm)

if (data["type"] == "obs_sky"):
print(data)
# sky_tm = self.sky_data(data, sky_tm)
except KeyboardInterrupt:
print("Keyboard Interupt")
s.close()
72 changes: 72 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import json
import socket


def open_socket_connection():

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(("0.0.0.0", 50222))

stopped = False
try:
while not stopped:
try:
hub = s.recvfrom(1024)
data = json.loads(hub[0].decode("utf-8")) # hub is a truple (json, ip, port)
except json.JSONDecodeError:
print("JSON processing of data failed")
continue

if (data["type"] == "obs_air"):
print(data)
# air_tm = self.air_data(data, air_tm)

if (data["type"] == "obs_st"):
print(data)
parse_tempest_data(data)
# st_tm = self.tempest_data(data, st_tm)

if (data["type"] == "obs_sky"):
print(data)
# sky_tm = self.sky_data(data, sky_tm)
except KeyboardInterrupt:
print("Keyboard Interupt")
s.close()


def parse_tempest_data(data):
timestamp = data['obs'][0][0] # ts
# convert wind speed from m/s to MPH
if (data["obs"][0][1] is not None):
wind_lull = data["obs"][0][1] * 2.2369 # wind lull
else:
wind_lull = 0
if (data["obs"][0][2] is not None):
wind_speed = data["obs"][0][2] * 2.2369 # wind speed
else:
wind_speed = 0
if (data["obs"][0][3] is not None):
wind_gust = data["obs"][0][3] * 2.2369 # wind gust
else:
wind_gust = 0
wind_direction = data['obs'][0][4] # wind direction
pressure = data['obs'][0][6] # pressure
temperature = data['obs'][0][7] # temp
humidity = data['obs'][0][8] # humidity
illumination = data['obs'][0][9] # Illumination
uv_index = data['obs'][0][10] # UV Index
solar_radiation = data['obs'][0][11] # solar radiation
rain = float(data['obs'][0][12]) # rain
strikes = data['obs'][0][14] # strikes
lightening_distance = data['obs'][0][15] # distance
reporting_interval = data['obs'][0][17] # reporting interval


def main():
open_socket_connection()


if __name__ == "__main__":
main()

0 comments on commit 9632777

Please sign in to comment.