@smappee/node-red-contrib-smappee-solar
Version:
62 lines (50 loc) • 1.79 kB
JavaScript
const context = context
const flow = flow
const msg = msg
// Value to base charge level thresholds on
const thresholds = [
[], // From 00:00 to the next
[], // From 12:00 to the next
[] // From 18:00 to end of day
]
// Smappee values
const production = msg.totalExportEnergy
const consumption = msg.totalImportEnergy
const excessProduction = production > consumption
// State variables
const lastUpdate = context.get('lastUpdate') || 0
const chargeLevel = flow.get('chargeLevel') || undefined
const chargingState = flow.get('chargingState') || false
const chargingMode = flow.get('chargingMode') || 'auto'
// Update state every 5 minutes if necessary
const shouldUpdate = (Date.now() - lastUpdate) > (5 * 60 * 1000)
// Message variables
let solarMsg = null
let evMsg = null
// Check if charge level should be updated
if (excessProduction && shouldUpdate) {
solarMsg = {payload: true}
context.set('lastUpdate', Date.now())
}
// Use the first value as the default
let threshold = thresholds[0][1]
// Dynamically determine appropriate threshold value
const hours = new Date().getHours()
for (let i = 1; i < thresholds.length; i++) {
let condition = thresholds[i][0]
// Always pick last applicable condition
if (hours <= condition) {
threshold = thresholds[i][1]
}
}
// Determine if EV should be turned on
if (chargingMode === 'auto') {
if (excessProduction && !chargingState && chargeLevel > threshold) {
evMsg = {payload: true}
} else if (!excessProduction || (chargingState && chargeLevel <= threshold)) {
evMsg = {payload: false}
}
} else if ((chargingMode === 'on' && !chargingState) || (chargingMode === 'off' && chargingState)) {
evMsg = {payload: chargingMode === 'on'}
}
return [solarMsg, evMsg, {payload: chargingMode}]