Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/commitlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Lint Commit Messages

on:
pull_request:

jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ jobs:
generate-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set package version
run: |
export VERSION=$(echo $GITHUB_REF | sed 's/refs\/tags\/v//')
echo "VERSION set to $VERSION"
echo VERSION = \'$VERSION\' > filament_scale_enhanced/fse_version.py
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install OctoPrint
Expand All @@ -39,4 +39,4 @@ jobs:
draft: false
files: |
LICENSE.txt
dist/Filament_Scale_Enhanced.zip
dist/Filament_Scale_Enhanced.zip
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install OctoPrint
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ or manually using this URL:

Once you have wired up the HX711, it must be calibrated. This is a pretty straightforward process, and all you will need is an object of known weight. Attach the load cell to your printer with the printed bracket, then follow the instructions on the plugin's settings page.

## MQTT

If you would like weight messages published via MQTT, install and configure [Octoprint-MQTT](https://plugins.octoprint.org/plugins/mqtt/)

Once it's configured correctly, this library will automatically detect it and start publishing messages in the following format:
```
baseTopic/plugin/filament_scale/filament_weight 171
```

## Troubleshooting

`NaN` may be occasionally displayed in the interface when the weight can't be read correctly. The cheap boards vary in quality and are a little sensitive to vibration/power stability. Ensure the cabling is secure, you have a sufficiently sized load cell, and a good power supply.
Expand All @@ -39,4 +48,4 @@ pip install OctoPrint Mock.GPIO
pip install ".[development]"
```

Running Tests: `pytest -v`
Running Tests: `pytest -v`
8 changes: 8 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const Configuration = {
extends: ['@commitlint/config-conventional'],
rules: {
'subject-case': [1, 'never'],
},
}

module.exports = Configuration
133 changes: 93 additions & 40 deletions filament_scale_enhanced/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,115 @@
from .hx711 import HX711

try:
import RPi.GPIO as GPIO
from RPi import GPIO
except (ModuleNotFoundError, RuntimeError):
import Mock.GPIO as GPIO # noqa: F401
from Mock import GPIO # noqa: F401


# pylint: disable=too-many-ancestors
class FilamentScalePlugin(octoprint.plugin.SettingsPlugin,
octoprint.plugin.AssetPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.StartupPlugin):
class FilamentScalePlugin(
octoprint.plugin.SettingsPlugin,
octoprint.plugin.AssetPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.StartupPlugin,
):

hx = None
t = None
tq = None

@staticmethod
def get_template_configs():
return [
dict(type="settings", custom_bindings=True)
]
def get_template_configs(): # pylint: disable=arguments-differ
return [{"type": "settings", "custom_bindings": True}]

@staticmethod
def get_settings_defaults():
return dict(
tare=8430152,
reference_unit=-411,
spool_weight=200,
clockpin=21,
datapin=20,
lastknownweight=0
)
def get_settings_defaults(): # pylint: disable=arguments-differ
return {
"tare": 8430152,
"reference_unit": -411,
"spool_weight": 200,
"clockpin": 21,
"datapin": 20,
"lastknownweight": 0,
}

@staticmethod
def get_assets():
return dict(
js=["js/filament_scale.js"],
css=["css/filament_scale.css"],
less=["less/filament_scale.less"]
)
def get_assets(): # pylint: disable=arguments-differ
return {
"js": ["js/filament_scale.js"],
"css": ["css/filament_scale.css"],
"less": ["less/filament_scale.less"],
}

def __init__(self):
super().__init__()
self.mqtt_publish = lambda *args, **kwargs: None
self.mqtt = False
self.mqtt_topic = ''
self.last_weight = 0
self.last_sent_weight = -1

def on_startup(self, host, port): # pylint: disable=unused-argument
self.hx = HX711(20, 21)
self.hx.set_reading_format("LSB", "MSB")
self.hx.reset()
self.hx.power_up()
self.t = octoprint.util.RepeatedTimer(3.0, self.check_weight)
self.t.start()
try:
self.hx = HX711(20, 21)
self.hx.set_reading_format("LSB", "MSB")
self.hx.reset()
self.hx.power_up()
self.t = octoprint.util.RepeatedTimer(3.0, self.check_weight)
self.t.start()
self.tq = octoprint.util.RepeatedTimer(10.0, self.send_weight_mqtt)
self.tq.start()
except Exception as err: # pylint: disable=broad-exception-caught
self._logger.exception(err)

def on_after_startup(self):
helpers = self._plugin_manager.get_helpers("mqtt", "mqtt_publish")
if not helpers or "mqtt_publish" not in helpers:
self._logger.debug(
"MQTT plugin helpers not found scale value will not be published"
)
return

def check_weight(self):
self.hx.power_up()
v = self.hx.read()
self._plugin_manager.send_plugin_message(self._identifier, v)
self.hx.power_down()
base_topic = self._settings.global_get(
["plugins", "mqtt", "publish", "baseTopic"]
)
self.mqtt_topic = f"{base_topic.rstrip('/')}/plugin/{self._identifier}"
self._logger.debug("Topic: %s", self.mqtt_topic)

# pylint: disable=line-too-long
self.mqtt_publish = helpers["mqtt_publish"]
self.mqtt = True
self._logger.debug(
"MQTT plugIn Helpers Found. Scale value will be published"
)

def real_weight(self) -> int:
tare = self._settings.get(["tare"])
reference = self._settings.get(["reference_unit"])
spool = self._settings.get(["spool_weight"])
weight = (self.last_weight - tare) / reference
return int(weight) - int(spool)

def send_weight_mqtt(self):
if not self.mqtt:
return
real_weight = self.real_weight()
if real_weight == self.last_sent_weight:
return
self.last_sent_weight = real_weight
self.mqtt_publish(f'{self.mqtt_topic}/filament_weight', str(real_weight))

def check_weight(self):
self._logger.debug("Begin hxRead")
try:
self.hx.power_up()
v = self.hx.read_average()
self.last_weight = v
self._plugin_manager.send_plugin_message(self._identifier, v)
self.hx.power_down()
except Exception as err: # pylint: disable=broad-exception-caught
self._logger.exception(err)

# pylint: disable=line-too-long,use-dict-literal
def get_update_information(self):
# Define the configuration for your plugin to use with the
# Software Update Plugin here.
Expand All @@ -70,15 +125,13 @@ def get_update_information(self):
filament_scale=dict(
displayName="Filament Scale Plugin",
displayVersion=self._plugin_version,

# version check: github repository
type="github_release",
user="techman83",
repo="Filament-Scale-Enhanced",
current=self._plugin_version,

# update method: pip
pip="https://github.com/techman83/Filament-Scale-Enhanced/releases/latest/download/Filament_Scale_Enhanced.zip" # noqa: E501
pip="https://github.com/techman83/Filament-Scale-Enhanced/releases/latest/download/Filament_Scale_Enhanced.zip", # noqa: E501
)
)

Expand Down
4 changes: 2 additions & 2 deletions filament_scale_enhanced/hx711.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import statistics

try:
import RPi.GPIO as GPIO
from RPi import GPIO
except (ModuleNotFoundError, RuntimeError):
import Mock.GPIO as GPIO
from Mock import GPIO


def bitsToBytes(a):
Expand Down
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[pytest]
python_files = tests/__init__.py
addopts = -p no:cacheprovider --mypy --pylint --flake8
filterwarnings =
ignore
default:::filament_scale.*
default:::tests.*
10 changes: 7 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from setuptools import setup

version = {}
with open("filament_scale_enhanced/fse_version.py") as fp:
with open("filament_scale_enhanced/fse_version.py", encoding="utf8") as fp:
exec(fp.read(), version) # pylint: disable=exec-used

try:
Expand Down Expand Up @@ -38,7 +38,9 @@
'pytest-pylint',
'pylint',
'pytest-flake8',
'Mock.GPIO'
'Mock.GPIO',
# Flake8 is likely a dead end
'flake8<5',
],
'test': [
'pytest',
Expand All @@ -47,7 +49,9 @@
'pytest-pylint',
'pylint',
'pytest-flake8',
'Mock.GPIO'
'Mock.GPIO',
# Flake8 is likely a dead end
'flake8<5',
]
}

Expand Down