לאחרונה יצא לי להטמיע חיישני SNMP ב Home Assistant מתוך מטרה לדלות מידע מהראוטר שלי, שהוא של חברת צ'קפויינט. הכל היה טוב ויפה כל עוד הייתי צריך "לשלוף" מידע כמו מהירות הרשת, מצב הזכרון ואת גרסאת ה Firmware של המערכת. אז איפה הבעיה? הבעיה החלה כאשר הייתי צריך לשלוף ערכים שאינם חוזרים כמחרוזת טקסט סטנדרטית, למשל את כתובת ה IP החיצונית (WAN) ואז החיישן הציג את המידע בג'יבריש:
אחרי מחקר של כמה ימים הבנתי שאין כל כך מה לעשות, המפתחים של Home Assistant קיבלו דיווח על כך שהבעיה קיימת באותה חבילת בסיס שמשרתת את הקומפוננטה כבר לפני מספר גרסאות אך לא נראה שהם מתכוונים לתקנה בקרוב. לכן, כתבתי בפייתון מעיין rest api אשר יקבל את ה OID עבור שאילתת ה SNMP ויחזיר את התשובה בפורמט תקין, וכך באמצעות rest sensor בתוך Home-Assistant אוכל להציג את הערכים בצורה תקינה:
במדריך זה אסביר כיצד להתקין אצלכם את ה service וכיצד להשתמש בו באמצעות Home Assistant.
שלב א' – התקנת התלויות והכנת קובץ השירות
על מנת שה service יעבוד בצורה תקינה יש להתקין מספר תלויות. לצורך כך כתבו את הפקודה הבאה:
sudo pip3 install flask flask_restful pysnmp
כעת, צרו תיקיה תחת /opt/ וקראו לה snmpsvc:
sudo mkdir /opt/snmpsvc
וצרו בתוכה קובץ בשם snmp.py והדביקו פנימה את הטקסט הבא:
import datetime
from flask import Flask, request, make_response
from flask_restful import Resource, Api
from json import dumps
community = 'public'
target = '0.0.0.0'
def snmpget(oid):
from pysnmp.entity.rfc3413.oneliner import cmdgen
import datetime
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
cmdgen.CommunityData(community),
cmdgen.UdpTransportTarget((target, 161)),
oid
)
# Check for errors and print out results
if errorIndication:
print(errorIndication)
else:
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex)-1] or '?'
)
)
else:
for name, val in varBinds:
print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
return val.prettyPrint()
app = Flask(__name__)
api = Api(app)
class GetSnmpValue(Resource):
def get(self, oid):
answer = snmpget(oid)
return make_response(answer)
api.add_resource(GetSnmpValue, '/snmp/<oid>')
if __name__ == '__main__':
app.run(host='0.0.0.0',port=2222)
כאשר:
- בתחילת הקובץ החליפו את כתובת ה IP תחת target לכתובת ה IP של השרת/רכיב אותו תרצו לתשאל ב SNMP.
- בסוף הקובץ החליפו את ה port שכרגע עומד על 2222 בזה שתרצו שהשירות יאזין עליו.
שמרו את השינויים וצאו מהקובץ.
חלק ב' – התקנת הסקריפט כשירות שיעלה עם עליית השרת
על מנת שהשירות יעבוד תמיד ברקע ויעלה עם הדלקת השרת, יש לרשום אותו כ service במערכת. לצורך כך כתבו את הפקודה הבאה:
nano /etc/systemd/system/snmpsvc.service
והדביקו פנימה את קטע הקוד הבא:
[Unit]
Description=Snmp Rest Service
After=network.target
[Service]
Type=simple
User=[your user]
ExecStart=/usr/bin/python3 /opt/snmpsvc/snmp.py
[Install]
WantedBy=multi-user.target
החליפו את [your user] במשתמש שלכם. הוא המשתמש שתחתיו ירוץ השירות.
שמרו את הקובץ וצאו מהעורך.
כעת, כתבו את הפקודות הבאות כדי להפעיל את השרות ולרשום אותו כשרות מערכת:
sudo systemctl --system daemon-reload
sudo systemctl enable snmpsvc.service
sudo systemctl start snmpsvc.service
כעת, כתבו את הפקודה הבאה על מנת לוודא כי השרות רץ בצורה תקינה:
sudo systemctl status snmpsvc.service
אם ביצעתם את ההתקנה בצורה תקינה, אתם אמורים לקבל פלט שנראה כך:
כעת פתחו את הדפדפן, והקישו את כתובת השרת בתוספת הפורט ו ה OID לתשאות בצורה הבאה:
http://192.168.1.22:2222/snmp/1.3.6.1.4.1.2620.1.6.50.1.1.4.14.0
והפלט שיתקבל אמור להראות כך:
חלק ג' – שימוש ב rest sensor בתוך home-assistant
בחלק זה של המדריך, אסביר כיצד ניתן להשתמש ב rest sensor המובנה של home-assistant על מנת להציג את הנתונים של ה SNMP. לצורך כך פתחו את קובץ ה configuration.yaml והוסיפו פנימה את הקודה הבא:
sensor:
- platform: rest
resource: http://192.168.1.1:222/snmp/1.3.6.1.4.1.2620.1.6.50.1.1.4.14.0
name: CP LAN IP
scan_interval: 60
value_template: '{{value }}'
החליפו את כתובת השרת, הפורט וה OID בזה שלכם, שמרו את הקובץ ואתחלו את Home-Assistant. אם בצעתם הכל לפי ההוראות, תוכלו לראות כי כעת הנתונים מוצגים כראוי.
בהצלחה!
Leave a Reply