Skip to content

Commit

Permalink
Add support to output active limits to MQTT
Browse files Browse the repository at this point in the history
  • Loading branch information
longzheng committed Dec 11, 2024
1 parent d3f1dd3 commit 791a5e3
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
33 changes: 33 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,39 @@
"description": "MQTT meter configuration"
}
]
},
"outputActiveLimits": {
"type": "object",
"properties": {
"mqtt": {
"type": "object",
"properties": {
"host": {
"type": "string",
"description": "The host of the MQTT broker, including \"mqtt://\""
},
"username": {
"type": "string",
"description": "The username for the MQTT broker"
},
"password": {
"type": "string",
"description": "The password for the MQTT broker"
},
"topic": {
"type": "string",
"description": "The topic to publish limits"
}
},
"required": [
"host",
"topic"
],
"additionalProperties": false
}
},
"additionalProperties": false,
"description": "Optionally output active control limits"
}
},
"required": [
Expand Down
32 changes: 32 additions & 0 deletions src/coordinator/helpers/activeLimitOutput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import mqtt from 'mqtt';
import { type Config } from '../../helpers/config.js';
import { type ActiveInverterControlLimit } from './inverterController.js';

export class ActiveLimitOutput {
private mqttClient: mqtt.MqttClient | undefined;

constructor({ config }: { config: Config }) {
if (config.outputActiveLimits?.mqtt) {
this.mqttClient = mqtt.connect(
config.outputActiveLimits.mqtt.host,
{
username: config.outputActiveLimits.mqtt.username,
password: config.outputActiveLimits.mqtt.password,
},
);
}
}

onActiveInverterControlLimit({
limit,
}: {
limit: ActiveInverterControlLimit;
}) {
if (this.mqttClient) {
this.mqttClient.publish(
'inverterControlLimit',
JSON.stringify(limit),
);
}
}
}
7 changes: 7 additions & 0 deletions src/coordinator/helpers/inverterController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { CappedArrayStack } from '../../helpers/cappedArrayStack.js';
import { timeWeightedAverage } from '../../helpers/timeWeightedAverage.js';
import { differenceInSeconds } from 'date-fns';
import { type ControlsModel } from '../../connections/sunspec/models/controls.js';
import { ActiveLimitOutput } from './activeLimitOutput.js';

export type SupportedControlTypes = Extract<
ControlType,
Expand Down Expand Up @@ -69,6 +70,7 @@ const defaultValues = {
} as const satisfies Record<ControlType, unknown>;

export class InverterController {
private activeLimitOutput: ActiveLimitOutput;
private cachedDerSample = new CappedArrayStack<DerSample>({ limit: 100 });
private cachedSiteSample = new CappedArrayStack<SiteSample>({ limit: 100 });
private logger: Logger;
Expand Down Expand Up @@ -105,6 +107,7 @@ export class InverterController {
inverterConfiguration: InverterConfiguration,
) => Promise<void>;
}) {
this.activeLimitOutput = new ActiveLimitOutput({ config });
this.secondsToSample = config.inverterControl.sampleSeconds;
this.controlFrequencyMinimumSeconds =
config.inverterControl.controlFrequencyMinimumSeconds;
Expand Down Expand Up @@ -172,6 +175,10 @@ export class InverterController {

writeActiveControlLimit({ limit: activeInverterControlLimit });

this.activeLimitOutput.onActiveInverterControlLimit({
limit: activeInverterControlLimit,
});

this.controlLimitsCache = {
controlLimitsByLimiter,
activeInverterControlLimit,
Expand Down
23 changes: 23 additions & 0 deletions src/helpers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,29 @@ A longer time will smooth out load changes but may result in overshoot.`,
})
.describe('MQTT meter configuration'),
]),
outputActiveLimits: z
.object({
mqtt: z
.object({
host: z
.string()
.describe(
'The host of the MQTT broker, including "mqtt://"',
),
username: z
.string()
.optional()
.describe('The username for the MQTT broker'),
password: z
.string()
.optional()
.describe('The password for the MQTT broker'),
topic: z.string().describe('The topic to publish limits'),
})
.optional(),
})
.describe('Optionally output active control limits')
.optional(),
});

export type Config = z.infer<typeof configSchema>;
Expand Down

0 comments on commit 791a5e3

Please sign in to comment.