diff --git a/README.md b/README.md
index 18e27b1e..f1d5ca8b 100755
--- a/README.md
+++ b/README.md
@@ -7,7 +7,6 @@ Scans for devices connected to your WIFI / LAN and alerts you if new and unknown
![Main screen][main]
-
# 🐳 Docker image
[](https://github.com/jokob-sk/Pi.Alert/actions/workflows/docker_prod.yml)
[](https://github.com/jokob-sk/Pi.Alert)
@@ -30,7 +29,6 @@ The system continuously scans the network for, **New devices**, **New connection
examines the DHCP leases (addresses assigned) to find active devices
that were not discovered by the other methods.
-
## 🧩 Integrations
- [Apprise](https://hub.docker.com/r/caronc/apprise), [Pushsafer](https://www.pushsafer.com/), [NTFY](https://ntfy.sh/)
- [Webhooks](https://github.com/jokob-sk/Pi.Alert/blob/main/docs/WEBHOOK_N8N.md) ([sample JSON](docs/webhook_json_sample.json))
@@ -49,18 +47,16 @@ The system continuously scans the network for, **New devices**, **New connection
- Sessions, Connected devices, Favorites, Events, Presence, Concurrent devices, Down alerts, IP's
- Manual Nmap scans, Optional speedtest for Device "Internet"
- Simple Network relationship display
- - Maintenance tasks and Settings like:
- - Status Infos (active scans, database size, backup counter)
- - Theme Selection (blue, red, green, yellow, black, purple) and Light/Dark-Mode Switch
- - Language Selection (English, German, Spanish)
- - Pause arp-scan
+ - Maintenance tasks and Settings like:
+ - Theme Selection (blue, red, green, yellow, black, purple) and Light/Dark-Mode Switch
- DB maintenance, Backup, Restore tools and CSV Export / Import
- - Configurable login to prevent unauthorized use.
+ - Simple login Support
- 🌟(Experimental) [Plugin system](https://github.com/jokob-sk/Pi.Alert/tree/main/front/plugins)
- Create custom plugins with automatically generated settings and UI.
- Monitor anything for changes
- - Check the instructions carefully if you are up for a challenge!
- - Help/FAQ Section
+ - Check the instructions carefully if you are up for a challenge! Current plugins include:
+ - Detecting Rogue DHCP servers
+ - Monitoring HTTP status changes of domains/URLs
| ![Screen 1][screen1] | ![Screen 2][screen2] | ![Screen 5][screen5] |
|----------------------|----------------------| ----------------------|
@@ -93,8 +89,6 @@ Device Management [instructions](docs/DEVICE_MANAGEMENT.md) | Old Versions [Hist
## ☕ Support me
-Disclaimer: Please only donate if you don't have any debt yourself. Support yourself first, then others.
-
diff --git a/back/pialert.py b/back/pialert.py
index 63cb57a2..71a080a4 100755
--- a/back/pialert.py
+++ b/back/pialert.py
@@ -1197,8 +1197,6 @@ def copy_pihole_network ():
#-------------------------------------------------------------------------------
def read_DHCP_leases ():
- reporting = False
-
# Read DHCP Leases
# Bugfix #1 - dhcp.leases: lines with different number of columns (5 col)
data = []
@@ -1209,14 +1207,13 @@ def read_DHCP_leases ():
if len(row) == 5 :
data.append (row)
- # Insert into PiAlert table
- sql.execute ("DELETE FROM DHCP_Leases")
+ # Insert into PiAlert table
sql.executemany ("""INSERT INTO DHCP_Leases (DHCP_DateTime, DHCP_MAC,
DHCP_IP, DHCP_Name, DHCP_MAC2)
VALUES (?, ?, ?, ?, ?)
""", data)
- return reporting
+
#-------------------------------------------------------------------------------
def save_scanned_devices (p_arpscan_devices, p_cycle_interval):
@@ -1591,8 +1588,7 @@ def update_devices_data_from_scan ():
sql.execute ("""UPDATE Devices
SET dev_NAME = (SELECT PH_Name FROM PiHole_Network
WHERE PH_MAC = dev_MAC)
- WHERE (dev_Name = "(unknown)"
- OR dev_Name = ""
+ WHERE (dev_Name in ("(unknown)", "(name not found)", "" )
OR dev_Name IS NULL)
AND EXISTS (SELECT 1 FROM PiHole_Network
WHERE PH_MAC = dev_MAC
@@ -1603,8 +1599,7 @@ def update_devices_data_from_scan ():
sql.execute ("""UPDATE Devices
SET dev_NAME = (SELECT DHCP_Name FROM DHCP_Leases
WHERE DHCP_MAC = dev_MAC)
- WHERE (dev_Name = "(unknown)"
- OR dev_Name = ""
+ WHERE (dev_Name in ("(unknown)", "(name not found)", "" )
OR dev_Name IS NULL)
AND EXISTS (SELECT 1 FROM DHCP_Leases
WHERE DHCP_MAC = dev_MAC)""")
@@ -1625,6 +1620,8 @@ def update_devices_data_from_scan ():
sql.executemany ("UPDATE Devices SET dev_Vendor = ? WHERE dev_MAC = ? ",
recordsToUpdate )
+ # clean-up device leases table
+ sql.execute ("DELETE FROM DHCP_Leases")
print_log ('Update devices end')
#-------------------------------------------------------------------------------
@@ -2353,15 +2350,7 @@ def send_notifications ():
mail_text = mail_text.replace ('', portsTxt )
if 'plugins' in INCLUDED_SECTIONS and ENABLE_PLUGINS:
- # Compose Plugins Section
- # sqlQuery = get_plugin_events_to_report_on_SQL()
-
- # # handle plugins
- # for plugin in plugins:
- # print_plugin_info(plugin, ['display_name','description'])
-
- # pref = plugin["unique_prefix"]
-
+ # Compose Plugins Section
sqlQuery = """SELECT Plugin, Object_PrimaryId, Object_SecondaryId, DateTimeChanged, Watched_Value1, Watched_Value2, Watched_Value3, Watched_Value4, Status from Plugins_Events"""
notiStruc = construct_notifications(sqlQuery, "Plugins")
@@ -3994,7 +3983,7 @@ def process_plugin_events(plugin):
pluginEvents[index].status = "watched-not-changed"
index += 1
- # Merge existing plugin objects with newly discovered ones and update existin ones with new values
+ # Merge existing plugin objects with newly discovered ones and update existing ones with new values
for eveObj in pluginEvents:
if eveObj.status == 'new':
pluginObjects.append(eveObj)
@@ -4037,7 +4026,74 @@ def process_plugin_events(plugin):
# insert only events if they are to be reported on
if plugObj.status in get_plugin_setting_value(plugin, "REPORT_ON"):
- sql.execute ("INSERT INTO Plugins_Events (Plugin, Object_PrimaryID, Object_SecondaryID, DateTimeCreated, DateTimeChanged, Watched_Value1, Watched_Value2, Watched_Value3, Watched_Value4, Status, Extra, UserData, ForeignKey) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", (plugObj.pluginPref, plugObj.primaryId , plugObj.secondaryId , createdTime, plugObj.changed , plugObj.watched1 , plugObj.watched2 , plugObj.watched3 , plugObj.watched4 , plugObj.status , plugObj.extra, plugObj.userData, plugObj.foreignKey ))
+ sql.execute ("INSERT INTO Plugins_Events (Plugin, Object_PrimaryID, Object_SecondaryID, DateTimeCreated, DateTimeChanged, Watched_Value1, Watched_Value2, Watched_Value3, Watched_Value4, Status, Extra, UserData, ForeignKey) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", (plugObj.pluginPref, plugObj.primaryId , plugObj.secondaryId , createdTime, plugObj.changed , plugObj.watched1 , plugObj.watched2 , plugObj.watched3 , plugObj.watched4 , plugObj.status , plugObj.extra, plugObj.userData, plugObj.foreignKey ))
+
+ # Perform databse table mapping if enabled for the plugin
+ # "mapped_to_table": "DHCP_Leases",
+
+ if len(pluginEvents) > 0 and "mapped_to_table" in plugin:
+
+ sqlParams = []
+
+ dbTable = plugin['mapped_to_table']
+
+ mylog('debug', [' [Plugins] Mapping objects to database table: ', dbTable])
+
+ # collect all columns to be mapped
+ mappedCols = []
+ columnsStr = ''
+ valuesStr = ''
+
+ for clmn in plugin['database_column_definitions']:
+ if 'mapped_to_column' in clmn:
+ mappedCols.append(clmn)
+ columnsStr = f'{columnsStr}, "{clmn["mapped_to_column"]}"'
+ valuesStr = f'{valuesStr}, ?'
+
+ if len(columnsStr) > 0:
+ columnsStr = columnsStr[1:] # remove first ','
+ valuesStr = valuesStr[1:] # remove first ','
+
+ # map the column names to plugin object event values
+ for plgEv in pluginEvents:
+
+ tmpList = []
+
+ for col in mappedCols:
+ if col['column'] == 'Index':
+ tmpList.append(plgEv.index)
+ elif col['column'] == 'Plugin':
+ tmpList.append(plgEv.pluginPref)
+ elif col['column'] == 'Object_PrimaryID':
+ tmpList.append(plgEv.primaryId)
+ elif col['column'] == 'Object_SecondaryID':
+ tmpList.append(plgEv.secondaryId)
+ elif col['column'] == 'DateTimeCreated':
+ tmpList.append(plgEv.created)
+ elif col['column'] == 'DateTimeChanged':
+ tmpList.append(plgEv.changed)
+ elif col['column'] == 'Watched_Value1':
+ tmpList.append(plgEv.watched1)
+ elif col['column'] == 'Watched_Value2':
+ tmpList.append(plgEv.watched2)
+ elif col['column'] == 'Watched_Value3':
+ tmpList.append(plgEv.watched3)
+ elif col['column'] == 'Watched_Value4':
+ tmpList.append(plgEv.watched4)
+ elif col['column'] == 'UserData':
+ tmpList.append(plgEv.userData)
+ elif col['column'] == 'Extra':
+ tmpList.append(plgEv.extra)
+ elif col['column'] == 'Status':
+ tmpList.append(plgEv.status)
+
+ sqlParams.append(tuple(tmpList))
+
+ q = f'INSERT into {dbTable} ({columnsStr}) VALUES ({valuesStr})'
+
+ mylog('debug', [' [Plugins] SQL query for mapping: ', q ])
+
+ sql.executemany (q, sqlParams)
commitDB()
@@ -4084,7 +4140,7 @@ class plugin_object_class:
self.watchedHash = str(hash(tmp))
-
+
#-------------------------------------------------------------------------------
# Combine plugin objects, keep user-defined values, created time, changed time if nothing changed and the index
def combine_plugin_objects(old, new):
diff --git a/docker-compose.yml b/docker-compose.yml
index 83359199..fd148df4 100755
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -7,9 +7,9 @@ services:
network_mode: "host"
restart: unless-stopped
volumes:
- - ${APP_DATA_LOCATION}/pialert/config:/home/pi/pialert/config
+ - ${APP_DATA_LOCATION}/pialert2/config:/home/pi/pialert/config
# - ${APP_DATA_LOCATION}/pialert/db/pialert.db:/home/pi/pialert/db/pialert.db
- - ${APP_DATA_LOCATION}/pialert/db:/home/pi/pialert/db
+ - ${APP_DATA_LOCATION}/pialert2/db:/home/pi/pialert/db
# (optional) useful for debugging if you have issues setting up the container
- ${LOGS_LOCATION}:/home/pi/pialert/front/log
# DELETE START anyone trying to use this file: comment out / delete BELOW lines, they are only for development purposes
diff --git a/front/plugins/dhcp_leases/config.json b/front/plugins/dhcp_leases/config.json
index 4616911f..f24960d4 100755
--- a/front/plugins/dhcp_leases/config.json
+++ b/front/plugins/dhcp_leases/config.json
@@ -4,6 +4,7 @@
"enabled": true,
"data_source": "python-script",
"localized": ["display_name", "description", "icon"],
+ "mapped_to_table": "DHCP_Leases",
"display_name" : [{
"language_code":"en_us",
"string" : "DHCP Leases"
@@ -25,7 +26,7 @@
"database_column_definitions":
[
{
- "column": "Index",
+ "column": "Index",
"css_classes": "col-sm-2",
"show": false,
"type": "label",
@@ -52,6 +53,7 @@
},
{
"column": "Object_PrimaryID",
+ "mapped_to_column": "DHCP_MAC",
"css_classes": "col-sm-2",
"show": true,
"type": "devicemac",
@@ -60,11 +62,12 @@
"localized": ["name"],
"name":[{
"language_code":"en_us",
- "string" : "IP"
+ "string" : "MAC address"
}]
},
{
"column": "Object_SecondaryID",
+ "mapped_to_column": "DHCP_IP",
"css_classes": "col-sm-2",
"show": true,
"type": "deviceip",
@@ -73,7 +76,7 @@
"localized": ["name"],
"name":[{
"language_code":"en_us",
- "string" : "MAC address"
+ "string" : "IP"
}]
} ,
{
@@ -91,6 +94,7 @@
},
{
"column": "DateTimeChanged",
+ "mapped_to_column": "DHCP_DateTime",
"css_classes": "col-sm-2",
"show": true,
"type": "label",
@@ -117,6 +121,7 @@
},
{
"column": "Watched_Value2",
+ "mapped_to_column": "DHCP_Name",
"css_classes": "col-sm-2",
"show": true,
"type": "label",