+54
-7
@@ -5,11 +5,15 @@ const NodeHelper = require("node_helper");
|
||||
const QRCode = require("qrcode");
|
||||
const NextcloudPublicShare = require("./lib/nextcloud-public-share");
|
||||
const { parseYield, scaleRecipe } = require("./lib/recipe-scaler");
|
||||
const { normalizeProgress, updateProgress } = require("./lib/recipe-progress");
|
||||
|
||||
module.exports = NodeHelper.create({
|
||||
start() {
|
||||
this.config = { controlPath: "/MMM-NextcloudCookbook/control" };
|
||||
this.state = { active: false, recipeId: null, recipe: null, portions: null, error: null };
|
||||
this.state = {
|
||||
active: false, recipeId: null, recipe: null, portions: null,
|
||||
progress: normalizeProgress(), error: null
|
||||
};
|
||||
this.recipeCache = { expires: 0, recipes: [] };
|
||||
this.stateFile = path.join(process.cwd(), "config", "MMM-NextcloudCookbook-state.json");
|
||||
this.configureClient();
|
||||
@@ -18,6 +22,10 @@ module.exports = NodeHelper.create({
|
||||
},
|
||||
|
||||
socketNotificationReceived(notification, payload) {
|
||||
if (notification === "UPDATE_PROGRESS") {
|
||||
this.updateProgressFromMirror(payload);
|
||||
return;
|
||||
}
|
||||
if (notification !== "CONFIG") return;
|
||||
this.config = { ...this.config, ...payload };
|
||||
try {
|
||||
@@ -82,11 +90,17 @@ module.exports = NodeHelper.create({
|
||||
return response.status(400).json({ error: "recipeId is required" });
|
||||
}
|
||||
const recipe = await this.getClient().getRecipe(recipeId);
|
||||
const isResumingRecipe = this.state.recipeId === recipeId
|
||||
&& Number.isInteger(this.state.portions)
|
||||
&& this.state.portions > 0;
|
||||
this.state = {
|
||||
active: true,
|
||||
recipeId,
|
||||
recipe,
|
||||
portions: Math.max(1, Math.round(parseYield(recipe.recipeYield) || 1)),
|
||||
portions: isResumingRecipe
|
||||
? this.state.portions
|
||||
: Math.max(1, Math.round(parseYield(recipe.recipeYield) || 1)),
|
||||
progress: isResumingRecipe ? this.state.progress : normalizeProgress(),
|
||||
error: null
|
||||
};
|
||||
await this.saveState();
|
||||
@@ -113,9 +127,25 @@ module.exports = NodeHelper.create({
|
||||
return next(error);
|
||||
}
|
||||
});
|
||||
this.expressApp.post("/MMM-NextcloudCookbook/api/progress", async (request, response, next) => {
|
||||
try {
|
||||
if (!this.state.active || !this.state.recipe) {
|
||||
return response.status(409).json({ error: "No recipe is active" });
|
||||
}
|
||||
this.state.progress = updateProgress(this.state.recipe, this.state.progress, request.body || {});
|
||||
await this.saveState();
|
||||
this.sendSocketNotification("STATE", this.publicState());
|
||||
return response.json(this.publicState());
|
||||
} catch (error) {
|
||||
if (error.message === "Invalid progress update" || error.message === "Progress item does not exist") {
|
||||
return response.status(400).json({ error: error.message });
|
||||
}
|
||||
return next(error);
|
||||
}
|
||||
});
|
||||
this.expressApp.post("/MMM-NextcloudCookbook/api/exit", async (_request, response, next) => {
|
||||
try {
|
||||
this.state = { active: false, recipeId: null, recipe: null, portions: null, error: null };
|
||||
this.state = { ...this.state, active: false, error: null };
|
||||
await this.saveState();
|
||||
this.sendSocketNotification("STATE", this.publicState());
|
||||
response.json(this.publicState());
|
||||
@@ -144,12 +174,13 @@ module.exports = NodeHelper.create({
|
||||
async loadState() {
|
||||
try {
|
||||
const persisted = JSON.parse(await fs.readFile(this.stateFile, "utf8"));
|
||||
if (!persisted.active || !persisted.recipeId) return;
|
||||
if (!persisted.recipeId) return;
|
||||
this.state = {
|
||||
active: true,
|
||||
active: Boolean(persisted.active),
|
||||
recipeId: persisted.recipeId,
|
||||
recipe: null,
|
||||
portions: Number.isInteger(persisted.portions) ? persisted.portions : null,
|
||||
progress: normalizeProgress(persisted.progress),
|
||||
error: null
|
||||
};
|
||||
} catch (error) {
|
||||
@@ -174,7 +205,8 @@ module.exports = NodeHelper.create({
|
||||
await fs.writeFile(temporary, `${JSON.stringify({
|
||||
active: this.state.active,
|
||||
recipeId: this.state.recipeId,
|
||||
portions: this.state.portions
|
||||
portions: this.state.portions,
|
||||
progress: this.state.progress
|
||||
})}\n`, {
|
||||
mode: 0o600
|
||||
});
|
||||
@@ -190,9 +222,24 @@ module.exports = NodeHelper.create({
|
||||
return {
|
||||
active: this.state.active,
|
||||
recipeId: this.state.recipeId,
|
||||
recipe: this.state.recipe ? scaleRecipe(this.state.recipe, this.state.portions) : null,
|
||||
recipe: this.state.active && this.state.recipe
|
||||
? scaleRecipe(this.state.recipe, this.state.portions)
|
||||
: null,
|
||||
portions: this.state.portions,
|
||||
progress: this.state.progress,
|
||||
error: this.state.error
|
||||
};
|
||||
},
|
||||
|
||||
async updateProgressFromMirror(payload) {
|
||||
try {
|
||||
if (!this.state.active || !this.state.recipe) return;
|
||||
this.state.progress = updateProgress(this.state.recipe, this.state.progress, payload || {});
|
||||
await this.saveState();
|
||||
this.sendSocketNotification("STATE", this.publicState());
|
||||
} catch (error) {
|
||||
console.error(`[MMM-NextcloudCookbook] ${error.message}`);
|
||||
this.sendSocketNotification("STATE", this.publicState());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user