Compare commits

..

4 Commits

Author SHA1 Message Date
Daniele Verducci (Slimpenguin)
998315ef05 Match different server successful response, Fixed error log, Added date and time on logs 2024-01-11 07:59:01 +01:00
Daniele Verducci (Slimpenguin)
07e1126a58 Updated readme 2023-12-21 08:38:35 +01:00
Daniele Verducci (Slimpenguin)
a146b668f9 Added LCD description in main README 2023-12-21 08:30:52 +01:00
Daniele Verducci (Slimpenguin)
43a5402706 Refinements in readme 2023-12-21 08:16:41 +01:00
5 changed files with 47 additions and 47 deletions

View File

@ -1,8 +1,10 @@
# Selfhost utilities
A collection of utilities for self hosters.
Every utility is in a folder with its relevant configuration and is completely separated from the other, so you can install only the ones you need.
## 🚨 HEALTHCHECK
A simple server health check.
Allows to keep under control the machine vitals (cpu usage, raid status, thermals...) and alert the sysadmin in case of anomalies.
@ -18,9 +20,18 @@ Tested on Debian 11, but should run on almost any standard linux box.
Please see [healthcheck documentation](healthcheck/README.md)
## 🖥 MDDCLIENT
A DynDns2 client supporting multiple domains with individual API calls. Developed to allow updating multiple (sub)domains on Infomaniak dynamic DNS, that supports only one domain per request. Works with any provider supporting DynDns2 protocol.
Please see [mddclient documentation](mddclient/README.md)
## 📟 ESP32-LCD
A status LCD for your homelab! Low cost (about 20€ in parts), simple to build (no circuit board, no components, only an LCD, a ESP32 and, if needed, a potentiometer). Connects to your local wifi and receives HTTP requests from your homelab machines, and shows them to the screen.
![ESP32-LCD prototype](images/esp32-lcd.jpg)
Please see [ESP32-LCD documentation](esp32-lcd/README.md)
# License
This whole repository is released under GNU General Public License version 3: see http://www.gnu.org/licenses/

View File

@ -14,26 +14,28 @@ A status LCD for your homelab.
Connect the LCD to the board:
LCD Pin ESP32 Pin
____________________________________
PIN01-VSS GND
PIN02-VDD 5V
PIN03 V0 10K Pot (Middle pin)
PIN04 RS GPIO19
PIN05 RW GND
PIN06 E GPIO23
PIN07 D0 NOT USED
PIN08 D1 NOT USED
PIN09 D2 NOT USED
PIN10 D3 NOT USED
PIN11 D4 GPIO18
PIN12 D5 GPIO17
PIN13 D6 GPIO16
PIN14 D7 GPIO15
PIN15 A 5V
PIN16 K GND
**LCD Pin -> ESP32 Pin**
Open config.h file and set display size and your wifi data.
- PIN01-VSS -> GND
- PIN02-VDD -> 5V
- PIN03 V0 -> 10K Pot (Middle pin)
- PIN04 RS -> GPIO19
- PIN05 RW -> GND
- PIN06 E -> GPIO23
- PIN07 D0 -> NOT USED
- PIN08 D1 -> NOT USED
- PIN09 D2 -> NOT USED
- PIN10 D3 -> NOT USED
- PIN11 D4 -> GPIO18
- PIN12 D5 -> GPIO17
- PIN13 D6 -> GPIO16
- PIN14 D7 -> GPIO15
- PIN15 A -> 5V
- PIN16 K -> GND
Connect the potentiometer lateral pins to VCC and GND. Use the potentiometer to set the screen contrast.
Open config.h file and set display size and your wifi access data.
Flash the code to the ESP32. If you use the Arduino ide to do it, just open the esp32-lcd.ino file with the Arduino ide and follow [this instructions](https://randomnerdtutorials.com/getting-started-with-esp32/)
@ -45,8 +47,10 @@ Restart the ESP32. The display shows "Conn to wifi..." with the WIFI name in the
- Make a GET request to the same IP address with a parameter "message" containing some text
> Example: to make the request using CURL from command line, try something along this lines (replace the IP addr with the one shown in the display):
> curl -G http://192.168.1.78 --data-urlencode "message=Something interesting happened!"
> `curl -G http://192.168.1.78 --data-urlencode "message=Something interesting happened!"`
## Troubleshooting
The ESP32 logs are written in the serial monitor at 115200 baud. Just open the Arduino ide Serial Monitor from Tools menu and look at the logs.
If the screen is supplied with power but not initialized (maybe due to bad contacts or non working esp32 firmware), it should show some black blocks on the first line. If you canot see those (nor any other text), first of all check the contrast using the potentiometer.

View File

@ -80,14 +80,6 @@ NOTIFY_ALARM_END=TRUE
# success result, error result, command failure. Then paste the command
# and regex in this config, enable the check and run to verify is working.
#### AVOID FLAPPING ####
# For values slowly changing, like a server cabinet temperature, a lot of start/end alarm notifications
# may be generated if the value is near the limit (e.g. alarm set to 30, temperature jumping between 30.1
# and 29.9). To avoid this, a "grace" delta can be set with:
# DELTA=0.5
# In the previous example, this make the alarm fire at 30.5 and stop at 29.5.
# If not specified, the delta is 0.
[system_load_1min]
# The system load average in the last minute

View File

@ -169,20 +169,13 @@ class Main:
# Compare detected value with equal, not equal, more than and less values
logging.info('detected {}'.format(detectedValue))
# String comparison
if config.alarm_string_equal and (detectedValue == config.alarm_string_equal):
return 'value is "{}"'.format(detectedValue)
if config.alarm_string_not_equal and (detectedValue != config.alarm_string_not_equal):
return 'value is "{}", but should be "{}"'.format(detectedValue, config.alarm_string_not_equal)
# Numeric comparison
numeric_value = locale.atof(detectedValue)
delta_upper = numeric_value + config.delta
delta_lower = numeric_value - config.delta
if config.alarm_value_equal and (delta_lower < float(config.alarm_value_equal) or delta_upper > float(config.alarm_value_equal)):
if config.alarm_value_equal and (locale.atof(detectedValue) == float(config.alarm_value_equal)):
return 'value is {}'.format(detectedValue)
if config.alarm_value_not_equal and (delta_lower > float(config.alarm_value_not_equal) or delta_upper < float(config.alarm_value_not_equal)):
if config.alarm_value_not_equal and (locale.atof(detectedValue) != float(config.alarm_value_not_equal)):
return 'value is {}, but should be {}'.format(detectedValue, config.alarm_value_not_equal)
if config.alarm_value_more_than and locale.atof(detectedValue) > float(config.alarm_value_more_than):
return 'value is {}, but should not exceed {}'.format(locale.atof(detectedValue), config.alarm_value_more_than)

View File

@ -48,13 +48,13 @@ import json
NAME = 'mddclient'
VERSION = '0.1'
VERSION = '0.2'
DESCRIPTION = 'A DynamicDns client like ddclient, but supporting multiple (sub)domains'
STATUS_FILE = '/tmp/mddclient.tmp'
CHECKIP_REQUEST_ADDR = 'http://checkip.dyndns.org'
CHECKIP_RESPONSE_PARSER = '<body>Current IP Address: (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})</body>'
DDCLIENT2_REQUEST_ADDR = "https://{}/nic/update?system=dyndns&hostname={}&myip={}"
DDCLIENT2_RESPONSE_PARSER = '^(nochg|good) (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})$'
DDCLIENT2_RESPONSE_PARSER = '^(nochg|no_change|good) (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})$'
USER_AGENT = 'Selfhost Utils Mddclient ' + VERSION
class Main:
@ -121,11 +121,7 @@ class Main:
def getCurrentIp(self):
'''Obtains current IP from checkip.dyndns.org'''
try:
response = requests.get(CHECKIP_REQUEST_ADDR)
except Exception as e:
self._log.error('Unable to obtain new IP addr: connection error: {}'.format(e))
return
response = requests.get(CHECKIP_REQUEST_ADDR)
match = re.search(CHECKIP_RESPONSE_PARSER, response.text, re.MULTILINE)
if not match:
@ -159,7 +155,7 @@ class Main:
if operationResult == 'good':
# Success!
return ipAddr
elif operationResult == 'nochg':
elif operationResult == 'nochg' or operationResult == 'no_change':
# Should not happen: IP didn't need update
self._log.warning('Ip addres didn\'t need update: this should happen only at first run')
return ipAddr
@ -182,7 +178,7 @@ class Main:
elif operationResult == '911':
raise Exception('There is a problem or scheduled maintenance on server side')
else:
raise Exception('Server returned an unknown result code: {}}'.format(operationResult))
raise Exception('Server returned an unknown result code: {}'.format(operationResult))
class Status:
@ -268,7 +264,11 @@ if __name__ == '__main__':
level = logging.WARNING
else:
level = logging.INFO
logging.basicConfig(level=level, format='%(asctime)s %(message)s')
logging.basicConfig(
format='%(asctime)s %(levelname)-8s %(message)s',
level=level,
datefmt='%Y-%m-%d %H:%M:%S'
)
try:
main = Main(args.configFile)