Skip to content

Commit

Permalink
updated repo to current InvenHost defaults (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
matmair authored Jan 4, 2024
1 parent f1cc756 commit 9b1b21e
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 73 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ on:

jobs:
plugin-action:
uses: matmair/inventree-meta-plugin/.github/workflows/plugin_action.yaml@main
secrets: inherit
name: CI
uses: matmair/inventree-meta-plugin/.github/workflows/plugin_action.yaml@next
secrets:
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
37 changes: 16 additions & 21 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: .*/(static|migrations|locale)/.*
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: mixed-line-ending
- repo: https://github.com/pycqa/flake8
rev: '6.0.0'
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: mixed-line-ending
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.11
hooks:
- id: flake8
additional_dependencies: [
'flake8-bugbear',
'flake8-docstrings',
'flake8-string-format',
'pep8-naming ',
]
- repo: https://github.com/pycqa/isort
rev: '5.12.0'
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
- id: isort
- id: codespell
27 changes: 22 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@

[build-system]
requires = ["setuptools", "wheel", "pyyaml"]
build-backend = "setuptools.build_meta"

[project]
name = "inventree-wled-locator"
version = "0.2.2"
version = "0.3.0"
description="Use WLED to locate InvenTree StockLocations."
readme = "README.md"
license = {text = "MIT license"}
Expand All @@ -23,7 +22,7 @@ classifiers=[
"Intended Audience :: Manufacturing",
"Intended Audience :: End Users/Desktop",
"Topic :: Scientific/Engineering",
'License :: OSI Approved :: MIT License',
'License :: OSI Approved :: MIT License',
]
requires-python=">=3.9"
dependencies = ['django', 'requests']
Expand All @@ -32,11 +31,29 @@ dependencies = ['django', 'requests']
dev = ['twine', 'setuptools']

[project.urls]
"Repository" = "https://github.com/matmair/inventree-wled-locator"
"Bug Tracker" = "https://github.com/matmair/inventree-wled-locator/issues"
"Repository" = "https://github.com/invenhost/inventree-wled-locator"
"Bug Tracker" = "https://github.com/invenhost/inventree-wled-locator/issues"

[project.entry-points."inventree_plugins"]
inventree_wled_locator = "inventree_wled_locator:WledPlugin"

[tool.setuptools.packages.find]
where = ["src"]

[tool.ruff]
exclude=[".git","__pycache__","dist","build","test.py","tests", "venv","env",".venv",".env"]

[tool.ruff.lint]
select = ["A", "B", "C4", "D", "DJ", "N", "I","S"]
ignore = ["N999", ]

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.isort]
combine-as-imports = true
section-order = ["future", "standard-library", "django", "third-party", "first-party", "local-folder" ]
known-first-party = ["src", "plugin", "InvenTree", "common"]

[tool.ruff.lint.isort.sections]
"django" = ["django"]
9 changes: 0 additions & 9 deletions setup.cfg

This file was deleted.

110 changes: 75 additions & 35 deletions src/inventree_wled_locator/WledPlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@
import json
import logging

import requests
from common.notifications import NotificationBody
from django.conf.urls import url
from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator
from django.http import JsonResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _

import requests
from stock.models import StockLocation

from common.notifications import NotificationBody
from InvenTree.helpers_model import notify_users
from plugin import InvenTreePlugin
from plugin.mixins import LocateMixin, SettingsMixin, UrlsMixin
from stock.models import StockLocation

logger = logging.getLogger('inventree')
logger = logging.getLogger("inventree")


def superuser_check(user):
Expand All @@ -28,26 +30,29 @@ def superuser_check(user):
class WledPlugin(UrlsMixin, LocateMixin, SettingsMixin, InvenTreePlugin):
"""Use WLED to locate InvenTree StockLocations.."""

NAME = 'WledPlugin'
SLUG = 'inventree-wled-locator'
NAME = "WledPlugin"
SLUG = "inventree-wled-locator"
TITLE = "WLED Locator"

NO_LED_NOTIFICATION = NotificationBody(
name=_("No location for {verbose_name}"),
slug='{app_label}.no_led_{model_name}',
slug="{app_label}.no_led_{model_name}",
message=_("No LED number is assigned for {verbose_name}"),
)

SETTINGS = {
'ADDRESS': {
'name': _('IP Address'),
'description': _('IP address of your WLED device'),
"ADDRESS": {
"name": _("IP Address"),
"description": _("IP address of your WLED device"),
},
'MAX_LEDS': {
'name': _('Max LEDs'),
'description': _('Maximum number of LEDs in your WLED device'),
'default': 1,
'validator': [int, MinValueValidator(1), ],
"MAX_LEDS": {
"name": _("Max LEDs"),
"description": _("Maximum number of LEDs in your WLED device"),
"default": 1,
"validator": [
int,
MinValueValidator(1),
],
},
}

Expand All @@ -63,13 +68,18 @@ def locate_stock_location(self, location_pk):

try:
location = StockLocation.objects.get(pk=location_pk)
led_nbr = int(location.get_metadata('wled_led'))
led_nbr = int(location.get_metadata("wled_led"))
if led_nbr is not None:
self._set_led(led_nbr)
else:
# notify superusers that a location has no LED number
logger.error(f"Location ID {location_pk} has no WLED LED number!")
notify_users(self.superusers, location, StockLocation, content=self.NO_LED_NOTIFICATION)
notify_users(
self.superusers,
location,
StockLocation,
content=self.NO_LED_NOTIFICATION,
)

except (ValueError, StockLocation.DoesNotExist): # pragma: no cover
logger.error(f"Location ID {location_pk} does not exist!")
Expand All @@ -89,7 +99,7 @@ def view_unregister(self, request, pk):

try:
item = StockLocation.objects.get(pk=pk)
item.set_metadata('wled_led', None)
item.set_metadata("wled_led", None)
except StockLocation.DoesNotExist:
pass
return redirect(self.settings_url)
Expand All @@ -99,41 +109,63 @@ def view_register(self, request, pk=None, led=None, context=None):
if not superuser_check(request.user):
raise PermissionError("Only superusers can turn off all LEDs")

if pk is None and led is None and str(request.body, encoding='utf8') == '':
return JsonResponse({'actions': {'POST': ['stocklocation', 'led', ], }})
if pk is None and led is None and str(request.body, encoding="utf8") == "":
return JsonResponse(
{
"actions": {
"POST": [
"stocklocation",
"led",
],
}
}
)
elif request.body is not None:
data = json.loads(request.body)
pk = data.get('stocklocation')
led = data.get('led')
pk = data.get("stocklocation")
led = data.get("led")

try:
item = StockLocation.objects.get(pk=pk)
item.set_metadata('wled_led', led)
item.set_metadata("wled_led", led)
except StockLocation.DoesNotExist:
pass
return redirect(self.settings_url)

def setup_urls(self):
"""Return the URLs defined by this plugin."""
return [
url(r'off/', self.view_off, name='off'),
url(r'unregister/(?P<pk>\d+)/', self.view_unregister, name='unregister'),
url(r'register/(?P<pk>\d+)/(?P<led>\w+)/', self.view_register, name='register'),
url(r'register/', self.view_register, name='register-simple'),
url(r"off/", self.view_off, name="off"),
url(r"unregister/(?P<pk>\d+)/", self.view_unregister, name="unregister"),
url(
r"register/(?P<pk>\d+)/(?P<led>\w+)/",
self.view_register,
name="register",
),
url(r"register/", self.view_register, name="register-simple"),
]

def get_settings_content(self, request):
"""Add context to the settings panel."""
stocklocations = StockLocation.objects.filter(metadata__isnull=False).all()

target_locs = [{'name': loc.pathstring, 'led': loc.get_metadata('wled_led'), 'id': loc.id} for loc in stocklocations if loc.get_metadata('wled_led')]
stock_strings = ''.join([f"""<tr>
target_locs = [
{"name": loc.pathstring, "led": loc.get_metadata("wled_led"), "id": loc.id}
for loc in stocklocations
if loc.get_metadata("wled_led")
]
stock_strings = "".join(
[
f"""<tr>
<td>{a["name"]}</td>
<td>{a["led"]}</td>
<td><a class="btn btn-primary" href="{reverse("plugin:inventree-wled-locator:unregister", kwargs={"pk": a["id"]})}">unregister</a></td>
</tr>""" for a in target_locs])
</tr>"""
for a in target_locs
]
)
return f"""
<h3>WLED controlls</h3>
<h3>WLED controls</h3>
<a class="btn btn-primary" href="{reverse('plugin:inventree-wled-locator:off')}">Turn off</a>
<button class="btn btn-primary" onclick="led_register()">Register LED</button>
<table class="table table-striped">
Expand All @@ -160,12 +192,20 @@ def get_settings_content(self, request):
def _set_led(self, target_led: int = None):
"""Turn on a specific LED."""
base_url = f'http://{self.get_setting("ADDRESS")}/json/state'
color_black = '000000'
color_marked = 'FF0000'
color_black = "000000"
color_marked = "FF0000"

# Turn off all segments
requests.post(base_url, json={"seg": {"i": [0, self.get_setting("MAX_LEDS"), color_black]}})
requests.post(
base_url,
json={"seg": {"i": [0, self.get_setting("MAX_LEDS"), color_black]}},
timeout=3,
)

# Turn on target led
if target_led is not None:
requests.post(base_url, json={"seg": {"i": [target_led, color_marked]}})
requests.post(
base_url,
json={"seg": {"i": [target_led, color_marked]}},
timeout=3,
)
4 changes: 3 additions & 1 deletion src/inventree_wled_locator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

from .WledPlugin import WledPlugin

__all__ = [WledPlugin, ]
__all__ = [
WledPlugin,
]

0 comments on commit 9b1b21e

Please sign in to comment.