bricklogger 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bricklogger-0.2.0/LICENSE +21 -0
- bricklogger-0.2.0/PKG-INFO +208 -0
- bricklogger-0.2.0/README.md +163 -0
- bricklogger-0.2.0/pyproject.toml +126 -0
- bricklogger-0.2.0/pyproject.toml.orig +103 -0
- bricklogger-0.2.0/src/bricklogger/__init__.py +17 -0
- bricklogger-0.2.0/src/bricklogger/__main__.py +6 -0
- bricklogger-0.2.0/src/bricklogger/cli/__init__.py +107 -0
- bricklogger-0.2.0/src/bricklogger/cli/client.py +62 -0
- bricklogger-0.2.0/src/bricklogger/cli/config.py +199 -0
- bricklogger-0.2.0/src/bricklogger/cli/context.py +32 -0
- bricklogger-0.2.0/src/bricklogger/cli/daemon_commands.py +386 -0
- bricklogger-0.2.0/src/bricklogger/cli/guided.py +141 -0
- bricklogger-0.2.0/src/bricklogger/cli/init.py +184 -0
- bricklogger-0.2.0/src/bricklogger/cli/mcp_command.py +330 -0
- bricklogger-0.2.0/src/bricklogger/cli/model.py +422 -0
- bricklogger-0.2.0/src/bricklogger/cli/notify.py +93 -0
- bricklogger-0.2.0/src/bricklogger/cli/output.py +41 -0
- bricklogger-0.2.0/src/bricklogger/cli/plugins.py +410 -0
- bricklogger-0.2.0/src/bricklogger/cli/query.py +102 -0
- bricklogger-0.2.0/src/bricklogger/cli/roles.py +685 -0
- bricklogger-0.2.0/src/bricklogger/cli/serve.py +66 -0
- bricklogger-0.2.0/src/bricklogger/config/__init__.py +95 -0
- bricklogger-0.2.0/src/bricklogger/config/daemon.py +76 -0
- bricklogger-0.2.0/src/bricklogger/config/examples.py +110 -0
- bricklogger-0.2.0/src/bricklogger/config/instances.py +91 -0
- bricklogger-0.2.0/src/bricklogger/config/issues.py +72 -0
- bricklogger-0.2.0/src/bricklogger/config/loader.py +325 -0
- bricklogger-0.2.0/src/bricklogger/config/schema.py +425 -0
- bricklogger-0.2.0/src/bricklogger/config/validation.py +283 -0
- bricklogger-0.2.0/src/bricklogger/config/values.py +125 -0
- bricklogger-0.2.0/src/bricklogger/daemon/__init__.py +1 -0
- bricklogger-0.2.0/src/bricklogger/daemon/api.py +505 -0
- bricklogger-0.2.0/src/bricklogger/daemon/codes.py +53 -0
- bricklogger-0.2.0/src/bricklogger/daemon/core.py +1199 -0
- bricklogger-0.2.0/src/bricklogger/daemon/explorer.py +818 -0
- bricklogger-0.2.0/src/bricklogger/daemon/instances.py +432 -0
- bricklogger-0.2.0/src/bricklogger/daemon/jobs.py +133 -0
- bricklogger-0.2.0/src/bricklogger/daemon/logging.py +93 -0
- bricklogger-0.2.0/src/bricklogger/daemon/metadata.py +79 -0
- bricklogger-0.2.0/src/bricklogger/daemon/notify.py +790 -0
- bricklogger-0.2.0/src/bricklogger/daemon/overlay.py +171 -0
- bricklogger-0.2.0/src/bricklogger/daemon/plan.py +184 -0
- bricklogger-0.2.0/src/bricklogger/daemon/plugins.py +212 -0
- bricklogger-0.2.0/src/bricklogger/daemon/rules.py +306 -0
- bricklogger-0.2.0/src/bricklogger/daemon/run.py +62 -0
- bricklogger-0.2.0/src/bricklogger/daemon/sink.py +115 -0
- bricklogger-0.2.0/src/bricklogger/daemon/sparql.py +92 -0
- bricklogger-0.2.0/src/bricklogger/daemon/spool.py +164 -0
- bricklogger-0.2.0/src/bricklogger/daemon/state.py +650 -0
- bricklogger-0.2.0/src/bricklogger/docs/README.md +24 -0
- bricklogger-0.2.0/src/bricklogger/docs/architecture.md +808 -0
- bricklogger-0.2.0/src/bricklogger/docs/docker.md +376 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/api.md +316 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/cli.md +409 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/configuration.md +285 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/daemon.md +287 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/destinations.md +101 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/mcp.md +233 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/notifications.md +191 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/plugins.md +594 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/sources.md +404 -0
- bricklogger-0.2.0/src/bricklogger/docs/features/web.md +248 -0
- bricklogger-0.2.0/src/bricklogger/docs/getting-started.md +254 -0
- bricklogger-0.2.0/src/bricklogger/docs/vision.md +82 -0
- bricklogger-0.2.0/src/bricklogger/mcp/__init__.py +7 -0
- bricklogger-0.2.0/src/bricklogger/mcp/http.py +95 -0
- bricklogger-0.2.0/src/bricklogger/mcp/instructions.py +47 -0
- bricklogger-0.2.0/src/bricklogger/mcp/server.py +609 -0
- bricklogger-0.2.0/src/bricklogger/model/Brick.ttl +57114 -0
- bricklogger-0.2.0/src/bricklogger/model/LICENSE-Brick.txt +32 -0
- bricklogger-0.2.0/src/bricklogger/model/__init__.py +109 -0
- bricklogger-0.2.0/src/bricklogger/model/diff.py +77 -0
- bricklogger-0.2.0/src/bricklogger/model/inference.py +257 -0
- bricklogger-0.2.0/src/bricklogger/model/ontology.py +22 -0
- bricklogger-0.2.0/src/bricklogger/model/prefixes.py +91 -0
- bricklogger-0.2.0/src/bricklogger/model/shapes.ttl +31 -0
- bricklogger-0.2.0/src/bricklogger/model/upload.py +121 -0
- bricklogger-0.2.0/src/bricklogger/model/versions.py +145 -0
- bricklogger-0.2.0/src/bricklogger/model/working_graph.py +93 -0
- bricklogger-0.2.0/src/bricklogger/ops/__init__.py +28 -0
- bricklogger-0.2.0/src/bricklogger/ops/catalogue.py +135 -0
- bricklogger-0.2.0/src/bricklogger/ops/client.py +216 -0
- bricklogger-0.2.0/src/bricklogger/ops/config.py +239 -0
- bricklogger-0.2.0/src/bricklogger/ops/context.py +61 -0
- bricklogger-0.2.0/src/bricklogger/ops/docs.py +57 -0
- bricklogger-0.2.0/src/bricklogger/ops/environment.py +588 -0
- bricklogger-0.2.0/src/bricklogger/ops/errors.py +53 -0
- bricklogger-0.2.0/src/bricklogger/ops/plugin_volume.py +257 -0
- bricklogger-0.2.0/src/bricklogger/ops/status.py +104 -0
- bricklogger-0.2.0/src/bricklogger/ops/tools.py +46 -0
- bricklogger-0.2.0/src/bricklogger/ops/tree.py +84 -0
- bricklogger-0.2.0/src/bricklogger/plugins/__init__.py +1 -0
- bricklogger-0.2.0/src/bricklogger/plugins/bacnet_ip/__init__.py +1 -0
- bricklogger-0.2.0/src/bricklogger/plugins/bacnet_ip/config.py +215 -0
- bricklogger-0.2.0/src/bricklogger/plugins/bacnet_ip/declaration.py +80 -0
- bricklogger-0.2.0/src/bricklogger/plugins/bacnet_ip/references.py +313 -0
- bricklogger-0.2.0/src/bricklogger/plugins/bacnet_ip/source.py +705 -0
- bricklogger-0.2.0/src/bricklogger/plugins/bacnet_ip/tools.py +594 -0
- bricklogger-0.2.0/src/bricklogger/plugins/bacnet_ip/values.py +126 -0
- bricklogger-0.2.0/src/bricklogger/plugins/timescaledb/__init__.py +1 -0
- bricklogger-0.2.0/src/bricklogger/plugins/timescaledb/config.py +26 -0
- bricklogger-0.2.0/src/bricklogger/plugins/timescaledb/declaration.py +17 -0
- bricklogger-0.2.0/src/bricklogger/plugins/timescaledb/destination.py +316 -0
- bricklogger-0.2.0/src/bricklogger/py.typed +0 -0
- bricklogger-0.2.0/src/bricklogger/sdk/__init__.py +73 -0
- bricklogger-0.2.0/src/bricklogger/sdk/bacnet.py +112 -0
- bricklogger-0.2.0/src/bricklogger/sdk/contract.py +299 -0
- bricklogger-0.2.0/src/bricklogger/sdk/declaration.py +169 -0
- bricklogger-0.2.0/src/bricklogger/sdk/registry.py +198 -0
- bricklogger-0.2.0/src/bricklogger/sdk/testing.py +269 -0
- bricklogger-0.2.0/src/bricklogger/web/__init__.py +1 -0
- bricklogger-0.2.0/src/bricklogger/web/app.py +967 -0
- bricklogger-0.2.0/src/bricklogger/web/client.py +131 -0
- bricklogger-0.2.0/src/bricklogger/web/forms.py +158 -0
- bricklogger-0.2.0/src/bricklogger/web/static/css/app.css +155 -0
- bricklogger-0.2.0/src/bricklogger/web/static/css/explorer.css +149 -0
- bricklogger-0.2.0/src/bricklogger/web/static/fonts/ibm-plex-mono-400.woff2 +0 -0
- bricklogger-0.2.0/src/bricklogger/web/static/fonts/ibm-plex-mono-500.woff2 +0 -0
- bricklogger-0.2.0/src/bricklogger/web/static/fonts/ibm-plex-mono-600.woff2 +0 -0
- bricklogger-0.2.0/src/bricklogger/web/static/fonts/ibm-plex-sans-var.woff2 +0 -0
- bricklogger-0.2.0/src/bricklogger/web/static/js/explorer.js +1185 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/LICENSES.md +12 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/codemirror-yaml.min.js +8 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/codemirror.min.css +8 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/codemirror.min.js +8 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/cytoscape.min.js +31 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/htmx.min.js +1 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/yasgui.min.css +1 -0
- bricklogger-0.2.0/src/bricklogger/web/static/vendor/yasgui.min.js +3 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/base.html +62 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/config.html +77 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/daemon.html +6 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/explorer.html +124 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/instances.html +44 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/login.html +24 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/model.html +30 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/notifications.html +7 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/overview.html +7 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/config_result.html +13 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/daemon.html +20 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/diff.html +14 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/health.html +1 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/instances.html +69 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/job.html +31 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/model_versions.html +37 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/notifications.html +20 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/notify_test.html +9 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/overview.html +47 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/plugins.html +53 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/points.html +36 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/statusline.html +13 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/tool_result.html +26 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/partials/unreachable.html +4 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/plugins.html +6 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/points.html +37 -0
- bricklogger-0.2.0/src/bricklogger/web/templates/query.html +24 -0
- bricklogger-0.2.0/src/bricklogger/web/texts.py +363 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CX1 ApS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bricklogger
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Data bridge for building automation: collects data based on a Brick model and writes it to time-series databases
|
|
5
|
+
Keywords: brick,bacnet,building-automation,timescaledb,data-logger
|
|
6
|
+
Author: Michael Rosenlund
|
|
7
|
+
Author-email: Michael Rosenlund <michael.rosenlund@cx1.dk>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Environment :: Web Environment
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Home Automation
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Requires-Dist: pydantic>=2.7
|
|
23
|
+
Requires-Dist: pyyaml>=6.0
|
|
24
|
+
Requires-Dist: typer>=0.12
|
|
25
|
+
Requires-Dist: httpx>=0.27
|
|
26
|
+
Requires-Dist: fastapi>=0.110
|
|
27
|
+
Requires-Dist: uvicorn>=0.29
|
|
28
|
+
Requires-Dist: jinja2>=3.1
|
|
29
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
30
|
+
Requires-Dist: itsdangerous>=2.1
|
|
31
|
+
Requires-Dist: rdflib>=7.0
|
|
32
|
+
Requires-Dist: pyshacl>=0.30
|
|
33
|
+
Requires-Dist: reasonable>=0.4
|
|
34
|
+
Requires-Dist: pyoxigraph>=0.4
|
|
35
|
+
Requires-Dist: bacpypes3>=0.0.90
|
|
36
|
+
Requires-Dist: psycopg[binary]>=3.1
|
|
37
|
+
Requires-Dist: mcp>=2.2.0
|
|
38
|
+
Requires-Dist: packaging>=24
|
|
39
|
+
Requires-Python: >=3.11
|
|
40
|
+
Project-URL: Homepage, https://github.com/CX1-ApS/bricklogger
|
|
41
|
+
Project-URL: Documentation, https://cx1-aps.github.io/bricklogger/
|
|
42
|
+
Project-URL: Source, https://github.com/CX1-ApS/bricklogger
|
|
43
|
+
Project-URL: Issues, https://github.com/CX1-ApS/bricklogger/issues
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
# Bricklogger
|
|
47
|
+
|
|
48
|
+
Bricklogger is a data bridge for building automation. It reads a
|
|
49
|
+
[Brick](https://brickschema.org/) model of a building, collects the values of
|
|
50
|
+
the points the model describes from the building's automation systems, and
|
|
51
|
+
writes them to a time-series database. The model decides what is collected:
|
|
52
|
+
upload a new model, and the logger follows it.
|
|
53
|
+
|
|
54
|
+
- **Sources:** BACnet/IP on the local network is built in; other systems are
|
|
55
|
+
added as plugins, such as the [iBOS source](https://github.com/CX1-ApS/bricklogger-ibos)
|
|
56
|
+
for the iBOS Data API in the cloud.
|
|
57
|
+
- **Destination:** TimescaleDB, with every observation timestamped by its
|
|
58
|
+
source and a spool that holds them while the database is away.
|
|
59
|
+
- **Interfaces:** a command-line interface first, a web interface with the same
|
|
60
|
+
abilities beside it — including a model explorer — an HTTP API, and an MCP
|
|
61
|
+
server so an AI assistant can configure the logger for you.
|
|
62
|
+
- **Read only:** Bricklogger never writes to a building automation system.
|
|
63
|
+
|
|
64
|
+
The full documentation is at **<https://cx1-aps.github.io/bricklogger/>**. This
|
|
65
|
+
page is the short version.
|
|
66
|
+
|
|
67
|
+
## What you need
|
|
68
|
+
|
|
69
|
+
- A Linux machine, amd64 or arm64, that can reach the building's network —
|
|
70
|
+
for BACnet/IP, on the same subnet as the devices or with a route to them.
|
|
71
|
+
- A Brick model of the building as Turtle (`.ttl`), with the points' external
|
|
72
|
+
references (BACnet device and object, for instance).
|
|
73
|
+
- A TimescaleDB database Bricklogger may create tables in.
|
|
74
|
+
|
|
75
|
+
## Install
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
curl -fsSL https://github.com/CX1-ApS/bricklogger/releases/latest/download/install.sh | sudo sh
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The script brings its own Python, so the machine needs only `curl`. With
|
|
82
|
+
`sudo` it installs a service: the program under `/opt/bricklogger`, the
|
|
83
|
+
configuration in `/etc/bricklogger`, the data in `/var/lib/bricklogger` and
|
|
84
|
+
three systemd units, left stopped. Without `sudo` everything stays in your home
|
|
85
|
+
directory. `--version 0.2.0` installs a given version; options come after
|
|
86
|
+
`--` when the script is piped: `… | sudo sh -s -- --version 0.2.0`.
|
|
87
|
+
|
|
88
|
+
**As a container** the same program is `ghcr.io/cx1-aps/bricklogger`, with a
|
|
89
|
+
compose file for the daemon, the web interface and the MCP server; see
|
|
90
|
+
[Docker](https://cx1-aps.github.io/bricklogger/docker/).
|
|
91
|
+
|
|
92
|
+
## Prepare the database
|
|
93
|
+
|
|
94
|
+
```sql
|
|
95
|
+
CREATE DATABASE brick;
|
|
96
|
+
\c brick
|
|
97
|
+
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
|
98
|
+
CREATE ROLE bricklogger LOGIN PASSWORD '...';
|
|
99
|
+
GRANT ALL ON SCHEMA public TO bricklogger;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Bricklogger creates and migrates its own tables at the first start.
|
|
103
|
+
|
|
104
|
+
## First setup
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
bricklogger init # guided: sources, destinations, secrets
|
|
108
|
+
bricklogger validate # after any edit by hand
|
|
109
|
+
bricklogger daemon start # or: sudo systemctl enable --now bricklogger
|
|
110
|
+
bricklogger model upload building.ttl # validate, infer, activate
|
|
111
|
+
bricklogger status
|
|
112
|
+
bricklogger points --outcome active # the last value of every point
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`init` asks for the settings of each source and destination and writes four
|
|
116
|
+
files: `sources.yaml`, `destinations.yaml`, `rules.yaml` and `daemon.yaml`.
|
|
117
|
+
Secrets, such as the database password, go into an `env` file beside them and
|
|
118
|
+
are referred to as `${NAME}`. The first rule set accepts every point in the
|
|
119
|
+
model every five minutes; [rules](https://cx1-aps.github.io/bricklogger/features/configuration/)
|
|
120
|
+
narrow that down by class, location, equipment or any SPARQL pattern.
|
|
121
|
+
|
|
122
|
+
## The web interface and an assistant
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
bricklogger serve # http://127.0.0.1:8421
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Everything the CLI does can be done there, and the model explorer shows the
|
|
129
|
+
building as a tree and a graph, with every point's outcome and value.
|
|
130
|
+
|
|
131
|
+
To let an AI assistant that speaks MCP set up sources, destinations and rules,
|
|
132
|
+
register the MCP server with it — for Claude Code on the same machine:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
claude mcp add --transport stdio bricklogger -- bricklogger mcp serve
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The assistant reads the plugins' schemas and this documentation, validates
|
|
139
|
+
before it writes, and never takes a secret's value. See
|
|
140
|
+
[MCP](https://cx1-aps.github.io/bricklogger/features/mcp/) for remote use.
|
|
141
|
+
|
|
142
|
+
## Plugins
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
bricklogger plugins # what is installed
|
|
146
|
+
bricklogger plugins add bricklogger-ibos # add a plugin from PyPI
|
|
147
|
+
bricklogger plugins remove ibos # remove one by its type
|
|
148
|
+
sudo systemctl restart bricklogger # the daemon reads plugins at start
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
A plugin is a Python package that provides a source or a destination type. A
|
|
152
|
+
plugin that cannot load stops nothing: its instances show as failed and the
|
|
153
|
+
rest keep running. Writing one is described under
|
|
154
|
+
[plugins](https://cx1-aps.github.io/bricklogger/features/plugins/).
|
|
155
|
+
|
|
156
|
+
## Mail notifications
|
|
157
|
+
|
|
158
|
+
Bricklogger can mail an administrator when something goes wrong, when it is
|
|
159
|
+
put right, and once a day as proof that it is alive. Put the mail server and
|
|
160
|
+
recipients under `notifications` in `daemon.yaml`, then:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
bricklogger notify test
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
See [notifications](https://cx1-aps.github.io/bricklogger/features/notifications/).
|
|
167
|
+
|
|
168
|
+
## Upgrade
|
|
169
|
+
|
|
170
|
+
Run the install script again; it leaves the plugins, the configuration and the
|
|
171
|
+
data where they are. Then restart the daemon. A container pulls the new image
|
|
172
|
+
instead:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
curl -fsSL https://github.com/CX1-ApS/bricklogger/releases/latest/download/install.sh | sudo sh
|
|
176
|
+
sudo systemctl restart bricklogger
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
After an upgrade to a new minor version, `bricklogger plugins` shows whether
|
|
180
|
+
every plugin still loads.
|
|
181
|
+
|
|
182
|
+
**Upgrading from 0.1 with an iBOS source:** iBOS is no longer built in. The
|
|
183
|
+
`ibos` instance shows as failed until the plugin is added with
|
|
184
|
+
`bricklogger plugins add bricklogger-ibos` and the daemon is restarted; the
|
|
185
|
+
configuration and the collected history stay as they were.
|
|
186
|
+
|
|
187
|
+
## If nothing arrives
|
|
188
|
+
|
|
189
|
+
- `bricklogger status warnings` lists what stands in the way, one line per
|
|
190
|
+
cause — points no source claims, points without a reference, read errors.
|
|
191
|
+
- `bricklogger sources bacnet_main discover` shows the BACnet devices that
|
|
192
|
+
answer. If none does, the address in `sources.yaml` or the network is the
|
|
193
|
+
problem, not the model.
|
|
194
|
+
- `bricklogger sources bacnet_main resolve <point>` shows how one point's
|
|
195
|
+
reference resolves, and reads it.
|
|
196
|
+
- `bricklogger destinations status` shows whether the database takes writes.
|
|
197
|
+
While it does not, observations wait in the spool.
|
|
198
|
+
|
|
199
|
+
## Reporting a problem
|
|
200
|
+
|
|
201
|
+
Bugs and questions go in the
|
|
202
|
+
[issues](https://github.com/CX1-ApS/bricklogger/issues). A security
|
|
203
|
+
vulnerability is reported privately, as [SECURITY.md](https://github.com/CX1-ApS/bricklogger/blob/main/SECURITY.md) describes.
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
[MIT](https://github.com/CX1-ApS/bricklogger/blob/main/LICENSE). Bricklogger bundles Brick's ontology and a few web libraries
|
|
208
|
+
and fonts under their own licenses, listed with them in the package.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Bricklogger
|
|
2
|
+
|
|
3
|
+
Bricklogger is a data bridge for building automation. It reads a
|
|
4
|
+
[Brick](https://brickschema.org/) model of a building, collects the values of
|
|
5
|
+
the points the model describes from the building's automation systems, and
|
|
6
|
+
writes them to a time-series database. The model decides what is collected:
|
|
7
|
+
upload a new model, and the logger follows it.
|
|
8
|
+
|
|
9
|
+
- **Sources:** BACnet/IP on the local network is built in; other systems are
|
|
10
|
+
added as plugins, such as the [iBOS source](https://github.com/CX1-ApS/bricklogger-ibos)
|
|
11
|
+
for the iBOS Data API in the cloud.
|
|
12
|
+
- **Destination:** TimescaleDB, with every observation timestamped by its
|
|
13
|
+
source and a spool that holds them while the database is away.
|
|
14
|
+
- **Interfaces:** a command-line interface first, a web interface with the same
|
|
15
|
+
abilities beside it — including a model explorer — an HTTP API, and an MCP
|
|
16
|
+
server so an AI assistant can configure the logger for you.
|
|
17
|
+
- **Read only:** Bricklogger never writes to a building automation system.
|
|
18
|
+
|
|
19
|
+
The full documentation is at **<https://cx1-aps.github.io/bricklogger/>**. This
|
|
20
|
+
page is the short version.
|
|
21
|
+
|
|
22
|
+
## What you need
|
|
23
|
+
|
|
24
|
+
- A Linux machine, amd64 or arm64, that can reach the building's network —
|
|
25
|
+
for BACnet/IP, on the same subnet as the devices or with a route to them.
|
|
26
|
+
- A Brick model of the building as Turtle (`.ttl`), with the points' external
|
|
27
|
+
references (BACnet device and object, for instance).
|
|
28
|
+
- A TimescaleDB database Bricklogger may create tables in.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
curl -fsSL https://github.com/CX1-ApS/bricklogger/releases/latest/download/install.sh | sudo sh
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The script brings its own Python, so the machine needs only `curl`. With
|
|
37
|
+
`sudo` it installs a service: the program under `/opt/bricklogger`, the
|
|
38
|
+
configuration in `/etc/bricklogger`, the data in `/var/lib/bricklogger` and
|
|
39
|
+
three systemd units, left stopped. Without `sudo` everything stays in your home
|
|
40
|
+
directory. `--version 0.2.0` installs a given version; options come after
|
|
41
|
+
`--` when the script is piped: `… | sudo sh -s -- --version 0.2.0`.
|
|
42
|
+
|
|
43
|
+
**As a container** the same program is `ghcr.io/cx1-aps/bricklogger`, with a
|
|
44
|
+
compose file for the daemon, the web interface and the MCP server; see
|
|
45
|
+
[Docker](https://cx1-aps.github.io/bricklogger/docker/).
|
|
46
|
+
|
|
47
|
+
## Prepare the database
|
|
48
|
+
|
|
49
|
+
```sql
|
|
50
|
+
CREATE DATABASE brick;
|
|
51
|
+
\c brick
|
|
52
|
+
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
|
53
|
+
CREATE ROLE bricklogger LOGIN PASSWORD '...';
|
|
54
|
+
GRANT ALL ON SCHEMA public TO bricklogger;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Bricklogger creates and migrates its own tables at the first start.
|
|
58
|
+
|
|
59
|
+
## First setup
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bricklogger init # guided: sources, destinations, secrets
|
|
63
|
+
bricklogger validate # after any edit by hand
|
|
64
|
+
bricklogger daemon start # or: sudo systemctl enable --now bricklogger
|
|
65
|
+
bricklogger model upload building.ttl # validate, infer, activate
|
|
66
|
+
bricklogger status
|
|
67
|
+
bricklogger points --outcome active # the last value of every point
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`init` asks for the settings of each source and destination and writes four
|
|
71
|
+
files: `sources.yaml`, `destinations.yaml`, `rules.yaml` and `daemon.yaml`.
|
|
72
|
+
Secrets, such as the database password, go into an `env` file beside them and
|
|
73
|
+
are referred to as `${NAME}`. The first rule set accepts every point in the
|
|
74
|
+
model every five minutes; [rules](https://cx1-aps.github.io/bricklogger/features/configuration/)
|
|
75
|
+
narrow that down by class, location, equipment or any SPARQL pattern.
|
|
76
|
+
|
|
77
|
+
## The web interface and an assistant
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
bricklogger serve # http://127.0.0.1:8421
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Everything the CLI does can be done there, and the model explorer shows the
|
|
84
|
+
building as a tree and a graph, with every point's outcome and value.
|
|
85
|
+
|
|
86
|
+
To let an AI assistant that speaks MCP set up sources, destinations and rules,
|
|
87
|
+
register the MCP server with it — for Claude Code on the same machine:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
claude mcp add --transport stdio bricklogger -- bricklogger mcp serve
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The assistant reads the plugins' schemas and this documentation, validates
|
|
94
|
+
before it writes, and never takes a secret's value. See
|
|
95
|
+
[MCP](https://cx1-aps.github.io/bricklogger/features/mcp/) for remote use.
|
|
96
|
+
|
|
97
|
+
## Plugins
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
bricklogger plugins # what is installed
|
|
101
|
+
bricklogger plugins add bricklogger-ibos # add a plugin from PyPI
|
|
102
|
+
bricklogger plugins remove ibos # remove one by its type
|
|
103
|
+
sudo systemctl restart bricklogger # the daemon reads plugins at start
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
A plugin is a Python package that provides a source or a destination type. A
|
|
107
|
+
plugin that cannot load stops nothing: its instances show as failed and the
|
|
108
|
+
rest keep running. Writing one is described under
|
|
109
|
+
[plugins](https://cx1-aps.github.io/bricklogger/features/plugins/).
|
|
110
|
+
|
|
111
|
+
## Mail notifications
|
|
112
|
+
|
|
113
|
+
Bricklogger can mail an administrator when something goes wrong, when it is
|
|
114
|
+
put right, and once a day as proof that it is alive. Put the mail server and
|
|
115
|
+
recipients under `notifications` in `daemon.yaml`, then:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
bricklogger notify test
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
See [notifications](https://cx1-aps.github.io/bricklogger/features/notifications/).
|
|
122
|
+
|
|
123
|
+
## Upgrade
|
|
124
|
+
|
|
125
|
+
Run the install script again; it leaves the plugins, the configuration and the
|
|
126
|
+
data where they are. Then restart the daemon. A container pulls the new image
|
|
127
|
+
instead:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
curl -fsSL https://github.com/CX1-ApS/bricklogger/releases/latest/download/install.sh | sudo sh
|
|
131
|
+
sudo systemctl restart bricklogger
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
After an upgrade to a new minor version, `bricklogger plugins` shows whether
|
|
135
|
+
every plugin still loads.
|
|
136
|
+
|
|
137
|
+
**Upgrading from 0.1 with an iBOS source:** iBOS is no longer built in. The
|
|
138
|
+
`ibos` instance shows as failed until the plugin is added with
|
|
139
|
+
`bricklogger plugins add bricklogger-ibos` and the daemon is restarted; the
|
|
140
|
+
configuration and the collected history stay as they were.
|
|
141
|
+
|
|
142
|
+
## If nothing arrives
|
|
143
|
+
|
|
144
|
+
- `bricklogger status warnings` lists what stands in the way, one line per
|
|
145
|
+
cause — points no source claims, points without a reference, read errors.
|
|
146
|
+
- `bricklogger sources bacnet_main discover` shows the BACnet devices that
|
|
147
|
+
answer. If none does, the address in `sources.yaml` or the network is the
|
|
148
|
+
problem, not the model.
|
|
149
|
+
- `bricklogger sources bacnet_main resolve <point>` shows how one point's
|
|
150
|
+
reference resolves, and reads it.
|
|
151
|
+
- `bricklogger destinations status` shows whether the database takes writes.
|
|
152
|
+
While it does not, observations wait in the spool.
|
|
153
|
+
|
|
154
|
+
## Reporting a problem
|
|
155
|
+
|
|
156
|
+
Bugs and questions go in the
|
|
157
|
+
[issues](https://github.com/CX1-ApS/bricklogger/issues). A security
|
|
158
|
+
vulnerability is reported privately, as [SECURITY.md](https://github.com/CX1-ApS/bricklogger/blob/main/SECURITY.md) describes.
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
[MIT](https://github.com/CX1-ApS/bricklogger/blob/main/LICENSE). Bricklogger bundles Brick's ontology and a few web libraries
|
|
163
|
+
and fonts under their own licenses, listed with them in the package.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "bricklogger"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "Data bridge for building automation: collects data based on a Brick model and writes it to time-series databases"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.11"
|
|
9
|
+
keywords = [
|
|
10
|
+
"brick",
|
|
11
|
+
"bacnet",
|
|
12
|
+
"building-automation",
|
|
13
|
+
"timescaledb",
|
|
14
|
+
"data-logger",
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
"Environment :: Web Environment",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Intended Audience :: System Administrators",
|
|
22
|
+
"Operating System :: POSIX :: Linux",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Topic :: Home Automation",
|
|
28
|
+
"Topic :: Scientific/Engineering",
|
|
29
|
+
]
|
|
30
|
+
dependencies = [
|
|
31
|
+
"pydantic>=2.7",
|
|
32
|
+
"pyyaml>=6.0",
|
|
33
|
+
"typer>=0.12",
|
|
34
|
+
"httpx>=0.27",
|
|
35
|
+
"fastapi>=0.110",
|
|
36
|
+
"uvicorn>=0.29",
|
|
37
|
+
"jinja2>=3.1",
|
|
38
|
+
"python-multipart>=0.0.9",
|
|
39
|
+
"itsdangerous>=2.1",
|
|
40
|
+
"rdflib>=7.0",
|
|
41
|
+
"pyshacl>=0.30",
|
|
42
|
+
"reasonable>=0.4",
|
|
43
|
+
"pyoxigraph>=0.4",
|
|
44
|
+
"bacpypes3>=0.0.90",
|
|
45
|
+
"psycopg[binary]>=3.1",
|
|
46
|
+
"mcp>=2.2.0",
|
|
47
|
+
"packaging>=24",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[[project.authors]]
|
|
51
|
+
name = "Michael Rosenlund"
|
|
52
|
+
email = "michael.rosenlund@cx1.dk"
|
|
53
|
+
|
|
54
|
+
[project.urls]
|
|
55
|
+
Homepage = "https://github.com/CX1-ApS/bricklogger"
|
|
56
|
+
Documentation = "https://cx1-aps.github.io/bricklogger/"
|
|
57
|
+
Source = "https://github.com/CX1-ApS/bricklogger"
|
|
58
|
+
Issues = "https://github.com/CX1-ApS/bricklogger/issues"
|
|
59
|
+
|
|
60
|
+
[project.scripts]
|
|
61
|
+
bricklogger = "bricklogger.cli:main"
|
|
62
|
+
|
|
63
|
+
[project.entry-points."bricklogger.sources"]
|
|
64
|
+
bacnet-ip = "bricklogger.plugins.bacnet_ip.declaration:SOURCE"
|
|
65
|
+
|
|
66
|
+
[project.entry-points."bricklogger.destinations"]
|
|
67
|
+
timescaledb = "bricklogger.plugins.timescaledb.declaration:DESTINATION"
|
|
68
|
+
|
|
69
|
+
[dependency-groups]
|
|
70
|
+
dev = [
|
|
71
|
+
"pytest>=8.0",
|
|
72
|
+
"ruff>=0.5",
|
|
73
|
+
"mypy>=1.10",
|
|
74
|
+
"types-PyYAML>=6.0",
|
|
75
|
+
"mkdocs-material>=9.7.6",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[build-system]
|
|
79
|
+
requires = ["uv_build>=0.8,<0.13"]
|
|
80
|
+
build-backend = "uv_build"
|
|
81
|
+
|
|
82
|
+
[tool.uv.build-backend]
|
|
83
|
+
module-name = "bricklogger"
|
|
84
|
+
module-root = "src"
|
|
85
|
+
|
|
86
|
+
[tool.ruff]
|
|
87
|
+
line-length = 88
|
|
88
|
+
target-version = "py311"
|
|
89
|
+
src = [
|
|
90
|
+
"src",
|
|
91
|
+
"tests",
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
[tool.ruff.lint]
|
|
95
|
+
select = [
|
|
96
|
+
"E",
|
|
97
|
+
"F",
|
|
98
|
+
"W",
|
|
99
|
+
"I",
|
|
100
|
+
"UP",
|
|
101
|
+
"B",
|
|
102
|
+
"SIM",
|
|
103
|
+
"RUF",
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
[tool.mypy]
|
|
107
|
+
python_version = "3.11"
|
|
108
|
+
strict = true
|
|
109
|
+
plugins = ["pydantic.mypy"]
|
|
110
|
+
files = [
|
|
111
|
+
"src",
|
|
112
|
+
"tests",
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
[[tool.mypy.overrides]]
|
|
116
|
+
module = [
|
|
117
|
+
"bacpypes3.*",
|
|
118
|
+
"rdflib.*",
|
|
119
|
+
"pyshacl.*",
|
|
120
|
+
"reasonable.*",
|
|
121
|
+
]
|
|
122
|
+
ignore_missing_imports = true
|
|
123
|
+
|
|
124
|
+
[tool.pytest.ini_options]
|
|
125
|
+
testpaths = ["tests"]
|
|
126
|
+
addopts = "-q"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "bricklogger"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "Data bridge for building automation: collects data based on a Brick model and writes it to time-series databases"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Michael Rosenlund", email = "michael.rosenlund@cx1.dk" }]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
keywords = ["brick", "bacnet", "building-automation", "timescaledb", "data-logger"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Environment :: Web Environment",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Intended Audience :: System Administrators",
|
|
17
|
+
"Operating System :: POSIX :: Linux",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Topic :: Home Automation",
|
|
23
|
+
"Topic :: Scientific/Engineering",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
# core
|
|
27
|
+
"pydantic>=2.7",
|
|
28
|
+
"pyyaml>=6.0",
|
|
29
|
+
# CLI
|
|
30
|
+
"typer>=0.12",
|
|
31
|
+
"httpx>=0.27",
|
|
32
|
+
# API and web interface
|
|
33
|
+
"fastapi>=0.110",
|
|
34
|
+
"uvicorn>=0.29",
|
|
35
|
+
"jinja2>=3.1",
|
|
36
|
+
"python-multipart>=0.0.9",
|
|
37
|
+
"itsdangerous>=2.1",
|
|
38
|
+
# Brick model and working graph
|
|
39
|
+
"rdflib>=7.0",
|
|
40
|
+
"pyshacl>=0.30",
|
|
41
|
+
"reasonable>=0.4",
|
|
42
|
+
"pyoxigraph>=0.4",
|
|
43
|
+
# plugins
|
|
44
|
+
"bacpypes3>=0.0.90",
|
|
45
|
+
"psycopg[binary]>=3.1",
|
|
46
|
+
"mcp>=2.2.0",
|
|
47
|
+
# plugin management: the requirements and markers read at `plugins remove`
|
|
48
|
+
"packaging>=24",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[project.urls]
|
|
52
|
+
Homepage = "https://github.com/CX1-ApS/bricklogger"
|
|
53
|
+
Documentation = "https://cx1-aps.github.io/bricklogger/"
|
|
54
|
+
Source = "https://github.com/CX1-ApS/bricklogger"
|
|
55
|
+
Issues = "https://github.com/CX1-ApS/bricklogger/issues"
|
|
56
|
+
|
|
57
|
+
[project.scripts]
|
|
58
|
+
bricklogger = "bricklogger.cli:main"
|
|
59
|
+
|
|
60
|
+
[project.entry-points."bricklogger.sources"]
|
|
61
|
+
bacnet-ip = "bricklogger.plugins.bacnet_ip.declaration:SOURCE"
|
|
62
|
+
|
|
63
|
+
[project.entry-points."bricklogger.destinations"]
|
|
64
|
+
timescaledb = "bricklogger.plugins.timescaledb.declaration:DESTINATION"
|
|
65
|
+
|
|
66
|
+
[dependency-groups]
|
|
67
|
+
dev = [
|
|
68
|
+
"pytest>=8.0",
|
|
69
|
+
"ruff>=0.5",
|
|
70
|
+
"mypy>=1.10",
|
|
71
|
+
"types-PyYAML>=6.0",
|
|
72
|
+
"mkdocs-material>=9.7.6",
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
[build-system]
|
|
76
|
+
requires = ["uv_build>=0.8,<0.13"]
|
|
77
|
+
build-backend = "uv_build"
|
|
78
|
+
|
|
79
|
+
[tool.uv.build-backend]
|
|
80
|
+
module-name = "bricklogger"
|
|
81
|
+
module-root = "src"
|
|
82
|
+
|
|
83
|
+
[tool.ruff]
|
|
84
|
+
line-length = 88
|
|
85
|
+
target-version = "py311"
|
|
86
|
+
src = ["src", "tests"]
|
|
87
|
+
|
|
88
|
+
[tool.ruff.lint]
|
|
89
|
+
select = ["E", "F", "W", "I", "UP", "B", "SIM", "RUF"]
|
|
90
|
+
|
|
91
|
+
[tool.mypy]
|
|
92
|
+
python_version = "3.11"
|
|
93
|
+
strict = true
|
|
94
|
+
plugins = ["pydantic.mypy"]
|
|
95
|
+
files = ["src", "tests"]
|
|
96
|
+
|
|
97
|
+
[[tool.mypy.overrides]]
|
|
98
|
+
module = ["bacpypes3.*", "rdflib.*", "pyshacl.*", "reasonable.*"]
|
|
99
|
+
ignore_missing_imports = true
|
|
100
|
+
|
|
101
|
+
[tool.pytest.ini_options]
|
|
102
|
+
testpaths = ["tests"]
|
|
103
|
+
addopts = "-q"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Bricklogger: a data bridge for building automation, driven by a Brick model.
|
|
2
|
+
|
|
3
|
+
The package is laid out after the architecture in ``docs/architecture.md``:
|
|
4
|
+
|
|
5
|
+
- ``bricklogger.daemon`` — the long-running core that collects and writes,
|
|
6
|
+
- ``bricklogger.cli`` — the ``bricklogger`` command, the control plane,
|
|
7
|
+
- ``bricklogger.web`` — the web interface served by ``bricklogger serve``,
|
|
8
|
+
- ``bricklogger.mcp`` — the MCP server served by ``bricklogger mcp serve``, for
|
|
9
|
+
an AI assistant,
|
|
10
|
+
- ``bricklogger.ops`` — the operations the CLI and the MCP server share,
|
|
11
|
+
- ``bricklogger.sdk`` — the contract and the helpers plugins are built on,
|
|
12
|
+
- ``bricklogger.plugins`` — the built-in source (BACnet/IP) and
|
|
13
|
+
destination (TimescaleDB), registered through the same entry points as
|
|
14
|
+
external plugins.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
__version__ = "0.2.0"
|