pax_global_header 0000666 0000000 0000000 00000000064 15172161433 0014515 g ustar 00root root 0000000 0000000 52 comment=fc5699ab2f1a831939f573459845671e683c57b7
foxey-py-netgear-plus-fec1337/ 0000775 0000000 0000000 00000000000 15172161433 0016316 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/.devcontainer.json 0000664 0000000 0000000 00000002322 15172161433 0021747 0 ustar 00root root 0000000 0000000 {
"name": "foxey/py-netgear-plus",
"image": "mcr.microsoft.com/devcontainers/python:3.12",
"postCreateCommand": "scripts/setup",
"customizations": {
"vscode": {
"extensions": [
"charliermarsh.ruff",
"github.vscode-pull-request-github",
"ms-python.python",
"ms-python.vscode-pylance",
"ryanluker.vscode-coverage-gutters",
"esbenp.prettier-vscode",
"visualstudioexptteam.vscodeintellicode",
],
"settings": {
"files.eol": "\n",
"editor.tabSize": 4,
"editor.formatOnPaste": true,
"editor.formatOnSave": true,
"editor.formatOnType": false,
"files.trimTrailingWhitespace": true,
"python.analysis.typeCheckingMode": "basic",
"python.analysis.autoImportCompletions": true,
"python.defaultInterpreterPath": "/usr/local/bin/python",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
}
}
},
"remoteUser": "vscode",
"features": {}
} foxey-py-netgear-plus-fec1337/.gitattributes 0000664 0000000 0000000 00000000022 15172161433 0021203 0 ustar 00root root 0000000 0000000 * text=auto eol=lf foxey-py-netgear-plus-fec1337/.github/ 0000775 0000000 0000000 00000000000 15172161433 0017656 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 15172161433 0022041 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/.github/ISSUE_TEMPLATE/bug.yml 0000664 0000000 0000000 00000003057 15172161433 0023346 0 ustar 00root root 0000000 0000000 ---
name: "Bug report"
description: "Report a bug with the integration"
labels: "Bug"
body:
- type: markdown
attributes:
value: Before you open a new issue, search through the existing issues to see if others have had the same problem.
- type: checkboxes
attributes:
label: Checklist
options:
- label: I have enabled debug logging for my installation.
required: true
- label: I have filled out the issue template to the best of my ability.
required: true
- label: This issue only contains 1 issue (if you have multiple issues, open one issue for each issue).
required: true
- label: This issue is not a duplicate issue of any [previous issues](https://github.com/foxey/py-netgear-plus/issues?q=is%3Aissue+label%3A%22Bug%22+).
required: true
- type: textarea
attributes:
label: "Describe the issue"
description: "A clear and concise description of what the issue is."
validations:
required: true
- type: textarea
attributes:
label: Reproduction steps
description: "Without steps to reproduce, it will be hard to fix. It is very important that you fill out this part. Issues without it will be closed."
value: |
1.
2.
3.
...
validations:
required: true
- type: textarea
attributes:
label: "Debug logs"
description: "To enable debug logs add ```python import logging; logging.basicConfig(level=logging.DEBUG)``` to your python code."
validations:
required: true
foxey-py-netgear-plus-fec1337/.github/ISSUE_TEMPLATE/config.yml 0000664 0000000 0000000 00000000033 15172161433 0024025 0 ustar 00root root 0000000 0000000 blank_issues_enabled: false foxey-py-netgear-plus-fec1337/.github/ISSUE_TEMPLATE/feature_request.yml 0000664 0000000 0000000 00000003350 15172161433 0025770 0 ustar 00root root 0000000 0000000 ---
name: "Feature request"
description: "Suggest an idea for this project"
labels: "Feature+Request"
body:
- type: markdown
attributes:
value: Before you open a new feature request, search through the existing feature requests to see if others have had the same idea.
- type: checkboxes
attributes:
label: Checklist
options:
- label: I have filled out the template to the best of my ability.
required: true
- label: This only contains 1 feature request (if you have multiple feature requests, open one feature request for each feature request).
required: true
- label: This issue is not a duplicate feature request of [previous feature requests](https://github.com/ckarrie/ha-netgear-plus/issues?q=is%3Aissue+label%3A%22Feature+Request%22+).
required: true
- type: textarea
attributes:
label: "Is your feature request related to a problem? Please describe."
description: "A clear and concise description of what the problem is."
placeholder: "I'm always frustrated when [...]"
validations:
required: true
- type: textarea
attributes:
label: "Describe the solution you'd like"
description: "A clear and concise description of what you want to happen."
validations:
required: true
- type: textarea
attributes:
label: "Describe alternatives you've considered"
description: "A clear and concise description of any alternative solutions or features you've considered."
validations:
required: true
- type: textarea
attributes:
label: "Additional context"
description: "Add any other context or screenshots about the feature request here."
validations:
required: true
foxey-py-netgear-plus-fec1337/.github/ISSUE_TEMPLATE/task.yml 0000664 0000000 0000000 00000001171 15172161433 0023526 0 ustar 00root root 0000000 0000000 ---
name: "Task"
description: "Define a (sub)task to solve an issue (internal only)"
labels: "Task+Internal"
body:
- type: markdown
attributes:
value: This issue type is only to be used as a developer to create sub-issues. Newly reported issues of this type will be closed.
- type: textarea
attributes:
label: "Outcome"
description: "A detailed description of the desired outcome."
validations:
required: true
- type: textarea
attributes:
label: "Solution description"
description: "Description of the planned solution implementation."
validations:
required: false
foxey-py-netgear-plus-fec1337/.github/dependabot.yml 0000664 0000000 0000000 00000000521 15172161433 0022504 0 ustar 00root root 0000000 0000000 # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
foxey-py-netgear-plus-fec1337/.github/workflows/ 0000775 0000000 0000000 00000000000 15172161433 0021713 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/.github/workflows/ci.yml 0000664 0000000 0000000 00000002000 15172161433 0023021 0 ustar 00root root 0000000 0000000 name: "CI"
on:
push:
branches:
- "main"
pull_request:
branches:
- "main"
jobs:
ci:
name: "Ruff and Pytest QA"
runs-on: "ubuntu-latest"
permissions:
id-token: write
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- name: "Checkout the repository"
uses: "actions/checkout@v6.0.2"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6.2.0
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: "Install requirements"
run: python3 -m pip install -r requirements.txt
- name: "Lint with Ruff"
run: python3 -m ruff check .
- name: "Check format with Ruff"
run: python3 -m ruff format . --check
- name: "Install package"
run: |
python -m pip install -e .
- name: "Test package"
run: |
python -m pytest --cov=src/py_netgear_plus tests
foxey-py-netgear-plus-fec1337/.github/workflows/release.yml 0000664 0000000 0000000 00000003661 15172161433 0024064 0 ustar 00root root 0000000 0000000 name: "Release on PyPi and GitHub"
on:
push:
tags:
- "v*"
jobs:
release:
name: "Release pushed tag"
runs-on: "ubuntu-latest"
permissions:
id-token: write
contents: write
steps:
- name: "Checkout the repository"
uses: "actions/checkout@v6.0.2"
- name: "Set up Python"
uses: actions/setup-python@v6.2.0
with:
python-version: "3.12"
cache: "pip"
- name: "Install requirements"
run: python3 -m pip install -r requirements.txt
- name: "Lint with Ruff"
run: python3 -m ruff check .
- name: "Check format with Ruff"
run: python3 -m ruff format . --check
- name: "Install package"
run: |
python -m pip install -e .
- name: "Test package"
run: |
python -m pytest --cov=src/py_netgear_plus tests
- name: "Build packages"
run: |
python -m build
if: contains(github.ref, 'refs/tags')
- name: "Publish package on PyPi"
uses: pypa/gh-action-pypi-publish@v1.14.0
if: contains(github.ref, 'refs/tags')
- name: "Create GitHub release"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ github.ref_name }}
run: |
if [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Create release $tag"
gh release create "$tag" \
--repo="$GITHUB_REPOSITORY" \
--title="${GITHUB_REPOSITORY#*/} ${tag#v}" \
--generate-notes
elif [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(pre|rc)[0-9]+$ ]]; then
echo "Create prerelease $tag"
gh release create "$tag" \
--repo="$GITHUB_REPOSITORY" \
--title="${GITHUB_REPOSITORY#*/} ${tag#v}" \
--prerelease \
--generate-notes
else
echo "Not releasing $tag"
fi
foxey-py-netgear-plus-fec1337/.gitignore 0000664 0000000 0000000 00000000173 15172161433 0020307 0 ustar 00root root 0000000 0000000 # artifacts
__pycache__
*.pyc
*.egg-info
build/*
dist/*
src/secrets.py
# misc
.coverage
coverage.xml
.ruff_cache
.pypirc
foxey-py-netgear-plus-fec1337/.ruff.toml 0000664 0000000 0000000 00000001151 15172161433 0020231 0 ustar 00root root 0000000 0000000 # The contents of this file is based on https://github.com/home-assistant/core/blob/dev/pyproject.toml
target-version = "py312"
[lint]
select = [
"ALL",
]
ignore = [
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed
"D203", # no-blank-line-before-class (incompatible with formatter)
"D212", # multi-line-summary-first-line (incompatible with formatter)
"COM812", # incompatible with formatter
"ISC001", # incompatible with formatter
]
[lint.flake8-pytest-style]
fixture-parentheses = false
[lint.pyupgrade]
keep-runtime-typing = true
[lint.mccabe]
max-complexity = 25 foxey-py-netgear-plus-fec1337/.vscode/ 0000775 0000000 0000000 00000000000 15172161433 0017657 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/.vscode/settings.json 0000664 0000000 0000000 00000000442 15172161433 0022412 0 ustar 00root root 0000000 0000000 {
"python.analysis.autoImportCompletions": true,
"cSpell.words": [
"netgear",
"Netgear"
],
"python.testing.pytestArgs": [
"--cov=src/py_netgear_plus tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
} foxey-py-netgear-plus-fec1337/CONTRIBUTING.md 0000664 0000000 0000000 00000005054 15172161433 0020553 0 ustar 00root root 0000000 0000000 # Contribution guidelines
Contributing to this project should be as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
## Project Maintenance
The project owner [@foxey](https://github.com/foxey) currently lacks the time to actively review and support this project on a day-to-day basis.
To keep the project moving, review duties have been delegated to **Ada**, an AI assistant powered by [NanoClaw](https://github.com/foxey/nanoclaw). Ada will handle:
- Reviewing pull requests and posting feedback
- Triaging issues
- Merging approved contributions
Ada acts on behalf of @foxey. Final decisions on architectural changes or significant new features may still be escalated to @foxey directly.
If you're unsure whether your question needs a human, just open an issue or PR as usual — Ada will respond.
## Github is used for everything
Github is used to host code, to track issues and feature requests, as well as accept pull requests.
Pull requests are the best way to propose changes to the codebase.
1. Fork the repo and create your branch from `main`.
2. If you've changed something, update the documentation.
3. Make sure your code lints (using `scripts/lint`).
4. Test you contribution.
5. Issue that pull request!
## Any contributions you make will be under the Apache License
In short, when you submit code changes, your submissions are understood to be under the same [Apache License](https://www.apache.org/licenses/LICENSE-2.0) that covers the project. Feel free to contact the maintainers if that's a concern.
## Report bugs using Github's [issues](../../issues)
GitHub issues are used to track public bugs.
Report a bug by [opening a new issue](../../issues/new/choose); it's that easy!
## Write bug reports with detail, background, and sample code
**Great Bug Reports** tend to have:
- A quick summary and/or background
- Steps to reproduce
- Be specific!
- Give sample code if you can.
- What you expected would happen
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
People *love* thorough bug reports. I'm not even kidding.
## Use a Consistent Coding Style
Use [black](https://github.com/ambv/black) to make sure the code follows the style.
## Test your code modification
It comes with development environment in a container, easy to launch
if you use Visual Studio Code.
## License
By contributing, you agree that your contributions will be licensed under its Apache License.
foxey-py-netgear-plus-fec1337/HOWTO_Add_New_Models.md 0000664 0000000 0000000 00000013747 15172161433 0022440 0 ustar 00root root 0000000 0000000 # How to Add Additional Switch Models to py-netgear-plus
This guide provides step-by-step instructions on how to add support for additional Netgear Plus switch models to the **py-netgear-plus** Python library. The process involves defining a new switch model class, implementing the necessary attributes and methods, and registering the model in the library.
To add a new switch model, you need to update two files:
- **models.py**: This file defines various Netgear Plus switch models. Each model is implemented as a class inheriting from `AutodetectedSwitchModel`, with attributes specifying model-specific details.
- **parsers.py**: This file contains parsing functions used to extract and interpret data from switch responses. If a new model requires unique parsing logic, it should be added here.
---
## 1. Create a New Class for the Switch Model
Each switch model should inherit from `AutodetectedSwitchModel` or from the most similar existing model. Inheriting from a similar model reduces duplication and ensures compatibility with the library's structure. Ensure that `MODEL_NAME` is identical to the class name. Intermediate classes that define logic shared by multiple models should not have a defined `MODEL_NAME` to prevend that `py_netgear_plus.autodetect_model()` finds multiple matching classes.
You can create a new switch model class by following the structure below:
```python
from typing import ClassVar
class GSXYZ(AutodetectedSwitchModel): # Replace GSXYZ with the actual model name
"""Definition for Netgear GSXYZ model."""
MODEL_NAME = "GSXYZ" # Set the actual model name
PORTS = 8 # Define the number of ports on the switch
POE_PORTS: ClassVar = [1, 2, 3, 4] # Define PoE ports (if applicable)
POE_MAX_POWER_ALL_PORTS = 60 # Define maximum PoE power (if applicable)
ALLOWED_COOKIE_TYPES: ClassVar = ["SID"] # Define allowed cookie types
CHECKS_AND_RESULTS: ClassVar = [
("check_login_form_rand", [True]), # Detection methods
("parse_login_title_tag", ["GSXYZ"]),
]
# Mandatory request templates for interacting with the switch
LOGIN_TEMPLATE: ClassVar = {
"method": "post",
"url": "http://{ip}/login.cgi",
"params": {"password": "_password_hash"},
}
SWITCH_INFO_TEMPLATES: ClassVar = [
{"method": "get", "url": "http://{ip}/switch_info.cgi"},
]
PORT_STATUS_TEMPLATES: ClassVar = [
{"method": "get", "url": "http://{ip}/status.cgi"},
]
PORT_STATISTICS_TEMPLATES: ClassVar = [
{"method": "get", "url": "http://{ip}/portStatistics.cgi"},
]
LOGOUT_TEMPLATES: ClassVar = [
{"method": "get", "url": "http://{ip}/logout.cgi"},
]
```
The `LOGIN_TEMPLATE`, `SWITCH_INFO_TEMPLATES`, `PORT_STATUS_TEMPLATES`, and `PORT_STATISTICS_TEMPLATES` are mandatory to implement for proper communication with the switch.
Modify the class attributes according to the specific switch model.
---
## 2. Implement Any Additional Model-Specific Methods
If the switch model supports additional functionality (such as PoE settings, LED control, etc.), implement the corresponding methods. For example:
```python
def get_switch_poe_port_data(self, poe_port: int, state: str) -> dict:
"""Returns data for enabling/disabling a PoE port."""
return {
"ACTION": "Apply",
"portID": poe_port - 1,
"ADMIN_MODE": 1 if state == "on" else 0,
"PORT_PRIO": 0,
}
```
Refer to existing switch models in `models.py` for additional examples.
## 3. Create a Parser Class and Register It in `parsers.py`
Each switch model has its own parser class. If the new model introduces unique parsing logic, create a new parser class in `parsers.py`. Ensure that this parser class inherits from the most similar existing parser class to maintain consistency. The name of the parser class should be identical to the name of the model in `models.py`.
## 4. Add pages responses to the `pages/` folder
The repository contains a collection of page responses used by `pytest` to ensure that no regression problems are introduced during future updates.
The structure of the collection is as follows: `pages/MODEL_NAME/0` and `pages/MODE_NAME/1`. Add a copy of each first successful retrieval from these templates: `AUTODETECT_TEMPLATES', `LOGIN_TEMPLATE`, `SWITCH_INFO_TEMPLATES`, `PORT_STATUS_TEMPLATES`, and `PORT_STATISTICS_TEMPLATES`to both directories.
Ensure that the response of the login page is the first one sent (most switches redirect to a dashboard page after the initial response) and that the latter three pages are saved using a valid login session (otherwise the only contain a redirect to the login page). Also ensure that for the page retrieved by`PORT_STATISTICS_TEMPLATES`the copy in the`/1`folder is taken 10-60 seconds after the one in the`/0`. The test suite tests if the calculations for the `traffic_rx`and`traffic_tx` speeds are performed correctly.
## 5. Test the New Model and Update Unit Tests
1. Connect the switch to your network.
2. Run the auto-detection feature to verify if the switch is correctly identified.
3. Ensure that all required API endpoints work correctly.
4. If PoE or LED controls are implemented, test them thoroughly.
5. Add unit tests for the new model in the test suite:
- Locate the unit test file in `tests/test__init__.py` that contains tests for existing switch models.
- Add the new model to the `MODEL_PARAMETERS` list with appropriate test values (rand, crypted password, and response content).
- If the model lacks complete test data, add it to `MODELS_FOR_GET_SWITCH_INFOS` with an appropriate `pytest.mark.xfail` annotation.
- Run the test suite with `pytest` to confirm all tests pass, and fix any issues as needed.
## 6. Submit a Pull Request
Please share the new model code by creating a pull request in the `py-netgear-plus` repository:
1. Fork the repository.
2. Commit your changes with a descriptive message.
3. Push the changes to your forked repository.
4. Submit a pull request with details about the new model.
foxey-py-netgear-plus-fec1337/LICENSE.md 0000664 0000000 0000000 00000026135 15172161433 0017731 0 ustar 00root root 0000000 0000000 Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
foxey-py-netgear-plus-fec1337/README.md 0000664 0000000 0000000 00000014110 15172161433 0017572 0 ustar 00root root 0000000 0000000 # Python Library for NETGEAR Plus Switches
## What it does
Grabs statistical network data from [supported NETGEAR Switches](#supported-and-tested-netgear-modelsproducts-and-firmwares) from the
[Plus Managed Network Switch](https://www.netgear.com/business/wired/switches/plus/) line. These switches can only be managed using a
Web interface and not through SNMP or cli. This library uses web scraping to collect the switch configuration, statistics and
some basic configuration updates.
## How it works
1. Detecting Switch Model/Product in login.cgi
2. Connects to the Switch and asks for a cookie (`http://IP_OF_SWITCH/login.cgi`)
3. HTTP-Request send to the Switch twice (`http://IP_OF_SWITCH/portStatistics.cgi`) and compared with previous data ("in response time")
### List of port statistics
| Name | key from `get_switch_infos()` | Unit |
| ----------------------------- | ---------------------------------- | ----------------------------------- |
| Port {port} Traffic Received | `port_{port}_traffic_rx_mbytes` | MB (in response time) |
| Port {port} Traffic Sent | `port_{port}_traffic_tx_mbytes` | MB (in response time) |
| Port {port} Receiving | `port_{port}_speed_rx_mbytes` | MB/s |
| Port {port} Transferring | `port_{port}_speed_tx_mbytes` | MB/s |
| Port {port} IO | `port_{port}_speed_io_mbytes` | MB/s |
| Port {port} Total Received | `port_{port}_sum_rx_mbytes` | MB (since last switch reboot/reset) |
| Port {port} Total Transferred | `port_{port}_sum_tx_mbytes` | MB (since last switch reboot/reset) |
| Port {port} Connection Speed | `port_{port}_connection_speed` | MB/s |
| Port {port} Status | `port_{port}_status` | "on"/"off" |
| Port {poe_port} POE Power | `port_{poe_port}_poe_power_active` | "on"/"off" |
### List of aggregated statistics
| Sensor Name | key from `get_switch_infos()` | Unit |
| ----------------------- | ----------------------------- | --------------------- |
| Switch IO | `sum_port_speed_bps_io` | MB/s |
| Switch Traffic Received | `sum_port_traffic_rx` | MB (in response time) |
| Switch Traffic Sent | `sum_port_traffic_tx` | MB (in response time) |
## Supported and tested NETGEAR Models/Products and firmware versions
| Model | Ports | Firmware versions | Bootloader versions |
| --------- | ----- | -------------------------------------- | ------------------- |
| GS105E | 5 | ? | |
| GS105Ev2 | 5 | V1.6.0.15 | V1.4.0.5-VB |
| GS105PE | 5 | V1.6.0.17 | V1.6.0.2-VB |
| GS108E | 8 | V1.00.11 | V1.00.03 |
| GS105Ev3 | 5 | ? | |
| GS108Ev3 | 8 | V2.00.05, V2.06.10, V2.06.17, V2.06.24 | V2.06.01 - V2.06.03 |
| GS108Ev4 | 8 | V1.0.1.3 | |
| GS108PEv3 | 8 | V2.06.24 | V0.00.00 |
| GS110EMX | 10 | V1.0.2.8 | |
| GS116Ev2 | 16 | V2.6.0.48, V2.6.0.50 | |
| GS305E | 5 | V1.0.0.16 | V1.0.0.2 |
| GS305EP | 5 | V1.0.1.1 | |
| GS305EPP | 5 | V1.0.1.4 | |
| GS308E | 8 | V1.00.11 | V1.00.03 |
| GS308EP | 8 | V1.0.0.10, V1.0.1.4, V2.0.0.5 | |
| GS308EPP | 8 | V1.0.1.4 | |
| GS308Ev4 | 8 | V1.0.1.3 | |
| GS316EP | 16 | V1.0.4.4 | |
| GS316EPP | 16 | V1.0.4.4 | |
| JGS516PE | 16 | V2.6.0.48 | |
| JGS24Ev2 | 24 | V2.6.0.48 | |
| MS305E | 5 | v1.0.0.9 | |
| MS308E | 8 | v1.0.0.9 | |
| XS512EM | 12 | V1.0.2.8 | |
Supported firmware languages: GR (German), EN (English)
## Unsupported models
| Model | Support status |
| -------- | --------------------------------------------------------------- |
| JGS524PE | See [#93](https://github.com/ckarrie/ha-netgear-plus/issues/93) |
| MS108EUP | See [#91](https://github.com/ckarrie/ha-netgear-plus/issues/91) |
`HOWTO_Add_New_Models.md` contains instructions to add unsupported models.
## CLI usage
```shell
export NETGEAR_PLUS_PASSWORD=s3cr3t # replace with your password
ngp-cli login 192.168.178.68 # replace with IP address of your switch
ngp-cli status
ngp-cli logout
ngp-cli -h
```
## Library Usage
### Create a python virtual environment
```shell
python3 -m venv .venv
source .venv/bin/activate
pip install py-netgear-plus
```
Using this VENV go to your local source folder
### Example calls
```shell
cd src
python3
```
```python
ip = '192.168.178.68' # replace with IP address of your switch
p = 'fyce4gKZemkqjDY' # replace with your password
import py_netgear_plus
sw = py_netgear_plus.NetgearSwitchConnector(ip, p)
sw.autodetect_model()
sw.get_login_cookie()
data = sw.get_switch_infos()
print(sw.switch_model.MODEL_NAME)
print(data["port_1_sum_rx_mbytes"])
print(data)
sw.turn_off_poe_port(1) # Supported only on PoE capable models
sw.turn_on_poe_port(1)
```
foxey-py-netgear-plus-fec1337/pages/ 0000775 0000000 0000000 00000000000 15172161433 0017415 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/pages/GS105Ev2/ 0000775 0000000 0000000 00000000000 15172161433 0020531 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/pages/GS105Ev2/0/ 0000775 0000000 0000000 00000000000 15172161433 0020670 5 ustar 00root root 0000000 0000000 foxey-py-netgear-plus-fec1337/pages/GS105Ev2/0/device_reboot.cgi 0000664 0000000 0000000 00000003026 15172161433 0024166 0 ustar 00root root 0000000 0000000
Device Reboot
Check box and click Apply button to reboot switch.