emodul 0.1.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.
@@ -0,0 +1,11 @@
1
+ # Enable GitHub Sponsors / external funding links to appear on the repo
2
+ # sidebar. Uncomment + fill in only what you actually use — leaving keys
3
+ # commented hides the "Sponsor this project" button entirely.
4
+ #
5
+ # Reference: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository
6
+
7
+ github: [hculap] # Your GitHub Sponsors handle
8
+ # ko_fi: yourhandle # https://ko-fi.com/yourhandle
9
+ # buy_me_a_coffee: yourhandle # https://buymeacoffee.com/yourhandle
10
+ # patreon: yourhandle # https://patreon.com/yourhandle
11
+ # custom: ['https://example.com/donate']
@@ -0,0 +1,55 @@
1
+ name: Bug report
2
+ description: Something doesn't work as expected
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for the report! Before submitting, please **anonymise** your
9
+ output — do not paste your JWT, `user_id`, `udid`, full controller
10
+ name, or other personal data.
11
+
12
+ - type: input
13
+ id: version
14
+ attributes:
15
+ label: emodul version
16
+ description: Output of `emodul --version`
17
+ placeholder: "emodul, version 0.1.0"
18
+ validations:
19
+ required: true
20
+
21
+ - type: input
22
+ id: controller
23
+ attributes:
24
+ label: Controller model
25
+ description: From `emodul --json modules list` (the `version` field)
26
+ placeholder: "TECH: L-4X WIFI (v.1.0.13)"
27
+ validations:
28
+ required: true
29
+
30
+ - type: textarea
31
+ id: command
32
+ attributes:
33
+ label: Exact command + output
34
+ description: |
35
+ Paste the command and its stdout/stderr. Run with `--json` if
36
+ possible so the output is parseable.
37
+ render: shell
38
+ validations:
39
+ required: true
40
+
41
+ - type: textarea
42
+ id: expected
43
+ attributes:
44
+ label: Expected behaviour
45
+ validations:
46
+ required: true
47
+
48
+ - type: textarea
49
+ id: env
50
+ attributes:
51
+ label: Environment
52
+ description: macOS / Linux distro, Python version, anything special
53
+ placeholder: "macOS 14.5, Python 3.12.3"
54
+ validations:
55
+ required: false
@@ -0,0 +1,36 @@
1
+ name: Feature request
2
+ description: Suggest a new command, flag, or supported endpoint
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: What problem does this solve?
9
+ description: Describe the use case in 1-3 sentences.
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: proposal
15
+ attributes:
16
+ label: Proposed solution
17
+ description: |
18
+ Concrete command shape if you have one, e.g.
19
+ `emodul zones export --format ical`
20
+ validations:
21
+ required: true
22
+
23
+ - type: input
24
+ id: endpoint
25
+ attributes:
26
+ label: Relevant eModul API endpoint (if you know it)
27
+ placeholder: "GET /api/v1/users/{user_id}/modules/{udid}/..."
28
+ validations:
29
+ required: false
30
+
31
+ - type: textarea
32
+ id: alternatives
33
+ attributes:
34
+ label: Alternatives you considered
35
+ validations:
36
+ required: false
@@ -0,0 +1,60 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ smoke:
11
+ name: Install + smoke test on Python ${{ matrix.python-version }}
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-latest, macos-latest]
17
+ python-version: ["3.11", "3.12", "3.13"]
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install package
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install -e .
29
+
30
+ - name: Verify CLI entrypoint
31
+ run: |
32
+ emodul --version
33
+ emodul --help
34
+
35
+ - name: Verify every subcommand has --help (no import errors)
36
+ run: |
37
+ for cmd in auth modules zones menu settings schedules stats alarms tiles watch; do
38
+ echo "--- $cmd ---"
39
+ emodul "$cmd" --help
40
+ done
41
+
42
+ - name: Verify Python package imports cleanly
43
+ run: |
44
+ python -c "import emodul; from emodul import api, auth, config, format, i18n, settings_map, storage; print('all modules import ok')"
45
+
46
+ lint:
47
+ name: Lint with ruff
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - uses: actions/setup-python@v5
53
+ with:
54
+ python-version: "3.12"
55
+
56
+ - name: Install ruff
57
+ run: pip install ruff
58
+
59
+ - name: Check style + obvious errors
60
+ run: ruff check emodul/ --select=E,F,I,B --ignore=E501
@@ -0,0 +1,55 @@
1
+ name: Publish to PyPI
2
+
3
+ # Triggered when you push a tag like `v0.2.0`.
4
+ # Requires PYPI_API_TOKEN secret to be set in repo settings:
5
+ # Settings → Secrets and variables → Actions → New repository secret
6
+ # Name: PYPI_API_TOKEN
7
+ # Value: <token from https://pypi.org/manage/account/token/>
8
+ #
9
+ # Or use OIDC trusted publishing (preferred): https://docs.pypi.org/trusted-publishers/
10
+ # In which case remove the `password:` line and set `id-token: write` permission.
11
+
12
+ on:
13
+ push:
14
+ tags: ["v*.*.*"]
15
+ workflow_dispatch:
16
+
17
+ jobs:
18
+ build:
19
+ name: Build sdist + wheel
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.12"
27
+
28
+ - name: Install build tooling
29
+ run: pip install build
30
+
31
+ - name: Build
32
+ run: python -m build
33
+
34
+ - uses: actions/upload-artifact@v4
35
+ with:
36
+ name: dist
37
+ path: dist/
38
+
39
+ publish:
40
+ name: Upload to PyPI
41
+ needs: build
42
+ runs-on: ubuntu-latest
43
+ environment:
44
+ name: pypi
45
+ url: https://pypi.org/project/emodul/
46
+ steps:
47
+ - uses: actions/download-artifact@v4
48
+ with:
49
+ name: dist
50
+ path: dist/
51
+
52
+ - name: Publish
53
+ uses: pypa/gh-action-pypi-publish@release/v1
54
+ with:
55
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ venv/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+
10
+ # Local config and any saved API dumps (contain tokens / personal data)
11
+ benchamr/
12
+ probes/
13
+ config.local.json
14
+ *.token
15
+ .env
@@ -0,0 +1,54 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the
26
+ overall community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or
31
+ advances of any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email
35
+ address, without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement
40
+
41
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
42
+ reported to the project maintainer by opening a confidential issue or
43
+ contacting the repository owner directly via GitHub.
44
+
45
+ All complaints will be reviewed and investigated promptly and fairly.
46
+
47
+ ## Attribution
48
+
49
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
50
+ version 2.1, available at
51
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
52
+
53
+ [homepage]: https://www.contributor-covenant.org
54
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
@@ -0,0 +1,88 @@
1
+ # Contributing
2
+
3
+ Thanks for considering a contribution! This project is small and pragmatic —
4
+ issues, PRs, and ideas are welcome.
5
+
6
+ ## Quick start (dev setup)
7
+
8
+ ```bash
9
+ git clone https://github.com/hculap/emodul.git
10
+ cd emodul
11
+ python3 -m venv .venv
12
+ .venv/bin/pip install -e .
13
+ .venv/bin/emodul --help
14
+ ```
15
+
16
+ ## Before opening a PR
17
+
18
+ - **Match the existing style.** Small files, immutable patterns, no
19
+ unnecessary abstractions.
20
+ - **No tests required for trivial changes** but if you touch HTTP/API
21
+ shapes please verify against your own eModul account.
22
+ - **Don't commit secrets.** `~/.config/emodul/config.json`, any JWT, the
23
+ `benchamr/` dump, anything in `probes/` — all are `.gitignore`d, keep
24
+ it that way.
25
+ - **Squash before merge.** One feature = one commit.
26
+
27
+ ## Architecture overview
28
+
29
+ - `emodul/api.py` — every endpoint is a method on `ApiClient`. Add new
30
+ endpoints here first.
31
+ - `emodul/commands/*.py` — one click subcommand group per file.
32
+ - `emodul/settings_map.py` — named-slug settings inventory; add new
33
+ controller parameters here.
34
+ - `emodul/storage.py` — SQLite schema for the watcher; bump cautiously
35
+ (no migrations framework yet).
36
+
37
+ See [README.md § Architecture](README.md#architecture) for full layout.
38
+
39
+ ## Reporting bugs
40
+
41
+ Use the bug-report issue template. Include:
42
+ - `emodul --version`
43
+ - Controller model (visible via `emodul --json modules list`)
44
+ - Exact command + `--json` output
45
+ - Stderr (API errors print there)
46
+
47
+ **Do not paste your JWT, `user_id`, `udid` or controller name** in public
48
+ issues — anonymise first.
49
+
50
+ ## Adding support for a new controller
51
+
52
+ The CLI is tested on **L-4X WIFI** but the API surface is shared across
53
+ most Tech controllers (L-8, L-9, L-12, etc.). If your controller exposes
54
+ endpoints we don't wrap:
55
+
56
+ 1. Find the call in your browser DevTools (F12 → Network → XHR on
57
+ emodul.pl).
58
+ 2. Replicate via `emodul raw <METHOD> <path>` first.
59
+ 3. Once confirmed, add the method to `emodul/api.py` and a wrapping
60
+ command to `emodul/commands/`.
61
+ 4. If the parameter belongs to a menu, add a friendly slug in
62
+ `emodul/settings_map.py`.
63
+
64
+ ## Recording a demo
65
+
66
+ ```bash
67
+ brew install asciinema # macOS
68
+ # OR
69
+ apt install asciinema # Ubuntu
70
+
71
+ asciinema rec demo.cast
72
+ # ... run a few emodul commands ...
73
+ # Ctrl-D to stop
74
+
75
+ # Upload (optional):
76
+ asciinema upload demo.cast
77
+ ```
78
+
79
+ For animated GIF use [`agg`](https://github.com/asciinema/agg):
80
+
81
+ ```bash
82
+ agg demo.cast demo.gif
83
+ ```
84
+
85
+ ## Code of conduct
86
+
87
+ This project follows the
88
+ [Contributor Covenant v2.1](CODE_OF_CONDUCT.md). Be kind.
emodul-0.1.0/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Szymon Paluch
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.
22
+
23
+ ---
24
+
25
+ DISCLAIMER: This is an UNOFFICIAL third-party client. The author has no
26
+ affiliation with TECH STEROWNIKI Sp. z o.o. or the eModul.pl service.
27
+ "TECH", "Tech Sterowniki", "eModul" and related marks belong to their
28
+ respective owners. This software is provided for personal use; using it
29
+ to access services you do not own may violate those services' terms.