|
// Copyright Marc-Antoine Ruel 2024. |
|
|
|
const ColBrand = 1; // A |
|
const ColFilamentType = 2; // B |
|
const ColColor = 3; // C |
|
const ColGrams = 4; // D |
|
const ColLastUpdate = 8; // H |
|
const ColColorHex = 9; // I |
|
const ColRFID = 10; // J |
|
|
|
// Handles HTTP post from Home Assistant. |
|
// |
|
// See https://developers.google.com/apps-script/guides/logging#use_the_execution_log |
|
function doPost(e) { |
|
let results = []; |
|
try { |
|
const spools = JSON.parse(e.postData.contents).spools; |
|
if (!spools) { |
|
return ContentService.createTextOutput(JSON.stringify(["Bad json parameter?", e.postData.contents])); |
|
} |
|
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Stocks"); |
|
for (let i = 0; i < spools.length; i++) { |
|
const spool = spools[i]; |
|
if (spool.empty) { |
|
results.push("Slot #" + (i+1) + ": empty"); |
|
continue; |
|
} |
|
let tag_uid = spool.tag_uid; |
|
if (!tag_uid || tag_uid == "0000000000000000") { |
|
results.push("Slot #" + (i+1) + ": no RFID"); |
|
continue; |
|
} |
|
const s = spool.name.indexOf(" "); |
|
const brand = spool.name.substring(0, s); |
|
const type = spool.name.slice(s+1); |
|
const color = spool.color.substring(0, 7); |
|
|
|
// See AMSTray in |
|
// https://github.com/greghesp/ha-bambulab/blob/main/custom_components/bambu_lab/pybambu/models.py |
|
let match = sheet.createTextFinder(tag_uid).matchEntireCell(true).findNext(); |
|
if (!match) { |
|
// Often the RFID LSB bit is toggled. :( |
|
// This causes 0<->1, 2<->3, ..., C<->D, E<->F to be reported interchangeably |
|
// on the first character. Ignore it. |
|
match = sheet.createTextFinder("^." + tag_uid.substring(1) + "$").useRegularExpression(true).findNext(); |
|
if (match) { |
|
tag_uid = match.getValue(); |
|
results.push("Slot #" + (i+1) + ": Tag UID " + spool.tag_uid + " found as " + tag_uid); |
|
} |
|
} |
|
if (!match) { |
|
results.push("Slot #" + (i+1) + ": New roll! " + tag_uid); |
|
console.log("New roll! %s", tag_uid); |
|
// Sadly appendRow() doesn't return the row number (!!) |
|
var newRow = [...Array(ColRFID-1)].map(() => ""); |
|
newRow.push(tag_uid); |
|
newRow[ColColor] = "<add color>"; |
|
sheet.appendRow(newRow); |
|
match = sheet.createTextFinder(tag_uid).matchEntireCell(true).findNext(); |
|
} |
|
const row = match.getRow(); |
|
results.push("Found roll at row " + row); |
|
console.log("Found roll at row %d", row); |
|
sheet.getRange(row, ColBrand).setValue(brand); |
|
sheet.getRange(row, ColFilamentType).setValue(type); |
|
sheet.getRange(row, ColGrams).setValue(spool.remain * 10); |
|
sheet.getRange(row, ColColorHex).setValue(color); |
|
const today = new Date(); |
|
sheet.getRange(row, ColLastUpdate).setValue(today.getFullYear() + "-" + String(today.getMonth() + 1).padStart(2, "0") + "-" + String(today.getDate()).padStart(2, "0")); |
|
setRowSpoolColor(sheet, row, color); |
|
} |
|
return ContentService.createTextOutput(JSON.stringify(results)); |
|
} catch (err) { |
|
console.log("Failed with error %s", err.message); |
|
return ContentService.createTextOutput(JSON.stringify(results + [err.message])); |
|
} |
|
} |
|
|
|
// Handle text editing. |
|
// |
|
// Update cell color based on hex value. |
|
function onEdit(e) { |
|
const range = e.range; |
|
const sheet = range.getSheet(); |
|
if (sheet != "Stocks" && sheet != "Want" && range.getColumn() != ColColorHex) { |
|
return; |
|
} |
|
setRowSpoolColor(sheet, range.getRow(), range.getValue()); |
|
} |
|
|
|
// Handle sheet opening. |
|
// |
|
// Add a menu item to reset colors. |
|
function onOpen() { |
|
var ui = SpreadsheetApp.getUi(); |
|
ui.createMenu('Spools') |
|
.addItem('Reset colors', 'menuResetColor') |
|
.addToUi(); |
|
} |
|
|
|
function setRowSpoolColor(sheet, row, color) { |
|
const r = Number("0x"+color.substring(1, 3)); |
|
const g = Number("0x"+color.substring(3, 5)); |
|
const b = Number("0x"+color.substring(5, 7)); |
|
const y = Math.pow(r/255.0, 2.2) * 0.2126 + Math.pow(g/255.0, 2.2) * 0.7152 + Math.pow(b/255.0, 2.2) * 0.0722; |
|
sheet.getRange(row, ColColor).setBackground(color).setFontColor((y < 0.36) ? "#ffffff" : "#000000"); |
|
} |
|
|
|
// Reset all the filmanet cell background colors. |
|
function menuResetColor() { |
|
const sheet = SpreadsheetApp.getActiveSheet(); |
|
const name = sheet.getName(); |
|
if (name != "Stocks" && name != "Want") { |
|
SpreadsheetApp.getUi().alert("Can't work on that sheet"); |
|
return; |
|
} |
|
const start = 2; |
|
const end = sheet.getLastRow()+1; |
|
const all = sheet.getRange(start, ColColorHex, end-1, 1).getValues(); |
|
for (let i = start; i < end; i++) { |
|
//Logger.log("Row:" + i + "; Value:" + all[i-start][0]); |
|
//setRowSpoolColor(sheet, i, sheet.getRange(i, ColColorHex).getValue()); |
|
setRowSpoolColor(sheet, i, all[i-start][0]); |
|
} |
|
} |
Im getting an access denied error when I try to run the service. I presume its because my OAuth is in testing, but how do I do this without publishing the app?