Skip to content

Instantly share code, notes, and snippets.

@vankxr
Last active January 5, 2022 12:08
Show Gist options
  • Save vankxr/a7acad10b0ddfe273724b21b2dd46c1d to your computer and use it in GitHub Desktop.
Save vankxr/a7acad10b0ddfe273724b21b2dd46c1d to your computer and use it in GitHub Desktop.
Read HP Common slot PSUs via I2C from NodeJS
const I2C = require("i2c-bus");
function psu_calc_checksum(addr, buf)
{
let cs = (addr << 1);
for(let i = 0; i < buf.length - 1; i++)
cs += buf.readUInt8(i);
buf.writeUInt8(((0xFF - cs) + 1) & 0xFF, buf.length - 1);
}
function psu_check_checksum(buf)
{
let cs = 0;
for(let i = 0; i < buf.length; i++)
cs += buf.readUInt8(i);
if((((0xFF - cs) + 1) & 0xFF) === 0)
return true;
return false;
}
async function psu_write_reg(bus, addr, reg, data)
{
let buf = Buffer.alloc(4, 0);
buf.writeUInt8(reg, 0);
buf.writeUInt16LE(data, 1);
psu_calc_checksum(addr, buf);
return bus.i2cWrite(addr, buf.length, buf);
}
async function psu_read_reg(bus, addr, reg)
{
let buf = Buffer.alloc(2, 0);
buf.writeUInt8(reg, 0);
psu_calc_checksum(addr, buf);
await bus.i2cWrite(addr, buf.length, buf);
buf = Buffer.alloc(3, 0);
let result = await bus.i2cRead(addr, 3, buf);
if(!result)
return 0;
if(result.bytesRead < 3)
return 0;
if(!psu_check_checksum(result.buffer))
return 0;
return result.buffer.readUInt16LE(0);
}
async function psu_read_eeprom(bus, addr, mem_addr, count)
{
let buf = Buffer.alloc(1, 0);
buf.writeUInt8(mem_addr, 0);
await bus.i2cWrite(addr, buf.length, buf);
buf = Buffer.alloc(count, 0);
let result = await bus.i2cRead(addr, count, buf);
if(!result)
return 0;
if(result.bytesRead < count)
return 0;
return result.buffer;
}
async function main()
{
const psu_ee_addr = 0x57;
const psu_addr = 0x5F;
const I2C0 = await I2C.openPromisified(0);
let found = await I2C0.scan();
if(found.indexOf(psu_addr) === -1)
return console.log("PSU not found at address %d", psu_addr);
if(found.indexOf(psu_ee_addr) === -1)
return console.log("PSU EEPROM not found at address %d", psu_ee_addr);
console.log("PSU found at address %d", psu_addr);
console.log("PSU EEPROM found at address %d", psu_ee_addr);
console.log("-----------------");
let psu_spn = await psu_read_eeprom(I2C0, psu_ee_addr, 0x12, 10);
let psu_date = await psu_read_eeprom(I2C0, psu_ee_addr, 0x1D, 8);
let psu_name = await psu_read_eeprom(I2C0, psu_ee_addr, 0x32, 26);
let psu_ct = await psu_read_eeprom(I2C0, psu_ee_addr, 0x5B, 14);
console.log("PSU SPN: %s", psu_spn.toString("utf8"));
console.log("PSU Date: %s", psu_date.toString("utf8"));
console.log("PSU Name: %s", psu_name.toString("utf8"));
console.log("PSU CT: %s", psu_ct.toString("utf8"));
let in_v = await psu_read_reg(I2C0, psu_addr, 0x08) / 32;
let in_a = await psu_read_reg(I2C0, psu_addr, 0x0A) / 256;
let in_a_max = await psu_read_reg(I2C0, psu_addr, 0x34) / 256;
let in_w = await psu_read_reg(I2C0, psu_addr, 0x0C) / 4;
let in_w_max = await psu_read_reg(I2C0, psu_addr, 0x32) / 4;
let in_ws = (await psu_read_reg(I2C0, psu_addr, 0x2C) + (await psu_read_reg(I2C0, psu_addr, 0x2E) << 16)) / 4;
let out_v = await psu_read_reg(I2C0, psu_addr, 0x0E) / 256;
let out_a = await psu_read_reg(I2C0, psu_addr, 0x10) / 64;
let out_a_max = await psu_read_reg(I2C0, psu_addr, 0x36) / 64;
let out_w = await psu_read_reg(I2C0, psu_addr, 0x12) / 4;
let intake_temp = await psu_read_reg(I2C0, psu_addr, 0x1A) / 64;
let internal_temp = await psu_read_reg(I2C0, psu_addr, 0x1C) / 64;
let fan_rpm = await psu_read_reg(I2C0, psu_addr, 0x1E);
let fan_target_rpm = await psu_read_reg(I2C0, psu_addr, 0x40);
let on_time = await psu_read_reg(I2C0, psu_addr, 0x30);
let status_flags = await psu_read_reg(I2C0, psu_addr, 0x02);
console.log("Input Voltage: %d V", in_v);
console.log("Input Current: %d A (max. %d A)", in_a, in_a_max);
console.log("Input Power: %d W (max. %d W)", in_w, in_w_max);
console.log("Input Energy: %d kWh", in_ws / 3600000);
console.log("Output Voltage: %d V", out_v);
console.log("Output Current: %d A (max. %d A)", out_a, out_a_max);
console.log("Output Power: %d W", out_w);
console.log("Intake Temperature: %d C", intake_temp);
console.log("Internal Temperature: %d C", internal_temp);
console.log("Fan speed: %d RPM", fan_rpm);
console.log("Fan target speed: %d RPM", fan_target_rpm);
console.log("On time: %d s", on_time);
console.log("Status flags: %d", status_flags);
console.log("PSU ON: " + ((status_flags & 0x05) === 0x05));
psu_write_reg(I2C0, psu_addr, 0x40, 0);
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment