scrypted-tempest
Version:
Scrypted Tempest Plugin
390 lines (369 loc) • 13 kB
text/typescript
import { Sensor, Setting } from "@scrypted/sdk"
import { UnitConverter, Unit, UnitGroup } from '../../scrypted-homeassistant/src/unitConverter';
export interface Observations {
observations: ObservationsData[];
}
export interface ObservationsData {
stationID: string
obsTimeUtc: string
obsTimeLocal: string
neighborhood: string
softwareType: string
country: string
solarRadiation: number
lon: number
realtimeFrequency: any
epoch: number
lat: number
uv: number
winddir: number
humidity: number
qcStatus: number
metric: {
temp: number
heatIndex: number
dewpt: number
windChill: number
windSpeed: number
windGust: number
pressure: number
precipRate: number
precipTotal: number
elev: number
}
}
export interface ForecastData {
calendarDayTemperatureMax: number[]
calendarDayTemperatureMin: number[]
dayOfWeek: string[]
expirationTimeUtc: number[]
moonPhase: string[]
moonPhaseCode: string[]
moonPhaseDay: number[]
moonriseTimeLocal: string[]
moonriseTimeUtc: number | undefined[]
moonsetTimeLocal: string[]
moonsetTimeUtc: number[]
narrative: string[]
qpf: number[]
qpfSnow: number[]
sunriseTimeLocal: string[]
sunriseTimeUtc: number[]
sunsetTimeLocal: string[]
sunsetTimeUtc: number[]
temperatureMax: number[]
temperatureMin: number[]
validTimeLocal: string[]
validTimeUtc: number[]
daypart: Daypart[]
}
export interface Daypart {
cloudCover: number[]
dayOrNight: string[]
daypartName: string[]
iconCode: number[]
iconCodeExtend: number[]
narrative: string[]
precipChance: number[]
precipType: string[]
qpf: number[]
qpfSnow: number[]
qualifierCode: string | undefined[]
qualifierPhrase: string | undefined[]
relativeHumidity: number[]
snowRange: string[]
temperature: number[]
temperatureHeatIndex: number[]
temperatureWindChill: number[]
thunderCategory: any[]
thunderIndex: number[]
uvDescription: string[]
uvIndex: number[]
windDirection: number[]
windDirectionCardinal: string[]
windPhrase: string[]
windSpeed: number[]
wxPhraseLong: string[]
wxPhraseShort: string[]
}
export const convertWeatherDataToSensors = (data: ObservationsData) => {
const newSensorsData: Record<string, Sensor> = {};
newSensorsData['solarRadiation'] = {
name: 'Solar radiation',
unit: 'W/m²',
value: data.solarRadiation,
};
newSensorsData['uvIndex'] = {
name: 'UV index',
value: data.uv,
};
newSensorsData['windDirection'] = {
name: 'Wind direction',
unit: '°',
value: data.uv,
};
newSensorsData['humidity'] = {
name: 'Humidity',
unit: '%',
value: data.humidity,
};
newSensorsData['temperature'] = {
name: 'Temperature',
unit: '°C',
value: data.metric.temp,
};
newSensorsData['heatIndex'] = {
name: 'Head index',
value: data.metric.heatIndex,
};
newSensorsData['dewPoint'] = {
name: 'Dew point',
unit: '°C',
value: data.metric.dewpt,
};
newSensorsData['windChill'] = {
name: 'Wind chill',
unit: '°C',
value: data.metric.windChill,
};
newSensorsData['windSpeed'] = {
name: 'Wind speed',
unit: 'km/h',
value: data.metric.windSpeed,
};
newSensorsData['windGust'] = {
name: 'Wind gust',
unit: 'km/h',
value: data.metric.windGust,
};
newSensorsData['pressure'] = {
name: 'Pressure',
unit: 'hPa',
value: data.metric.pressure,
};
newSensorsData['rainRate'] = {
name: 'Rain rate',
unit: 'mm/h',
value: data.metric.precipRate,
};
newSensorsData['elevation'] = {
name: 'Elevation',
unit: 'm',
value: data.metric.elev,
};
return newSensorsData;
}
export enum UnitsSelector {
Imperial = 'e=English',
Metric = 'm=Metric',
}
const getUnit = (units: UnitsSelector, unitGroup: UnitGroup) => {
const isMetric = units === UnitsSelector.Metric;
if (unitGroup === UnitGroup.Temperature) {
return isMetric ? Unit.C : Unit.F;
} else if (unitGroup === UnitGroup.Speed) {
return isMetric ? Unit.KM_H : Unit.MI_H;
}
}
export const convertForecastDataToSensors = (data: ForecastData, units: UnitsSelector) => {
const daysAmount = data.dayOfWeek.length;
const partsPerDay = data.daypart[0].daypartName.length / daysAmount;
const dayIndexes = Array.from(Array(daysAmount), (_, index) => index);
const settings: Setting[] = [];
const newSensorsData: Record<string, Sensor> = {};
for (const dayIndex of dayIndexes) {
const dayPartIndexes = Array.from(Array(partsPerDay), (_, index) => index);
const group = dayIndex === 0 ? 'Today' : data.dayOfWeek[dayIndex];
const addSetting = (props: {
name: string;
sensorId: string;
subgroup?: string;
value: any;
unit?: string;
}) => {
const { name, sensorId, subgroup, value, unit } = props;
let textValue = value;
if (unit) {
textValue += ` (${unit})`;
}
newSensorsData[sensorId] = {
name: subgroup ? `${name} ${subgroup}` : `${name} ${group}`,
unit,
value,
};
settings.push({
key: sensorId,
title: `${name} (${sensorId})`,
type: 'string',
readonly: true,
value: textValue,
group,
subgroup,
});
};
addSetting({
name: `Narrative`,
sensorId: `narrative${dayIndex}`,
value: data.narrative[dayIndex],
});
// addSetting({
// name: `Expiration time UTC`,
// sensorId: `expirationTime${dayIndex}`,
// value: data.expirationTimeUtc[dayIndex],
// });
// addSetting({
// name: `Moonphase`,
// sensorId: `moonPhase${dayIndex}`,
// value: data.moonPhase[dayIndex],
// });
// addSetting({
// name: `Moonrise time local`,
// sensorId: `moonriseTimeLocal${dayIndex}`,
// value: data.moonriseTimeLocal[dayIndex],
// });
// addSetting({
// name: `Moonset time local`,
// sensorId: `moonsetTimeLocal${dayIndex}`,
// value: data.moonsetTimeLocal[dayIndex],
// });
addSetting({
name: `Sunrise time local`,
sensorId: `sunriseTimeLocal${dayIndex}`,
value: data.sunriseTimeLocal[dayIndex],
});
addSetting({
name: `Sunset time local`,
sensorId: `sunsetTimeLocal${dayIndex}`,
value: data.sunsetTimeLocal[dayIndex],
});
addSetting({
name: `Temperature min`,
sensorId: `temperatureMin${dayIndex}`,
value: UnitConverter.localToSi(
data.temperatureMin[dayIndex] ?? data.calendarDayTemperatureMin[dayIndex],
getUnit(units, UnitGroup.Temperature)
),
unit: Unit.C
});
addSetting({
name: `Temperature max`,
sensorId: `temperatureMax${dayIndex}`,
value: UnitConverter.localToSi(
data.temperatureMax[dayIndex] ?? data.calendarDayTemperatureMax[dayIndex],
getUnit(units, UnitGroup.Temperature)
),
unit: Unit.C
});
for (const dayPartIndex of dayPartIndexes) {
const partIndex = dayPartIndex + (dayIndex * partsPerDay);
const partName = data.daypart[0]?.daypartName[partIndex];
const partCode = data.daypart[0]?.dayOrNight[partIndex];
if (partName) {
addSetting({
name: `Narrative`,
sensorId: `narrative${dayIndex}${partCode}`,
value: data.daypart[0]?.narrative[partIndex],
subgroup: partName
});
addSetting({
name: `Qualifier phrase`,
sensorId: `qualifierPhrase${dayIndex}${partCode}`,
value: data.daypart[0]?.qualifierPhrase[partIndex],
subgroup: partName
});
addSetting({
name: `Sensible weather phrase`,
sensorId: `sensibleWeatherPhrase${dayIndex}${partCode}`,
value: data.daypart[0]?.wxPhraseLong[partIndex],
subgroup: partName
});
addSetting({
name: `Cloud coverage`,
sensorId: `cloudCover${dayIndex}${partCode}`,
value: data.daypart[0]?.cloudCover[partIndex],
unit: '%',
subgroup: partName
});
addSetting({
name: `Precipitation chance`,
sensorId: `precipChance${dayIndex}${partCode}`,
value: data.daypart[0]?.precipChance[partIndex],
unit: '%',
subgroup: partName
});
addSetting({
name: `Precipitation type`,
sensorId: `precipType${dayIndex}${partCode}`,
value: data.daypart[0]?.precipType[partIndex],
subgroup: partName
});
addSetting({
name: `Relative humidity`,
sensorId: `relativeHumidity${dayIndex}${partCode}`,
value: data.daypart[0]?.relativeHumidity[partIndex],
unit: '%',
subgroup: partName
});
addSetting({
name: `Temperature`,
sensorId: `temperature${dayIndex}${partCode}`,
value: UnitConverter.localToSi(data.daypart[0]?.temperature[partIndex], getUnit(units, UnitGroup.Temperature)),
unit: Unit.C,
subgroup: partName
});
// addSetting({
// name: `Heat index`,
// sensorId: `temperatureHeatIndex${dayIndex}${partCode}`,
// value: data.daypart[0]?.temperatureHeatIndex[partIndex],
// subgroup: partName
// });
// addSetting({
// name: `Thunder index`,
// sensorId: `thunderIndex${dayIndex}${partCode}`,
// value: data.daypart[0]?.thunderIndex[partIndex],
// subgroup: partName
// });
// addSetting({
// name: `UV index`,
// sensorId: `uvIndex${dayIndex}${partCode}`,
// value: data.daypart[0]?.uvIndex[partIndex],
// subgroup: partName
// });
addSetting({
name: `UV phrase`,
sensorId: `uvDescription${dayIndex}${partCode}`,
value: data.daypart[0]?.uvDescription[partIndex],
subgroup: partName
});
addSetting({
name: `Wind chill`,
sensorId: `uvDescription${dayIndex}${partCode}`,
value: UnitConverter.localToSi(data.daypart[0]?.temperatureWindChill[partIndex], getUnit(units, UnitGroup.Temperature)),
unit: Unit.C,
subgroup: partName
});
addSetting({
name: `Wind direction`,
sensorId: `windDirection${dayIndex}${partCode}`,
value: data.daypart[0]?.windDirection[partIndex],
unit: '°',
subgroup: partName
});
addSetting({
name: `Wind phrase`,
sensorId: `windPhrase${dayIndex}${partCode}`,
value: data.daypart[0]?.windPhrase[partIndex],
subgroup: partName
});
addSetting({
name: `Wind speed`,
sensorId: `windSpeed${dayIndex}${partCode}`,
value: UnitConverter.localToSi(data.daypart[0]?.windSpeed[partIndex], getUnit(units, UnitGroup.Speed)),
unit: Unit.M_S,
subgroup: partName
});
}
}
}
return { newSensorsData, settings };
}