Skip to content

Commit

Permalink
add inverter sun2000
Browse files Browse the repository at this point in the history
  • Loading branch information
groupsky committed Oct 15, 2023
1 parent 763d04c commit 2dbbe95
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 1 deletion.
60 changes: 60 additions & 0 deletions config/modbus-serial/inverter.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
function getFile(filePath) {
if (filePath) {
const fs = require('fs');

try {
if (fs.existsSync(filePath)) {
return fs.readFileSync(filePath);
}
} catch (err) {
console.error('Failed to read file', filePath, err);
}
}
return null;
}

function getFileEnv(envVariable) {
const origVar = process.env[envVariable];
const fileVar = process.env[envVariable + '_FILE'];
if (fileVar) {
const file = getFile(fileVar);
if (file) {
return file.toString().split(/\r?\n/)[0].trim();
}
}
return origVar;
}

module.exports = {
modbus: {
type: 'tcp',
port: '192.168.0.51',
portConfig: {
port: 502,
},
},
devices: [
{
name: 'inverter',
address: 0x01,
type: 'sun2000',
},
],
integrations: {
console: {},
mqtt: {
url: process.env.BROKER,
publishTopic: process.env.TOPIC,
},
mongodb: {
collection: process.env.COLLECTION,
url: process.env.MONGODB_URL,
options: {
auth: {
username: getFileEnv('MONGODB_USERNAME'),
password: getFileEnv('MONGODB_PASSWORD'),
}
}
},
},
}
36 changes: 36 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,42 @@ services:
- /dev/serial:/dev/serial
- ${CONFIG_PATH}/modbus-serial/solar.config.js:/etc/config.js:ro

dry-switches:
build: docker/modbus-serial
depends_on:
- broker
- mongo
- influxdb
restart: unless-stopped
privileged: true
networks:
- automation
- egress
security_opt:
- no-new-privileges:true
secrets:
- influxdb_write_user
- influxdb_write_user_password
- mongo_root_username
- mongo_root_password
environment:
- MONGODB_URL=mongodb://mongo:27017/${MONGO_DATABASE}?authSource=admin
- MONGODB_USERNAME_FILE=/run/secrets/mongo_root_username
- MONGODB_PASSWORD_FILE=/run/secrets/mongo_root_password
- COLLECTION=inverter
- CONFIG=/etc/config.js
- BROKER=mqtt://broker
- TOPIC=/modbus/inverter/{name}/reading
- SUBSCRIBE_TOPIC=/modbus/inverter/{name}/write
- INFLUXDB_URL=http://influxdb:8086
- INFLUXDB_USERNAME_FILE=/run/secrets/influxdb_write_user
- INFLUXDB_PASSWORD_FILE=/run/secrets/influxdb_write_user_password
- INFLUXDB_DATABASE=${INFLUXDB_DATABASE}
- INFLUXDB_TAGS={"bus":"inverter"}
- INFLUXDB_MEASUREMENT=inverter
volumes:
- ${CONFIG_PATH}/modbus-serial/inverter.config.js:/etc/config.js:ro

influxdb:
build: docker/influxdb
restart: unless-stopped
Expand Down
43 changes: 43 additions & 0 deletions docker/modbus-serial/devices/sun2000.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Huawei SUN2000 Inverter

const readLong = (msb, lsb) => msb << 16 | lsb

async function read (client) {
let data

data = await client.readHoldingRegisters(32106, 2);
// Accumulated energy yield (kWh) * 100
const total_p = readLong(data.data[0], data.data[1]) / 100

data = await client.readHoldingRegisters(32114, 2);
// Daily energy yield (kWh) * 100
const daily_p = readLong(data.data[0], data.data[1]) / 100

data = await client.readHoldingRegisters(32080, 9)
// Active power (kW) * 1000
const ap = readLong(data.data[0], data.data[1]) / 1000
// Reactive power (kVar) * 1000
const rp = readLong(data.data[2], data.data[3]) / 1000
// Power factor (1) * 1000
const pf = data.data[4] / 1000
// Grid frequency (Hz) * 100
const freq = data.data[5] / 100
// Efficiency (%) * 100
const eff = data.data[6] / 100
// Internal temperature (°C) * 10
const temp = data.data[7] / 10
// Insulation resistance (MΩ) * 1000
const ins = data.data[8] / 1000

return {
total_p,
daily_p,
ap,
rp,
pf,
freq,
eff,
temp,
ins,
}
}
5 changes: 4 additions & 1 deletion docker/modbus-serial/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { Mutex, withTimeout } = require('async-mutex')
const ModbusRTU = require('modbus-serial')
const {
modbus: {
type = 'rtu', // 'rtu' or 'tcp'
port,
portConfig,
msDelayBetweenDevices = 150,
Expand Down Expand Up @@ -82,7 +83,9 @@ const poll = async () => {
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))

Promise.all([
modbusClient.connectRTUBuffered(port, portConfig)
type === 'tcp'
? modbusClient.connectTCP(port, portConfig)
: modbusClient.connectRTUBuffered(port, portConfig)
]).then(async () => {
modbusClient.setTimeout(msTimeout)

Expand Down
Empty file added docs/wiring/v2/load.mermaid
Empty file.

0 comments on commit 2dbbe95

Please sign in to comment.