Homeassistant companion for Linux. Inspired by the functionality provided by the Mac companion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

136 lines
5.4 KiB

import os
import socket
import sys
from uuid import getnode as get_mac
import paho.mqtt.client as mqtt
from time import sleep
version='0.0.1'
hostname=socket.gethostname()
mac=get_mac()
client = mqtt.Client()
batt_perc_file=open("/sys/class/power_supply/BAT0/capacity",'r')
ac_status_file=open('/sys/class/power_supply/AC0/online','r')
camera='/dev/video0'
system_info_file=open('/sys/devices/virtual/dmi/id/sys_vendor','r')
system_vendor=system_info_file.readline()
system_vendor=system_vendor[0:-1]
system_info_file.close()
system_info_file=open('/sys/devices/virtual/dmi/id/bios_version','r')
sw_version=system_info_file.readline()
sw_version=sw_version[0:-1]
system_info_file.close()
system_info_file=open('/sys/devices/virtual/dmi/id/product_name','r')
model=system_info_file.readline()
system_info_file.close()
model=model[0:-1]
topic='homeassistant'
client.connect("192.168.0.102", 1883, 60)
def help():
'''
The output for the help command
'''
myMessage='''Usage: python3 main.py [OPTION]
Publishes sensor information from the current host to the configured MQTT broker.
If homeassistant is set to listen from the same broker, it will autodiscover the device and sensors.
Options:
-d --daemon Run as a "daemon", updating sensors every 5 seconds
-h --help Print this help and exit
-i --init Publish sensor information to homeassistant MQTT discovery topics
-u --update Updates the sensor information [DEFAULT]
-V --version Print version number and exit
'''
print(myMessage)
def sensor_init():
'''
This is the function which initialises the sensors in homeassistant. Right now, we do everything in via MQTT.
Maybe later, we use the Mobile App integration.
'''
#Binary Sensor, is the computer active?
mytopic = topic+'/binary_sensor/'+hostname+'/active/config'
init_payload = '{"name": "'+hostname+' Active", "device_class": "power", "state_topic": "homeassistant/binary_sensor/'+hostname+'/active/state", "unique_id": "'+hostname+' Active", "off_delay": 120,"device": {"model": "'+model+'" ,"manufacturer": "'+system_vendor+'", "connections": [["mac","'+str(mac)+'"]], "sw_version": "'+sw_version+'", "name": "'+hostname+'"} }'
client.publish(mytopic,init_payload)
#Sensor, Battery status
mytopic = topic+'/sensor/'+hostname+'/battery_percentage/config'
init_payload = '{"name": "'+hostname+' Battery Percentage", "device_class": "battery","state_class": "measurement", "state_topic": "homeassistant/sensor/'+hostname+'/battery_perc/state", "unique_id": "'+hostname+' Battery Perc","device": {"model": "'+model+'" ,"manufacturer": "'+system_vendor+'", "connections": [["mac","'+str(mac)+'"]], "sw_version": "'+sw_version+'", "name": "'+hostname+'"} }'
client.publish(mytopic,init_payload)
#Binary Sensor, is the camera in use ?
mytopic = topic+'/binary_sensor/'+hostname+'/camera_active/config'
init_payload = '{"name": "'+hostname+' Camera Active", "device_class": "opening", "state_topic": "homeassistant/binary_sensor/'+hostname+'/camera_active/state", "unique_id": "'+hostname+' Camera Active", "off_delay": 120,"device": {"model": "'+model+'" ,"manufacturer": "'+system_vendor+'", "connections": [["mac","'+str(mac)+'"]], "sw_version": "'+sw_version+'", "name": "'+hostname+'"} }'
client.publish(mytopic,init_payload)
#Binary Sensor, is the AC plugged in?
mytopic = topic+'/binary_sensor/'+hostname+'/charging/config'
init_payload = '{"name": "'+hostname+' Plugged In", "device_class": "plug", "state_topic": "homeassistant/binary_sensor/'+hostname+'/charging/state", "unique_id": "'+hostname+' Plugged In", "device": {"model": "'+model+'" ,"manufacturer": "'+system_vendor+'", "connections": [["mac","'+str(mac)+'"]], "sw_version": "'+sw_version+'", "name": "'+hostname+'"} }'
client.publish(mytopic,init_payload)
def sensors_update():
'''
This function updates all defined sensors.
Really need to make this cleaner. Much much cleaner
'''
#Binary Sensor, is the computer active ?
#This is hardcoded on, if we are able to report, we are active.
mytopic='homeassistant/binary_sensor/'+hostname+'/active/state'
client.publish(mytopic,'ON')
#Sensor, what's the battery percentage ?
mytopic='homeassistant/sensor/'+hostname+'/battery_perc/state'
mypayload=batt_perc_file.readline()
batt_perc_file.seek(0)
client.publish(mytopic,mypayload)
#Binary Sensor, is the camera in use ?
mytopic='homeassistant/binary_sensor/'+hostname+'/camera_active/state'
if (os.system('fuser '+camera) == 0) :
mypayload='ON'
else:
mypayload='OFF'
client.publish(mytopic,mypayload)
#Binary sensor, is the computer plugged in to AC ?
mytopic='homeassistant/binary_sensor/'+hostname+'/charging/state'
if(ac_status_file.read(1) == '1'):
mypayload='ON'
else:
mypayload='OFF'
ac_status_file.seek(0)
client.publish(mytopic,mypayload)
if( len(sys.argv) == 1 ):
sensors_update()
exit()
if ( sys.argv[1] == '-h' or sys.argv[1] == '--help'):
help()
if (sys.argv[1] == '-d' or sys.argv[1] =='--daemon'):
while True:
sleep(5)
sensors_update()
if (sys.argv[1] == '-i' or sys.argv[1] == '--init'):
sensor_init()
if (sys.argv[1] == '-V' or sys.argv[1] == '--version'):
myMessage = 'homeassistant-linux version: '+version
print(myMessage)
if (sys.argv[1] == '-u' or sys.argv[1] == '--update'):
sensors_update()