-
-
Save dnoegel/c6cb7f176d25199c0575dce97ee87253 to your computer and use it in GitHub Desktop.
Typescript Modbus Iobroker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var dec, number, bitPosition, einspeisung, timeout2, timeout; | |
// Beschreibe diese Funktion … | |
async function extractRunningStates(dec) { | |
function decToBit(dec, bitPosition) { | |
return (dec & (1 << bitPosition)) === 0 ? false : true; | |
} | |
// Creates a state if it does not exist yet | |
function createStateIfNotExists(state, name) | |
{ | |
// createState(state, 0, true, {name: name, type: "number", role: 'value'}, function () {}); | |
if ( !existsState(state )) { | |
createState(state, 0, false, {name: name, type: "number", role: 'value'}, function () {}); | |
} | |
} | |
// Create states | |
createStateIfNotExists("0_userdata.0.PV.PvToLoad", "Power from PV to load"); | |
createStateIfNotExists("0_userdata.0.PV.PvToBat", "Power from PV to bat"); | |
createStateIfNotExists("0_userdata.0.PV.PvToGrid", "Power from PV to grid"); | |
createStateIfNotExists("0_userdata.0.PV.BatToLoad", "Power from Bat to load"); | |
createStateIfNotExists("0_userdata.0.PV.BatToGrid", "Power from Bat to grid"); | |
createStateIfNotExists("0_userdata.0.PV.GridToLoad", "Power from grid to load"); | |
createStateIfNotExists("0_userdata.0.PV.GridToBat", "Power from Gridto battery"); | |
createStateIfNotExists("0_userdata.0.PV.SignedBat", "Battery but with minus sign for charging"); | |
// Decode running state flags | |
$powerGeneratedFromPV = decToBit(dec, 0); | |
$batteryCharging = decToBit(dec, 1); | |
$batteryDischarging = decToBit(dec, 2); | |
$loadActive = decToBit(dec, 3); | |
$powerFeedIntoGrid = decToBit(dec, 4); | |
$powerImportFromGrid = decToBit(dec, 5); | |
$powerGeneratedFromLoad = decToBit(dec, 7); | |
// Save running state more speaking fields | |
setState("0_userdata.0.PV.PowerGeneratedFromPV", $powerGeneratedFromPV, true); | |
setState("0_userdata.0.PV.BatteryCharging", $batteryCharging, true); | |
setState("0_userdata.0.PV.BatteryDischarging", $batteryDischarging, true); | |
setState("0_userdata.0.PV.LoadActive", $loadActive, true); | |
setState("0_userdata.0.PV.PowerFeedIntoGrid", $powerFeedIntoGrid, true); | |
setState("0_userdata.0.PV.PowerImportFromGrid", $powerImportFromGrid, true); | |
setState("0_userdata.0.PV.PowerGeneratedFromLoad", $powerGeneratedFromLoad, true); | |
// Read current power levels of bat, pv, load and grid | |
$load = getState("modbus.0.inputRegisters.13007_Load_power_").val; | |
$grid = getState("modbus.0.inputRegisters.13009_Export_power").val; | |
$pv = getState("modbus.0.inputRegisters.5016_Total_DC_Power").val; | |
//$pv = getState("modbus.0.inputRegisters.13033_Total_active_power").val; // This register gives more plausible values regarding pvToGrid and the actual grid values. But was wrong by a few 100 watts in the mornung | |
$battery = getState("modbus.0.inputRegisters.13021_Battery_power_").val; | |
// Write signed bat | |
setState("0_userdata.0.PV.SignedBat", $batteryCharging ? $battery * -1 : $battery, true); | |
// Calculate PV | |
$pvToBat = 0; | |
$pvToLoad = 0; | |
$pvToGrid = 0; | |
$loadRemaining = $load; | |
if ($powerGeneratedFromPV) { | |
$remaining = $pv; | |
if ($remaining > $loadRemaining) { | |
$pvToLoad = $loadRemaining; | |
$remaining -= $load; | |
$loadRemaining = 0; | |
} else { | |
$pvToLoad = $remaining; | |
$loadRemaining = $load - $remaining; | |
$remaining = 0; | |
} | |
if ($batteryCharging) { | |
if ($remaining > $battery) { | |
$pvToBat = $battery; | |
$remaining -= $battery; | |
} else { | |
$pvToBat = $remaining; | |
$remaining = 0; | |
} | |
} | |
if ($grid > 0) { | |
$pvToGrid = Math.min($grid, $remaining); | |
} | |
} | |
setState("0_userdata.0.PV.PvToLoad", $pvToLoad); | |
setState("0_userdata.0.PV.PvToBat", $pvToBat); | |
setState("0_userdata.0.PV.PvToGrid", $pvToGrid); | |
// Calculate Bat | |
$batToLoad = 0; | |
$batToGrid = 0; | |
if ($batteryDischarging) { | |
$remaining = $battery; | |
if ($remaining > $loadRemaining) { | |
$batToLoad = $loadRemaining; | |
$remaining -= $loadRemaining; | |
$loadRemaining = 0; | |
} else { | |
$batToLoad = $remaining; | |
$loadRemaining -= $remaining; | |
$remaining = 0; | |
} | |
if ($powerFeedIntoGrid) { | |
$batToGrid = Math.min($grid, $remaining); | |
} | |
} | |
setState("0_userdata.0.PV.BatToLoad", $batToLoad); | |
setState("0_userdata.0.PV.BatToGrid", $batToGrid); | |
// Calculate grid | |
$gridToBat = 0; | |
$gridToLoad = 0; | |
if ($grid < 0) { | |
$remaining = Math.abs($grid); | |
if ($remaining > $loadRemaining) { | |
$gridToLoad = $loadRemaining; | |
$remaining -= $loadRemaining; | |
$loadRemaining = 0; | |
} else { | |
$gridToLoad = $remaining; | |
$loadRemaining -= $remaining; | |
$remaining = 0; | |
} | |
if ($batteryCharging) { | |
$gridToBat = Math.min($battery, $remaining);; | |
} | |
} | |
setState("0_userdata.0.PV.GridToLoad", $gridToLoad); | |
setState("0_userdata.0.PV.GridToBat", $gridToBat); | |
} | |
// Beschreibe diese Funktion … | |
async function getBit(number, bitPosition) { | |
return (number & (1 << bitPosition)) === 0 ? 0 : 1; | |
} | |
// Beschreibe diese Funktion … | |
async function debug_output(dec) { | |
// create some debug messages so we can check state changes in the log after the fact | |
console.log(('Power generation' + String(await getBit(dec, 0)))); | |
console.log(('Battery charging' + String(await getBit(dec, 1)))); | |
console.log(('Battery discharging' + String(await getBit(dec, 2)))); | |
console.log(('Positive load' + String(await getBit(dec, 3)))); | |
console.log(('Power feed into the grid' + String(await getBit(dec, 4)))); | |
console.log(('Power from the grid' + String(await getBit(dec, 5)))); | |
console.log(('Power from load' + String(await getBit(dec, 7)))); | |
} | |
// MPPT Leistung ausmultiplizieren | |
on({id: [].concat(['modbus.0.inputRegisters.5010_MPPT_1_Voltage']).concat(['modbus.0.inputRegisters.5012_MPPT_2_Voltage']), change: "ne"}, async function (obj) { | |
setState("0_userdata.0.PV.MPPT1"/*MPPT1*/, (Math.round(parseFloat(getState("modbus.0.inputRegisters.5010_MPPT_1_Voltage").val) * getState("modbus.0.inputRegisters.5011_MPPT_1_Current").val)), true); | |
setState("0_userdata.0.PV.MPPT2"/*MPPT2*/, (Math.round(parseFloat(getState("modbus.0.inputRegisters.5012_MPPT_2_Voltage").val) * getState("modbus.0.inputRegisters.5013_MPPT_2_Current").val)), true); | |
}); | |
// Bei Änderung von Status oder Wirkleistung | |
// Running state + Leistungen extrahieren | |
on({id: [].concat(['modbus.0.inputRegisters.13000_Running_State']).concat(['modbus.0.inputRegisters.13007_Load_power_']), change: "ne"}, async function (obj) { | |
await wait(50); | |
await extractRunningStates(getState("modbus.0.inputRegisters.13000_Running_State").val); | |
setState("0_userdata.0.PV.EnergyConsumptionToday"/*EnergyConsumptionToday*/, Math.round(([getState("modbus.0.inputRegisters.13016_Daily_direct__Energy_Consumption").val, getState("modbus.0.inputRegisters.13035_Daily_Import_Energy").val, getState("modbus.0.inputRegisters.13025_Daily_battery_discharge_Energy").val].reduce(function(x, y) {return x + y;}))*10)/10, true); | |
}); | |
// Alle 10 Minuten: Running States ausgeben | |
schedule("*/10 * * * *", async function () { | |
}); | |
await debug_output(getState("modbus.0.inputRegisters.13000_Running_State").val); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment