kopia lustrzana https://github.com/Yakifo/amqtt
commit
c3f3d0d3a2
|
@ -0,0 +1,37 @@
|
|||
# Image name and tag
|
||||
IMAGE_NAME := amqtt
|
||||
IMAGE_TAG := latest
|
||||
VERSION_TAG := 0.11.0
|
||||
REGISTRY := amqtt/$(IMAGE_NAME)
|
||||
|
||||
# Platforms to build for
|
||||
PLATFORMS := linux/amd64,linux/arm64
|
||||
|
||||
# Default target
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
# Build multi-platform image
|
||||
.PHONY: build
|
||||
build:
|
||||
docker buildx build \
|
||||
--platform $(PLATFORMS) \
|
||||
--tag $(REGISTRY):$(IMAGE_TAG) \
|
||||
--tag $(REGISTRY):$(VERSION_TAG) \
|
||||
--file Dockerfile \
|
||||
--push .
|
||||
|
||||
# Optional: build without pushing (for local testing)
|
||||
.PHONY: build-local
|
||||
build-local:
|
||||
docker buildx build \
|
||||
--tag $(REGISTRY):$(IMAGE_TAG) \
|
||||
--tag $(REGISTRY):$(VERSION_TAG) \
|
||||
--file Dockerfile \
|
||||
--load .
|
||||
|
||||
# Create builder if not exists
|
||||
.PHONY: init
|
||||
init:
|
||||
docker buildx create --use --name multi-builder || true
|
||||
docker buildx inspect --bootstrap
|
|
@ -7,7 +7,7 @@
|
|||

|
||||
[](https://pypi.org/project/amqtt/)
|
||||
|
||||

|
||||

|
||||
|
||||
`aMQTT` is an open source [MQTT](http://www.mqtt.org) broker and client[^1], natively implemented with Python's [asyncio](https://docs.python.org/3/library/asyncio.html).
|
||||
|
||||
|
|
192
docs/Makefile
192
docs/Makefile
|
@ -1,192 +0,0 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " applehelp to make an Apple Help Book"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/HBMQTT.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/HBMQTT.qhc"
|
||||
|
||||
applehelp:
|
||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
||||
@echo
|
||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
||||
"~/Library/Documentation/Help or install it in your application" \
|
||||
"bundle."
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/HBMQTT"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/HBMQTT"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
coverage:
|
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
@echo "Testing of coverage in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/coverage/python.txt."
|
||||
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
|
@ -2,13 +2,42 @@
|
|||
|
||||
## 0.11.0
|
||||
|
||||
- Removed hbmqtt compatibility, importing amqtt is now mandatory
|
||||
- Removed loop parameter from all functions
|
||||
- Python 3.10 to 3.13 compatibility
|
||||
- Fixed a major bug in plugin api, see [PR #92](https://github.com/Yakifo/amqtt/pull/92)
|
||||
- Migrated from `docopts` to `typer`
|
||||
- upgrades to support python 3.10, 3.11, 3.12 and 3.13
|
||||
- complete type hinting of the entire codebase
|
||||
- linting with ruff, pylint and mypy to keep the codebase consistent in format and structure
|
||||
- github workflow CI of linting before pull requests can be merged
|
||||
- run linting with git pre-commit hooks
|
||||
- add docker container
|
||||
- switch to discord
|
||||
- updates to community contribution guidance, code of conduct, etc.
|
||||
- overhaul of the documentation, including move to mkdocs with the materials UI
|
||||
- updated plugin documentation and full docs for the broker/client configuration
|
||||
- updated doc strings and cli help messages, including auto generation of those aspects into the docs
|
||||
- [Issue #215](https://github.com/Yakifo/amqtt/issues/215) test_sys.py fails on github, but not locally
|
||||
- [Issue #210](https://github.com/Yakifo/amqtt/issues/210) NoDataError thrown instead of ConnectError when client fails authentication
|
||||
- [Issue #199](https://github.com/Yakifo/amqtt/issues/199) will message being sent even if client properly disconnects
|
||||
- [Issue #180](https://github.com/Yakifo/amqtt/issues/180) plugin broker sys: incorrect uptime topic
|
||||
- [Issue #178](https://github.com/Yakifo/amqtt/issues/178) consolidate broker configuration documentation
|
||||
- [Issue #170](https://github.com/Yakifo/amqtt/issues/170) compatibility test cases: paho-mqtt
|
||||
- [Issue #159](https://github.com/Yakifo/amqtt/issues/159) Client last will (LWT) example and documentation
|
||||
- [Issue #157](https://github.com/Yakifo/amqtt/issues/157) loop = asyncio.get_event_loop() is deprecated
|
||||
- [Issue #154](https://github.com/Yakifo/amqtt/issues/154) broker rejects connect with empty will message
|
||||
- [Issue #144](https://github.com/Yakifo/amqtt/issues/144) Allow amqtt.client.MQTTClient to always reconnect via config
|
||||
- [Issue #105](https://github.com/Yakifo/amqtt/issues/105) Add stack traces to logging
|
||||
- [Issue #95](https://github.com/Yakifo/amqtt/issues/95) asyncio.get_event_loop() deprecated in Python 3.10
|
||||
- [Issue #94](https://github.com/Yakifo/amqtt/issues/94) test matrix for dependencies
|
||||
- [Issue #70](https://github.com/Yakifo/amqtt/issues/70) event and plugin documentation
|
||||
- [Issue #67](https://github.com/Yakifo/amqtt/issues/67) MQTTClient fails to raise appropriate exception if URI is broken
|
||||
- [Issue #51](https://github.com/Yakifo/amqtt/issues/51) failing plugin kills the broker
|
||||
- [Issue #48](https://github.com/Yakifo/amqtt/issues/48) Setup unit tests running against different versions of dependencies
|
||||
- [Issue #35](https://github.com/Yakifo/amqtt/issues/35) plugin interface and optimization
|
||||
|
||||
## 0.10.0
|
||||
|
||||
## 0.10.2
|
||||
|
||||
- create the necessary .readthedocs.yaml to generate sphinx docs from the 0.10.x series
|
||||
|
||||
## 0.10.1
|
||||
|
||||
- First release under new package name: amqtt
|
||||
- Reworked unit tests
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Containerization
|
||||
|
||||
Built from [dockerfile](https://github.com/Yakifo/amqtt/blob/main/dockerfile), the default `aMQTT` broker is publicly available on [DockerHub](https://hub.docker.com/repository/docker/amqtt/amqtt).
|
||||
`amqtt` library is available on [PyPI](https://pypi.python.org/pypi/amqtt), [GitHub](https://github.com/Yakifo/amqtt) and [Read the Docs](http://amqtt.readthedocs.org/).
|
||||
|
||||
Built from [Dockerfile](https://github.com/Yakifo/amqtt/blob/main/dockerfile), the default `aMQTT` broker is publicly available on [DockerHub](https://hub.docker.com/repository/docker/amqtt/amqtt).
|
||||
|
||||
## Launch
|
||||
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
HBMQTT Transition
|
||||
==================================
|
||||
|
||||
This document is for those porting from HBMQTT to aMQTT.
|
||||
Basically you can search and replace ``hbmqtt`` with ``amqtt`` and all should work out.
|
||||
Details below.
|
||||
|
||||
|
||||
Imports
|
||||
-------
|
||||
|
||||
The module changed from ``hbmqtt`` to ``amqtt``.
|
||||
For the 0.10.x releases it will still be possible to ``import hbmqtt``.
|
||||
In 0.11.x only ``amqtt`` will work.
|
||||
|
||||
Since the ``amqtt`` package does provide a ``hbmqtt`` module, installing the ``hbmqtt`` package in the same python installation is not possible.
|
||||
|
||||
|
||||
Random Client ID
|
||||
----------------
|
||||
|
||||
When not providing a client_id, a random id is automatically generated.
|
||||
These names were also changed from ``hbmqtt/<random>`` to ``amqtt/<random>``.
|
||||
|
||||
plugins / entrypoints
|
||||
---------------------
|
||||
|
||||
If you make use of python's entrypoint system to build aMQTT plugins, make sure to use the ``amqtt.*.plugins`` names instead of ``hbmqtt.*.plugins`` names.
|
||||
During the transition plugins with ``hbmqtt`` entrypoint should keep working for 0.10.x releases.
|
||||
|
||||
|
||||
CLI tools
|
||||
---------
|
||||
|
||||
* Renamed `hbmqtt` to `amqtt`
|
||||
* Renamed `hbmqtt_pub` to `amqtt_pub`
|
||||
* Renamed `hbmqtt_sub` to `amqtt_pub`
|
|
@ -1,2 +1,3 @@
|
|||
VITE_MQTT_WS_TYPE = ws
|
||||
VITE_MQTT_WS_HOST = not_set
|
||||
VITE_MQTT_WS_PORT = 9999
|
|
@ -1,2 +1,3 @@
|
|||
VITE_MQTT_WS_TYPE = ws
|
||||
VITE_MQTT_WS_HOST = localhost
|
||||
VITE_MQTT_WS_PORT = 8080
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
VITE_MQTT_WS_TYPE = wss
|
||||
VITE_MQTT_WS_HOST = test.amqtt.io
|
||||
VITE_MQTT_WS_PORT = 8080
|
||||
VITE_MQTT_WS_PORT = 8443
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "amqttio",
|
||||
"version": "0.0.0",
|
||||
"version": "0.11.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "amqttio",
|
||||
"version": "0.0.0",
|
||||
"version": "0.11.0",
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.0",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"name": "amqttio",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "0.11.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"build": "tsc -b && vite build --mode production",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
|
|
|
@ -5,11 +5,12 @@ import Typography from '@mui/material/Typography';
|
|||
import Copyright from '../internals/components/Copyright';
|
||||
import SessionsChart from './SessionsChart';
|
||||
import {useEffect, useState} from "react";
|
||||
import useMqtt from '../../assets/usemqtt';
|
||||
import type { DataPoint } from '../../assets/helpers';
|
||||
// @ts-ignore
|
||||
import useMqtt from '../../assets/usemqtt';
|
||||
import type {DataPoint} from '../../assets/helpers';
|
||||
import {Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material";
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faGithub, faPython, faDocker, faDiscord } from "@fortawesome/free-brands-svg-icons";
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'
|
||||
import {faGithub, faPython, faDocker, faDiscord} from "@fortawesome/free-brands-svg-icons";
|
||||
|
||||
import rtdIcon from "../../assets/readthedocs.svg";
|
||||
|
||||
|
@ -22,35 +23,36 @@ export default function MainGrid() {
|
|||
const [serverStart, setServerStart] = useState<string>('');
|
||||
const [serverUptime, setServerUptime] = useState<string>('');
|
||||
|
||||
function getRandomInt(min:number, max:number) {
|
||||
function getRandomInt(min: number, max: number) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
function secondsToDhms(seconds: int) {
|
||||
const days = Math.floor(seconds / (24 * 3600));
|
||||
seconds %= (24 * 3600);
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
seconds %= 3600;
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
seconds = seconds % 60;
|
||||
|
||||
return {
|
||||
days: days,
|
||||
hours: hours,
|
||||
minutes: minutes,
|
||||
seconds: seconds,
|
||||
};
|
||||
}
|
||||
function secondsToDhms(seconds: number) {
|
||||
const days = Math.floor(seconds / (24 * 3600));
|
||||
seconds %= (24 * 3600);
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
seconds %= 3600;
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
seconds = seconds % 60;
|
||||
|
||||
return {
|
||||
days: days,
|
||||
hours: hours,
|
||||
minutes: minutes,
|
||||
seconds: seconds,
|
||||
};
|
||||
}
|
||||
|
||||
const mqtt_settings = {
|
||||
url: 'ws://' + import.meta.env.VITE_MQTT_WS_HOST,
|
||||
client_id: `web-client-${getRandomInt(1, 100)}`,
|
||||
config: {
|
||||
port: import.meta.env.VITE_MQTT_WS_PORT
|
||||
}
|
||||
url: import.meta.env.VITE_MQTT_WS_TYPE + '://' + import.meta.env.VITE_MQTT_WS_HOST + ':' + import.meta.env.VITE_MQTT_WS_PORT, client_id: `web-client-${getRandomInt(1, 100)}`,
|
||||
clean: true,
|
||||
protocol: 'wss',
|
||||
protocolVersion: 4, // MQTT 3.1.1
|
||||
wsOptions: {
|
||||
protocol: 'mqtt'
|
||||
}
|
||||
};
|
||||
|
||||
const {mqttSubscribe, isConnected, messageQueue, messageTick} = useMqtt(mqtt_settings);
|
||||
|
@ -68,7 +70,7 @@ function secondsToDhms(seconds: int) {
|
|||
|
||||
while (messageQueue.current.length > 0) {
|
||||
const payload = messageQueue.current.shift()!;
|
||||
try {
|
||||
try {
|
||||
|
||||
const d = payload.message;
|
||||
if (payload.topic === '$SYS/broker/messages/publish/sent') {
|
||||
|
@ -99,28 +101,27 @@ function secondsToDhms(seconds: int) {
|
|||
const dt = new Date(d + "Z");
|
||||
setServerStart(dt.toLocaleString());
|
||||
} else if (payload.topic === '$SYS/broker/uptime') {
|
||||
const { days, hours, minutes, seconds } = secondsToDhms(d);
|
||||
const {days, hours, minutes, seconds} = secondsToDhms(d);
|
||||
setServerUptime(`${days} days, ${hours} hours, ${minutes} minutes, ${seconds} seconds`);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}, [messageTick, messageQueue]);
|
||||
|
||||
return (
|
||||
<Box sx={{ width: '100%', maxWidth: { sm: '100%', md: '1700px' } }}>
|
||||
<Box sx={{width: '100%', maxWidth: {sm: '100%', md: '1700px'}}}>
|
||||
{/* cards */}
|
||||
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
columns={12}
|
||||
sx={{ mb: (theme) => theme.spacing(2) }}
|
||||
sx={{mb: (theme) => theme.spacing(2)}}
|
||||
>
|
||||
<Grid size={{ xs: 10, md: 5 }}>
|
||||
<Typography component="h2" variant="h6" sx={{ mb: 2 }}>
|
||||
<Grid size={{xs: 10, md: 5}}>
|
||||
<Typography component="h2" variant="h6" sx={{mb: 2}}>
|
||||
Overview
|
||||
</Typography>
|
||||
<div>
|
||||
|
@ -134,15 +135,18 @@ function secondsToDhms(seconds: int) {
|
|||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style={{width:250}}>
|
||||
<td style={{width: 250}}>
|
||||
<p style={{textAlign: 'left'}}>
|
||||
<FontAwesomeIcon icon={faGithub} size="xl"/> github: <a href="https://github.com/Yakofo/amqtt">Yakifo/amqtt</a>
|
||||
<FontAwesomeIcon icon={faGithub} size="xl"/> github: <a
|
||||
href="https://github.com/Yakofo/amqtt">Yakifo/amqtt</a>
|
||||
</p>
|
||||
<p style={{textAlign: 'left'}}>
|
||||
<FontAwesomeIcon icon={faPython} size="xl"/> PyPi: <a href="https://pypi.org/project/amqtt/">aMQTT</a>
|
||||
<FontAwesomeIcon icon={faPython} size="xl"/> PyPi: <a
|
||||
href="https://pypi.org/project/amqtt/">aMQTT</a>
|
||||
</p>
|
||||
<p style={{textAlign: 'left'}}>
|
||||
<FontAwesomeIcon icon={faDiscord} size="xl"/> Discord: <a href="https://discord.gg/S3sP6dDaF3">aMQTT</a>
|
||||
<FontAwesomeIcon icon={faDiscord} size="xl"/> Discord: <a
|
||||
href="https://discord.gg/S3sP6dDaF3">aMQTT</a>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
|
@ -155,9 +159,10 @@ function secondsToDhms(seconds: int) {
|
|||
ReadTheDocs: <a href="https://amqtt.readthedocs.io/">aMQTT</a>
|
||||
</p>
|
||||
<p style={{textAlign: 'left'}}>
|
||||
<FontAwesomeIcon icon={faDocker} size="xl"/> DockerHub: <a href="https://hub.docker.com/repositories/amqtt">aMQTT</a>
|
||||
<FontAwesomeIcon icon={faDocker} size="xl"/> DockerHub: <a
|
||||
href="https://hub.docker.com/repositories/amqtt">aMQTT</a>
|
||||
</p>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -218,8 +223,8 @@ function secondsToDhms(seconds: int) {
|
|||
|
||||
|
||||
<strong>broker started at </strong> {serverStart}
|
||||
<strong>up for</strong> {serverUptime}
|
||||
</Grid>
|
||||
<strong>up for</strong> {serverUptime}
|
||||
</Grid>
|
||||
<Grid size={{xs: 12, md: 6}}>
|
||||
<SessionsChart title={'Sent Messages'} label={'Messages'} data={sent} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
|
@ -229,18 +234,18 @@ function secondsToDhms(seconds: int) {
|
|||
<Grid size={{xs: 12, md: 6}}>
|
||||
<SessionsChart title={'Bytes Out'} label={'Bytes'} data={bytesOut} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12, md: 6 }}>
|
||||
<SessionsChart title={'Bytes In'} label={'Bytes'} data={bytesIn} isConnected={isConnected} />
|
||||
<Grid size={{xs: 12, md: 6}}>
|
||||
<SessionsChart title={'Bytes In'} label={'Bytes'} data={bytesIn} isConnected={isConnected}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid container spacing={2} columns={12}>
|
||||
<Grid size={{ xs: 12, lg: 9 }}></Grid>
|
||||
<Grid size={{ xs: 12, lg: 3 }}>
|
||||
<Stack gap={2} direction={{ xs: 'column', sm: 'row', lg: 'column' }}></Stack>
|
||||
<Grid size={{xs: 12, lg: 9}}></Grid>
|
||||
<Grid size={{xs: 12, lg: 3}}>
|
||||
<Stack gap={2} direction={{xs: 'column', sm: 'row', lg: 'column'}}></Stack>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Copyright sx={{ my: 4 }} />
|
||||
<Copyright sx={{my: 4}}/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import Stack from '@mui/material/Stack';
|
|||
import { LineChart } from '@mui/x-charts/LineChart';
|
||||
import CountUp from 'react-countup';
|
||||
import type { DataPoint } from '../../assets/helpers.jsx';
|
||||
import React from "react";
|
||||
import {CircularProgress} from "@mui/material";
|
||||
|
||||
const currentTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
|
|
|
@ -11,7 +11,7 @@ listeners:
|
|||
bind: 0.0.0.0:8883
|
||||
ssl: on
|
||||
certfile: /etc/letsencrypt/live/test.amqtt.io/fullchain.pem
|
||||
keyfile: /etc/letsencrypt/live/test.amqtt.io/privkey.pemkk
|
||||
keyfile: /etc/letsencrypt/live/test.amqtt.io/privkey.pem
|
||||
tls-ws:
|
||||
type: ws
|
||||
bind: 0.0.0.0:8443
|
||||
|
|
|
@ -5,7 +5,7 @@ site_description: "Python's asyncio-native MQTT broker and client."
|
|||
site_url: http://github.com
|
||||
repo_url: https://github.com/Yakifo/amqtt
|
||||
repo_name: Yakifo/amqtt
|
||||
site_dir: "site"
|
||||
site_dir: "dist/rtd"
|
||||
watch:
|
||||
- mkdocs.rtd.yml
|
||||
- README.md
|
||||
|
|
|
@ -3,7 +3,7 @@ site_description: "MQTT broker and client natively implemented with Python's asy
|
|||
site_url: http://github.com
|
||||
repo_url: https://github.com/Yakifo/amqtt
|
||||
repo_name: Yakifo/amqtt
|
||||
site_dir: "site_web"
|
||||
site_dir: "dist/web"
|
||||
docs_dir: docs_web
|
||||
watch: [mkdocs.web.yml, docs_web]
|
||||
copyright: "amqtt.io © 2025"
|
||||
|
|
|
@ -20,7 +20,7 @@ classifiers = [
|
|||
"Programming Language :: Python :: 3.13"
|
||||
]
|
||||
|
||||
version = "0.11.0rc1"
|
||||
version = "0.11.0"
|
||||
requires-python = ">=3.10.0"
|
||||
readme = "README.md"
|
||||
license = { text = "MIT" }
|
||||
|
@ -33,7 +33,6 @@ dependencies = [
|
|||
"passlib==1.7.4", # https://pypi.org/project/passlib
|
||||
"PyYAML==6.0.2", # https://pypi.org/project/PyYAML
|
||||
"typer==0.15.4",
|
||||
"dacite>=1.9.2",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
|
@ -88,15 +87,13 @@ amqtt_pub = "amqtt.scripts.pub_script:main"
|
|||
amqtt_sub = "amqtt.scripts.sub_script:main"
|
||||
|
||||
[tool.hatch.build.targets.sdist]
|
||||
include = ["/amqtt"]
|
||||
include = ["/amqtt", "README.md"]
|
||||
|
||||
[tool.hatch.version]
|
||||
source = "vcs"
|
||||
|
||||
[tool.poe.tasks]
|
||||
rtd = "mkdocs serve -f mkdocs.rtd.yml"
|
||||
test = "pytest"
|
||||
docs = "mkdocs build"
|
||||
[tool.hatch.publish.indexes.testpypi]
|
||||
url = "https://test.pypi.org/legacy/"
|
||||
|
||||
# ___________________________________ PLUGINS __________________________________
|
||||
[project.entry-points."amqtt.test.plugins"]
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
services:
|
||||
amqtt:
|
||||
image: amqtt
|
||||
image: amqtt/amqtt
|
||||
container_name: amqtt
|
||||
ports:
|
||||
- "1883:1883"
|
||||
- "8080:8080"
|
||||
- "8443:8443"
|
||||
- "8883:8883"
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
|
@ -12,3 +14,4 @@ services:
|
|||
max-file: "3"
|
||||
volumes:
|
||||
- ./broker.yaml:/app/conf/broker.yaml
|
||||
- /etc/letsencrypt:/app/cert:ro
|
||||
|
|
13
uv.lock
13
uv.lock
|
@ -9,10 +9,9 @@ resolution-markers = [
|
|||
|
||||
[[package]]
|
||||
name = "amqtt"
|
||||
version = "0.11.0rc1"
|
||||
version = "0.11.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "dacite" },
|
||||
{ name = "passlib" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "transitions" },
|
||||
|
@ -67,7 +66,6 @@ docs = [
|
|||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "coveralls", marker = "extra == 'ci'", specifier = "==4.0.1" },
|
||||
{ name = "dacite", specifier = ">=1.9.2" },
|
||||
{ name = "passlib", specifier = "==1.7.4" },
|
||||
{ name = "pyyaml", specifier = "==6.0.2" },
|
||||
{ name = "transitions", specifier = "==0.9.2" },
|
||||
|
@ -487,15 +485,6 @@ version = "0.9.5"
|
|||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f1/2a/8c3ac3d8bc94e6de8d7ae270bb5bc437b210bb9d6d9e46630c98f4abd20c/csscompressor-0.9.5.tar.gz", hash = "sha256:afa22badbcf3120a4f392e4d22f9fff485c044a1feda4a950ecc5eba9dd31a05", size = 237808, upload-time = "2017-11-26T21:13:08.238Z" }
|
||||
|
||||
[[package]]
|
||||
name = "dacite"
|
||||
version = "1.9.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/55/a0/7ca79796e799a3e782045d29bf052b5cde7439a2bbb17f15ff44f7aacc63/dacite-1.9.2.tar.gz", hash = "sha256:6ccc3b299727c7aa17582f0021f6ae14d5de47c7227932c47fec4cdfefd26f09", size = 22420, upload-time = "2025-02-05T09:27:29.757Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/94/35/386550fd60316d1e37eccdda609b074113298f23cef5bddb2049823fe666/dacite-1.9.2-py3-none-any.whl", hash = "sha256:053f7c3f5128ca2e9aceb66892b1a3c8936d02c686e707bee96e19deef4bc4a0", size = 16600, upload-time = "2025-02-05T09:27:24.345Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dill"
|
||||
version = "0.4.0"
|
||||
|
|
Ładowanie…
Reference in New Issue