mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-04-02 08:12:21 -07:00
Compare commits
46 Commits
v26.3.7
...
next_relea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f80d2e57f | ||
|
|
b18cf98266 | ||
|
|
77369c3ce8 | ||
|
|
cd0a3f6de0 | ||
|
|
13e91731be | ||
|
|
7ef19b1c12 | ||
|
|
4daead1f8f | ||
|
|
48454f6f2f | ||
|
|
7305fd78e3 | ||
|
|
ec3e4c8988 | ||
|
|
250e533655 | ||
|
|
37730301f4 | ||
|
|
7278ee8cfa | ||
|
|
fa22523a0b | ||
|
|
7569923481 | ||
|
|
d7c7bd2cd2 | ||
|
|
b311113575 | ||
|
|
43984132c4 | ||
|
|
0a7ecb5b7c | ||
|
|
c7399215ec | ||
|
|
0bb6db155b | ||
|
|
7221b4ba96 | ||
|
|
c4904739b2 | ||
|
|
67cab9d606 | ||
|
|
f75c53fc5d | ||
|
|
bff87f4d61 | ||
|
|
6f7d2c3253 | ||
|
|
0766fb2de6 | ||
|
|
d19cb3d679 | ||
|
|
9b71c210b2 | ||
|
|
c9cb1f3fba | ||
|
|
78a8030c6a | ||
|
|
b5b0bcc766 | ||
|
|
13515603e4 | ||
|
|
518608cffc | ||
|
|
df3ca50c5c | ||
|
|
93fc126da2 | ||
|
|
a60ec9ed3a | ||
|
|
e1d206ca74 | ||
|
|
2771a6e9c2 | ||
|
|
aba1ddd3df | ||
|
|
165c9d3baa | ||
|
|
0b0c88f712 | ||
|
|
d49abd9d02 | ||
|
|
abf024d4d3 | ||
|
|
4eb5947ceb |
9
.github/skills/code-standards/SKILL.md
vendored
9
.github/skills/code-standards/SKILL.md
vendored
@@ -5,13 +5,14 @@ description: NetAlertX coding standards and conventions. Use this when writing c
|
||||
|
||||
# Code Standards
|
||||
|
||||
- ask me to review before going to each next step (mention n step out of x)
|
||||
- before starting, prepare implementation plan
|
||||
- ask me to review before going to each next step (mention n step out of x) (AI only)
|
||||
- before starting, prepare implementation plan (AI only)
|
||||
- ask me to review it and ask any clarifying questions first
|
||||
- add test creation as last step - follow repo architecture patterns - do not place in the root of /test
|
||||
- code has to be maintainable, no duplicate code
|
||||
- follow DRY principle
|
||||
- follow DRY principle - maintainability of code is more important than speed of implementation
|
||||
- code files should be less than 500 LOC for better maintainability
|
||||
- DB columns must not contain underscores, use camelCase instead (e.g., deviceInstanceId, not device_instance_id)
|
||||
|
||||
## File Length
|
||||
|
||||
@@ -64,7 +65,7 @@ Use timeNowUTC(as_string=False) for datetime operations (scheduling, comparisons
|
||||
|
||||
## String Sanitization
|
||||
|
||||
Use sanitizers from `server/helper.py` before storing user input.
|
||||
Use sanitizers from `server/helper.py` before storing user input. MAC addresses are always lowercased and normalized. IP addresses should be validated.
|
||||
|
||||
## Devcontainer Constraints
|
||||
|
||||
|
||||
6
.github/workflows/mkdocs.yml
vendored
6
.github/workflows/mkdocs.yml
vendored
@@ -22,8 +22,10 @@ jobs:
|
||||
|
||||
- name: Install MkDocs
|
||||
run: |
|
||||
pip install mkdocs mkdocs-material
|
||||
pip install mkdocs-github-admonitions-plugin
|
||||
pip install \
|
||||
mkdocs==1.6.0 \
|
||||
mkdocs-material==9.5.21 \
|
||||
mkdocs-github-admonitions-plugin==0.0.4
|
||||
|
||||
- name: Build MkDocs
|
||||
run: mkdocs build
|
||||
|
||||
16
.github/workflows/run-all-tests.yml
vendored
16
.github/workflows/run-all-tests.yml
vendored
@@ -3,6 +3,10 @@ name: 🧪 Manual Test Suite Selector
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run_all:
|
||||
description: '✅ Run ALL tests (overrides individual selectors)'
|
||||
type: boolean
|
||||
default: false
|
||||
run_scan:
|
||||
description: '📂 scan/ (Scan, Logic, Locks, IPs)'
|
||||
type: boolean
|
||||
@@ -23,6 +27,10 @@ on:
|
||||
description: '📂 ui/ (Selenium & Dashboard)'
|
||||
type: boolean
|
||||
default: false
|
||||
run_plugins:
|
||||
description: '📂 plugins/ (Sync insert schema-aware logic)'
|
||||
type: boolean
|
||||
default: false
|
||||
run_root_files:
|
||||
description: '📄 Root Test Files (WOL, Atomicity, etc.)'
|
||||
type: boolean
|
||||
@@ -42,12 +50,20 @@ jobs:
|
||||
id: builder
|
||||
run: |
|
||||
PATHS=""
|
||||
|
||||
# run_all overrides everything
|
||||
if [ "${{ github.event.inputs.run_all }}" == "true" ]; then
|
||||
echo "final_paths=test/" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Folder Mapping with 'test/' prefix
|
||||
if [ "${{ github.event.inputs.run_scan }}" == "true" ]; then PATHS="$PATHS test/scan/"; fi
|
||||
if [ "${{ github.event.inputs.run_api }}" == "true" ]; then PATHS="$PATHS test/api_endpoints/ test/server/"; fi
|
||||
if [ "${{ github.event.inputs.run_backend }}" == "true" ]; then PATHS="$PATHS test/backend/ test/db/"; fi
|
||||
if [ "${{ github.event.inputs.run_docker_env }}" == "true" ]; then PATHS="$PATHS test/docker_tests/"; fi
|
||||
if [ "${{ github.event.inputs.run_ui }}" == "true" ]; then PATHS="$PATHS test/ui/"; fi
|
||||
if [ "${{ github.event.inputs.run_plugins }}" == "true" ]; then PATHS="$PATHS test/plugins/"; fi
|
||||
|
||||
# Root Files Mapping (files sitting directly in /test/)
|
||||
if [ "${{ github.event.inputs.run_root_files }}" == "true" ]; then
|
||||
|
||||
@@ -1,23 +1,38 @@
|
||||
# 🤝 Contributing to NetAlertX
|
||||
# Contributing to NetAlertX
|
||||
|
||||
First off, **thank you** for taking the time to contribute! NetAlertX is built and improved with the help of passionate people like you.
|
||||
|
||||
---
|
||||
|
||||
## 📂 Issues, Bugs, and Feature Requests
|
||||
## Issues, Bugs, and Feature Requests
|
||||
|
||||
Please use the [GitHub Issue Tracker](https://github.com/netalertx/NetAlertX/issues) for:
|
||||
- Bug reports 🐞
|
||||
- Feature requests 💡
|
||||
- Documentation feedback 📖
|
||||
- Bug reports
|
||||
- Feature requests
|
||||
- Documentation feedback
|
||||
|
||||
Before opening a new issue:
|
||||
- 🛑 [Check Common Issues & Debug Tips](https://docs.netalertx.com/DEBUG_TIPS#common-issues)
|
||||
- 🔍 [Search Closed Issues](https://github.com/netalertx/NetAlertX/issues?q=is%3Aissue+is%3Aclosed)
|
||||
- [Check Common Issues & Debug Tips](https://docs.netalertx.com/DEBUG_TIPS#common-issues)
|
||||
- [Search Closed Issues](https://github.com/netalertx/NetAlertX/issues?q=is%3Aissue+is%3Aclosed)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Submitting Pull Requests (PRs)
|
||||
## Use of AI
|
||||
|
||||
Use of AI-assisted tools is permitted, provided all generated code is reviewed, understood, and verified before submission.
|
||||
|
||||
- All AI-generated code must meet the project's **quality, security, and performance standards**.
|
||||
- Contributors are responsible for **fully understanding** any code they submit, regardless of how it was produced.
|
||||
- Prefer **clarity and maintainability over cleverness or brevity**. Readable code is always favored over dense or obfuscated implementations.
|
||||
- Follow the **DRY (Don't Repeat Yourself) principle** where appropriate, without sacrificing readability.
|
||||
- Do not submit code that you cannot confidently explain or debug.
|
||||
|
||||
All changes must pass the **full test suite** before opening a PR.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Submitting Pull Requests (PRs)
|
||||
|
||||
We welcome PRs to improve the code, docs, or UI!
|
||||
|
||||
@@ -28,10 +43,23 @@ Please:
|
||||
- Provide a clear title and description for your PR
|
||||
- If relevant, add or update tests and documentation
|
||||
- For plugins, refer to the [Plugin Dev Guide](https://docs.netalertx.com/PLUGINS_DEV)
|
||||
- Switch the PR to DRAFT mode if still being worked on
|
||||
- Keep PRs **focused and minimal** — avoid unrelated changes in a single PR
|
||||
- PRs that do not meet these guidelines may be closed without review
|
||||
|
||||
## Commit Messages
|
||||
|
||||
- Use clear, descriptive commit messages
|
||||
- Explain *why* a change was made, not just *what* changed
|
||||
- Reference related issues where applicable
|
||||
|
||||
## Code Quality
|
||||
|
||||
- Read and follow the [code standards](/.github/skills/code-standards/SKILL.md)
|
||||
|
||||
---
|
||||
|
||||
## 🌟 First-Time Contributors
|
||||
## First-Time Contributors
|
||||
|
||||
New to open source? Check out these resources:
|
||||
- [How to Fork and Submit a PR](https://opensource.guide/how-to-contribute/)
|
||||
@@ -39,15 +67,15 @@ New to open source? Check out these resources:
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Code of Conduct
|
||||
## Code of Conduct
|
||||
|
||||
By participating, you agree to follow our [Code of Conduct](./CODE_OF_CONDUCT.md), which ensures a respectful and welcoming community.
|
||||
|
||||
---
|
||||
|
||||
## 📬 Contact
|
||||
## Contact
|
||||
|
||||
If you have more in-depth questions or want to discuss contributing in other ways, feel free to reach out at:
|
||||
📧 [jokob@duck.com](mailto:jokob@duck.com?subject=NetAlertX%20Contribution)
|
||||
[jokob.sk@gmail.com](mailto:jokob.sk@gmail.com?subject=NetAlertX%20Contribution)
|
||||
|
||||
We appreciate every contribution, big or small! 💙
|
||||
|
||||
@@ -58,12 +58,12 @@ The Events API provides access to **device event logs**, allowing creation, retr
|
||||
"success": true,
|
||||
"events": [
|
||||
{
|
||||
"eve_MAC": "00:11:22:33:44:55",
|
||||
"eve_IP": "192.168.1.10",
|
||||
"eve_DateTime": "2025-08-24T12:00:00Z",
|
||||
"eve_EventType": "Device Down",
|
||||
"eve_AdditionalInfo": "",
|
||||
"eve_PendingAlertEmail": 1
|
||||
"eveMac": "00:11:22:33:44:55",
|
||||
"eveIp": "192.168.1.10",
|
||||
"eveDateTime": "2025-08-24T12:00:00Z",
|
||||
"eveEventType": "Device Down",
|
||||
"eveAdditionalInfo": "",
|
||||
"evePendingAlertEmail": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -102,11 +102,11 @@ The Events API provides access to **device event logs**, allowing creation, retr
|
||||
"count": 5,
|
||||
"events": [
|
||||
{
|
||||
"eve_DateTime": "2025-12-07 12:00:00",
|
||||
"eve_EventType": "New Device",
|
||||
"eve_MAC": "AA:BB:CC:DD:EE:FF",
|
||||
"eve_IP": "192.168.1.100",
|
||||
"eve_AdditionalInfo": "Device detected"
|
||||
"eveDateTime": "2025-12-07 12:00:00",
|
||||
"eveEventType": "New Device",
|
||||
"eveMac": "AA:BB:CC:DD:EE:FF",
|
||||
"eveIp": "192.168.1.100",
|
||||
"eveAdditionalInfo": "Device detected"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -127,9 +127,9 @@ The Events API provides access to **device event logs**, allowing creation, retr
|
||||
"count": 10,
|
||||
"events": [
|
||||
{
|
||||
"eve_DateTime": "2025-12-07 12:00:00",
|
||||
"eve_EventType": "Device Down",
|
||||
"eve_MAC": "AA:BB:CC:DD:EE:FF"
|
||||
"eveDateTime": "2025-12-07 12:00:00",
|
||||
"eveEventType": "Device Down",
|
||||
"eveMac": "AA:BB:CC:DD:EE:FF"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -159,9 +159,9 @@ The Events API provides access to **device event logs**, allowing creation, retr
|
||||
1. Total events in the period
|
||||
2. Total sessions
|
||||
3. Missing sessions
|
||||
4. Voided events (`eve_EventType LIKE 'VOIDED%'`)
|
||||
5. New device events (`eve_EventType LIKE 'New Device'`)
|
||||
6. Device down events (`eve_EventType LIKE 'Device Down'`)
|
||||
4. Voided events (`eveEventType LIKE 'VOIDED%'`)
|
||||
5. New device events (`eveEventType LIKE 'New Device'`)
|
||||
6. Device down events (`eveEventType LIKE 'Device Down'`)
|
||||
|
||||
---
|
||||
|
||||
@@ -187,7 +187,7 @@ Event endpoints are available as **MCP Tools** for AI assistant integration:
|
||||
```
|
||||
|
||||
* Events are stored in the **Events table** with the following fields:
|
||||
`eve_MAC`, `eve_IP`, `eve_DateTime`, `eve_EventType`, `eve_AdditionalInfo`, `eve_PendingAlertEmail`.
|
||||
`eveMac`, `eveIp`, `eveDateTime`, `eveEventType`, `eveAdditionalInfo`, `evePendingAlertEmail`.
|
||||
|
||||
* Event creation automatically logs activity for debugging.
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@ GraphQL queries are **read-optimized for speed**. Data may be slightly out of da
|
||||
|
||||
* Devices
|
||||
* Settings
|
||||
* Events
|
||||
* PluginsObjects
|
||||
* PluginsHistory
|
||||
* PluginsEvents
|
||||
* Language Strings (LangStrings)
|
||||
|
||||
## Endpoints
|
||||
@@ -254,11 +258,160 @@ curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||
|
||||
---
|
||||
|
||||
## Plugin Tables (Objects, Events, History)
|
||||
|
||||
Three queries expose the plugin database tables with server-side pagination, filtering, and search:
|
||||
|
||||
* `pluginsObjects` — current plugin object state
|
||||
* `pluginsEvents` — unprocessed plugin events
|
||||
* `pluginsHistory` — historical plugin event log
|
||||
|
||||
All three share the same `PluginQueryOptionsInput` and return the same `PluginEntry` shape.
|
||||
|
||||
### Sample Query
|
||||
|
||||
```graphql
|
||||
query GetPluginObjects($options: PluginQueryOptionsInput) {
|
||||
pluginsObjects(options: $options) {
|
||||
dbCount
|
||||
count
|
||||
entries {
|
||||
index plugin objectPrimaryId objectSecondaryId
|
||||
dateTimeCreated dateTimeChanged
|
||||
watchedValue1 watchedValue2 watchedValue3 watchedValue4
|
||||
status extra userData foreignKey
|
||||
syncHubNodeName helpVal1 helpVal2 helpVal3 helpVal4 objectGuid
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Query Parameters (`PluginQueryOptionsInput`)
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ------------ | ----------------- | ------------------------------------------------------ |
|
||||
| `page` | Int | Page number (1-based). |
|
||||
| `limit` | Int | Rows per page (max 1000). |
|
||||
| `sort` | [SortOptionsInput] | Sorting options (`field`, `order`). |
|
||||
| `search` | String | Free-text search across key columns. |
|
||||
| `filters` | [FilterOptionsInput] | Column-value exact-match filters. |
|
||||
| `plugin` | String | Plugin prefix to scope results (e.g. `"ARPSCAN"`). |
|
||||
| `foreignKey` | String | Foreign key filter (e.g. device MAC). |
|
||||
| `dateFrom` | String | Start of date range filter on `dateTimeCreated`. |
|
||||
| `dateTo` | String | End of date range filter on `dateTimeCreated`. |
|
||||
|
||||
### Response Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
| --------- | ------------- | ------------------------------------------------------------- |
|
||||
| `dbCount` | Int | Total rows for the requested plugin (before search/filters). |
|
||||
| `count` | Int | Total rows after all filters (before pagination). |
|
||||
| `entries` | [PluginEntry] | Paginated list of plugin entries. |
|
||||
|
||||
### `curl` Example
|
||||
|
||||
```sh
|
||||
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||
-X POST \
|
||||
-H 'Authorization: Bearer API_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"query": "query GetPluginObjects($options: PluginQueryOptionsInput) { pluginsObjects(options: $options) { dbCount count entries { index plugin objectPrimaryId status foreignKey } } }",
|
||||
"variables": {
|
||||
"options": {
|
||||
"plugin": "ARPSCAN",
|
||||
"page": 1,
|
||||
"limit": 25
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Badge Prefetch (Batched Counts)
|
||||
|
||||
Use GraphQL aliases to fetch counts for all plugins in a single request:
|
||||
|
||||
```graphql
|
||||
query BadgeCounts {
|
||||
ARPSCAN: pluginsObjects(options: {plugin: "ARPSCAN", page: 1, limit: 1}) { dbCount }
|
||||
INTRNT: pluginsObjects(options: {plugin: "INTRNT", page: 1, limit: 1}) { dbCount }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Events Query
|
||||
|
||||
Access the Events table with server-side pagination, filtering, and search.
|
||||
|
||||
### Sample Query
|
||||
|
||||
```graphql
|
||||
query GetEvents($options: EventQueryOptionsInput) {
|
||||
events(options: $options) {
|
||||
dbCount
|
||||
count
|
||||
entries {
|
||||
eveMac
|
||||
eveIp
|
||||
eveDateTime
|
||||
eveEventType
|
||||
eveAdditionalInfo
|
||||
evePendingAlertEmail
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Query Parameters (`EventQueryOptionsInput`)
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ----------- | ------------------ | ------------------------------------------------ |
|
||||
| `page` | Int | Page number (1-based). |
|
||||
| `limit` | Int | Rows per page (max 1000). |
|
||||
| `sort` | [SortOptionsInput] | Sorting options (`field`, `order`). |
|
||||
| `search` | String | Free-text search across key columns. |
|
||||
| `filters` | [FilterOptionsInput] | Column-value exact-match filters. |
|
||||
| `eveMac` | String | Filter by device MAC address. |
|
||||
| `eventType` | String | Filter by event type (e.g. `"New Device"`). |
|
||||
| `dateFrom` | String | Start of date range filter on `eveDateTime`. |
|
||||
| `dateTo` | String | End of date range filter on `eveDateTime`. |
|
||||
|
||||
### Response Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
| --------- | ------------ | ------------------------------------------------------------ |
|
||||
| `dbCount` | Int | Total rows in the Events table (before any filters). |
|
||||
| `count` | Int | Total rows after all filters (before pagination). |
|
||||
| `entries` | [EventEntry] | Paginated list of event entries. |
|
||||
|
||||
### `curl` Example
|
||||
|
||||
```sh
|
||||
curl 'http://host:GRAPHQL_PORT/graphql' \
|
||||
-X POST \
|
||||
-H 'Authorization: Bearer API_TOKEN' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"query": "query GetEvents($options: EventQueryOptionsInput) { events(options: $options) { dbCount count entries { eveMac eveIp eveDateTime eveEventType } } }",
|
||||
"variables": {
|
||||
"options": {
|
||||
"eveMac": "00:11:22:33:44:55",
|
||||
"page": 1,
|
||||
"limit": 50
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
* Device, settings, and LangStrings queries can be combined in **one request** since GraphQL supports batching.
|
||||
* Device, settings, LangStrings, plugin, and event queries can be combined in **one request** since GraphQL supports batching.
|
||||
* The `fallback_to_en` feature ensures UI always has a value even if a translation is missing.
|
||||
* Data is **cached in memory** per JSON file; changes to language or plugin files will only refresh after the cache detects a file modification.
|
||||
* The `setOverriddenByEnv` flag helps identify setting values that are locked at container runtime.
|
||||
* The schema is **read-only** — updates must be performed through other APIs or configuration management. See the other [API](API.md) endpoints for details.
|
||||
* Plugin queries scope `dbCount` to the requested `plugin`/`foreignKey` so badge counts reflect per-plugin totals.
|
||||
* The schema is **read-only** — updates must be performed through other APIs or configuration management. See the other [API](API.md) endpoints for details.
|
||||
|
||||
|
||||
@@ -106,12 +106,12 @@ curl -X DELETE "http://<server_ip>:<GRAPHQL_PORT>/sessions/delete" \
|
||||
"success": true,
|
||||
"sessions": [
|
||||
{
|
||||
"ses_MAC": "AA:BB:CC:DD:EE:FF",
|
||||
"ses_Connection": "2025-08-01 10:00",
|
||||
"ses_Disconnection": "2025-08-01 12:00",
|
||||
"ses_Duration": "2h 0m",
|
||||
"ses_IP": "192.168.1.10",
|
||||
"ses_Info": ""
|
||||
"sesMac": "AA:BB:CC:DD:EE:FF",
|
||||
"sesDateTimeConnection": "2025-08-01 10:00",
|
||||
"sesDateTimeDisconnection": "2025-08-01 12:00",
|
||||
"sesDuration": "2h 0m",
|
||||
"sesIp": "192.168.1.10",
|
||||
"sesAdditionalInfo": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -194,12 +194,12 @@ curl -X GET "http://<server_ip>:<GRAPHQL_PORT>/sessions/calendar?start=2025-08-0
|
||||
"success": true,
|
||||
"sessions": [
|
||||
{
|
||||
"ses_MAC": "AA:BB:CC:DD:EE:FF",
|
||||
"ses_Connection": "2025-08-01 10:00",
|
||||
"ses_Disconnection": "2025-08-01 12:00",
|
||||
"ses_Duration": "2h 0m",
|
||||
"ses_IP": "192.168.1.10",
|
||||
"ses_Info": ""
|
||||
"sesMac": "AA:BB:CC:DD:EE:FF",
|
||||
"sesDateTimeConnection": "2025-08-01 10:00",
|
||||
"sesDateTimeDisconnection": "2025-08-01 12:00",
|
||||
"sesDuration": "2h 0m",
|
||||
"sesIp": "192.168.1.10",
|
||||
"sesAdditionalInfo": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -224,15 +224,33 @@ curl -X GET "http://<server_ip>:<GRAPHQL_PORT>/sessions/AA:BB:CC:DD:EE:FF?period
|
||||
* `type` → Event type (`all`, `sessions`, `missing`, `voided`, `new`, `down`)
|
||||
Default: `all`
|
||||
* `period` → Period to retrieve events (`7 days`, `1 month`, etc.)
|
||||
* `page` → Page number, 1-based (default: `1`)
|
||||
* `limit` → Rows per page, max 1000 (default: `100`)
|
||||
* `search` → Free-text search filter across all columns
|
||||
* `sortCol` → Column index to sort by, 0-based (default: `0`)
|
||||
* `sortDir` → Sort direction: `asc` or `desc` (default: `desc`)
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
/sessions/session-events?type=all&period=7 days
|
||||
/sessions/session-events?type=all&period=7 days&page=1&limit=25&sortCol=3&sortDir=desc
|
||||
```
|
||||
|
||||
**Response:**
|
||||
Returns a list of events or sessions with formatted connection, disconnection, duration, and IP information.
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [...],
|
||||
"total": 150,
|
||||
"recordsFiltered": 150
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----------------- | ---- | ------------------------------------------------- |
|
||||
| `data` | list | Paginated rows (each row is a list of values). |
|
||||
| `total` | int | Total rows before search filter. |
|
||||
| `recordsFiltered` | int | Total rows after search filter (before paging). |
|
||||
|
||||
#### `curl` Example
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ Input data from the plugin might cause mapping issues in specific edge cases. Lo
|
||||
17:31:05 [Scheduler] run for PIHOLE: YES
|
||||
17:31:05 [Plugin utils] ---------------------------------------------
|
||||
17:31:05 [Plugin utils] display_name: PiHole (Device sync)
|
||||
17:31:05 [Plugins] CMD: SELECT n.hwaddr AS Object_PrimaryID, {s-quote}null{s-quote} AS Object_SecondaryID, datetime() AS DateTime, na.ip AS Watched_Value1, n.lastQuery AS Watched_Value2, na.name AS Watched_Value3, n.macVendor AS Watched_Value4, {s-quote}null{s-quote} AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE {s-quote}ip-%{s-quote} AND n.hwaddr is not {s-quote}00:00:00:00:00:00{s-quote} AND na.ip is not null
|
||||
17:31:05 [Plugins] CMD: SELECT n.hwaddr AS objectPrimaryId, {s-quote}null{s-quote} AS objectSecondaryId, datetime() AS DateTime, na.ip AS watchedValue1, n.lastQuery AS watchedValue2, na.name AS watchedValue3, n.macVendor AS watchedValue4, {s-quote}null{s-quote} AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE {s-quote}ip-%{s-quote} AND n.hwaddr is not {s-quote}00:00:00:00:00:00{s-quote} AND na.ip is not null
|
||||
17:31:05 [Plugins] setTyp: subnets
|
||||
17:31:05 [Plugin utils] Flattening the below array
|
||||
17:31:05 ['192.168.1.0/24 --interface=eth1']
|
||||
@@ -52,7 +52,7 @@ Input data from the plugin might cause mapping issues in specific edge cases. Lo
|
||||
17:31:05 [Plugins] Convert to Base64: True
|
||||
17:31:05 [Plugins] base64 value: b'MTkyLjE2OC4xLjAvMjQgLS1pbnRlcmZhY2U9ZXRoMQ=='
|
||||
17:31:05 [Plugins] Timeout: 10
|
||||
17:31:05 [Plugins] Executing: SELECT n.hwaddr AS Object_PrimaryID, 'null' AS Object_SecondaryID, datetime() AS DateTime, na.ip AS Watched_Value1, n.lastQuery AS Watched_Value2, na.name AS Watched_Value3, n.macVendor AS Watched_Value4, 'null' AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE 'ip-%' AND n.hwaddr is not '00:00:00:00:00:00' AND na.ip is not null
|
||||
17:31:05 [Plugins] Executing: SELECT n.hwaddr AS objectPrimaryId, 'null' AS objectSecondaryId, datetime() AS DateTime, na.ip AS watchedValue1, n.lastQuery AS watchedValue2, na.name AS watchedValue3, n.macVendor AS watchedValue4, 'null' AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE 'ip-%' AND n.hwaddr is not '00:00:00:00:00:00' AND na.ip is not null
|
||||
🔻
|
||||
17:31:05 [Plugins] SUCCESS, received 2 entries
|
||||
17:31:05 [Plugins] sqlParam entries: [(0, 'PIHOLE', '01:01:01:01:01:01', 'null', 'null', '2023-12-25 06:31:05', '172.30.0.1', 0, 'aaaa', 'vvvvvvvvv', 'not-processed', 'null', 'null', '01:01:01:01:01:01'), (0, 'PIHOLE', '02:42:ac:1e:00:02', 'null', 'null', '2023-12-25 06:31:05', '172.30.0.2', 0, 'dddd', 'vvvvv2222', 'not-processed', 'null', 'null', '02:42:ac:1e:00:02')]
|
||||
|
||||
@@ -30,6 +30,14 @@ services:
|
||||
- CHOWN # Required for root-entrypoint to chown /data + /tmp before dropping privileges
|
||||
- SETUID # Required for root-entrypoint to switch to non-root user
|
||||
- SETGID # Required for root-entrypoint to switch to non-root group
|
||||
# --- ARP FLUX MITIGATION ---
|
||||
# Note: When using `network_mode: host`, these sysctls require the
|
||||
# NET_ADMIN capability to be applied to the host namespace.
|
||||
#
|
||||
# If your environment restricts capabilities, or you prefer to configure
|
||||
# them on the Host OS, REMOVE the sysctls block below and apply via:
|
||||
# sudo sysctl -w net.ipv4.conf.all.arp_ignore=1 net.ipv4.conf.all.arp_announce=2
|
||||
# ---------------------------
|
||||
sysctls: # ARP flux mitigation (reduces duplicate/ambiguous ARP behavior on host networking)
|
||||
net.ipv4.conf.all.arp_ignore: 1
|
||||
net.ipv4.conf.all.arp_announce: 2
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Notifications 📧
|
||||
|
||||
> [!TIP]
|
||||
> Want to customize how devices appear in text notifications? See [Notification Text Templates](NOTIFICATION_TEMPLATES.md).
|
||||
|
||||
There are 4 ways how to influence notifications:
|
||||
|
||||
1. On the device itself
|
||||
@@ -33,7 +36,7 @@ The following device properties influence notifications. You can:
|
||||
On almost all plugins there are 2 core settings, `<plugin>_WATCH` and `<plugin>_REPORT_ON`.
|
||||
|
||||
1. `<plugin>_WATCH` specifies the columns which the app should watch. If watched columns change the device state is considered changed. This changed status is then used to decide to send out notifications based on the `<plugin>_REPORT_ON` setting.
|
||||
2. `<plugin>_REPORT_ON` let's you specify on which events the app should notify you. This is related to the `<plugin>_WATCH` setting. So if you select `watched-changed` and in `<plugin>_WATCH` you only select `Watched_Value1`, then a notification is triggered if `Watched_Value1` is changed from the previous value, but no notification is send if `Watched_Value2` changes.
|
||||
2. `<plugin>_REPORT_ON` let's you specify on which events the app should notify you. This is related to the `<plugin>_WATCH` setting. So if you select `watched-changed` and in `<plugin>_WATCH` you only select `watchedValue1`, then a notification is triggered if `watchedValue1` is changed from the previous value, but no notification is send if `watchedValue2` changes.
|
||||
|
||||
Click the **Read more in the docs.** Link at the top of each plugin to get more details on how the given plugin works.
|
||||
|
||||
|
||||
100
docs/NOTIFICATION_TEMPLATES.md
Normal file
100
docs/NOTIFICATION_TEMPLATES.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Notification Text Templates
|
||||
|
||||
> Customize how devices and events appear in **text** notifications (email previews, push notifications, Apprise messages).
|
||||
|
||||
By default, NetAlertX formats each device as a vertical list of `Header: Value` pairs. Text templates let you define a **single-line format per device** using `{FieldName}` placeholders — ideal for mobile notification previews and high-volume alerts.
|
||||
|
||||
HTML email tables are **not affected** by these templates.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Go to **Settings → Notification Processing**.
|
||||
2. Set a template string for the section you want to customize, e.g.:
|
||||
- **Text Template: New Devices** → `{devName} ({eveMac}) - {eveIp}`
|
||||
3. Save. The next notification will use your format.
|
||||
|
||||
**Before (default):**
|
||||
```
|
||||
🆕 New devices
|
||||
---------
|
||||
devName: MyPhone
|
||||
eveMac: aa:bb:cc:dd:ee:ff
|
||||
devVendor: Apple
|
||||
eveIp: 192.168.1.42
|
||||
eveDateTime: 2025-01-15 10:30:00
|
||||
eveEventType: New Device
|
||||
devComments:
|
||||
```
|
||||
|
||||
**After (with template `{devName} ({eveMac}) - {eveIp}`):**
|
||||
```
|
||||
🆕 New devices
|
||||
---------
|
||||
MyPhone (aa:bb:cc:dd:ee:ff) - 192.168.1.42
|
||||
```
|
||||
|
||||
## Settings Reference
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
|---------|------|---------|-------------|
|
||||
| `NTFPRCS_TEXT_SECTION_HEADERS` | Boolean | `true` | Show/hide section titles (e.g. `🆕 New devices \n---------`). |
|
||||
| `NTFPRCS_TEXT_TEMPLATE_new_devices` | String | *(empty)* | Template for new device rows. |
|
||||
| `NTFPRCS_TEXT_TEMPLATE_down_devices` | String | *(empty)* | Template for down device rows. |
|
||||
| `NTFPRCS_TEXT_TEMPLATE_down_reconnected` | String | *(empty)* | Template for reconnected device rows. |
|
||||
| `NTFPRCS_TEXT_TEMPLATE_events` | String | *(empty)* | Template for event rows. |
|
||||
| `NTFPRCS_TEXT_TEMPLATE_plugins` | String | *(empty)* | Template for plugin event rows. |
|
||||
|
||||
When a template is **empty**, the section uses the original vertical `Header: Value` format (full backward compatibility).
|
||||
|
||||
## Template Syntax
|
||||
|
||||
Use `{FieldName}` to insert a value from the notification data. Field names are **case-sensitive** and must match the column names exactly.
|
||||
|
||||
```
|
||||
{devName} ({eveMac}) connected at {eveDateTime}
|
||||
```
|
||||
|
||||
- No loops, conditionals, or nesting — just simple string replacement.
|
||||
- If a `{FieldName}` does not exist in the data, it is left as-is in the output (safe failure). For example, `{NonExistent}` renders literally as `{NonExistent}`.
|
||||
|
||||
## Variable Availability by Section
|
||||
|
||||
All four device sections (`new_devices`, `down_devices`, `down_reconnected`, `events`) share the same unified field names.
|
||||
|
||||
### `new_devices`, `down_devices`, `down_reconnected`, and `events`
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `{devName}` | Device display name |
|
||||
| `{eveMac}` | Device MAC address |
|
||||
| `{devVendor}` | Device vendor/manufacturer |
|
||||
| `{eveIp}` | Device IP address |
|
||||
| `{eveDateTime}` | Event timestamp |
|
||||
| `{eveEventType}` | Type of event (e.g. `New Device`, `Connected`, `Device Down`) |
|
||||
| `{devComments}` | Device comments |
|
||||
|
||||
**Example (new_devices/events):** `{devName} ({eveMac}) - {eveIp} [{eveEventType}]`
|
||||
|
||||
**Example (down_devices):** `{devName} ({eveMac}) {devVendor} - went down at {eveDateTime}`
|
||||
|
||||
**Example (down_reconnected):** `{devName} ({eveMac}) reconnected at {eveDateTime}`
|
||||
|
||||
### `plugins`
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `{plugin}` | Plugin code name |
|
||||
| `{objectPrimaryId}` | Primary identifier of the object |
|
||||
| `{objectSecondaryId}` | Secondary identifier |
|
||||
| `{dateTimeChanged}` | Timestamp of change |
|
||||
| `{watchedValue1}` | First watched value |
|
||||
| `{watchedValue2}` | Second watched value |
|
||||
| `{watchedValue3}` | Third watched value |
|
||||
| `{watchedValue4}` | Fourth watched value |
|
||||
| `{status}` | Plugin event status |
|
||||
|
||||
**Example:** `{plugin}: {objectPrimaryId} - {status}`
|
||||
|
||||
## Section Headers Toggle
|
||||
|
||||
Set **Text Section Headers** (`NTFPRCS_TEXT_SECTION_HEADERS`) to `false` to remove the section title separators from text notifications. This is useful when you want compact output without the `🆕 New devices \n---------` banners.
|
||||
@@ -179,13 +179,13 @@ Quick reference:
|
||||
|
||||
| Column | Name | Required | Example |
|
||||
|--------|------|----------|---------|
|
||||
| 0 | Object_PrimaryID | **YES** | `"device_name"` or `"192.168.1.1"` |
|
||||
| 1 | Object_SecondaryID | no | `"secondary_id"` or `null` |
|
||||
| 0 | objectPrimaryId | **YES** | `"device_name"` or `"192.168.1.1"` |
|
||||
| 1 | objectSecondaryId | no | `"secondary_id"` or `null` |
|
||||
| 2 | DateTime | **YES** | `"2023-01-02 15:56:30"` |
|
||||
| 3 | Watched_Value1 | **YES** | `"online"` or `"200"` |
|
||||
| 4 | Watched_Value2 | no | `"ip_address"` or `null` |
|
||||
| 5 | Watched_Value3 | no | `null` |
|
||||
| 6 | Watched_Value4 | no | `null` |
|
||||
| 3 | watchedValue1 | **YES** | `"online"` or `"200"` |
|
||||
| 4 | watchedValue2 | no | `"ip_address"` or `null` |
|
||||
| 5 | watchedValue3 | no | `null` |
|
||||
| 6 | watchedValue4 | no | `null` |
|
||||
| 7 | Extra | no | `"additional data"` or `null` |
|
||||
| 8 | ForeignKey | no | `"aa:bb:cc:dd:ee:ff"` or `null` |
|
||||
|
||||
@@ -243,7 +243,7 @@ Control which rows display in the UI:
|
||||
{
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -267,7 +267,7 @@ To import plugin data into NetAlertX tables for device discovery or notification
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"show": true,
|
||||
"type": "device_mac",
|
||||
@@ -345,7 +345,7 @@ See [PLUGINS_DEV_SETTINGS.md](PLUGINS_DEV_SETTINGS.md) for complete settings doc
|
||||
|
||||
### Plugin Output Format
|
||||
```
|
||||
Object_PrimaryID|Object_SecondaryID|DateTime|Watched_Value1|Watched_Value2|Watched_Value3|Watched_Value4|Extra|ForeignKey
|
||||
objectPrimaryId|objectSecondaryId|DateTime|watchedValue1|watchedValue2|watchedValue3|watchedValue4|Extra|ForeignKey
|
||||
```
|
||||
9 required columns, 4 optional helpers = 13 max
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ It also describes plugin output expectations and the main plugin categories.
|
||||
* `database_column_definitions`
|
||||
* `mapped_to_table`
|
||||
|
||||
**Example:** `Object_PrimaryID → devMAC`
|
||||
**Example:** `objectPrimaryId → devMAC`
|
||||
|
||||
---
|
||||
|
||||
@@ -88,9 +88,9 @@ Output values are pipe-delimited in a fixed order.
|
||||
|
||||
#### Identifiers
|
||||
|
||||
* `Object_PrimaryID` and `Object_SecondaryID` uniquely identify records (for example, `MAC|IP`).
|
||||
* `objectPrimaryId` and `objectSecondaryId` uniquely identify records (for example, `MAC|IP`).
|
||||
|
||||
#### Watched Values (`Watched_Value1–4`)
|
||||
#### Watched Values (`watchedValue1–4`)
|
||||
|
||||
* Used by the core to detect changes between runs.
|
||||
* Changes in these fields can trigger notifications.
|
||||
@@ -114,7 +114,7 @@ Output values are pipe-delimited in a fixed order.
|
||||
### 7. Persistence
|
||||
|
||||
* Parsed data is **upserted** into the database.
|
||||
* Conflicts are resolved using the combined key: `Object_PrimaryID + Object_SecondaryID`.
|
||||
* Conflicts are resolved using the combined key: `objectPrimaryId + objectSecondaryId`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ Query the NetAlertX SQLite database and display results.
|
||||
{
|
||||
"function": "CMD",
|
||||
"type": {"dataType": "string", "elements": [{"elementType": "input", "elementOptions": [], "transformers": []}]},
|
||||
"default_value": "SELECT dv.devName as Object_PrimaryID, cast(dv.devLastIP as VARCHAR(100)) || ':' || cast(SUBSTR(ns.Port, 0, INSTR(ns.Port, '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, ns.Service as Watched_Value1, ns.State as Watched_Value2, null as Watched_Value3, null as Watched_Value4, ns.Extra as Extra, dv.devMac as ForeignKey FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT devName, devMac, devLastIP FROM Devices) dv ON ns.MAC = dv.devMac",
|
||||
"default_value": "SELECT dv.devName as objectPrimaryId, cast(dv.devLastIP as VARCHAR(100)) || ':' || cast(SUBSTR(ns.Port, 0, INSTR(ns.Port, '/')) as VARCHAR(100)) as objectSecondaryId, datetime() as DateTime, ns.Service as watchedValue1, ns.State as watchedValue2, null as watchedValue3, null as watchedValue4, ns.Extra as Extra, dv.devMac as ForeignKey FROM (SELECT * FROM Nmap_Scan) ns LEFT JOIN (SELECT devName, devMac, devLastIP FROM Devices) dv ON ns.MAC = dv.devMac",
|
||||
"localized": ["name"],
|
||||
"name": [{"language_code": "en_us", "string": "SQL to run"}],
|
||||
"description": [{"language_code": "en_us", "string": "This SQL query populates the plugin table"}]
|
||||
@@ -118,13 +118,13 @@ Query the NetAlertX SQLite database and display results.
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
e.EventValue as Object_PrimaryID,
|
||||
d.devName as Object_SecondaryID,
|
||||
e.EventValue as objectPrimaryId,
|
||||
d.devName as objectSecondaryId,
|
||||
e.EventDateTime as DateTime,
|
||||
e.EventType as Watched_Value1,
|
||||
d.devLastIP as Watched_Value2,
|
||||
null as Watched_Value3,
|
||||
null as Watched_Value4,
|
||||
e.EventType as watchedValue1,
|
||||
d.devLastIP as watchedValue2,
|
||||
null as watchedValue3,
|
||||
null as watchedValue4,
|
||||
e.EventDetails as Extra,
|
||||
d.devMac as ForeignKey
|
||||
FROM
|
||||
@@ -181,7 +181,7 @@ Then set data source and query:
|
||||
```json
|
||||
{
|
||||
"function": "CMD",
|
||||
"default_value": "SELECT hwaddr as Object_PrimaryID, cast('http://' || (SELECT ip FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1) as VARCHAR(100)) || ':' || cast(SUBSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1), 0, INSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1), '/')) as VARCHAR(100)) as Object_SecondaryID, datetime() as DateTime, macVendor as Watched_Value1, lastQuery as Watched_Value2, (SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1) as Watched_Value3, null as Watched_Value4, '' as Extra, hwaddr as ForeignKey FROM EXTERNAL_PIHOLE.network WHERE hwaddr NOT LIKE 'ip-%' AND hwaddr <> '00:00:00:00:00:00'",
|
||||
"default_value": "SELECT hwaddr as objectPrimaryId, cast('http://' || (SELECT ip FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1) as VARCHAR(100)) || ':' || cast(SUBSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1), 0, INSTR((SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1), '/')) as VARCHAR(100)) as objectSecondaryId, datetime() as DateTime, macVendor as watchedValue1, lastQuery as watchedValue2, (SELECT name FROM EXTERNAL_PIHOLE.network_addresses WHERE network_id = id ORDER BY lastseen DESC LIMIT 1) as watchedValue3, null as watchedValue4, '' as Extra, hwaddr as ForeignKey FROM EXTERNAL_PIHOLE.network WHERE hwaddr NOT LIKE 'ip-%' AND hwaddr <> '00:00:00:00:00:00'",
|
||||
"localized": ["name"],
|
||||
"name": [{"language_code": "en_us", "string": "SQL to run"}]
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@ Plugins communicate with NetAlertX by writing results to a **pipe-delimited log
|
||||
## Column Specification
|
||||
|
||||
> [!NOTE]
|
||||
> The order of columns is **FIXED** and cannot be changed. All 9 mandatory columns must be provided. If you use any optional column (`HelpVal1`), you must supply all optional columns (`HelpVal1` through `HelpVal4`).
|
||||
> The order of columns is **FIXED** and cannot be changed. All 9 mandatory columns must be provided. If you use any optional column (`helpVal1`), you must supply all optional columns (`helpVal1` through `helpVal4`).
|
||||
|
||||
### Mandatory Columns (0–8)
|
||||
|
||||
| Order | Column Name | Type | Required | Description |
|
||||
|-------|-------------|------|----------|-------------|
|
||||
| 0 | `Object_PrimaryID` | string | **YES** | The primary identifier for grouping. Examples: device MAC, hostname, service name, or any unique ID |
|
||||
| 1 | `Object_SecondaryID` | string | no | Secondary identifier for relationships (e.g., IP address, port, sub-ID). Use `null` if not needed |
|
||||
| 0 | `objectPrimaryId` | string | **YES** | The primary identifier for grouping. Examples: device MAC, hostname, service name, or any unique ID |
|
||||
| 1 | `objectSecondaryId` | string | no | Secondary identifier for relationships (e.g., IP address, port, sub-ID). Use `null` if not needed |
|
||||
| 2 | `DateTime` | string | **YES** | Timestamp when the event/data was collected. Format: `YYYY-MM-DD HH:MM:SS` |
|
||||
| 3 | `Watched_Value1` | string | **YES** | Primary watched value. Changes trigger notifications. Examples: IP address, status, version |
|
||||
| 4 | `Watched_Value2` | string | no | Secondary watched value. Use `null` if not needed |
|
||||
| 5 | `Watched_Value3` | string | no | Tertiary watched value. Use `null` if not needed |
|
||||
| 6 | `Watched_Value4` | string | no | Quaternary watched value. Use `null` if not needed |
|
||||
| 3 | `watchedValue1` | string | **YES** | Primary watched value. Changes trigger notifications. Examples: IP address, status, version |
|
||||
| 4 | `watchedValue2` | string | no | Secondary watched value. Use `null` if not needed |
|
||||
| 5 | `watchedValue3` | string | no | Tertiary watched value. Use `null` if not needed |
|
||||
| 6 | `watchedValue4` | string | no | Quaternary watched value. Use `null` if not needed |
|
||||
| 7 | `Extra` | string | no | Any additional metadata to display in UI and notifications. Use `null` if not needed |
|
||||
| 8 | `ForeignKey` | string | no | Foreign key linking to parent object (usually MAC address for device relationship). Use `null` if not needed |
|
||||
|
||||
@@ -38,10 +38,10 @@ Plugins communicate with NetAlertX by writing results to a **pipe-delimited log
|
||||
|
||||
| Order | Column Name | Type | Required | Description |
|
||||
|-------|-------------|------|----------|-------------|
|
||||
| 9 | `HelpVal1` | string | *conditional* | Helper value 1. If used, all help values must be supplied |
|
||||
| 10 | `HelpVal2` | string | *conditional* | Helper value 2. If used, all help values must be supplied |
|
||||
| 11 | `HelpVal3` | string | *conditional* | Helper value 3. If used, all help values must be supplied |
|
||||
| 12 | `HelpVal4` | string | *conditional* | Helper value 4. If used, all help values must be supplied |
|
||||
| 9 | `helpVal1` | string | *conditional* | Helper value 1. If used, all help values must be supplied |
|
||||
| 10 | `helpVal2` | string | *conditional* | Helper value 2. If used, all help values must be supplied |
|
||||
| 11 | `helpVal3` | string | *conditional* | Helper value 3. If used, all help values must be supplied |
|
||||
| 12 | `helpVal4` | string | *conditional* | Helper value 4. If used, all help values must be supplied |
|
||||
|
||||
## Usage Guide
|
||||
|
||||
@@ -58,15 +58,15 @@ Watched values are fields that the NetAlertX core monitors for **changes between
|
||||
|
||||
**How to use them:**
|
||||
|
||||
- `Watched_Value1`: Always required; primary indicator of status/state
|
||||
- `Watched_Value2–4`: Optional; use for secondary/tertiary state information
|
||||
- `watchedValue1`: Always required; primary indicator of status/state
|
||||
- `watchedValue2–4`: Optional; use for secondary/tertiary state information
|
||||
- Leave unused ones as `null`
|
||||
|
||||
**Example:**
|
||||
|
||||
- Device scanner: `Watched_Value1 = "online"` or `"offline"`
|
||||
- Port scanner: `Watched_Value1 = "80"` (port number), `Watched_Value2 = "open"` (state)
|
||||
- Service monitor: `Watched_Value1 = "200"` (HTTP status), `Watched_Value2 = "0.45"` (response time)
|
||||
- Device scanner: `watchedValue1 = "online"` or `"offline"`
|
||||
- Port scanner: `watchedValue1 = "80"` (port number), `watchedValue2 = "open"` (state)
|
||||
- Service monitor: `watchedValue1 = "200"` (HTTP status), `watchedValue2 = "0.45"` (response time)
|
||||
|
||||
### Foreign Key
|
||||
|
||||
@@ -110,14 +110,14 @@ https://google.com|null|2023-01-02 15:56:30|200|0.7898||null|null
|
||||
Missing pipe
|
||||
```
|
||||
|
||||
❌ **Missing mandatory Watched_Value1** (column 3):
|
||||
❌ **Missing mandatory watchedValue1** (column 3):
|
||||
```csv
|
||||
https://duckduckgo.com|192.168.1.1|2023-01-02 15:56:30|null|0.9898|null|null|Best|null
|
||||
↑
|
||||
Must not be null
|
||||
```
|
||||
|
||||
❌ **Incomplete optional columns** (has HelpVal1 but missing HelpVal2–4):
|
||||
❌ **Incomplete optional columns** (has helpVal1 but missing helpVal2–4):
|
||||
```csv
|
||||
device|null|2023-01-02 15:56:30|status|null|null|null|null|null|helper1
|
||||
↑
|
||||
@@ -146,19 +146,19 @@ plugin_objects = Plugin_Objects("YOURPREFIX")
|
||||
|
||||
# Add objects
|
||||
plugin_objects.add_object(
|
||||
Object_PrimaryID="device_id",
|
||||
Object_SecondaryID="192.168.1.1",
|
||||
objectPrimaryId="device_id",
|
||||
objectSecondaryId="192.168.1.1",
|
||||
DateTime="2023-01-02 15:56:30",
|
||||
Watched_Value1="online",
|
||||
Watched_Value2=None,
|
||||
Watched_Value3=None,
|
||||
Watched_Value4=None,
|
||||
watchedValue1="online",
|
||||
watchedValue2=None,
|
||||
watchedValue3=None,
|
||||
watchedValue4=None,
|
||||
Extra="Additional data",
|
||||
ForeignKey="aa:bb:cc:dd:ee:ff",
|
||||
HelpVal1=None,
|
||||
HelpVal2=None,
|
||||
HelpVal3=None,
|
||||
HelpVal4=None
|
||||
helpVal1=None,
|
||||
helpVal2=None,
|
||||
helpVal3=None,
|
||||
helpVal4=None
|
||||
)
|
||||
|
||||
# Write results (handles formatting, sanitization, and file creation)
|
||||
@@ -177,7 +177,7 @@ The library automatically:
|
||||
|
||||
The core runs **de-duplication once per hour** on the `Plugins_Objects` table:
|
||||
|
||||
- **Duplicate Detection Key:** Combination of `Object_PrimaryID`, `Object_SecondaryID`, `Plugin` (auto-filled from `unique_prefix`), and `UserData`
|
||||
- **Duplicate Detection Key:** Combination of `objectPrimaryId`, `objectSecondaryId`, `Plugin` (auto-filled from `unique_prefix`), and `UserData`
|
||||
- **Resolution:** Oldest duplicate entries are removed, newest are kept
|
||||
- **Use Case:** Prevents duplicate notifications when the same object is detected multiple times
|
||||
|
||||
@@ -213,9 +213,9 @@ Before writing your plugin's `script.py`, ensure:
|
||||
|
||||
- [ ] **9 or 13 columns** in each output line (8 or 12 pipe separators)
|
||||
- [ ] **Mandatory columns filled:**
|
||||
- Column 0: `Object_PrimaryID` (not null)
|
||||
- Column 0: `objectPrimaryId` (not null)
|
||||
- Column 2: `DateTime` in `YYYY-MM-DD HH:MM:SS` format
|
||||
- Column 3: `Watched_Value1` (not null)
|
||||
- Column 3: `watchedValue1` (not null)
|
||||
- [ ] **Null values as literal string** `null` (not empty string or special chars)
|
||||
- [ ] **No extra pipes or misaligned columns**
|
||||
- [ ] **If using optional helpers** (columns 9–12), all 4 must be present
|
||||
|
||||
@@ -68,13 +68,13 @@ try:
|
||||
|
||||
# Add an object to results
|
||||
plugin_objects.add_object(
|
||||
Object_PrimaryID="example_id",
|
||||
Object_SecondaryID=None,
|
||||
objectPrimaryId="example_id",
|
||||
objectSecondaryId=None,
|
||||
DateTime="2023-01-02 15:56:30",
|
||||
Watched_Value1="value1",
|
||||
Watched_Value2=None,
|
||||
Watched_Value3=None,
|
||||
Watched_Value4=None,
|
||||
watchedValue1="value1",
|
||||
watchedValue2=None,
|
||||
watchedValue3=None,
|
||||
watchedValue4=None,
|
||||
Extra="additional_data",
|
||||
ForeignKey=None
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ Each column definition specifies:
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "devMac",
|
||||
"mapped_to_column_data": null,
|
||||
"css_classes": "col-sm-2",
|
||||
@@ -39,7 +39,7 @@ Each column definition specifies:
|
||||
|
||||
| Property | Type | Required | Description |
|
||||
|----------|------|----------|-------------|
|
||||
| `column` | string | **YES** | Source column name from data contract (e.g., `Object_PrimaryID`, `Watched_Value1`) |
|
||||
| `column` | string | **YES** | Source column name from data contract (e.g., `objectPrimaryId`, `watchedValue1`) |
|
||||
| `mapped_to_column` | string | no | Target database column if mapping to a table like `CurrentScan` |
|
||||
| `mapped_to_column_data` | object | no | Static value to map instead of using column data |
|
||||
| `css_classes` | string | no | Bootstrap CSS classes for width/spacing (e.g., `"col-sm-2"`, `"col-sm-6"`) |
|
||||
@@ -64,7 +64,7 @@ Plain text display (read-only).
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
"localized": ["name"],
|
||||
@@ -99,7 +99,7 @@ Resolves an IP address to a MAC address and creates a device link.
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
"localized": ["name"],
|
||||
@@ -117,7 +117,7 @@ Creates a device link with the target device's name as the link label.
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
"localized": ["name"],
|
||||
@@ -135,7 +135,7 @@ Renders as a clickable HTTP/HTTPS link.
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"show": true,
|
||||
"type": "url",
|
||||
"localized": ["name"],
|
||||
@@ -153,7 +153,7 @@ Creates two links (HTTP and HTTPS) as lock icons for the given IP/hostname.
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"show": true,
|
||||
"type": "url_http_https",
|
||||
"localized": ["name"],
|
||||
@@ -207,7 +207,7 @@ Color-codes values based on ranges. Useful for status codes, latency, capacity p
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"show": true,
|
||||
"type": "threshold",
|
||||
"options": [
|
||||
@@ -252,7 +252,7 @@ Replaces specific values with display strings or HTML.
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
"options": [
|
||||
@@ -286,7 +286,7 @@ Applies a regular expression to extract/transform values.
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"show": true,
|
||||
"type": "regex",
|
||||
"options": [
|
||||
@@ -310,7 +310,7 @@ Evaluates JavaScript code with access to the column value (use `${value}` or `{v
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
"default_value": "",
|
||||
@@ -322,7 +322,7 @@ Evaluates JavaScript code with access to the column value (use `${value}` or `{v
|
||||
**Example with custom formatting:**
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
"options": [
|
||||
@@ -347,7 +347,7 @@ You can chain multiple transformations with dot notation:
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"show": true,
|
||||
"type": "regex.url_http_https",
|
||||
"options": [
|
||||
@@ -376,7 +376,7 @@ Use SQL query results to populate dropdown options:
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"show": true,
|
||||
"type": "select",
|
||||
"options": ["{value}"],
|
||||
@@ -405,7 +405,7 @@ Use plugin settings to populate options:
|
||||
|
||||
```json
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"show": true,
|
||||
"type": "select",
|
||||
"options": ["{value}"],
|
||||
@@ -439,7 +439,7 @@ To import plugin data into the device scan pipeline (for notifications, heuristi
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"show": true,
|
||||
"type": "device_mac",
|
||||
@@ -447,7 +447,7 @@ To import plugin data into the device scan pipeline (for notifications, heuristi
|
||||
"name": [{"language_code": "en_us", "string": "MAC Address"}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
@@ -501,7 +501,7 @@ Control which rows are displayed based on filter conditions. Filters are applied
|
||||
{
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -545,7 +545,7 @@ When viewing a device detail page, the `txtMacFilter` field is populated with th
|
||||
{
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -555,7 +555,7 @@ When viewing a device detail page, the `txtMacFilter` field is populated with th
|
||||
"name": [{"language_code": "en_us", "string": "MAC Address"}]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -574,7 +574,7 @@ When viewing a device detail page, the `txtMacFilter` field is populated with th
|
||||
"name": [{"language_code": "en_us", "string": "Last Seen"}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "threshold",
|
||||
@@ -589,7 +589,7 @@ When viewing a device detail page, the `txtMacFilter` field is populated with th
|
||||
"name": [{"language_code": "en_us", "string": "HTTP Status"}]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
|
||||
@@ -21,7 +21,9 @@ The running environment does not provide the expected kernel sysctl values. This
|
||||
|
||||
## How to Correct the Issue
|
||||
|
||||
Set these sysctls at container runtime.
|
||||
### Option A: Via Docker (Standard Bridge Networking or `network_mode: host` with `NET_ADMIN`)
|
||||
|
||||
If you are using standard bridged networking, or `network_mode: host` and the container is granted the `NET_ADMIN` capability (as is the default recommendation), set these sysctls at container runtime.
|
||||
|
||||
- In `docker-compose.yml` (preferred):
|
||||
```yaml
|
||||
@@ -44,6 +46,24 @@ Set these sysctls at container runtime.
|
||||
> - Use `--privileged` with `docker run`.
|
||||
> - Use the more restrictive `--cap-add=NET_ADMIN` (or `cap_add: [NET_ADMIN]` in `docker-compose` service definitions) to allow the sysctls to be applied at runtime.
|
||||
|
||||
### Option B: Via Host OS (Fallback for `network_mode: host`)
|
||||
|
||||
If you are running the container with `network_mode: host` and cannot grant the `NET_ADMIN` capability, or if your container runtime environment explicitly blocks sysctl overrides, applying these settings via the container configuration will fail. Attempting to do so without sufficient privileges typically results in an OCI runtime error: `sysctl "net.ipv4.conf.all.arp_announce" not allowed in host network namespace`.
|
||||
|
||||
In this scenario, you must apply the settings directly on your host operating system:
|
||||
|
||||
1. **Remove** the `sysctls` section from your `docker-compose.yml`.
|
||||
2. **Apply** on the host immediately:
|
||||
```bash
|
||||
sudo sysctl -w net.ipv4.conf.all.arp_ignore=1
|
||||
sudo sysctl -w net.ipv4.conf.all.arp_announce=2
|
||||
```
|
||||
3. **Make persistent** by adding the following lines to `/etc/sysctl.conf` on the host:
|
||||
```text
|
||||
net.ipv4.conf.all.arp_ignore=1
|
||||
net.ipv4.conf.all.arp_announce=2
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
For broader Docker Compose guidance, see:
|
||||
|
||||
@@ -61,16 +61,16 @@ $(document).ready(function () {
|
||||
appEvents(options: $options) {
|
||||
count
|
||||
appEvents {
|
||||
DateTimeCreated
|
||||
AppEventProcessed
|
||||
AppEventType
|
||||
ObjectType
|
||||
ObjectPrimaryID
|
||||
ObjectSecondaryID
|
||||
ObjectStatus
|
||||
ObjectPlugin
|
||||
ObjectGUID
|
||||
GUID
|
||||
dateTimeCreated
|
||||
appEventProcessed
|
||||
appEventType
|
||||
objectType
|
||||
objectPrimaryId
|
||||
objectSecondaryId
|
||||
objectStatus
|
||||
objectPlugin
|
||||
objectGuid
|
||||
guid
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,16 +128,16 @@ $(document).ready(function () {
|
||||
},
|
||||
|
||||
columns: [
|
||||
{ data: 'DateTimeCreated', title: getString('AppEvents_DateTimeCreated') },
|
||||
{ data: 'AppEventProcessed', title: getString('AppEvents_AppEventProcessed') },
|
||||
{ data: 'AppEventType', title: getString('AppEvents_Type') },
|
||||
{ data: 'ObjectType', title: getString('AppEvents_ObjectType') },
|
||||
{ data: 'ObjectPrimaryID', title: getString('AppEvents_ObjectPrimaryID') },
|
||||
{ data: 'ObjectSecondaryID', title: getString('AppEvents_ObjectSecondaryID') },
|
||||
{ data: 'ObjectStatus', title: getString('AppEvents_ObjectStatus') },
|
||||
{ data: 'ObjectPlugin', title: getString('AppEvents_Plugin') },
|
||||
{ data: 'ObjectGUID', title: 'Object GUID' },
|
||||
{ data: 'GUID', title: 'Event GUID' }
|
||||
{ data: 'dateTimeCreated', title: getString('AppEvents_DateTimeCreated') },
|
||||
{ data: 'appEventProcessed', title: getString('AppEvents_AppEventProcessed') },
|
||||
{ data: 'appEventType', title: getString('AppEvents_Type') },
|
||||
{ data: 'objectType', title: getString('AppEvents_ObjectType') },
|
||||
{ data: 'objectPrimaryId', title: getString('AppEvents_ObjectPrimaryID') },
|
||||
{ data: 'objectSecondaryId', title: getString('AppEvents_ObjectSecondaryID') },
|
||||
{ data: 'objectStatus', title: getString('AppEvents_ObjectStatus') },
|
||||
{ data: 'objectPlugin', title: getString('AppEvents_Plugin') },
|
||||
{ data: 'objectGuid', title: 'Object GUID' },
|
||||
{ data: 'guid', title: 'Event GUID' }
|
||||
],
|
||||
|
||||
columnDefs: [
|
||||
|
||||
@@ -299,7 +299,7 @@ function updateChevrons(currentMac) {
|
||||
|
||||
showSpinner();
|
||||
|
||||
cacheDevices().then(() => {
|
||||
cacheDevices(true).then(() => {
|
||||
hideSpinner();
|
||||
|
||||
// Retry after re-caching
|
||||
@@ -507,7 +507,7 @@ function updateDevicePageName(mac) {
|
||||
if (mac != 'new' && (name === null|| owner === null)) {
|
||||
console.warn("Device not found in cache, retrying after re-cache:", mac);
|
||||
showSpinner();
|
||||
cacheDevices().then(() => {
|
||||
cacheDevices(true).then(() => {
|
||||
hideSpinner();
|
||||
// Retry after successful cache
|
||||
updateDevicePageName(mac);
|
||||
|
||||
@@ -32,51 +32,64 @@
|
||||
|
||||
function loadEventsData() {
|
||||
const hideConnections = $('#chkHideConnectionEvents')[0].checked;
|
||||
const hideConnectionsStr = hideConnections ? 'true' : 'false';
|
||||
|
||||
let period = $("#period").val();
|
||||
let { start, end } = getPeriodStartEnd(period);
|
||||
|
||||
const rawSql = `
|
||||
SELECT eve_DateTime, eve_EventType, eve_IP, eve_AdditionalInfo
|
||||
FROM Events
|
||||
WHERE eve_MAC = "${mac}"
|
||||
AND eve_DateTime BETWEEN "${start}" AND "${end}"
|
||||
AND (
|
||||
(eve_EventType NOT IN ("Connected", "Disconnected", "VOIDED - Connected", "VOIDED - Disconnected"))
|
||||
OR "${hideConnectionsStr}" = "false"
|
||||
)
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const apiBase = getApiBase();
|
||||
const graphqlUrl = `${apiBase}/graphql`;
|
||||
|
||||
const query = `
|
||||
query Events($options: EventQueryOptionsInput) {
|
||||
events(options: $options) {
|
||||
count
|
||||
entries {
|
||||
eveDateTime
|
||||
eveEventType
|
||||
eveIp
|
||||
eveAdditionalInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
|
||||
const apiBaseUrl = getApiBase();
|
||||
const url = `${apiBaseUrl}/dbquery/read`;
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
url: graphqlUrl,
|
||||
method: "POST",
|
||||
contentType: "application/json",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${apiToken}`
|
||||
},
|
||||
data: JSON.stringify({
|
||||
rawSql: btoa(rawSql)
|
||||
query,
|
||||
variables: {
|
||||
options: {
|
||||
eveMac: mac,
|
||||
dateFrom: start,
|
||||
dateTo: end,
|
||||
limit: 500,
|
||||
sort: [{ field: "eveDateTime", order: "desc" }]
|
||||
}
|
||||
}
|
||||
}),
|
||||
success: function (data) {
|
||||
// assuming read_query returns rows directly
|
||||
const rows = data["results"].map(row => {
|
||||
const rawDate = row.eve_DateTime;
|
||||
const formattedDate = rawDate ? localizeTimestamp(rawDate) : '-';
|
||||
const CONNECTION_TYPES = ["Connected", "Disconnected", "VOIDED - Connected", "VOIDED - Disconnected"];
|
||||
|
||||
return [
|
||||
formattedDate,
|
||||
row.eve_DateTime,
|
||||
row.eve_EventType,
|
||||
row.eve_IP,
|
||||
row.eve_AdditionalInfo
|
||||
];
|
||||
});
|
||||
const rows = data.data.events.entries
|
||||
.filter(row => !hideConnections || !CONNECTION_TYPES.includes(row.eveEventType))
|
||||
.map(row => {
|
||||
const rawDate = row.eveDateTime;
|
||||
const formattedDate = rawDate ? localizeTimestamp(rawDate) : '-';
|
||||
|
||||
return [
|
||||
formattedDate,
|
||||
row.eveDateTime,
|
||||
row.eveEventType,
|
||||
row.eveIp,
|
||||
row.eveAdditionalInfo
|
||||
];
|
||||
});
|
||||
|
||||
const table = $('#tableEvents').DataTable();
|
||||
table.clear();
|
||||
|
||||
@@ -121,12 +121,12 @@ function loadSessionsData() {
|
||||
if (data.success && data.sessions.length) {
|
||||
data.sessions.forEach(session => {
|
||||
table.row.add([
|
||||
session.ses_DateTimeOrder,
|
||||
session.ses_Connection,
|
||||
session.ses_Disconnection,
|
||||
session.ses_Duration,
|
||||
session.ses_IP,
|
||||
session.ses_Info
|
||||
session.sesDateTimeOrder,
|
||||
session.sesConnection,
|
||||
session.sesDisconnection,
|
||||
session.sesDuration,
|
||||
session.sesIp,
|
||||
session.sesInfo
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -767,6 +767,7 @@ function initializeDatatable (status) {
|
||||
${_gqlFields}
|
||||
}
|
||||
count
|
||||
dbCount
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -807,9 +808,10 @@ function initializeDatatable (status) {
|
||||
console.log("Raw response:", res);
|
||||
const json = res["data"];
|
||||
|
||||
// Set the total number of records for pagination at the *root level* so DataTables sees them
|
||||
res.recordsTotal = json.devices.count || 0;
|
||||
res.recordsFiltered = json.devices.count || 0;
|
||||
// recordsTotal = raw DB count (before filters/search) so DataTables uses emptyTable
|
||||
// only when the DB is genuinely empty, and zeroRecords when a filter returns nothing.
|
||||
res.recordsTotal = json.devices.dbCount || 0;
|
||||
res.recordsFiltered = json.devices.count || 0;
|
||||
|
||||
// console.log("recordsTotal:", res.recordsTotal, "recordsFiltered:", res.recordsFiltered);
|
||||
// console.log("tableRows:", tableRows);
|
||||
@@ -1049,7 +1051,8 @@ function initializeDatatable (status) {
|
||||
// Processing
|
||||
'processing' : true,
|
||||
'language' : {
|
||||
emptyTable: buildEmptyDeviceTableMessage(getString('Device_NextScan_Imminent')),
|
||||
emptyTable: buildEmptyDeviceTableMessage(getString('Device_NextScan_Imminent')),
|
||||
zeroRecords: "<?= lang('Device_NoMatch_Title');?>",
|
||||
"lengthMenu": "<?= lang('Device_Tablelenght');?>",
|
||||
"search": "<?= lang('Device_Searchbox');?>: ",
|
||||
"paginate": {
|
||||
|
||||
111
front/events.php
111
front/events.php
@@ -105,21 +105,64 @@ function main() {
|
||||
$('#period').val(period);
|
||||
initializeDatatable();
|
||||
getEventsTotals();
|
||||
getEvents(eventsType);
|
||||
getEvents(eventsType); // triggers first serverSide draw
|
||||
}
|
||||
|
||||
/* ---------------- Initialize DataTable ---------------- */
|
||||
function initializeDatatable() {
|
||||
const table = $('#tableEvents').DataTable({
|
||||
paging: true,
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
|
||||
$('#tableEvents').DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
paging: true,
|
||||
lengthChange: true,
|
||||
lengthMenu: getLengthMenu(getSetting("UI_DEFAULT_PAGE_SIZE")),
|
||||
searching: true,
|
||||
ordering: true,
|
||||
info: true,
|
||||
autoWidth: false,
|
||||
order: [[0, "desc"], [3, "desc"], [5, "desc"]],
|
||||
pageLength: tableRows,
|
||||
lengthMenu: getLengthMenu(getSetting("UI_DEFAULT_PAGE_SIZE")),
|
||||
searching: true,
|
||||
ordering: true,
|
||||
info: true,
|
||||
autoWidth: false,
|
||||
order: [[0, "desc"]],
|
||||
pageLength: tableRows,
|
||||
|
||||
ajax: function (dtRequest, callback) {
|
||||
const page = Math.floor(dtRequest.start / dtRequest.length) + 1;
|
||||
const limit = dtRequest.length;
|
||||
const search = dtRequest.search?.value || '';
|
||||
const sortCol = dtRequest.order?.length ? dtRequest.order[0].column : 0;
|
||||
const sortDir = dtRequest.order?.length ? dtRequest.order[0].dir : 'desc';
|
||||
|
||||
const url = `${apiBase}/sessions/session-events`
|
||||
+ `?type=${encodeURIComponent(eventsType)}`
|
||||
+ `&period=${encodeURIComponent(period)}`
|
||||
+ `&page=${page}`
|
||||
+ `&limit=${limit}`
|
||||
+ `&sortCol=${sortCol}`
|
||||
+ `&sortDir=${sortDir}`
|
||||
+ (search ? `&search=${encodeURIComponent(search)}` : '');
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
success: function (response) {
|
||||
callback({
|
||||
data: response.data || [],
|
||||
recordsTotal: response.total || 0,
|
||||
recordsFiltered: response.recordsFiltered || 0
|
||||
});
|
||||
hideSpinner();
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
console.error("Error fetching session events:", status, error, xhr.responseText);
|
||||
callback({ data: [], recordsTotal: 0, recordsFiltered: 0 });
|
||||
hideSpinner();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
columnDefs: [
|
||||
{ targets: [0,5,6,7,8,10,11,12,13], visible: false },
|
||||
{ targets: [7], orderData: [8] },
|
||||
@@ -131,14 +174,14 @@ function initializeDatatable() {
|
||||
{ targets: [3], createdCell: (td, cellData) => $(td).html(localizeTimestamp(cellData)) },
|
||||
{ targets: [4,5,6,7], createdCell: (td, cellData) => $(td).html(translateHTMLcodes(cellData)) }
|
||||
],
|
||||
processing: true, // Shows "processing" overlay
|
||||
|
||||
language: {
|
||||
processing: '<table><td width="130px" align="middle"><?= lang("Events_Loading"); ?></td><td><i class="fa-solid fa-spinner fa-spin-pulse"></i></td></table>',
|
||||
emptyTable: 'No data',
|
||||
lengthMenu: "<?= lang('Events_Tablelenght'); ?>",
|
||||
search: "<?= lang('Events_Searchbox'); ?>: ",
|
||||
paginate: { next: "<?= lang('Events_Table_nav_next'); ?>", previous: "<?= lang('Events_Table_nav_prev'); ?>" },
|
||||
info: "<?= lang('Events_Table_info'); ?>"
|
||||
search: "<?= lang('Events_Searchbox'); ?>: ",
|
||||
paginate: { next: "<?= lang('Events_Table_nav_next'); ?>", previous: "<?= lang('Events_Table_nav_prev'); ?>" },
|
||||
info: "<?= lang('Events_Table_info'); ?>"
|
||||
}
|
||||
});
|
||||
|
||||
@@ -179,53 +222,33 @@ function getEventsTotals() {
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------------- Fetch events and reload DataTable ---------------- */
|
||||
/* ---------------- Switch event type and reload DataTable ---------------- */
|
||||
function getEvents(type) {
|
||||
eventsType = type;
|
||||
const table = $('#tableEvents').DataTable();
|
||||
|
||||
// Event type config: title, color, session columns visibility
|
||||
const config = {
|
||||
all: {title: 'Events_Shortcut_AllEvents', color: 'aqua', sesionCols: false},
|
||||
sessions: {title: 'Events_Shortcut_Sessions', color: 'green', sesionCols: true},
|
||||
missing: {title: 'Events_Shortcut_MissSessions', color: 'yellow', sesionCols: true},
|
||||
voided: {title: 'Events_Shortcut_VoidSessions', color: 'yellow', sesionCols: false},
|
||||
new: {title: 'Events_Shortcut_NewDevices', color: 'yellow', sesionCols: false},
|
||||
down: {title: 'Events_Shortcut_DownAlerts', color: 'red', sesionCols: false}
|
||||
all: {title: 'Events_Shortcut_AllEvents', color: 'aqua', sesionCols: false},
|
||||
sessions: {title: 'Events_Shortcut_Sessions', color: 'green', sesionCols: true},
|
||||
missing: {title: 'Events_Shortcut_MissSessions', color: 'yellow', sesionCols: true},
|
||||
voided: {title: 'Events_Shortcut_VoidSessions', color: 'yellow', sesionCols: false},
|
||||
new: {title: 'Events_Shortcut_NewDevices', color: 'yellow', sesionCols: false},
|
||||
down: {title: 'Events_Shortcut_DownAlerts', color: 'red', sesionCols: false}
|
||||
}[type] || {title: 'Events_Shortcut_Events', color: '', sesionCols: false};
|
||||
|
||||
// Update title and color
|
||||
$('#tableEventsTitle').attr('class', 'box-title text-' + config.color).html(getString(config.title));
|
||||
$('#tableEventsBox').attr('class', 'box box-' + config.color);
|
||||
|
||||
// Toggle columns visibility
|
||||
// Toggle column visibility
|
||||
table.column(3).visible(!config.sesionCols);
|
||||
table.column(4).visible(!config.sesionCols);
|
||||
table.column(5).visible(config.sesionCols);
|
||||
table.column(6).visible(config.sesionCols);
|
||||
table.column(7).visible(config.sesionCols);
|
||||
|
||||
// Build API URL
|
||||
const apiBase = getApiBase();
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const url = `${apiBase}/sessions/session-events?type=${encodeURIComponent(type)}&period=${encodeURIComponent(period)}`;
|
||||
|
||||
table.clear().draw(); // Clear old rows
|
||||
|
||||
showSpinner()
|
||||
|
||||
$.ajax({
|
||||
url,
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
beforeSend: showSpinner, // Show spinner during fetch
|
||||
complete: hideSpinner, // Hide spinner after fetch
|
||||
success: response => {
|
||||
const data = Array.isArray(response) ? response : response.data || [];
|
||||
table.rows.add(data).draw();
|
||||
},
|
||||
error: (xhr, status, error) => console.error("Error fetching session events:", status, error, xhr.responseText)
|
||||
});
|
||||
showSpinner();
|
||||
table.ajax.reload(null, true); // reset to page 1
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
var completedCalls = []
|
||||
var completedCalls_final = ['cacheApiConfig', 'cacheSettings', 'cacheStrings', 'cacheDevices'];
|
||||
var completedCalls_final = ['cacheApiConfig', 'cacheSettings', 'cacheStrings_v2', 'cacheDevices'];
|
||||
var lang_completedCalls = 0;
|
||||
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ function getSetting (key) {
|
||||
// -----------------------------------------------------------------------------
|
||||
function cacheStrings() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(getCache(CACHE_KEYS.initFlag('cacheStrings')) === "true")
|
||||
if(getCache(CACHE_KEYS.initFlag('cacheStrings_v2')) === "true")
|
||||
{
|
||||
// Core strings are cached, but plugin strings may have failed silently on
|
||||
// the first load (non-fatal fetch). Always re-fetch them so that plugin
|
||||
@@ -304,7 +304,7 @@ function cacheStrings() {
|
||||
.then((data) => {
|
||||
if (!Array.isArray(data)) { data = []; }
|
||||
data.forEach((langString) => {
|
||||
setCache(CACHE_KEYS.langString(langString.String_Key, langString.Language_Code), langString.String_Value);
|
||||
setCache(CACHE_KEYS.langString(langString.stringKey, langString.languageCode), langString.stringValue);
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
@@ -347,11 +347,11 @@ function cacheStrings() {
|
||||
if (!Array.isArray(data)) { data = []; }
|
||||
// Store plugin translations
|
||||
data.forEach((langString) => {
|
||||
setCache(CACHE_KEYS.langString(langString.String_Key, langString.Language_Code), langString.String_Value);
|
||||
setCache(CACHE_KEYS.langString(langString.stringKey, langString.languageCode), langString.stringValue);
|
||||
});
|
||||
|
||||
// Handle successful completion of language processing
|
||||
handleSuccess('cacheStrings');
|
||||
handleSuccess('cacheStrings_v2');
|
||||
resolveLang();
|
||||
});
|
||||
})
|
||||
@@ -370,7 +370,7 @@ function cacheStrings() {
|
||||
})
|
||||
.catch((error) => {
|
||||
// Handle failure in any of the language processing
|
||||
handleFailure('cacheStrings');
|
||||
handleFailure('cacheStrings_v2');
|
||||
reject(error);
|
||||
});
|
||||
|
||||
@@ -451,11 +451,23 @@ function getDevDataByMac(macAddress, dbColumn) {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Cache the devices as one JSON
|
||||
function cacheDevices()
|
||||
/**
|
||||
* Fetches the full device list from table_devices.json and stores it in
|
||||
* localStorage under CACHE_KEYS.DEVICES_ALL.
|
||||
*
|
||||
* On subsequent calls the fetch is skipped if the initFlag is already set,
|
||||
* unless forceRefresh is true. Pass forceRefresh = true whenever the caller
|
||||
* knows the cached list may be stale (e.g. a device was not found by MAC and
|
||||
* the page needs to recover without a full clearCache()).
|
||||
*
|
||||
* @param {boolean} [forceRefresh=false] - When true, bypasses the initFlag
|
||||
* guard and always fetches fresh data from the server.
|
||||
* @returns {Promise<void>} Resolves when the cache has been populated.
|
||||
*/
|
||||
function cacheDevices(forceRefresh = false)
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
if(getCache(CACHE_KEYS.initFlag('cacheDevices')) === "true")
|
||||
if(!forceRefresh && getCache(CACHE_KEYS.initFlag('cacheDevices')) === "true")
|
||||
{
|
||||
// One-time migration: normalize legacy { data: [...] } wrapper to a plain array.
|
||||
// Old cache entries from prior versions stored the raw API envelope; re-write
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/server/db.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/language/lang.php';
|
||||
?>
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@ function initOnlineHistoryGraph() {
|
||||
|
||||
res.data.forEach(function(entry) {
|
||||
|
||||
var formattedTime = localizeTimestamp(entry.Scan_Date).slice(11, 17);
|
||||
var formattedTime = localizeTimestamp(entry.scanDate).slice(11, 17);
|
||||
|
||||
timeStamps.push(formattedTime);
|
||||
onlineCounts.push(entry.Online_Devices);
|
||||
downCounts.push(entry.Down_Devices);
|
||||
offlineCounts.push(entry.Offline_Devices);
|
||||
archivedCounts.push(entry.Archived_Devices);
|
||||
onlineCounts.push(entry.onlineDevices);
|
||||
downCounts.push(entry.downDevices);
|
||||
offlineCounts.push(entry.offlineDevices);
|
||||
archivedCounts.push(entry.archivedDevices);
|
||||
});
|
||||
|
||||
// Call your presenceOverTime function after data is ready
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "Problemes guardant el dispositiu",
|
||||
"Device_Save_Unauthorized": "Token invàlid - No autoritzat",
|
||||
"Device_Saved_Success": "S'ha guardat el dispositiu",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "Gerät erfolgreich gespeichert",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "If devices don't appear after the scan, check your SCAN_SUBNETS setting and <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">documentation</a>.",
|
||||
"Device_NoData_Scanning": "Waiting for the first scan - this may take several minutes after the initial setup.",
|
||||
"Device_NoData_Title": "No devices found yet",
|
||||
"Device_NoMatch_Title": "No devices match the current filter",
|
||||
"Device_Save_Failed": "Failed to save device",
|
||||
"Device_Save_Unauthorized": "Unauthorized - invalid API token",
|
||||
"Device_Saved_Success": "Device saved successfully",
|
||||
|
||||
@@ -210,6 +210,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "Fallo al guardar el dispositivo",
|
||||
"Device_Save_Unauthorized": "No autorizado - Token de API inválido",
|
||||
"Device_Saved_Success": "Dispositivo guardado exitósamente",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
"DevDetail_SessionTable_Duration": "Durée",
|
||||
"DevDetail_SessionTable_IP": "IP",
|
||||
"DevDetail_SessionTable_Order": "Ordre",
|
||||
"DevDetail_Shortcut_CurrentStatus": "État actuel",
|
||||
"DevDetail_Shortcut_CurrentStatus": "État",
|
||||
"DevDetail_Shortcut_DownAlerts": "Alertes de panne",
|
||||
"DevDetail_Shortcut_Presence": "Présence",
|
||||
"DevDetail_Shortcut_Sessions": "Sessions",
|
||||
@@ -203,16 +203,17 @@
|
||||
"Device_MultiEdit_MassActions": "Actions en masse :",
|
||||
"Device_MultiEdit_No_Devices": "Aucun appareil sélectionné.",
|
||||
"Device_MultiEdit_Tooltip": "Attention. Ceci va appliquer la valeur de gauche à tous les appareils sélectionnés au-dessus.",
|
||||
"Device_NextScan_Imminent": "",
|
||||
"Device_NextScan_In": "",
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NextScan_Imminent": "Imminent...",
|
||||
"Device_NextScan_In": "Prochain scan dans ",
|
||||
"Device_NoData_Help": "Si les appareils n'apparaissent pas après le scan, vérifiez vos paramètres SCAN_SUBNETS et la <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">documentation</a>.",
|
||||
"Device_NoData_Scanning": "En attente du premier scan - cela peut prendre quelques minutes après le premier paramétrage.",
|
||||
"Device_NoData_Title": "Aucun appareil trouvé pour le moment",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "Erreur à l'enregistrement de l'appareil",
|
||||
"Device_Save_Unauthorized": "Non autorisé - Jeton d'API invalide",
|
||||
"Device_Saved_Success": "Appareil enregistré avec succès",
|
||||
"Device_Saved_Unexpected": "La mise à jour de l'appareil a renvoyé une réponse inattendue",
|
||||
"Device_Scanning": "",
|
||||
"Device_Scanning": "Scan en cours...",
|
||||
"Device_Searchbox": "Rechercher",
|
||||
"Device_Shortcut_AllDevices": "Mes appareils",
|
||||
"Device_Shortcut_AllNodes": "Tous les nœuds",
|
||||
@@ -322,7 +323,7 @@
|
||||
"Gen_AddDevice": "Ajouter un appareil",
|
||||
"Gen_Add_All": "Ajouter tous",
|
||||
"Gen_All_Devices": "Tous les appareils",
|
||||
"Gen_Archived": "",
|
||||
"Gen_Archived": "Archivés",
|
||||
"Gen_AreYouSure": "Êtes-vous sûr ?",
|
||||
"Gen_Backup": "Lancer la sauvegarde",
|
||||
"Gen_Cancel": "Annuler",
|
||||
@@ -333,7 +334,7 @@
|
||||
"Gen_Delete": "Supprimer",
|
||||
"Gen_DeleteAll": "Supprimer tous",
|
||||
"Gen_Description": "Description",
|
||||
"Gen_Down": "",
|
||||
"Gen_Down": "En panne",
|
||||
"Gen_Error": "Erreur",
|
||||
"Gen_Filter": "Filtrer",
|
||||
"Gen_Flapping": "",
|
||||
@@ -342,7 +343,7 @@
|
||||
"Gen_Invalid_Value": "Une valeur invalide a été renseignée",
|
||||
"Gen_LockedDB": "Erreur - La base de données est peut-être verrouillée - Vérifier avec les outils de dév via F12 -> Console ou essayer plus tard.",
|
||||
"Gen_NetworkMask": "Masque réseau",
|
||||
"Gen_New": "",
|
||||
"Gen_New": "Nouveau",
|
||||
"Gen_Offline": "Hors ligne",
|
||||
"Gen_Okay": "OK",
|
||||
"Gen_Online": "En ligne",
|
||||
@@ -360,7 +361,7 @@
|
||||
"Gen_SelectIcon": "<i class=\"fa-solid fa-chevron-down fa-fade\"></i>",
|
||||
"Gen_SelectToPreview": "Sélectionnez pour prévisualiser",
|
||||
"Gen_Selected_Devices": "Appareils sélectionnés :",
|
||||
"Gen_Sleeping": "",
|
||||
"Gen_Sleeping": "En sommeil",
|
||||
"Gen_Subnet": "Sous-réseau",
|
||||
"Gen_Switch": "Basculer",
|
||||
"Gen_Upd": "Mise à jour réussie",
|
||||
@@ -804,4 +805,4 @@
|
||||
"settings_system_label": "Système",
|
||||
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. <b>Il n'y a pas de pas de contrôle.</b>",
|
||||
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"API_CUSTOM_SQL_description": "Puoi specificare una query SQL personalizzata che genererà un file JSON e quindi lo esporrà tramite l'<a href=\"/php/server/query_json.php?file=table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code>endpoint del file</a>.",
|
||||
"API_CUSTOM_SQL_description": "Puoi specificare una query SQL personalizzata che genererà un file JSON e quindi lo esporrà tramite <a href=\"/php/server/query_json.php?file=table_custom_endpoint.json\" target=\"_blank\"><code>table_custom_endpoint.json</code> endpoint del file</a>.",
|
||||
"API_CUSTOM_SQL_name": "Endpoint personalizzato",
|
||||
"API_TOKEN_description": "Token API per comunicazioni sicure. Generane uno o inserisci un valore qualsiasi. Viene inviato nell'intestazione della richiesta e utilizzato nel plugin <code>SYNC</code>, nel server GraphQL e in altri endpoint API. Puoi utilizzare gli endpoint API per creare integrazioni personalizzate come descritto nella <a href=\"https://docs.netalertx.com/API\" target=\"_blank\">documentazione API</a>.",
|
||||
"API_TOKEN_name": "Token API",
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "Se i dispositivi non vengono visualizzati dopo la scansione, controlla l'impostazione SCAN_SUBNETS e la <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">documentazione</a>.",
|
||||
"Device_NoData_Scanning": "In attesa della prima scansione: potrebbero volerci diversi minuti dopo la configurazione iniziale.",
|
||||
"Device_NoData_Title": "Ancora nessun dispositivo trovato",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "Impossibile salvare il dispositivo",
|
||||
"Device_Save_Unauthorized": "Non autorizzato: token API non valido",
|
||||
"Device_Saved_Success": "Dispositivo salvato correttamente",
|
||||
@@ -567,13 +568,13 @@
|
||||
"Network_ManageEdit_Type_text": "-- Seleziona tipo --",
|
||||
"Network_ManageLeaf": "Gestisci assegnazione",
|
||||
"Network_ManageUnassign": "Annulla assegnazione",
|
||||
"Network_NoAssignedDevices": "A questo nodo di rete non sono assegnati dispositivi (nodi foglia). Assegnane uno dall'elenco qui sotto o vai alla scheda <b><i class=\"fa fa-info-circle\"></i>Dettagli</b> di qualsiasi dispositivo in <a href=\"devices.php\"><b > <i class=\"fa fa-laptop\"></i>Dispositivi</b></a> e assegnalo a un <b><i class=\"fa fa-server\"></i>Nodo di rete (MAC)</b> e una <b><i class=\"fa fa-ethernet\"></i>Porta</b>.",
|
||||
"Network_NoAssignedDevices": "A questo nodo di rete non sono assegnati dispositivi (nodi foglia). Assegnane uno dall'elenco qui sotto o vai alla scheda <b><i class=\"fa fa-info-circle\"></i> Dettagli</b> di qualsiasi dispositivo in <a href=\"devices.php\"><b > <i class=\"fa fa-laptop\"></i> Dispositivi</b></a> e assegnalo a un <b><i class=\"fa fa-server\"></i> Nodo di rete (MAC)</b> e una <b><i class=\"fa fa-ethernet\"></i> Porta</b>.",
|
||||
"Network_NoDevices": "Nessun dispositivo da configurare",
|
||||
"Network_Node": "Nodo di rete",
|
||||
"Network_Node_Name": "Nome nodo",
|
||||
"Network_Parent": "Dispositivo di rete principale",
|
||||
"Network_Root": "Nodo radice",
|
||||
"Network_Root_Not_Configured": "Seleziona un tipo di dispositivo di rete, ad esempio un <b>Gateway</b>, nel campo <b>Tipo</b> del <a href=\"deviceDetails.php?mac=Internet\">dispositivo root Internet</a> per iniziare a configurare questa schermata. <br/><br/> Ulteriore documentazione è disponibile nella guida <a href=\"https://docs.netalertx.com/NETWORK_TREE\" target=\"_blank\"> Come impostare la tua pagina di rete</a>",
|
||||
"Network_Root_Not_Configured": "Seleziona un tipo di dispositivo di rete, ad esempio un <b>Gateway</b>, nel campo <b>Tipo</b> del <a href=\"deviceDetails.php?mac=Internet\">dispositivo root Internet</a> per iniziare a configurare questa schermata. <br/><br/> Ulteriore documentazione è disponibile nella guida <a href=\"https://docs.netalertx.com/NETWORK_TREE\" target=\"_blank\">Come impostare la tua pagina di rete</a>",
|
||||
"Network_Root_Unconfigurable": "Radice non configurabile",
|
||||
"Network_ShowArchived": "Mostra archiviati",
|
||||
"Network_ShowOffline": "Mostra offline",
|
||||
@@ -584,7 +585,7 @@
|
||||
"Network_UnassignedDevices": "Dispositivi non assegnati",
|
||||
"Notifications_All": "Tutte le notifiche",
|
||||
"Notifications_Mark_All_Read": "Segna tutto come letto",
|
||||
"PIALERT_WEB_PASSWORD_description": "La password predefinita è <code>123456</code>. Per modificare la password esegui <code>/app/back/pialert-cli</code> nel contenitore o utilizza il <a onclick=\"toggleAllSettings()\" href=\"#SETPWD_RUN\"><code>SETPWD_RUN</code>plugin imposta password</a>.",
|
||||
"PIALERT_WEB_PASSWORD_description": "La password predefinita è <code>123456</code>. Per modificare la password esegui <code>/app/back/pialert-cli</code> nel contenitore o utilizza il <a onclick=\"toggleAllSettings()\" href=\"#SETPWD_RUN\"><code>SETPWD_RUN</code> plugin imposta password</a>.",
|
||||
"PIALERT_WEB_PASSWORD_name": "Password login",
|
||||
"PIALERT_WEB_PROTECTION_description": "Se abilitato, viene mostrata una finestra di login. Leggi attentamente qui sotto se rimani bloccato fuori dall'istanza.",
|
||||
"PIALERT_WEB_PROTECTION_name": "Abilita login",
|
||||
@@ -804,4 +805,4 @@
|
||||
"settings_system_label": "Sistema",
|
||||
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
|
||||
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,11 +203,12 @@
|
||||
"Device_MultiEdit_MassActions": "大量のアクション:",
|
||||
"Device_MultiEdit_No_Devices": "デバイスが選択されていません。",
|
||||
"Device_MultiEdit_Tooltip": "注意。これをクリックすると、左側の値が上記で選択したすべてのデバイスに適用されます。",
|
||||
"Device_NextScan_Imminent": "まもなく",
|
||||
"Device_NextScan_In": "次のスキャン ",
|
||||
"Device_NextScan_Imminent": "まもなく...",
|
||||
"Device_NextScan_In": "次のスキャンまでおよそ ",
|
||||
"Device_NoData_Help": "スキャン後にデバイスが表示されない場合は、SCAN_SUBNETS設定と<a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">ドキュメント</a>を確認してください。",
|
||||
"Device_NoData_Scanning": "最初のスキャンを待機中 - 初期設定後、数分かかる場合があります。",
|
||||
"Device_NoData_Title": "デバイスが見つかりません",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "デバイスの保存に失敗しました",
|
||||
"Device_Save_Unauthorized": "許可されていない - 無効なAPIトークン",
|
||||
"Device_Saved_Success": "デバイスが正常に保存されました",
|
||||
@@ -804,4 +805,4 @@
|
||||
"settings_system_label": "システム",
|
||||
"settings_update_item_warning": "以下の値を更新してください。以前のフォーマットに従うよう注意してください。<b>検証は行われません。</b>",
|
||||
"test_event_tooltip": "設定をテストする前に、まず変更を保存してください。"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ $pia_lang_selected = isset($_langMatch[1]) ? strtolower($_langMatch[1]) : $defau
|
||||
$result = $db->query("SELECT * FROM Plugins_Language_Strings");
|
||||
$strings = array();
|
||||
while ($row = $result->fetchArray(SQLITE3_ASSOC)) {
|
||||
$strings[$row['String_Key']] = $row['String_Value'];
|
||||
$strings[$row['stringKey']] = $row['stringValue'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -203,11 +203,12 @@
|
||||
"Device_MultiEdit_MassActions": "Массовые действия:",
|
||||
"Device_MultiEdit_No_Devices": "Устройства не выбраны.",
|
||||
"Device_MultiEdit_Tooltip": "Осторожно. При нажатии на эту кнопку значение слева будет применено ко всем устройствам, выбранным выше.",
|
||||
"Device_NextScan_Imminent": "Предстоящий...",
|
||||
"Device_NextScan_Imminent": "Скоро...",
|
||||
"Device_NextScan_In": "Следующее сканирование примерно через· ",
|
||||
"Device_NoData_Help": "Если устройства не отображаются после сканирования, проверьте настройку SCAN_SUBNETS и <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">документацию</a>.",
|
||||
"Device_NoData_Scanning": "Ожидание первого сканирования — это может занять несколько минут после первоначальной настройки.",
|
||||
"Device_NoData_Title": "Устройства пока не найдены",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "Не удалось сохранить устройство",
|
||||
"Device_Save_Unauthorized": "Не авторизован - недействительный токен API",
|
||||
"Device_Saved_Success": "Устройство успешно сохранено",
|
||||
@@ -231,7 +232,7 @@
|
||||
"Device_TableHead_FQDN": "FQDN",
|
||||
"Device_TableHead_Favorite": "Избранное",
|
||||
"Device_TableHead_FirstSession": "Первый сеанс",
|
||||
"Device_TableHead_Flapping": "",
|
||||
"Device_TableHead_Flapping": "Нестабильный",
|
||||
"Device_TableHead_GUID": "GUID",
|
||||
"Device_TableHead_Group": "Группа",
|
||||
"Device_TableHead_IPv4": "IPv4",
|
||||
@@ -336,7 +337,7 @@
|
||||
"Gen_Down": "Лежит",
|
||||
"Gen_Error": "Ошибка",
|
||||
"Gen_Filter": "Фильтр",
|
||||
"Gen_Flapping": "",
|
||||
"Gen_Flapping": "Нестабильный",
|
||||
"Gen_Generate": "Генерировать",
|
||||
"Gen_InvalidMac": "Неверный Mac-адрес.",
|
||||
"Gen_Invalid_Value": "Введено некорректное значение",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "Не вдалося зберегти пристрій",
|
||||
"Device_Save_Unauthorized": "Неавторизовано – недійсний токен API",
|
||||
"Device_Saved_Success": "Пристрій успішно збережено",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "",
|
||||
"Device_Save_Unauthorized": "",
|
||||
"Device_Saved_Success": "",
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
"Device_NoData_Help": "",
|
||||
"Device_NoData_Scanning": "",
|
||||
"Device_NoData_Title": "",
|
||||
"Device_NoMatch_Title": "",
|
||||
"Device_Save_Failed": "保存设备失败",
|
||||
"Device_Save_Unauthorized": "未授权 - API 令牌无效",
|
||||
"Device_Saved_Success": "设备保存成功",
|
||||
@@ -374,9 +375,9 @@
|
||||
"Gen_create_new_device_info": "通常使用<a target=\"_blank\" href=\"https://docs.netalertx.com/PLUGINS\">plugins</a>来发现设备。但是,在某些情况下,您可能需要手动添加设备。要探索特定场景,请查看<a target=\"_blank\" href=\"https://docs.netalertx.com/REMOTE_NETWORKS\">远程网络文档</a>。",
|
||||
"General_display_name": "通用",
|
||||
"General_icon": "<i class=\"fa fa-gears\"></i>",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "这是一项维护设置<b>删除设备</b>。如果启用该设置(<code>0</code> 为禁用),则标记为<b>新设备</b>的设备(如果其<b>首次会话</b>时间早于此设置中指定的小时数)将被删除。如果您想在 <code>X</code> 小时后自动删除<b>新设备</b>,请使用此设置。",
|
||||
"HRS_TO_KEEP_NEWDEV_description": "这是一项 <b>删除设备</b> 的维护性设置。如启用(<code>0</code> 代表禁用),被标记为 <b>新设备</b> 的设备将被删除,如果它们的 <b>首个会话</b> 时间比这个设置中指定的时长要短。如果想在 <code>X</code> 个小时后自动删除 <b>新设备</b> 请使用本设置。",
|
||||
"HRS_TO_KEEP_NEWDEV_name": "小时后删除新设备",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "这是维护设置<b>删除设备</b>。如果启用了这个设置(<code>0</code>是禁用),任何<b>上次链接</b>时间比设置里存的指定时间长的<b>离线</b>设备都会被删除。要是您想<code>X</code>小时以候自动处理<b>下线设备</b>,请用这个设置。",
|
||||
"HRS_TO_KEEP_OFFDEV_description": "这是<b>删除设备</b>的维护设置。如果启用了这个设置(<code>0</code>是禁用),任何<b>上次连接</b>时间比设置里存的指定时间长的<b>离线</b>设备都会被删除。要是您想在<code>X</code>小时后自动删除<b>离线设备</b>,请用这个设置。",
|
||||
"HRS_TO_KEEP_OFFDEV_name": "保留离线设备",
|
||||
"LOADED_PLUGINS_description": "加载哪些插件。添加插件可能会降低应用程序的速度。在<a target=\"_blank\" href=\"https://docs.netalertx.com/PLUGINS\">插件文档</a>中详细了解需要启用哪些插件、插件类型或扫描选项。卸载插件将丢失您的设置。只有<code>已禁用</code>的插件才能卸载。",
|
||||
"LOADED_PLUGINS_name": "已加载插件",
|
||||
@@ -804,4 +805,4 @@
|
||||
"settings_system_label": "系统",
|
||||
"settings_update_item_warning": "更新下面的值。请注意遵循先前的格式。<b>未执行验证。</b>",
|
||||
"test_event_tooltip": "在测试设置之前,请先保存更改。"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -403,7 +403,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -418,7 +418,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -434,7 +434,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -450,7 +450,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -466,7 +466,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -482,7 +482,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -498,7 +498,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -532,7 +532,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -547,7 +547,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -562,7 +562,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -50,7 +50,7 @@ def main():
|
||||
# make sure the below mapping is mapped in config.json, for example:
|
||||
# "database_column_definitions": [
|
||||
# {
|
||||
# "column": "Object_PrimaryID", <--------- the value I save into primaryId
|
||||
# "column": "objectPrimaryId", <--------- the value I save into primaryId
|
||||
# "mapped_to_column": "scanMac", <--------- gets inserted into the CurrentScan DB
|
||||
# table column scanMac
|
||||
#
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -46,7 +46,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -65,7 +65,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "url",
|
||||
@@ -80,7 +80,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -99,7 +99,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -114,7 +114,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -133,7 +133,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
@@ -153,7 +153,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-8",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -168,7 +168,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -187,7 +187,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -206,7 +206,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -225,7 +225,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -261,7 +261,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -46,7 +46,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -65,7 +65,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "url",
|
||||
@@ -80,7 +80,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -99,7 +99,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -114,7 +114,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -133,7 +133,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
@@ -153,7 +153,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-8",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -168,7 +168,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -187,7 +187,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -206,7 +206,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -225,7 +225,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -261,7 +261,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Watched_Value4",
|
||||
"compare_column": "watchedValue4",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -47,7 +47,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -62,7 +62,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -81,7 +81,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -96,7 +96,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -111,7 +111,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -126,7 +126,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -145,7 +145,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -160,7 +160,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -175,7 +175,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -190,7 +190,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -205,7 +205,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -224,7 +224,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
@@ -260,7 +260,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -212,14 +212,14 @@ class sensor_config:
|
||||
already known. If not, it marks the sensor as new and logs relevant information.
|
||||
"""
|
||||
# Retrieve the plugin object based on the sensor's hash
|
||||
plugObj = getPluginObject({"Plugin": "MQTT", "Watched_Value3": self.hash})
|
||||
plugObj = getPluginObject({"plugin": "MQTT", "watchedValue3": self.hash})
|
||||
|
||||
# Check if the plugin object is new
|
||||
if not plugObj:
|
||||
self.isNew = True
|
||||
mylog('verbose', [f"[{pluginName}] New sensor entry (name|mac|hash) : ({self.deviceName}|{self.mac}|{self.hash}"])
|
||||
else:
|
||||
device_name = plugObj.get("Watched_Value1", "Unknown")
|
||||
device_name = plugObj.get("watchedValue1", "Unknown")
|
||||
mylog('verbose', [f"[{pluginName}] Existing, skip Device Name: {device_name}"])
|
||||
self.isNew = False
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -46,7 +46,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -65,7 +65,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -80,7 +80,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -95,7 +95,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
@@ -115,7 +115,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -130,7 +130,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -145,7 +145,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "device_mac",
|
||||
@@ -160,7 +160,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -179,7 +179,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -215,7 +215,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -46,7 +46,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -65,7 +65,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -80,7 +80,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -95,7 +95,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
@@ -115,7 +115,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -130,7 +130,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -145,7 +145,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "device_mac",
|
||||
@@ -160,7 +160,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -179,7 +179,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -215,7 +215,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -46,7 +46,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -65,7 +65,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -80,7 +80,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -95,7 +95,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
@@ -115,7 +115,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -130,7 +130,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -145,7 +145,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "device_mac",
|
||||
@@ -160,7 +160,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -179,7 +179,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -215,7 +215,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -42,7 +42,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -61,7 +61,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "url",
|
||||
@@ -76,7 +76,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -95,7 +95,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -110,7 +110,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -129,7 +129,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
@@ -149,7 +149,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-8",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -164,7 +164,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -183,7 +183,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -202,7 +202,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -221,7 +221,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -257,7 +257,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -46,7 +46,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -65,7 +65,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -80,7 +80,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -95,7 +95,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "eval",
|
||||
@@ -115,7 +115,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -130,7 +130,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -145,7 +145,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "device_mac",
|
||||
@@ -160,7 +160,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -179,7 +179,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -215,7 +215,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -378,7 +378,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -393,7 +393,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -409,7 +409,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -425,7 +425,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -441,7 +441,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -457,7 +457,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -472,7 +472,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -506,7 +506,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -521,7 +521,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -536,7 +536,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -338,17 +338,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1", "Watched_Value2"],
|
||||
"default_value": ["watchedValue1", "watchedValue2"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -368,15 +368,15 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is IP</li><li><code>Watched_Value2</code> is Vendor</li><li><code>Watched_Value3</code> is Interface </li><li><code>Watched_Value4</code> is N/A </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is IP</li><li><code>watchedValue2</code> is Vendor</li><li><code>watchedValue3</code> is Interface </li><li><code>watchedValue4</code> is N/A </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envía una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Valor_observado1</code> es IP</li><li><code>Valor_observado2</code> es Proveedor</li><li><code>Valor_observado3</code> es Interfaz </li><li><code>Valor_observado4</code> es N/A </li></ul>"
|
||||
"string": "Envía una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es IP</li><li><code>watchedValue2</code> es Proveedor</li><li><code>watchedValue3</code> es Interfaz </li><li><code>watchedValue4</code> es N/A </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>Watched_Value1</code> ist die IP</li><li><code>Watched_Value2</code> ist der Hersteller</li><li><code>Watched_Value3</code> ist das Interface </li><li><code>Watched_Value4</code> ist nicht in Verwendung </li></ul>"
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>watchedValue1</code> ist die IP</li><li><code>watchedValue2</code> ist der Hersteller</li><li><code>watchedValue3</code> ist das Interface </li><li><code>watchedValue4</code> ist nicht in Verwendung </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -387,7 +387,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -484,7 +484,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -499,7 +499,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -515,7 +515,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -531,7 +531,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -582,7 +582,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -605,7 +605,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -628,7 +628,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -431,7 +431,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -448,7 +448,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": [
|
||||
@@ -474,7 +474,7 @@
|
||||
"type": "device_mac"
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": [
|
||||
@@ -500,7 +500,7 @@
|
||||
"type": "device_ip"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": [
|
||||
@@ -526,7 +526,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
@@ -573,7 +573,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -590,7 +590,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -607,7 +607,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -291,7 +291,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -306,7 +306,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -325,7 +325,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -344,7 +344,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -359,7 +359,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -374,7 +374,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -389,7 +389,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -404,7 +404,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -82,16 +82,16 @@ def cleanup_database(
|
||||
# Cleanup Online History
|
||||
mylog("verbose", [f"[{pluginName}] Online_History: Delete all but keep latest 150 entries"])
|
||||
cursor.execute(
|
||||
"""DELETE from Online_History where "Index" not in (
|
||||
SELECT "Index" from Online_History
|
||||
order by Scan_Date desc limit 150)"""
|
||||
"""DELETE from Online_History where "index" not in (
|
||||
SELECT "index" from Online_History
|
||||
order by scanDate desc limit 150)"""
|
||||
)
|
||||
mylog("verbose", [f"[{pluginName}] Online_History deleted rows: {cursor.rowcount}"])
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Cleanup Events
|
||||
mylog("verbose", f"[{pluginName}] Events: Delete all older than {str(DAYS_TO_KEEP_EVENTS)} days (DAYS_TO_KEEP_EVENTS setting)")
|
||||
sql = f"""DELETE FROM Events WHERE eve_DateTime <= date('now', '-{str(DAYS_TO_KEEP_EVENTS)} day')"""
|
||||
sql = f"""DELETE FROM Events WHERE eveDateTime <= date('now', '-{str(DAYS_TO_KEEP_EVENTS)} day')"""
|
||||
mylog("verbose", [f"[{pluginName}] SQL : {sql}"])
|
||||
cursor.execute(sql)
|
||||
mylog("verbose", [f"[{pluginName}] Events deleted rows: {cursor.rowcount}"])
|
||||
@@ -100,7 +100,7 @@ def cleanup_database(
|
||||
# Sessions (derived snapshot — trimmed to the same window as Events so the
|
||||
# two tables stay in sync without introducing a separate setting)
|
||||
mylog("verbose", f"[{pluginName}] Sessions: Delete all older than {str(DAYS_TO_KEEP_EVENTS)} days (reuses DAYS_TO_KEEP_EVENTS)")
|
||||
sql = f"""DELETE FROM Sessions WHERE ses_DateTimeConnection <= date('now', '-{str(DAYS_TO_KEEP_EVENTS)} day')"""
|
||||
sql = f"""DELETE FROM Sessions WHERE sesDateTimeConnection <= date('now', '-{str(DAYS_TO_KEEP_EVENTS)} day')"""
|
||||
mylog("verbose", [f"[{pluginName}] SQL : {sql}"])
|
||||
cursor.execute(sql)
|
||||
mylog("verbose", [f"[{pluginName}] Sessions deleted rows: {cursor.rowcount}"])
|
||||
@@ -113,7 +113,7 @@ def cleanup_database(
|
||||
SELECT "Index"
|
||||
FROM (
|
||||
SELECT "Index",
|
||||
ROW_NUMBER() OVER(PARTITION BY "Plugin" ORDER BY DateTimeChanged DESC) AS row_num
|
||||
ROW_NUMBER() OVER(PARTITION BY plugin ORDER BY dateTimeChanged DESC) AS row_num
|
||||
FROM Plugins_History
|
||||
) AS ranked_objects
|
||||
WHERE row_num <= {str(PLUGINS_KEEP_HIST)}
|
||||
@@ -130,7 +130,7 @@ def cleanup_database(
|
||||
SELECT "Index"
|
||||
FROM (
|
||||
SELECT "Index",
|
||||
ROW_NUMBER() OVER(PARTITION BY "Notifications" ORDER BY DateTimeCreated DESC) AS row_num
|
||||
ROW_NUMBER() OVER(PARTITION BY "index" ORDER BY dateTimeCreated DESC) AS row_num
|
||||
FROM Notifications
|
||||
) AS ranked_objects
|
||||
WHERE row_num <= {histCount}
|
||||
@@ -147,7 +147,7 @@ def cleanup_database(
|
||||
SELECT "Index"
|
||||
FROM (
|
||||
SELECT "Index",
|
||||
ROW_NUMBER() OVER(PARTITION BY "AppEvents" ORDER BY DateTimeCreated DESC) AS row_num
|
||||
ROW_NUMBER() OVER(PARTITION BY "index" ORDER BY dateTimeCreated DESC) AS row_num
|
||||
FROM AppEvents
|
||||
) AS ranked_objects
|
||||
WHERE row_num <= {histCount}
|
||||
@@ -192,10 +192,10 @@ def cleanup_database(
|
||||
DELETE FROM Plugins_Objects
|
||||
WHERE rowid > (
|
||||
SELECT MIN(rowid) FROM Plugins_Objects p2
|
||||
WHERE Plugins_Objects.Plugin = p2.Plugin
|
||||
AND Plugins_Objects.Object_PrimaryID = p2.Object_PrimaryID
|
||||
AND Plugins_Objects.Object_SecondaryID = p2.Object_SecondaryID
|
||||
AND Plugins_Objects.UserData = p2.UserData
|
||||
WHERE Plugins_Objects.plugin = p2.plugin
|
||||
AND Plugins_Objects.objectPrimaryId = p2.objectPrimaryId
|
||||
AND Plugins_Objects.objectSecondaryId = p2.objectSecondaryId
|
||||
AND Plugins_Objects.userData = p2.userData
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"enabled": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -432,17 +432,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"default_value": ["watchedValue1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -462,11 +462,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Previous IP (not recommended)</li><li><code>watchedValue2</code> unused</li><li><code>watchedValue3</code> unused </li><li><code>watchedValue4</code> unused </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>Watched_Value1</code> ist die Vorige IP (nicht empfohlen)</li><li><code>Watched_Value2</code> ist nicht in Verwendung</li><li><code>Watched_Value3</code> ist nicht in Verwendung </li><li><code>Watched_Value4</code> ist nicht in Verwendung </li></ul>"
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>watchedValue1</code> ist die Vorige IP (nicht empfohlen)</li><li><code>watchedValue2</code> ist nicht in Verwendung</li><li><code>watchedValue3</code> ist nicht in Verwendung </li><li><code>watchedValue4</code> ist nicht in Verwendung </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -477,7 +477,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -507,22 +507,22 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>Watched_ValueN</code> seleccionadas cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>Watched_ValueN</code>-Spalte hat sich geändert."
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>watchedValueN</code>-Spalte hat sich geändert."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -537,7 +537,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -560,7 +560,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
@@ -583,7 +583,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -628,7 +628,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -651,7 +651,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -674,7 +674,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -78,7 +78,7 @@ volumes:
|
||||
|
||||
10. Load the `DHCPLSS` plugin and add the search path: `/etc/dnsmasq/dnsmasq.leases`
|
||||
|
||||
Configure the plugin, and save everything. You can trigger a manual run.
|
||||
Configure the plugin, and save everything. You can trigger a manual run.
|
||||
|
||||
> [!NOTE]
|
||||
> DHCP leases don't allow for realtime tracking and the freshness of the data depends on the DHCP leasing time (usually set to 1 or 24h, or 3600 to 86400 seconds).
|
||||
@@ -93,8 +93,8 @@ DHCPLSS_CMD: 'python3 /app/front/plugins/dhcp_leases/script.py paths={paths}'
|
||||
DHCPLSS_paths_to_check: ['/etc/dnsmasq/dnsmasq.leases']
|
||||
DHCPLSS_RUN_SCHD: '*/5 * * * *'
|
||||
DHCPLSS_TUN_TIMEOUT: 5
|
||||
DHCPLSS_WATCH: ['Watched_Value1', 'Watched_Value4']
|
||||
DHCPLSS_REPORT_ON: ['new', 'watched_changed']
|
||||
DHCPLSS_WATCH: ['watchedValue1', 'watchedValue4']
|
||||
DHCPLSS_REPORT_ON: ['new', 'watched-changed']
|
||||
```
|
||||
|
||||
You can check the the `dnsmasq.leases` file in the container by running `ls /etc/dnsmasq/`:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"data_source": "script",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -64,7 +64,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -79,7 +79,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -102,7 +102,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -126,7 +126,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -150,7 +150,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -173,7 +173,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"mapped_to_column": "scanLastConnection",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -197,7 +197,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -220,7 +220,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -244,7 +244,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -267,7 +267,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -290,7 +290,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -313,7 +313,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -363,7 +363,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
@@ -753,17 +753,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1", "Watched_Value4"],
|
||||
"default_value": ["watchedValue1", "watchedValue4"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -783,15 +783,15 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Active </li><li><code>Watched_Value2</code> is Hostname </li><li><code>Watched_Value3</code> is hardware </li><li><code>Watched_Value4</code> is State </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Active </li><li><code>watchedValue2</code> is Hostname </li><li><code>watchedValue3</code> is hardware </li><li><code>watchedValue4</code> is State </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Enviar una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> está activo </li><li><code>Watched_Value2</code> es el nombre de host </li><li><code>Watched_Value3</code > es hardware </li><li><code>Watched_Value4</code> es Estado </li></ul>"
|
||||
"string": "Enviar una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> está activo </li><li><code>watchedValue2</code> es el nombre de host </li><li><code>watchedValue3</code > es hardware </li><li><code>watchedValue4</code> es Estado </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>Watched_Value1</code> ist der Aktivstatus</li><li><code>Watched_Value2</code> ist der Hostname</li><li><code>Watched_Value3</code> ist die Hardware</li><li><code>Watched_Value4</code> ist der Zustand </li></ul>"
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>watchedValue1</code> ist der Aktivstatus</li><li><code>watchedValue2</code> ist der Hostname</li><li><code>watchedValue3</code> ist die Hardware</li><li><code>watchedValue4</code> ist der Zustand </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -802,7 +802,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -832,15 +832,15 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>Watched_ValueN</code> seleccionadas cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>Watched_ValueN</code>-Spalte hat sich geändert."
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>watchedValueN</code>-Spalte hat sich geändert."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -55,7 +55,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -74,7 +74,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
@@ -93,7 +93,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -112,7 +112,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -131,7 +131,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -150,7 +150,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -169,7 +169,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -188,7 +188,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -207,7 +207,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -226,7 +226,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textbox_save",
|
||||
@@ -245,7 +245,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
@@ -281,7 +281,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -478,17 +478,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"default_value": ["watchedValue1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -504,11 +504,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Domain Name Server</li><li><code>Watched_Value2</code> is IP Offered</li><li><code>Watched_Value3</code> is Interface </li><li><code>Watched_Value4</code> is Router </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Domain Name Server</li><li><code>watchedValue2</code> is IP Offered</li><li><code>watchedValue3</code> is Interface </li><li><code>watchedValue4</code> is Router </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es servidor de nombres de dominio</li><li><code>Watched_Value2</code> es IP ofrecida</li><li><code>Watched_Value3</code> es Interfaz </li><li><code>Watched_Value4</code> es enrutador </li></ul>"
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es servidor de nombres de dominio</li><li><code>watchedValue2</code> es IP ofrecida</li><li><code>watchedValue3</code> es Interfaz </li><li><code>watchedValue4</code> es enrutador </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -519,7 +519,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -540,11 +540,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>Watched_ValueN</code> seleccionadas cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -299,7 +299,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -314,7 +314,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -333,7 +333,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -352,7 +352,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -367,7 +367,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -382,7 +382,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -397,7 +397,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -412,7 +412,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -376,7 +376,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -393,7 +393,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -411,7 +411,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -429,7 +429,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -447,7 +447,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -465,7 +465,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -483,7 +483,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -521,7 +521,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -538,7 +538,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -555,7 +555,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -364,7 +364,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -381,7 +381,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -399,7 +399,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -417,7 +417,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -434,7 +434,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -451,7 +451,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -468,7 +468,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -506,7 +506,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -523,7 +523,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -540,7 +540,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -324,17 +324,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"default_value": ["watchedValue1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -354,11 +354,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Previous IP (not recommended)</li><li><code>Watched_Value2</code> unused</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> type </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Previous IP (not recommended)</li><li><code>watchedValue2</code> unused</li><li><code>watchedValue3</code> unused </li><li><code>watchedValue4</code> type </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>Watched_Value1</code> ist die Vorige IP (nicht empfohlen)</li><li><code>Watched_Value2</code> ist nicht in Verwendung</li><li><code>Watched_Value3</code> ist nicht in Verwendung </li><li><code>Watched_Value4</code> ist nicht in Verwendung </li></ul>"
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>watchedValue1</code> ist die Vorige IP (nicht empfohlen)</li><li><code>watchedValue2</code> ist nicht in Verwendung</li><li><code>watchedValue3</code> ist nicht in Verwendung </li><li><code>watchedValue4</code> ist nicht in Verwendung </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -369,7 +369,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -399,15 +399,15 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>Watched_ValueN</code> seleccionadas cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>Watched_ValueN</code>-Spalte hat sich geändert."
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>watchedValueN</code>-Spalte hat sich geändert."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -478,7 +478,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -493,7 +493,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -517,7 +517,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -541,7 +541,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -560,7 +560,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textarea_readonly",
|
||||
@@ -575,7 +575,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -590,7 +590,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
@@ -633,7 +633,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -656,7 +656,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"mapped_to_column": "scanLastConnection",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -680,7 +680,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## Overview
|
||||
|
||||
A plugin allowing for executing regular internet speed tests.
|
||||
A plugin allowing for executing regular internet speed tests.
|
||||
|
||||
### Usage
|
||||
|
||||
@@ -43,9 +43,9 @@ Inside the container, a Python version of speedtest often exists in the virtual
|
||||
|
||||
### Data Mapping
|
||||
|
||||
- **Watched_Value1** — Download Speed (Mbps).
|
||||
- **Watched_Value2** — Upload Speed (Mbps).
|
||||
- **Watched_Value3** — Full JSON payload (useful for n8n or detailed webhooks).
|
||||
- **watchedValue1** — Download Speed (Mbps).
|
||||
- **watchedValue2** — Upload Speed (Mbps).
|
||||
- **watchedValue3** — Full JSON payload (useful for n8n or detailed webhooks).
|
||||
|
||||
### Notes
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"params": [],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -54,7 +54,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -77,7 +77,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "url",
|
||||
@@ -96,7 +96,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -119,7 +119,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -138,7 +138,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -161,7 +161,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "threshold",
|
||||
@@ -197,7 +197,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "threshold",
|
||||
@@ -233,7 +233,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -256,7 +256,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -279,7 +279,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -302,7 +302,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "replace",
|
||||
@@ -342,7 +342,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -561,17 +561,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -591,15 +591,15 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Download speed (not recommended)</li><li><code>Watched_Value2</code> is Upload speed (not recommended)</li><li><code>Watched_Value3</code> is JSON payload for webhooks (schema varies by engine)</li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Download speed (not recommended)</li><li><code>watchedValue2</code> is Upload speed (not recommended)</li><li><code>watchedValue3</code> is JSON payload for webhooks (schema varies by engine)</li><li><code>watchedValue4</code> unused </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Use <code>CTRL + Clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es la velocidad de descarga (no recomendado)</li><li><code>Watched_Value2</code> es la velocidad de carga (no recomendado)</li><li><code>Watched_Value3</code> es la carga útil JSON para webhooks (el esquema varía según el motor)</li><li><code>Watched_Value4</code> no se usa </li></ul>"
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Use <code>CTRL + Clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es la velocidad de descarga (no recomendado)</li><li><code>watchedValue2</code> es la velocidad de carga (no recomendado)</li><li><code>watchedValue3</code> es la carga útil JSON para webhooks (el esquema varía según el motor)</li><li><code>watchedValue4</code> no se usa </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>Watched_Value1</code> ist die Download-Geschwindigkeit (nicht empfohlen)</li><li><code>Watched_Value2</code> ist die Upload-Geschwindigkeit (nicht empfohlen)</li><li><code>Watched_Value3</code> ist JSON-Payload für Webhooks (Schema variiert je nach Engine)</li><li><code>Watched_Value4</code> ist nicht in Verwendung </li></ul>"
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>watchedValue1</code> ist die Download-Geschwindigkeit (nicht empfohlen)</li><li><code>watchedValue2</code> ist die Upload-Geschwindigkeit (nicht empfohlen)</li><li><code>watchedValue3</code> ist JSON-Payload für Webhooks (Schema variiert je nach Engine)</li><li><code>watchedValue4</code> ist nicht in Verwendung </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -610,7 +610,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -640,15 +640,15 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que seleccionó <code>Watched_ValueN Las columnas </code> cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>Watched_ValueN</code>-Spalte hat sich geändert."
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>watchedValueN</code>-Spalte hat sich geändert."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -273,7 +273,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -290,7 +290,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -308,7 +308,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -326,7 +326,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -344,7 +344,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -362,7 +362,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -380,7 +380,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -418,7 +418,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -435,7 +435,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -452,7 +452,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -450,7 +450,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -469,7 +469,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -489,7 +489,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -509,7 +509,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -528,7 +528,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -571,7 +571,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -590,7 +590,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -609,7 +609,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -351,7 +351,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -382,7 +382,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -398,7 +398,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
@@ -413,7 +413,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -429,7 +429,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -444,7 +444,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -459,7 +459,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "HelpVal1",
|
||||
"column": "helpVal1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -493,7 +493,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -512,7 +512,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -299,7 +299,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -314,7 +314,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -333,7 +333,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -352,7 +352,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -367,7 +367,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -382,7 +382,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -397,7 +397,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -412,7 +412,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -290,10 +290,10 @@
|
||||
},
|
||||
"default_value": [],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": [
|
||||
"name",
|
||||
@@ -316,15 +316,15 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Name</li><li><code>Watched_Value2</code> is Vendor</li><li><code>Watched_Value3</code> is Interface </li><li><code>Watched_Value4</code> is N/A </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Name</li><li><code>watchedValue2</code> is Vendor</li><li><code>watchedValue3</code> is Interface </li><li><code>watchedValue4</code> is N/A </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envía una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Valor_observado1</code> es Name</li><li><code>Valor_observado2</code> es Proveedor</li><li><code>Valor_observado3</code> es Interfaz </li><li><code>Valor_observado4</code> es N/A </li></ul>"
|
||||
"string": "Envía una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es Name</li><li><code>watchedValue2</code> es Proveedor</li><li><code>watchedValue3</code> es Interfaz </li><li><code>watchedValue4</code> es N/A </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>Watched_Value1</code> ist der Namen</li><li><code>Watched_Value2</code> ist der Hersteller</li><li><code>Watched_Value3</code> ist das Interface </li><li><code>Watched_Value4</code> ist nicht in Verwendung </li></ul>"
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>watchedValue1</code> ist der Namen</li><li><code>watchedValue2</code> ist der Hersteller</li><li><code>watchedValue3</code> ist das Interface </li><li><code>watchedValue4</code> ist nicht in Verwendung </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -522,7 +522,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -539,7 +539,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -557,7 +557,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -575,7 +575,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -593,7 +593,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -619,7 +619,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanLastQuery",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -670,7 +670,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -695,7 +695,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -720,7 +720,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -87,7 +87,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -102,7 +102,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -121,7 +121,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -140,7 +140,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -159,7 +159,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -178,7 +178,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -197,7 +197,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -215,7 +215,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "regex.url_http_https",
|
||||
@@ -239,7 +239,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -258,7 +258,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -277,7 +277,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "textbox_save",
|
||||
@@ -315,7 +315,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
@@ -553,17 +553,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"default_value": ["watchedValue1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -579,11 +579,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is service type (e.g.: http, ssh)</li><li><code>Watched_Value2</code> is Status (open or closed)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is service type (e.g.: http, ssh)</li><li><code>watchedValue2</code> is Status (open or closed)</li><li><code>watchedValue3</code> unused </li><li><code>watchedValue4</code> unused </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es el tipo de servicio (p. ej., http, ssh)</li><li><code>Watched_Value2</code> es el estado (abierto o cerrado)</li> <li><code>Watched_Value3</code> no utilizado </li><li><code>Watched_Value4</code> no utilizado </li></ul>"
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es el tipo de servicio (p. ej., http, ssh)</li><li><code>watchedValue2</code> es el estado (abierto o cerrado)</li> <li><code>watchedValue3</code> no utilizado </li><li><code>watchedValue4</code> no utilizado </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -594,7 +594,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -615,11 +615,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que seleccionó <code>Watched_ValueN Las columnas </code> cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@ The following notification types are available based on the `NTFPRCS_INCLUDED_SE
|
||||
- Notifies about specific events triggered by a device.
|
||||
- The device must have **Alert Events** enabled in its settings.
|
||||
- Includes events:
|
||||
- `Connected`, `Down Reconnected`, `Disconnected`,`IP Changed`
|
||||
- `Connected`, `Down Reconnected`, `Disconnected`,`IP Changed`
|
||||
- you can exclude devices with a custom where condition via the `NTFPRCS_event_condition` setting
|
||||
|
||||
### `plugins`
|
||||
- Notifies when an event is triggered by a plugin.
|
||||
- These notifications depend on the plugin's configuration of the `Watched_Value1-4` values and the `<plugin>_REPORT_ON` settings.
|
||||
- These notifications depend on the plugin's configuration of the `watchedValue1-4` values and the `<plugin>_REPORT_ON` settings.
|
||||
|
||||
## Device-Specific Overrides
|
||||
|
||||
|
||||
@@ -180,6 +180,150 @@
|
||||
"string": "You can specify a SQL where condition to filter out Events from notifications. For example <code>AND devLastIP NOT LIKE '192.168.3.%'</code> will always exclude any Event notifications for all devices with the IP starting with <code>192.168.3.%</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "TEXT_SECTION_HEADERS",
|
||||
"type": {
|
||||
"dataType": "boolean",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [{ "type": "checkbox" }], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": true,
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Text Section Headers"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Enable or disable section titles (e.g. <code>🆕 New devices \\n---------</code>) in text notifications. Enabled by default for backward compatibility."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "TEXT_TEMPLATE_new_devices",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Text Template: New Devices"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Custom text template for new device notifications. Use <code>{FieldName}</code> placeholders, e.g. <code>{devName} ({eveMac}) - {eveIp}</code>. Leave empty for default formatting. Available fields: <code>{devName}</code>, <code>{eveMac}</code>, <code>{devVendor}</code>, <code>{eveIp}</code>, <code>{eveDateTime}</code>, <code>{eveEventType}</code>, <code>{devComments}</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "TEXT_TEMPLATE_down_devices",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Text Template: Down Devices"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Custom text template for down device notifications. Use <code>{FieldName}</code> placeholders, e.g. <code>{devName} ({eveMac}) - {eveIp}</code>. Leave empty for default formatting. Available fields: <code>{devName}</code>, <code>{eveMac}</code>, <code>{devVendor}</code>, <code>{eveIp}</code>, <code>{eveDateTime}</code>, <code>{eveEventType}</code>, <code>{devComments}</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "TEXT_TEMPLATE_down_reconnected",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Text Template: Reconnected"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Custom text template for reconnected device notifications. Use <code>{FieldName}</code> placeholders, e.g. <code>{devName} ({eveMac}) reconnected at {eveDateTime}</code>. Leave empty for default formatting. Available fields: <code>{devName}</code>, <code>{eveMac}</code>, <code>{devVendor}</code>, <code>{eveIp}</code>, <code>{eveDateTime}</code>, <code>{eveEventType}</code>, <code>{devComments}</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "TEXT_TEMPLATE_events",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Text Template: Events"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Custom text template for event notifications. Use <code>{FieldName}</code> placeholders, e.g. <code>{devName} ({eveMac}) {eveEventType} at {eveDateTime}</code>. Leave empty for default formatting. Available fields: <code>{devName}</code>, <code>{eveMac}</code>, <code>{devVendor}</code>, <code>{eveIp}</code>, <code>{eveDateTime}</code>, <code>{eveEventType}</code>, <code>{devComments}</code>."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"function": "TEXT_TEMPLATE_plugins",
|
||||
"type": {
|
||||
"dataType": "string",
|
||||
"elements": [
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Text Template: Plugins"
|
||||
}
|
||||
],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Custom text template for plugin event notifications. Use <code>{FieldName}</code> placeholders, e.g. <code>{plugin}: {objectPrimaryId} - {status}</code>. Leave empty for default formatting. Available fields: <code>{plugin}</code>, <code>{objectPrimaryId}</code>, <code>{objectSecondaryId}</code>, <code>{dateTimeChanged}</code>, <code>{watchedValue1}</code>, <code>{watchedValue2}</code>, <code>{watchedValue3}</code>, <code>{watchedValue4}</code>, <code>{status}</code>."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"show_ui": true,
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -299,7 +299,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -314,7 +314,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -329,7 +329,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -344,7 +344,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -359,7 +359,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -374,7 +374,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -393,7 +393,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -412,7 +412,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -403,7 +403,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Hostname </li><li><code>Watched_Value2</code> is Parent Node </li><li><code>Watched_Value3</code> is Port </li><li><code>Watched_Value4</code> is SSID </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Hostname </li><li><code>watchedValue2</code> is Parent Node </li><li><code>watchedValue3</code> is Port </li><li><code>watchedValue4</code> is SSID </li></ul>"
|
||||
}
|
||||
],
|
||||
"function": "WATCH",
|
||||
@@ -419,17 +419,17 @@
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -440,7 +440,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
}
|
||||
],
|
||||
"function": "REPORT_ON",
|
||||
@@ -462,7 +462,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -542,7 +542,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -557,7 +557,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -581,7 +581,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -605,7 +605,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -621,7 +621,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanParentMAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -637,7 +637,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanParentPort",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -653,7 +653,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"mapped_to_column": "scanSSID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -669,7 +669,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
@@ -712,7 +712,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -735,7 +735,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -758,7 +758,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -319,7 +319,7 @@ def main():
|
||||
# make sure the below mapping is mapped in config.json, for example:
|
||||
# "database_column_definitions": [
|
||||
# {
|
||||
# "column": "Object_PrimaryID", <--------- the value I save into primaryId
|
||||
# "column": "objectPrimaryId", <--------- the value I save into primaryId
|
||||
# "mapped_to_column": "scanMac", <--------- gets unserted into the CurrentScan DB table column scanMac
|
||||
# watched1 = 'null' ,
|
||||
# figure a way to run my udpate script delayed
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -380,7 +380,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Device Name </li><li><code>Watched_Value2</code> is Parent Node MAC</li><li><code>Watched_Value3</code> is Parent Node Port </li><li><code>Watched_Value4</code> is Parent Node SSID </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Device Name </li><li><code>watchedValue2</code> is Parent Node MAC</li><li><code>watchedValue3</code> is Parent Node Port </li><li><code>watchedValue4</code> is Parent Node SSID </li></ul>"
|
||||
}
|
||||
],
|
||||
"function": "WATCH",
|
||||
@@ -392,17 +392,17 @@
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -413,7 +413,7 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
}
|
||||
],
|
||||
"function": "REPORT_ON",
|
||||
@@ -435,7 +435,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -517,7 +517,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -532,7 +532,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -548,7 +548,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -564,7 +564,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -580,7 +580,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanParentMAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -596,7 +596,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanParentPort",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -612,7 +612,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"mapped_to_column": "scanSSID",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -628,7 +628,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
@@ -663,7 +663,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -678,7 +678,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -693,7 +693,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "HelpVal1",
|
||||
"column": "helpVal1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -708,7 +708,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "HelpVal2",
|
||||
"column": "helpVal2",
|
||||
"mapped_to_column": "scanSite",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -724,7 +724,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "HelpVal3",
|
||||
"column": "helpVal3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -441,7 +441,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -456,7 +456,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -472,7 +472,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -488,7 +488,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -504,7 +504,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -520,7 +520,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -535,7 +535,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -569,7 +569,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -584,7 +584,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -599,7 +599,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -105,7 +105,7 @@
|
||||
{ "elementType": "input", "elementOptions": [], "transformers": [] }
|
||||
]
|
||||
},
|
||||
"default_value": "SELECT n.hwaddr AS Object_PrimaryID, {s-quote}null{s-quote} AS Object_SecondaryID, datetime() AS DateTime, na.ip AS Watched_Value1, n.lastQuery AS Watched_Value2, na.name AS Watched_Value3, n.macVendor AS Watched_Value4, {s-quote}null{s-quote} AS Extra, n.hwaddr AS ForeignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE {s-quote}ip-%{s-quote} AND n.hwaddr is not {s-quote}00:00:00:00:00:00{s-quote} AND na.ip is not null",
|
||||
"default_value": "SELECT n.hwaddr AS objectPrimaryId, {s-quote}null{s-quote} AS objectSecondaryId, datetime() AS dateTimeChanged, na.ip AS watchedValue1, n.lastQuery AS watchedValue2, na.name AS watchedValue3, n.macVendor AS watchedValue4, {s-quote}null{s-quote} AS extra, n.hwaddr AS foreignKey FROM EXTERNAL_PIHOLE.Network AS n LEFT JOIN EXTERNAL_PIHOLE.Network_Addresses AS na ON na.network_id = n.id WHERE n.hwaddr NOT LIKE {s-quote}ip-%{s-quote} AND n.hwaddr is not {s-quote}00:00:00:00:00:00{s-quote} AND na.ip is not null",
|
||||
"options": [],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -290,17 +290,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1", "Watched_Value2"],
|
||||
"default_value": ["watchedValue1", "watchedValue2"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -316,11 +316,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is IP</li><li><code>Watched_Value2</code> is Last Query</li><li><code>Watched_Value3</code> is Name </li><li><code>Watched_Value4</code> is N/A </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is IP</li><li><code>watchedValue2</code> is Last Query</li><li><code>watchedValue3</code> is Name </li><li><code>watchedValue4</code> is N/A </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es IP</li><li><code>Watched_Value2</code> es Proveedor</li><li><code>Watched_Value3</code> is es Interfaz</li><li><code>Watched_Value4</code> es N/A</li></ul>"
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es IP</li><li><code>watchedValue2</code> es Proveedor</li><li><code>watchedValue3</code> is es Interfaz</li><li><code>watchedValue4</code> es N/A</li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -331,7 +331,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -369,7 +369,7 @@
|
||||
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -384,7 +384,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -404,7 +404,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -419,7 +419,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -439,7 +439,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanLastQuery",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -455,7 +455,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -471,7 +471,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -510,7 +510,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -529,7 +529,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"data_source": "script",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -65,7 +65,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -80,7 +80,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -99,7 +99,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -119,7 +119,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -139,7 +139,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"mapped_to_column": "scanLastConnection",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -159,7 +159,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -179,7 +179,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -198,7 +198,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -217,7 +217,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -236,7 +236,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -255,7 +255,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -297,7 +297,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
@@ -658,17 +658,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"default_value": ["watchedValue1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -684,11 +684,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Hostname (not discoverable) </li><li><code>Watched_Value2</code> is Router IP </li><li><code>Watched_Value3</code> is not used </li><li><code>Watched_Value4</code> is not used </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Hostname (not discoverable) </li><li><code>watchedValue2</code> is Router IP </li><li><code>watchedValue3</code> is not used </li><li><code>watchedValue4</code> is not used </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es el nombre de host (no detectable) </li><li><code>Watched_Value2</code> es la IP del enrutador </li><li><code>Watched_Value3< /code> no se utiliza </li><li><code>Watched_Value4</code> no se utiliza </li></ul>"
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es el nombre de host (no detectable) </li><li><code>watchedValue2</code> es la IP del enrutador </li><li><code>watchedValue3</code> no se utiliza </li><li><code>watchedValue4</code> no se utiliza </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -699,7 +699,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -725,11 +725,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>Watched_ValueN</code> seleccionadas cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -667,7 +667,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -684,7 +684,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -710,7 +710,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -736,7 +736,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -754,7 +754,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -772,7 +772,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanSyncHubNode",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -790,7 +790,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -836,7 +836,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -861,7 +861,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -886,7 +886,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -222,27 +222,30 @@ def main():
|
||||
extra = '',
|
||||
foreignKey = device['devGUID'])
|
||||
|
||||
# Resolve the actual columns that exist in the Devices table once.
|
||||
# This automatically excludes computed/virtual fields (e.g. devStatus,
|
||||
# devIsSleeping) and 'rowid' without needing a maintained exclusion list.
|
||||
cursor.execute("PRAGMA table_info(Devices)")
|
||||
db_columns = {row[1] for row in cursor.fetchall()}
|
||||
|
||||
# Filter out existing devices
|
||||
new_devices = [device for device in device_data if device['devMac'] not in existing_mac_addresses]
|
||||
|
||||
# Remove 'rowid' key if it exists
|
||||
for device in new_devices:
|
||||
device.pop('rowid', None)
|
||||
device.pop('devStatus', None)
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] All devices: "{len(device_data)}"'])
|
||||
mylog('verbose', [f'[{pluginName}] New devices: "{len(new_devices)}"'])
|
||||
|
||||
# Prepare the insert statement
|
||||
if new_devices:
|
||||
|
||||
# creating insert statement, removing 'rowid', 'devStatus' as handled on the target and devStatus is resolved on the fly
|
||||
columns = ', '.join(k for k in new_devices[0].keys() if k not in ['rowid', 'devStatus'])
|
||||
placeholders = ', '.join('?' for k in new_devices[0] if k not in ['rowid', 'devStatus'])
|
||||
# Only keep keys that are real columns in the target DB; computed
|
||||
# or unknown fields are silently dropped regardless of source schema.
|
||||
insert_cols = [k for k in new_devices[0].keys() if k in db_columns]
|
||||
columns = ', '.join(insert_cols)
|
||||
placeholders = ', '.join('?' for _ in insert_cols)
|
||||
sql = f'INSERT INTO Devices ({columns}) VALUES ({placeholders})'
|
||||
|
||||
# Extract values for the new devices
|
||||
values = [tuple(device.values()) for device in new_devices]
|
||||
# Extract only the whitelisted column values for each device
|
||||
values = [tuple(device.get(col) for col in insert_cols) for device in new_devices]
|
||||
|
||||
mylog('verbose', [f'[{pluginName}] Inserting Devices SQL : "{sql}"'])
|
||||
mylog('verbose', [f'[{pluginName}] Inserting Devices VALUES: "{values}"'])
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"mapped_to_table": "CurrentScan",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -569,7 +569,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -586,7 +586,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": true,
|
||||
@@ -604,7 +604,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -622,7 +622,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -640,7 +640,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -658,7 +658,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -675,7 +675,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"mapped_to_column": "scanParentMAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -714,7 +714,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -731,7 +731,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -748,7 +748,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
],
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
"compare_operator": "==",
|
||||
@@ -81,7 +81,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -96,7 +96,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -119,7 +119,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -143,7 +143,7 @@
|
||||
"type": "device_mac"
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -167,7 +167,7 @@
|
||||
"type": "device_ip"
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -190,7 +190,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -214,7 +214,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -238,7 +238,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
@@ -262,7 +262,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"mapped_to_column": "scanType",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
@@ -286,7 +286,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -309,7 +309,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -359,7 +359,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -382,7 +382,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "HelpVal1",
|
||||
"column": "helpVal1",
|
||||
"mapped_to_column": "scanParentMAC",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
@@ -398,7 +398,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "HelpVal2",
|
||||
"column": "helpVal2",
|
||||
"mapped_to_column": "scanParentPort",
|
||||
"css_classes": "col-sm-2",
|
||||
"default_value": "",
|
||||
@@ -414,7 +414,7 @@
|
||||
"type": "label"
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"default_value": "",
|
||||
"localized": ["name"],
|
||||
@@ -992,15 +992,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"default_value": ["Watched_Value1", "Watched_Value4"],
|
||||
"default_value": ["watchedValue1", "watchedValue4"],
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Hostname </li><li><code>Watched_Value2</code> is Vendor </li><li><code>Watched_Value3</code> is Type </li><li><code>Watched_Value4</code> is Online </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is Hostname </li><li><code>watchedValue2</code> is Vendor </li><li><code>watchedValue3</code> is Type </li><li><code>watchedValue4</code> is Online </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es el nombre de host </li><li><code>Watched_Value2</code> es el proveedor </li><li><code>Watched_Value3</code> es el tipo </li><li><code>Watched_Value4</code> es Online </li></ul>"
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Utilice <code>CTRL + clic</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es el nombre de host </li><li><code>watchedValue2</code> es el proveedor </li><li><code>watchedValue3</code> es el tipo </li><li><code>watchedValue4</code> es Online </li></ul>"
|
||||
}
|
||||
],
|
||||
"function": "WATCH",
|
||||
@@ -1016,17 +1016,17 @@
|
||||
}
|
||||
],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"type": {
|
||||
"dataType": "array",
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -1037,11 +1037,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>Watched_ValueN</code> seleccionadas cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (una combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
}
|
||||
],
|
||||
"function": "REPORT_ON",
|
||||
@@ -1067,7 +1067,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
|
||||
@@ -299,17 +299,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"default_value": ["watchedValue1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -329,11 +329,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is vendor name</li><li><code>Watched_Value2</code> is device name</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is vendor name</li><li><code>watchedValue2</code> is device name</li><li><code>watchedValue3</code> unused </li><li><code>watchedValue4</code> unused </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>Watched_Value1</code> ist der Herstellername</li><li><code>Watched_Value2</code> ist der Gerätename</li><li><code>Watched_Value3</code> ist nicht in Verwendung </li><li><code>Watched_Value4</code> ist nicht in Verwendung </li></ul>"
|
||||
"string": "Sende eine Benachrichtigung, wenn ein ausgwählter Wert sich ändert. <code>STRG + klicken</code> zum aus-/abwählen. <ul> <li><code>watchedValue1</code> ist der Herstellername</li><li><code>watchedValue2</code> ist der Gerätename</li><li><code>watchedValue3</code> ist nicht in Verwendung </li><li><code>watchedValue4</code> ist nicht in Verwendung </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -344,7 +344,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -374,22 +374,22 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que seleccionó <code>Watched_ValueN Las columnas </code> cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que las columnas <code>watchedValueN</code> seleccionadas cambiaron."
|
||||
},
|
||||
{
|
||||
"language_code": "de_de",
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>Watched_ValueN</code>-Spalte hat sich geändert."
|
||||
"string": "Benachrichtige nur bei diesen Status. <code>new</code> bedeutet ein neues eindeutiges (einzigartige Kombination aus PrimaryId und SecondaryId) Objekt wurde erkennt. <code>watched-changed</code> bedeutet eine ausgewählte <code>watchedValueN</code>-Spalte hat sich geändert."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -404,7 +404,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -427,7 +427,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"mapped_to_column": "scanMac",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -451,7 +451,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"mapped_to_column": "scanLastIP",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -475,7 +475,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -498,7 +498,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"mapped_to_column": "scanLastConnection",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -549,7 +549,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"mapped_to_column": "scanVendor",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -569,7 +569,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"mapped_to_column": "scanName",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
@@ -593,7 +593,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -612,7 +612,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -631,7 +631,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "textbox_save",
|
||||
@@ -654,7 +654,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -673,7 +673,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"data_source": "script",
|
||||
"data_filters": [
|
||||
{
|
||||
"compare_column": "Object_PrimaryID",
|
||||
"compare_column": "objectPrimaryId",
|
||||
"compare_operator": "==",
|
||||
"compare_field_id": "txtMacFilter",
|
||||
"compare_js_template": "'{value}'.toString()",
|
||||
@@ -356,7 +356,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -371,7 +371,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_name_mac",
|
||||
@@ -386,7 +386,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "device_ip",
|
||||
@@ -401,7 +401,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -416,7 +416,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -431,7 +431,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -446,7 +446,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -476,7 +476,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -491,7 +491,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -506,7 +506,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
],
|
||||
"database_column_definitions": [
|
||||
{
|
||||
"column": "Index",
|
||||
"column": "index",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "none",
|
||||
@@ -66,7 +66,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Plugin",
|
||||
"column": "plugin",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -85,7 +85,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_PrimaryID",
|
||||
"column": "objectPrimaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "url",
|
||||
@@ -104,7 +104,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Object_SecondaryID",
|
||||
"column": "objectSecondaryId",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -123,7 +123,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeCreated",
|
||||
"column": "dateTimeCreated",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -142,7 +142,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "DateTimeChanged",
|
||||
"column": "dateTimeChanged",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -161,7 +161,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value1",
|
||||
"column": "watchedValue1",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "threshold",
|
||||
@@ -201,7 +201,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value2",
|
||||
"column": "watchedValue2",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "label",
|
||||
@@ -220,7 +220,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value3",
|
||||
"column": "watchedValue3",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -239,7 +239,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Watched_Value4",
|
||||
"column": "watchedValue4",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -258,7 +258,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "UserData",
|
||||
"column": "userData",
|
||||
"css_classes": "col-sm-2",
|
||||
"show": true,
|
||||
"type": "textbox_save",
|
||||
@@ -277,7 +277,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Status",
|
||||
"column": "status",
|
||||
"css_classes": "col-sm-1",
|
||||
"show": true,
|
||||
"type": "replace",
|
||||
@@ -313,7 +313,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"column": "Extra",
|
||||
"column": "extra",
|
||||
"css_classes": "col-sm-3",
|
||||
"show": false,
|
||||
"type": "label",
|
||||
@@ -538,17 +538,17 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_value": ["Watched_Value1"],
|
||||
"default_value": ["watchedValue1"],
|
||||
"options": [
|
||||
"Watched_Value1",
|
||||
"Watched_Value2",
|
||||
"Watched_Value3",
|
||||
"Watched_Value4"
|
||||
"watchedValue1",
|
||||
"watchedValue2",
|
||||
"watchedValue3",
|
||||
"watchedValue4"
|
||||
],
|
||||
"localized": ["name", "description"],
|
||||
"name": [
|
||||
@@ -564,11 +564,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is response status code (e.g.: 200, 404)</li><li><code>Watched_Value2</code> is Latency (not recommended)</li><li><code>Watched_Value3</code> unused </li><li><code>Watched_Value4</code> unused </li></ul>"
|
||||
"string": "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>watchedValue1</code> is response status code (e.g.: 200, 404)</li><li><code>watchedValue2</code> is Latency (not recommended)</li><li><code>watchedValue3</code> unused </li><li><code>watchedValue4</code> unused </li></ul>"
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Use <code>CTRL + Click</code> para seleccionar/deseleccionar. <ul> <li><code>Watched_Value1</code> es un código de estado de respuesta (por ejemplo: 200, 404) </li><li><code>Valor_observado2</code> es Latencia (no recomendado)</li><li><code>Valor_observado3</code> no utilizado </li><li><code>Valor_observado4 </ code> sin usar </li></ul>"
|
||||
"string": "Envíe una notificación si los valores seleccionados cambian. Use <code>CTRL + Click</code> para seleccionar/deseleccionar. <ul> <li><code>watchedValue1</code> es un código de estado de respuesta (por ejemplo: 200, 404) </li><li><code>watchedValue2</code> es Latencia (no recomendado)</li><li><code>watchedValue3</code> no utilizado </li><li><code>watchedValue4</code> sin usar </li></ul>"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -579,7 +579,7 @@
|
||||
"elements": [
|
||||
{
|
||||
"elementType": "select",
|
||||
"elementOptions": [{ "multiple": "true" }],
|
||||
"elementOptions": [{ "multiple": "true", "ordeable": "true"}],
|
||||
"transformers": []
|
||||
}
|
||||
]
|
||||
@@ -605,11 +605,11 @@
|
||||
"description": [
|
||||
{
|
||||
"language_code": "en_us",
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>Watched_ValueN</code> columns changed."
|
||||
"string": "Send a notification only on these statuses. <code>new</code> means a new unique (unique combination of objectPrimaryId and objectSecondaryId) object was discovered. <code>watched-changed</code> means that selected <code>watchedValueN</code> columns changed."
|
||||
},
|
||||
{
|
||||
"language_code": "es_es",
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que seleccionó <code>Watched_ValueN Las columnas </code> cambiaron."
|
||||
"string": "Envíe una notificación solo en estos estados. <code>new</code> significa que se descubrió un nuevo objeto único (combinación única de PrimaryId y SecondaryId). <code>watched-changed</code> significa que seleccionó <code>watchedValueN Las columnas </code> cambiaron."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -246,9 +246,9 @@ function genericSaveData (id) {
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
data: JSON.stringify({
|
||||
dbtable: "Plugins_Objects",
|
||||
columnName: "Index",
|
||||
columnName: "index",
|
||||
id: index,
|
||||
columns: "UserData",
|
||||
columns: "userData",
|
||||
values: columnValue
|
||||
}),
|
||||
contentType: "application/json",
|
||||
@@ -273,26 +273,23 @@ function genericSaveData (id) {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
pluginDefinitions = []
|
||||
pluginUnprocessedEvents = []
|
||||
pluginObjects = []
|
||||
pluginHistory = []
|
||||
|
||||
// Global counts map, populated before tabs are rendered.
|
||||
// null = counts unavailable (fail-open: show all plugins)
|
||||
let pluginCounts = null;
|
||||
|
||||
async function getData() {
|
||||
try {
|
||||
showSpinner();
|
||||
console.log("Plugins getData called");
|
||||
|
||||
const [plugins, events, objects, history] = await Promise.all([
|
||||
fetchJson('plugins.json'),
|
||||
fetchJson('table_plugins_events.json'),
|
||||
fetchJson('table_plugins_objects.json'),
|
||||
fetchJson('table_plugins_history.json')
|
||||
]);
|
||||
|
||||
const plugins = await fetchJson('plugins.json');
|
||||
pluginDefinitions = plugins.data;
|
||||
pluginUnprocessedEvents = events.data;
|
||||
pluginObjects = objects.data;
|
||||
pluginHistory = history.data;
|
||||
|
||||
// Fetch counts BEFORE rendering tabs so we can skip empty plugins (no flicker).
|
||||
// fetchPluginCounts never throws — returns null on failure (fail-open).
|
||||
const prefixes = pluginDefinitions.filter(p => p.show_ui).map(p => p.unique_prefix);
|
||||
pluginCounts = await fetchPluginCounts(prefixes);
|
||||
|
||||
generateTabs();
|
||||
} catch (err) {
|
||||
@@ -306,6 +303,169 @@ async function fetchJson(filename) {
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
// GraphQL helper — fires a paginated plugin table query and calls back with
|
||||
// the DataTables-compatible response plus the raw GraphQL result object.
|
||||
function postPluginGraphQL(gqlField, prefix, foreignKey, dtRequest, callback) {
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const apiBase = getApiBase();
|
||||
const page = Math.floor(dtRequest.start / dtRequest.length) + 1;
|
||||
const limit = dtRequest.length;
|
||||
const search = dtRequest.search?.value || null;
|
||||
|
||||
let sort = [];
|
||||
if (dtRequest.order?.length > 0) {
|
||||
const order = dtRequest.order[0];
|
||||
sort.push({ field: dtRequest.columns[order.column].data, order: order.dir });
|
||||
}
|
||||
|
||||
const query = `
|
||||
query PluginData($options: PluginQueryOptionsInput) {
|
||||
${gqlField}(options: $options) {
|
||||
count
|
||||
dbCount
|
||||
entries {
|
||||
index plugin objectPrimaryId objectSecondaryId
|
||||
dateTimeCreated dateTimeChanged
|
||||
watchedValue1 watchedValue2 watchedValue3 watchedValue4
|
||||
status extra userData foreignKey
|
||||
syncHubNodeName helpVal1 helpVal2 helpVal3 helpVal4 objectGuid
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: `${apiBase}/graphql`,
|
||||
headers: { "Authorization": `Bearer ${apiToken}`, "Content-Type": "application/json" },
|
||||
data: JSON.stringify({
|
||||
query,
|
||||
variables: { options: { page, limit, search, sort, plugin: prefix, foreignKey } }
|
||||
}),
|
||||
success: function(response) {
|
||||
if (response.errors) {
|
||||
console.error("[plugins] GraphQL errors:", response.errors);
|
||||
callback({ data: [], recordsTotal: 0, recordsFiltered: 0 });
|
||||
return;
|
||||
}
|
||||
const result = response.data[gqlField];
|
||||
callback({ data: result.entries, recordsTotal: result.dbCount, recordsFiltered: result.count }, result);
|
||||
},
|
||||
error: function() {
|
||||
callback({ data: [], recordsTotal: 0, recordsFiltered: 0 });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch counts for all plugins. Returns { PREFIX: { objects, events, history } }
|
||||
// or null on failure (fail-open so tabs still render).
|
||||
// Unfiltered: static JSON (~1KB pre-computed).
|
||||
// MAC-filtered: lightweight REST endpoint (single SQL query).
|
||||
async function fetchPluginCounts(prefixes) {
|
||||
if (prefixes.length === 0) return {};
|
||||
|
||||
const mac = $("#txtMacFilter").val();
|
||||
const foreignKey = (mac && mac !== "--") ? mac : null;
|
||||
|
||||
try {
|
||||
let counts = {};
|
||||
let rows;
|
||||
|
||||
if (!foreignKey) {
|
||||
// ---- FAST PATH: pre-computed static JSON ----
|
||||
const stats = await fetchJson('table_plugins_stats.json');
|
||||
rows = stats.data;
|
||||
} else {
|
||||
// ---- MAC-FILTERED PATH: single SQL via REST endpoint ----
|
||||
const apiToken = getSetting("API_TOKEN");
|
||||
const apiBase = getApiBase();
|
||||
const response = await $.ajax({
|
||||
method: "GET",
|
||||
url: `${apiBase}/plugins/stats?foreignKey=${encodeURIComponent(foreignKey)}`,
|
||||
headers: { "Authorization": `Bearer ${apiToken}` },
|
||||
});
|
||||
if (!response.success) {
|
||||
console.error("[plugins] /plugins/stats error:", response.error);
|
||||
return null;
|
||||
}
|
||||
rows = response.data;
|
||||
}
|
||||
|
||||
for (const row of rows) {
|
||||
const p = row.tableName; // 'objects' | 'events' | 'history'
|
||||
const plugin = row.plugin;
|
||||
if (!counts[plugin]) counts[plugin] = { objects: 0, events: 0, history: 0 };
|
||||
counts[plugin][p] = row.cnt;
|
||||
}
|
||||
return counts;
|
||||
} catch (err) {
|
||||
console.error('[plugins] fetchPluginCounts failed (fail-open):', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply pre-fetched counts to the DOM badges and hide empty tabs/sub-tabs.
|
||||
function applyPluginBadges(counts, prefixes) {
|
||||
// Update DOM badges
|
||||
for (const [prefix, c] of Object.entries(counts)) {
|
||||
$(`#badge_${prefix}`).text(c.objects);
|
||||
$(`#objCount_${prefix}`).text(c.objects);
|
||||
$(`#evtCount_${prefix}`).text(c.events);
|
||||
$(`#histCount_${prefix}`).text(c.history);
|
||||
}
|
||||
// Zero out plugins with no rows in any table
|
||||
prefixes.forEach(prefix => {
|
||||
if (!counts[prefix]) {
|
||||
$(`#badge_${prefix}`).text(0);
|
||||
$(`#objCount_${prefix}`).text(0);
|
||||
$(`#evtCount_${prefix}`).text(0);
|
||||
$(`#histCount_${prefix}`).text(0);
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-hide sub-tabs with zero results (outer tabs already excluded during creation)
|
||||
autoHideEmptyTabs(counts, prefixes);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Within visible plugins, hide inner sub-tabs (Objects/Events/History) whose count is 0.
|
||||
// Outer plugin tabs with zero total are already excluded during tab creation.
|
||||
function autoHideEmptyTabs(counts, prefixes) {
|
||||
prefixes.forEach(prefix => {
|
||||
const c = counts[prefix] || { objects: 0, events: 0, history: 0 };
|
||||
const $pane = $(`#tabs-content-location > #${prefix}`);
|
||||
|
||||
// Hide inner sub-tabs with zero count
|
||||
const subTabs = [
|
||||
{ href: `#objectsTarget_${prefix}`, count: c.objects },
|
||||
{ href: `#eventsTarget_${prefix}`, count: c.events },
|
||||
{ href: `#historyTarget_${prefix}`, count: c.history },
|
||||
];
|
||||
|
||||
let activeSubHidden = false;
|
||||
subTabs.forEach(st => {
|
||||
const $subLi = $pane.find(`ul.nav-tabs li:has(a[href="${st.href}"])`);
|
||||
const $subPane = $pane.find(st.href);
|
||||
if (st.count === 0) {
|
||||
if ($subLi.hasClass('active')) activeSubHidden = true;
|
||||
$subLi.hide();
|
||||
$subPane.removeClass('active').css('display', '');
|
||||
} else {
|
||||
$subLi.show();
|
||||
$subPane.css('display', '');
|
||||
}
|
||||
});
|
||||
|
||||
// If the active inner sub-tab was hidden, activate the first visible one
|
||||
// via Bootstrap's tab lifecycle so shown.bs.tab fires for deferred DataTable init
|
||||
if (activeSubHidden) {
|
||||
const $firstVisibleSubA = $pane.find('ul.nav-tabs li:visible:first a');
|
||||
if ($firstVisibleSubA.length) {
|
||||
$firstVisibleSubA.tab('show');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function generateTabs() {
|
||||
|
||||
@@ -315,18 +475,41 @@ function generateTabs() {
|
||||
// Sort pluginDefinitions by unique_prefix alphabetically
|
||||
pluginDefinitions.sort((a, b) => a.unique_prefix.localeCompare(b.unique_prefix));
|
||||
|
||||
assignActive = true;
|
||||
let assignActive = true;
|
||||
|
||||
// Iterate over the sorted pluginDefinitions to create tab headers and content
|
||||
pluginDefinitions.forEach(pluginObj => {
|
||||
if (pluginObj.show_ui) {
|
||||
stats = createTabContent(pluginObj, assignActive); // Create the content for each tab
|
||||
// When counts are available, skip plugins with 0 total count (no flicker).
|
||||
// When counts are null (fetch failed), show all show_ui plugins (fail-open).
|
||||
const countsAvailable = pluginCounts !== null;
|
||||
const visiblePlugins = pluginDefinitions.filter(pluginObj => {
|
||||
if (!pluginObj.show_ui) return false;
|
||||
if (!countsAvailable) return true; // fail-open: show all
|
||||
const c = pluginCounts[pluginObj.unique_prefix] || { objects: 0, events: 0, history: 0 };
|
||||
return (c.objects + c.events + c.history) > 0;
|
||||
});
|
||||
|
||||
if(stats.objectDataCount > 0)
|
||||
{
|
||||
createTabHeader(pluginObj, stats, assignActive); // Create the header for each tab
|
||||
assignActive = false; // only mark first with content active
|
||||
}
|
||||
// Create tab DOM for visible plugins only
|
||||
visiblePlugins.forEach(pluginObj => {
|
||||
const prefix = pluginObj.unique_prefix;
|
||||
const c = countsAvailable ? (pluginCounts[prefix] || { objects: 0, events: 0, history: 0 }) : null;
|
||||
createTabContent(pluginObj, assignActive, c);
|
||||
createTabHeader(pluginObj, assignActive, c);
|
||||
assignActive = false;
|
||||
});
|
||||
|
||||
// Now that ALL DOM elements exist (both <a> headers and tab panes),
|
||||
// wire up DataTable initialization: immediate for the active tab,
|
||||
// deferred via shown.bs.tab for the rest.
|
||||
let firstVisible = true;
|
||||
visiblePlugins.forEach(pluginObj => {
|
||||
const prefix = pluginObj.unique_prefix;
|
||||
const colDefinitions = getColumnDefinitions(pluginObj);
|
||||
if (firstVisible) {
|
||||
initializeDataTables(prefix, colDefinitions, pluginObj);
|
||||
firstVisible = false;
|
||||
} else {
|
||||
$(`a[href="#${prefix}"]`).one('shown.bs.tab', function() {
|
||||
initializeDataTables(prefix, colDefinitions, pluginObj);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -338,6 +521,12 @@ function generateTabs() {
|
||||
tabContainer: '#tabs-location'
|
||||
});
|
||||
|
||||
// Apply badge counts to the DOM and hide empty inner sub-tabs (only if counts loaded)
|
||||
if (countsAvailable) {
|
||||
const prefixes = visiblePlugins.map(p => p.unique_prefix);
|
||||
applyPluginBadges(pluginCounts, prefixes);
|
||||
}
|
||||
|
||||
hideSpinner()
|
||||
}
|
||||
|
||||
@@ -349,20 +538,18 @@ function resetTabs() {
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// left headers
|
||||
function createTabHeader(pluginObj, stats, assignActive) {
|
||||
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
||||
function createTabHeader(pluginObj, assignActive, counts) {
|
||||
const prefix = pluginObj.unique_prefix;
|
||||
const activeClass = assignActive ? "active" : "";
|
||||
const badgeText = counts ? counts.objects : '…';
|
||||
|
||||
// Determine the active class for the first tab
|
||||
assignActive ? activeClass = "active" : activeClass = "";
|
||||
|
||||
// Append the tab header to the tabs location
|
||||
$('#tabs-location').append(`
|
||||
<li class="left-nav ${activeClass} ">
|
||||
<a class="col-sm-12 textOverflow" href="#${prefix}" data-plugin-prefix="${prefix}" id="${prefix}_id" data-toggle="tab">
|
||||
${getString(`${prefix}_icon`)} ${getString(`${prefix}_display_name`)}
|
||||
|
||||
</a>
|
||||
${stats.objectDataCount > 0 ? `<div class="pluginBadgeWrap"><span title="" class="badge pluginBadge" >${stats.objectDataCount}</span></div>` : ""}
|
||||
<div class="pluginBadgeWrap"><span title="" class="badge pluginBadge" id="badge_${prefix}">${badgeText}</span></div>
|
||||
</li>
|
||||
`);
|
||||
|
||||
@@ -370,23 +557,17 @@ function createTabHeader(pluginObj, stats, assignActive) {
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Content of selected plugin (header)
|
||||
function createTabContent(pluginObj, assignActive) {
|
||||
const prefix = pluginObj.unique_prefix; // Get the unique prefix for the plugin
|
||||
const colDefinitions = getColumnDefinitions(pluginObj); // Get column definitions for DataTables
|
||||
function createTabContent(pluginObj, assignActive, counts) {
|
||||
const prefix = pluginObj.unique_prefix;
|
||||
const colDefinitions = getColumnDefinitions(pluginObj);
|
||||
|
||||
// Get data for events, objects, and history related to the plugin
|
||||
const objectData = getObjectData(prefix, colDefinitions, pluginObj);
|
||||
const eventData = getEventData(prefix, colDefinitions, pluginObj);
|
||||
const historyData = getHistoryData(prefix, colDefinitions, pluginObj);
|
||||
|
||||
// Append the content structure for the plugin's tab to the content location
|
||||
$('#tabs-content-location').append(`
|
||||
<div id="${prefix}" class="tab-pane ${objectData.length > 0 && assignActive? 'active' : ''}">
|
||||
${generateTabNavigation(prefix, objectData.length, eventData.length, historyData.length)} <!-- Create tab navigation -->
|
||||
<div id="${prefix}" class="tab-pane ${assignActive ? 'active' : ''}">
|
||||
${generateTabNavigation(prefix, counts)} <!-- Create tab navigation -->
|
||||
<div class="tab-content">
|
||||
${generateDataTable(prefix, 'Objects', objectData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'Events', eventData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'History', historyData, colDefinitions)}
|
||||
${generateDataTable(prefix, 'Objects', colDefinitions)}
|
||||
${generateDataTable(prefix, 'Events', colDefinitions)}
|
||||
${generateDataTable(prefix, 'History', colDefinitions)}
|
||||
</div>
|
||||
<div class='plugins-description'>
|
||||
${getString(`${prefix}_description`)} <!-- Display the plugin description -->
|
||||
@@ -395,14 +576,7 @@ function createTabContent(pluginObj, assignActive) {
|
||||
</div>
|
||||
`);
|
||||
|
||||
// Initialize DataTables for the respective sections
|
||||
initializeDataTables(prefix, objectData, eventData, historyData, colDefinitions);
|
||||
|
||||
return {
|
||||
"objectDataCount": objectData.length,
|
||||
"eventDataCount": eventData.length,
|
||||
"historyDataCount": historyData.length
|
||||
}
|
||||
// DataTable init is handled by generateTabs() after all DOM elements exist.
|
||||
}
|
||||
|
||||
function getColumnDefinitions(pluginObj) {
|
||||
@@ -410,53 +584,29 @@ function getColumnDefinitions(pluginObj) {
|
||||
return pluginObj["database_column_definitions"].filter(colDef => colDef.show);
|
||||
}
|
||||
|
||||
function getEventData(prefix, colDefinitions, pluginObj) {
|
||||
// Extract event data specific to the plugin and format it for DataTables
|
||||
return pluginUnprocessedEvents
|
||||
.filter(event => event.Plugin === prefix && shouldBeShown(event, pluginObj)) // Filter events for the specific plugin
|
||||
.map(event => colDefinitions.map(colDef => event[colDef.column] || '')); // Map to the defined columns
|
||||
}
|
||||
function generateTabNavigation(prefix, counts) {
|
||||
const objCount = counts ? counts.objects : '…';
|
||||
const evtCount = counts ? counts.events : '…';
|
||||
const histCount = counts ? counts.history : '…';
|
||||
|
||||
function getObjectData(prefix, colDefinitions, pluginObj) {
|
||||
// Extract object data specific to the plugin and format it for DataTables
|
||||
return pluginObjects
|
||||
.filter(object => object.Plugin === prefix && shouldBeShown(object, pluginObj)) // Filter objects for the specific plugin
|
||||
.map(object => colDefinitions.map(colDef => getFormControl(colDef, object[colDef.column], object["Index"], colDefinitions, object))); // Map to the defined columns
|
||||
}
|
||||
|
||||
function getHistoryData(prefix, colDefinitions, pluginObj) {
|
||||
|
||||
return pluginHistory
|
||||
.filter(history => history.Plugin === prefix && shouldBeShown(history, pluginObj)) // First, filter based on the plugin prefix
|
||||
.sort((a, b) => b.Index - a.Index) // Then, sort by the Index field in descending order
|
||||
.slice(0, 50) // Limit the result to the first 50 entries
|
||||
.map(object =>
|
||||
colDefinitions.map(colDef =>
|
||||
getFormControl(colDef, object[colDef.column], object["Index"], colDefinitions, object)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function generateTabNavigation(prefix, objectCount, eventCount, historyCount) {
|
||||
// Create navigation tabs for Objects, Unprocessed Events, and History
|
||||
return `
|
||||
<div class="nav-tabs-custom" style="margin-bottom: 0px">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="#objectsTarget_${prefix}" data-toggle="tab"><i class="fa fa-cube"></i> ${getString('Plugins_Objects')} (${objectCount})</a>
|
||||
<a href="#objectsTarget_${prefix}" data-toggle="tab"><i class="fa fa-cube"></i> ${getString('Plugins_Objects')} (<span id="objCount_${prefix}">${objCount}</span>)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#eventsTarget_${prefix}" data-toggle="tab"><i class="fa fa-bolt"></i> ${getString('Plugins_Unprocessed_Events')} (${eventCount})</a>
|
||||
<a href="#eventsTarget_${prefix}" data-toggle="tab"><i class="fa fa-bolt"></i> ${getString('Plugins_Unprocessed_Events')} (<span id="evtCount_${prefix}">${evtCount}</span>)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#historyTarget_${prefix}" data-toggle="tab"><i class="fa fa-clock"></i> ${getString('Plugins_History')} (${historyCount})</a>
|
||||
<a href="#historyTarget_${prefix}" data-toggle="tab"><i class="fa fa-clock"></i> ${getString('Plugins_History')} (<span id="histCount_${prefix}">${histCount}</span>)</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function generateDataTable(prefix, tableType, data, colDefinitions) {
|
||||
function generateDataTable(prefix, tableType, colDefinitions) {
|
||||
// Generate HTML for a DataTable and associated buttons for a given table type
|
||||
const headersHtml = colDefinitions.map(colDef => `<th class="${colDef.css_classes}">${getString(`${prefix}_${colDef.column}_name`)}</th>`).join('');
|
||||
|
||||
@@ -473,34 +623,72 @@ function generateDataTable(prefix, tableType, data, colDefinitions) {
|
||||
`;
|
||||
}
|
||||
|
||||
function initializeDataTables(prefix, objectData, eventData, historyData, colDefinitions) {
|
||||
// Common settings for DataTables initialization
|
||||
const commonDataTableSettings = {
|
||||
orderable: false, // Disable ordering
|
||||
createdRow: function(row, data) {
|
||||
$(row).attr('data-my-index', data[0]); // Set data attribute for indexing
|
||||
function initializeDataTables(prefix, colDefinitions, pluginObj) {
|
||||
const mac = $("#txtMacFilter").val();
|
||||
const foreignKey = (mac && mac !== "--") ? mac : null;
|
||||
|
||||
const tableConfigs = [
|
||||
{ tableId: `objectsTable_${prefix}`, gqlField: 'pluginsObjects', countId: `objCount_${prefix}`, badgeId: `badge_${prefix}` },
|
||||
{ tableId: `eventsTable_${prefix}`, gqlField: 'pluginsEvents', countId: `evtCount_${prefix}`, badgeId: null },
|
||||
{ tableId: `historyTable_${prefix}`, gqlField: 'pluginsHistory', countId: `histCount_${prefix}`, badgeId: null },
|
||||
];
|
||||
|
||||
function buildDT(tableId, gqlField, countId, badgeId) {
|
||||
if ($.fn.DataTable.isDataTable(`#${tableId}`)) {
|
||||
return; // already initialized
|
||||
}
|
||||
};
|
||||
$(`#${tableId}`).DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
paging: true,
|
||||
searching: true,
|
||||
ordering: false,
|
||||
pageLength: 25,
|
||||
lengthMenu: [[10, 25, 50, 100], [10, 25, 50, 100]],
|
||||
createdRow: function(row, data) {
|
||||
$(row).attr('data-my-index', data.index);
|
||||
},
|
||||
ajax: function(dtRequest, callback) {
|
||||
postPluginGraphQL(gqlField, prefix, foreignKey, dtRequest, function(dtResponse, result) {
|
||||
if (result) {
|
||||
$(`#${countId}`).text(result.count);
|
||||
if (badgeId) $(`#${badgeId}`).text(result.dbCount);
|
||||
}
|
||||
callback(dtResponse);
|
||||
});
|
||||
},
|
||||
columns: colDefinitions.map(colDef => ({
|
||||
data: colDef.column,
|
||||
title: getString(`${prefix}_${colDef.column}_name`),
|
||||
className: colDef.css_classes || '',
|
||||
createdCell: function(td, cellData, rowData) {
|
||||
$(td).html(getFormControl(colDef, cellData, rowData.index));
|
||||
}
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize DataTable for Objects
|
||||
$(`#objectsTable_${prefix}`).DataTable({
|
||||
data: objectData,
|
||||
columns: colDefinitions.map(colDef => ({ title: getString(`${prefix}_${colDef.column}_name`) })), // Column titles
|
||||
...commonDataTableSettings // Spread common settings
|
||||
});
|
||||
// Initialize the DataTable for whichever inner sub-tab is currently active
|
||||
// (may not be Objects if autoHideEmptyTabs switched it).
|
||||
// Defer the remaining sub-tabs until their shown.bs.tab fires.
|
||||
const [objCfg, evtCfg, histCfg] = tableConfigs;
|
||||
const allCfgs = [
|
||||
{ cfg: objCfg, href: `#objectsTarget_${prefix}` },
|
||||
{ cfg: evtCfg, href: `#eventsTarget_${prefix}` },
|
||||
{ cfg: histCfg, href: `#historyTarget_${prefix}` },
|
||||
];
|
||||
|
||||
// Initialize DataTable for Unprocessed Events
|
||||
$(`#eventsTable_${prefix}`).DataTable({
|
||||
data: eventData,
|
||||
columns: colDefinitions.map(colDef => ({ title: getString(`${prefix}_${colDef.column}_name`) })), // Column titles
|
||||
...commonDataTableSettings // Spread common settings
|
||||
});
|
||||
|
||||
// Initialize DataTable for History
|
||||
$(`#historyTable_${prefix}`).DataTable({
|
||||
data: historyData,
|
||||
columns: colDefinitions.map(colDef => ({ title: getString(`${prefix}_${colDef.column}_name`) })), // Column titles
|
||||
...commonDataTableSettings // Spread common settings
|
||||
allCfgs.forEach(({ cfg, href }) => {
|
||||
const $subPane = $(href);
|
||||
if ($subPane.hasClass('active') && $subPane.is(':visible')) {
|
||||
// This sub-tab is the currently active one — initialize immediately
|
||||
buildDT(cfg.tableId, cfg.gqlField, cfg.countId, cfg.badgeId);
|
||||
} else if ($subPane.closest('.tab-pane').length) {
|
||||
// Defer until shown
|
||||
$(`a[href="${href}"]`).one('shown.bs.tab', function() {
|
||||
buildDT(cfg.tableId, cfg.gqlField, cfg.countId, cfg.badgeId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@
|
||||
<?= lang('report_select_format') ;?>
|
||||
</label>
|
||||
<select id="formatSelect" class="pointer">
|
||||
<option value="HTML">HTML</option>
|
||||
<option value="JSON">JSON</option>
|
||||
<option value="Text">Text</option>
|
||||
<option value="html">HTML</option>
|
||||
<option value="json">JSON</option>
|
||||
<option value="text">Text</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -100,23 +100,23 @@
|
||||
|
||||
// Display the selected format data and update timestamp
|
||||
switch (format) {
|
||||
case 'HTML':
|
||||
case 'html':
|
||||
notificationData.innerHTML = formatData;
|
||||
break;
|
||||
case 'JSON':
|
||||
case 'json':
|
||||
notificationData.innerHTML = `<pre class="logs" cols="70" rows="10" wrap="off" readonly="">
|
||||
${jsonSyntaxHighlight(JSON.stringify(JSON.parse(formatData), undefined, 4))}
|
||||
</pre>`;
|
||||
break;
|
||||
case 'Text':
|
||||
notificationData.innerHTML = `<pre class="logs" cols="70" rows="10" wrap="off" readonly">${formatData}</pre>`;
|
||||
case 'text':
|
||||
notificationData.innerHTML = `<pre class="logs" cols="70" rows="10" wrap="off" readonly="">${formatData}</pre>`;
|
||||
break;
|
||||
}
|
||||
|
||||
// console.log(notification)
|
||||
|
||||
timestamp.textContent = localizeTimestamp(notification.DateTimeCreated);
|
||||
notiGuid.textContent = notification.GUID;
|
||||
timestamp.textContent = localizeTimestamp(notification.dateTimeCreated);
|
||||
notiGuid.textContent = notification.guid;
|
||||
currentIndex = index;
|
||||
|
||||
$("#notificationOutOff").html(`${currentIndex + 1}/${data.data.length}`);
|
||||
@@ -131,7 +131,7 @@
|
||||
|
||||
// Function to find the index of a notification by GUID
|
||||
function findIndexByGUID(data, guid) {
|
||||
return data.findIndex(notification => notification.GUID == guid);
|
||||
return data.findIndex(notification => notification.guid == guid);
|
||||
}
|
||||
|
||||
// Listen for format selection changes
|
||||
@@ -174,7 +174,7 @@
|
||||
} else {
|
||||
|
||||
// Initial data load
|
||||
updateData('HTML', -1); // Default format to HTML and load the latest report
|
||||
updateData('html', -1); // Default format to HTML and load the latest report
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user