From f07e4b5521403965237f191e5d07809d85c3aeb3 Mon Sep 17 00:00:00 2001 From: Tyler Matteson Date: Mon, 11 Aug 2025 18:28:25 -0400 Subject: [PATCH] wip: usb scale --- .pre-commit-config.yaml | 32 ++++++++------------ beam/docs/scale.md | 7 +++++ beam/public/js/beam.bundle.js | 1 + beam/public/js/scale/scale.js | 57 +++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 beam/docs/scale.md create mode 100644 beam/public/js/scale/scale.js diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aa7cc233..773a9ff6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ fail_fast: false repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v4.3.0 hooks: - id: trailing-whitespace files: 'beam.*' @@ -20,42 +20,43 @@ repos: - id: debug-statements - repo: https://github.com/asottile/pyupgrade - rev: v3.19.1 + rev: v2.34.0 hooks: - id: pyupgrade - args: ['--py310-plus'] + args: ['--py38-plus'] - - repo: https://github.com/agritheory/black + - repo: https://github.com/frappe/black rev: 951ccf4d5bb0d692b457a5ebc4215d755618eb68 hooks: - id: black - - repo: https://github.com/PyCQA/autoflake - rev: v2.3.1 + - repo: local hooks: - - id: autoflake - args: [--remove-all-unused-imports, --in-place] + - id: prettier + name: prettier + entry: npx prettier . --write --ignore-path .prettierignore + language: node - repo: https://github.com/PyCQA/isort - rev: 6.0.0 + rev: 5.12.0 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 7.1.1 + rev: 5.0.4 hooks: - id: flake8 additional_dependencies: ['flake8-bugbear'] - repo: https://github.com/codespell-project/codespell - rev: v2.4.1 + rev: v2.3.0 hooks: - id: codespell additional_dependencies: - tomli - repo: https://github.com/agritheory/test_utils - rev: v0.17.0 + rev: v1.0.0 hooks: - id: update_pre_commit_config - id: validate_copyright @@ -65,13 +66,6 @@ repos: args: ['--app', 'beam'] - id: validate_customizations - - repo: local - hooks: - - id: prettier - name: prettier - entry: npx prettier . --write --ignore-path .prettierignore - language: node - ci: autoupdate_schedule: weekly skip: [] diff --git a/beam/docs/scale.md b/beam/docs/scale.md new file mode 100644 index 00000000..18c8ed6b --- /dev/null +++ b/beam/docs/scale.md @@ -0,0 +1,7 @@ + + +# Using the scale features + +The WebHID protocol is not supported in all browsers, [look here for compatibility](https://developer.mozilla.org/en-US/docs/Web/API/WebHID_API#browser_compatibility) + diff --git a/beam/public/js/beam.bundle.js b/beam/public/js/beam.bundle.js index 70eaa466..4a3b6e4d 100644 --- a/beam/public/js/beam.bundle.js +++ b/beam/public/js/beam.bundle.js @@ -4,3 +4,4 @@ import './scan/scan.js' import './print/print.js' // import './example_custom_callback.js' +import './scale/scale.js' diff --git a/beam/public/js/scale/scale.js b/beam/public/js/scale/scale.js new file mode 100644 index 00000000..b4203631 --- /dev/null +++ b/beam/public/js/scale/scale.js @@ -0,0 +1,57 @@ +// Copyright (c) 2025, AgriTheory and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Purchase Receipt', { + async refresh(frm) { + await setup_scale(frm) + }, +}) + +async function setup_scale(frm) { + $('.form-sidebar').append(`
+

0.0 oz

+ +
`) + let scale_readout = $('#scale-readout') + $('#use-scale').on('click', () => use_scale(scale_readout)) + let array_of_weight_readings = [] + let weighed = false + let _mode = undefined + async function use_scale(scale_readout) { + $('#use-scale').hide() + const device = (await navigator.hid.requestDevice({ filters: [] }))?.[0] + await device.open() + + // think of this as a while loop + device.oninputreport = report => { + // check for "exit" or "weighed" flag + const { value, unit } = parseScaleData(report.data) + // detect if last __ on array are <= 0 as signal to move to next item + // + array_of_weight_readings.push(value) + _mode = scale_readout.html(`${value} ${unit}`) + } + } +} + +function parseScaleData(data) { + const sign = Number(data.getUint8(0)) == 4 ? 1 : -1 // 4 = positive, 5 = negative, 2 = zero + const unit = Number(data.getUint8(1)) == 2 ? 'g' : 'oz' // 2 = g, 11 = oz + const value = Number(data.getUint16(3, true)) // this one needs little endian + return { value: sign * (unit == 'oz' ? value / 10 : value), unit } +} + +function mode(arr) { + if (arr.filter((x, index) => arr.indexOf(x) == index).length == arr.length) return arr + else + return mode( + arr + .sort((x, index) => x - index) + .map((x, index) => (arr.indexOf(x) != index ? x : null)) + .filter(x => x != null) + ) +} + +function set_qty_uom_and_focus_on_next_qty_field(frm, qty, uom) { + console.log(qty, uom) +}