Come monitorare il sensore delle piante di Xiaomi con Domoticz

Il sensore che sto per presentarvi costa abbastanza su Amazon ma potete trovarlo a meno su qualche sito cinese, nel caso il prezzo sia troppo elevato.

Xiaomi tra le tante cose ha realizzato un sensore molto compatto che può monitorare praticamente tutto quello che può essere utile per gestire una pianta (che sia un Bonsai o altro non importa, il sensore andrà impiantato nel terreno come in figura).

Con l’integrazione con Domoticz potrete gestire comodamente tutte le statistiche e fare dei grafici che potrebbero tornarvi utili in qualche modo con automazioni varie (monitorando la quantità di luce e la temperatura, le opzioni sono infinite).

Iniziamo:

sudo git clone https://github.com/marcotini/miflora /home/pi/domoticz/scripts/

Modificate il file:

sudo nano /home/pi/domoticz/scripts/miflora/demo.py

Cambiando l’indirizzo MAC del vostro sensore (lo trovate nel retro o con una semplice scansione BLE):

poller = MiFloraPoller("AB:CD:12:34:56:78")

E cambiate ovviamente anche gli IDX di temperatura, luce, umidità, conduttività e batteria (ovviamente ognuno di questi dovrà essere un sensore virtuale già esistente) che vanno da 100 a 104.

Ora create uno script che sia facilmente chiamabile da Domoticz:

sudo nano /home/pi/domoticz/scripts/flora.sh

E incollate:

#!/bin/bash

sudo /usr/bin/python3 /home/pi/domoticz/scripts/miflora/demo.py

Potete quindi ora creare un sensore virtuale che all’On Action esegua:

script:///home/pi/domoticz/scripts/flor1.sh

E potrete anche automatizzarlo nel crontab con sudo crontab -e per farlo eseguire ogni 20 minuti (lo uso da mesi e la batteria non è praticamente scesa). Incollate al fondo:

20 * * * * /home/pi/domoticz/scripts/flora.sh

Guardate ad esempio il sensore della luce:

Oppure quello dell’umidità:

Con Domoticz potete ovviamente creare tutte le automazioni del caso quindi ad esempio essere informati quando arriva a un certo valore di umidità del terreno, oppure quando non c’è abbastanza luce. Le possibilità sono davvero illimitate!

Come monitorare la bilancia di Xiaomi con Domoticz

La Xiaomi Mi Scale è la bilancia di Xiaomi con il Bluetooth (quindi per farla semplice potrete salvarvi i dati dove meglio preferite e farvi un grafico con i pesi misurati) che potete acquistare qui.

Con l’integrazione con Domoticz potrete gestirla come meglio preferite, eventualmente anche con HomeKit di Apple e l’emulazione del server con Homebridge.

Iniziamo!

sudo git clone https://github.com/marcotini/node-xiaomi-scale /home/pi/domoticz/scripts

Ora create un sensore virtuale che abbia uno switch (quindi un semplice bottone) e mettete come On Action:

script:///home/pi/domoticz/scripts/weight.sh

Vi serviranno anche 2 sensori virtuali per persona che usa la bilancia, uno per i KG e uno per il valore di BMI.

Adesso create lo script con sudo nano /home/pi/domoticz/scripts/weight.sh e incollate:

#!/bin/bash

before=$(head -1  /home/pi/domoticz/scripts/node-xiaomi-scale/scaleData.txt)

sudo /usr/bin/node /home/pi/domoticz/scripts/node-xiaomi-scale/fetchscaledata.js > /home/pi/domoticz/scripts/node-xiaomi-scale/scaleData.txt

kg=$(head -1  /home/pi/domoticz/scripts/node-xiaomi-scale/scaleData.txt)
bmi=$(tail -1 /home/pi/domoticz/scripts/node-xiaomi-scale/scaleData.txt)

maggiore=60
zero=0

if (( $(echo "$kg != $before" |bc -l) )); then
if (( $(echo "$kg > $maggiore" |bc -l) )); then

curl -s -k "http://127.1.1.1:8080/json.htm?type=command&param=udevice&idx=123&nvalue=0&svalue=$kg" > /dev/null
curl -s -k "http://127.1.1.1:8080/json.htm?type=command&param=udevice&idx=456&nvalue=0&svalue=$bmi" > /dev/null

elif (( $(echo "$kg > $zero" |bc -l) )); then

curl -s -k "http://127.1.1.1:8080/json.htm?type=command&param=udevice&idx=789&nvalue=0&svalue=$kg" > /dev/null
curl -s -k "http://127.1.1.1:8080/json.htm?type=command&param=udevice&idx=012&nvalue=0&svalue=$bmi" > /dev/null

fi
fi

Lo script è utile per due persone ma può essere allargato per quante preferite.
Gli IDX 123 e 456 si riferiscono ai KG e BMI della persona che pesa di più di 60 KG (come potrete notare dalla variabile maggiore è stato settato così, ma potete benissimo mettere quello che preferite in base alla vostra differenza di peso). 789 e 012 invece si riferiscono a quella che ha peso inferiore.

Inoltre lo script controlla che il valore non sia uguale al precedente (nel caso abbiate effettuato due letture consecutive).

NB: dovete aver installato sul vostro sistema Node JS.

Eventualmente potete anche creare l’automazione per far in modo che (ad esempio il Raspberry Pi) la bilancia venga interrogata la mattina, ad esempio alle 7, 8 o 9 di mattina (così da non dover ogni volta ripremere il tasto su Domoticz). Voi sapete che ogni giorno alle 7.00 di mattina la bilancia fornisce i dati, se ce ne sono: lo script li salva. Altrimenti no. Eseguite sudo crontab -e e incollate:

0 7 * * * /home/pi/domoticz/scripts/weight.sh
0 8 * * * /home/pi/domoticz/scripts/weight.sh
0 9 * * * /home/pi/domoticz/scripts/weight.sh

Come gestire e monitorare i consumi con Domoticz e la presa TP-Link HS100/HS110

Se non conoscete ancora la presa intelligente della TP-Link è ora di conoscerla… e acquistarla! Qui potete acquistare la HS100 che ha solo lo swtich on e off. Mentre qua per soli 5 euro in più potete acquistare quella con anche il monitoraggio della corrente.

Dovete prima di tutto creare un sensore virtuale che sia di tipo Wall socket. Inserite in on e off questi due (cambiate ovviamente gli IP).

Per il tasto on:

script:///home/pi/domoticz/scripts/tplink-smartplug.py -t 172.24.1.123 -c on

Per il tasto off:

script:///home/pi/domoticz/scripts/tplink-smartplug.py -t 172.24.1.123 -c off

Non premetelo ancora! Prima create lo script monitorare il consumo:

sudo nano /home/pi/domoticz/scripts/HS110.py

E incollate:

#!/usr/bin/env python
#
# TP-Link Wi-Fi Smart Plug Protocol Client
# For use with TP-Link HS110: energy monitor
#
# Gets current power (W) and cumulative energy (kWh)
# and sends to Domoticz
import socket
import argparse
import json
import urllib
import urllib2
# ip, port, and command for HS110
ip = '172.24.1.123'
port = 9999
cmd = '{"emeter":{"get_realtime":{}}}'
# Domoticz command stub and IDx of HS110
baseURL = 'http://127.1.1.1:8080/json.htm?type=command&param=udevice&nvalue=0'
HSIdx = 456
# Encryption and Decryption of TP-Link Smart Home Protocol
# XOR Autokey Cipher with starting key = 171
def encrypt(string):
key = 171
result = "\0\0\0\0"
for i in string:
a = key ^ ord(i)
key = a
result += chr(a)
return result
def decrypt(string):
key = 171
result = ""
for i in string:
a = key ^ ord(i)
key = ord(i)
result += chr(a)
return result
def domoticzrequest (url):
request = urllib2.Request(url)
#   request.add_header("Authorization", "Basic %s" % base64string)
response = urllib2.urlopen(request)
return None;
# Send command and receive reply
try:
sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_tcp.connect((ip, port))
sock_tcp.send(encrypt(cmd))
data = sock_tcp.recv(2048)
sock_tcp.close()

#   print "Sent:     ", cmd
result = decrypt(data[4:])
jsonData = json.loads(result)
#   print "Received: "
#   print json.dumps(jsonData, indent=4, sort_keys=True)
power = jsonData['emeter']['get_realtime']['power']
total = jsonData['emeter']['get_realtime']['total'] * 1000
#   print power, total
except socket.error:
quit("Cound not connect to host " + ip + ":" + str(port))
# Send data to Domoticz
try:
url = baseURL + "&idx=%s&svalue=%s;%s" % (HSIdx, power, total)
domoticzrequest(url)
except urllib2.URLError, e:
print e.code

Create un altro sensore virtuale per monitorare il consumo:

Mentre questo sudo nano /home/pi/domoticz/scripts/tplink-smartplug.py incollate:

#!/usr/bin/env python
#
# TP-Link Wi-Fi Smart Plug Protocol Client
# For use with TP-Link HS-100 or HS-110
#
# by Lubomir Stroetmann
# Copyright 2016 softScheck GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
import socket
import argparse
version = 0.1
# Check if IP is valid
def validIP(ip):
try:
socket.inet_pton(socket.AF_INET, ip)
except socket.error:
parser.error("Invalid IP Address.")
return ip
# Predefined Smart Plug Commands
# For a full list of commands, consult tplink_commands.txt
commands = {'info'     : '{"system":{"get_sysinfo":{}}}',
'on'       : '{"system":{"set_relay_state":{"state":1}}}',
'off'      : '{"system":{"set_relay_state":{"state":0}}}',
'cloudinfo': '{"cnCloud":{"get_info":{}}}',
'wlanscan' : '{"netif":{"get_scaninfo":{"refresh":0}}}',
'time'     : '{"time":{"get_time":{}}}',
'schedule' : '{"schedule":{"get_rules":{}}}',
'countdown': '{"count_down":{"get_rules":{}}}',
'antitheft': '{"anti_theft":{"get_rules":{}}}',
'reboot'   : '{"system":{"reboot":{"delay":1}}}',
'reset'    : '{"system":{"reset":{"delay":1}}}'
}
# Encryption and Decryption of TP-Link Smart Home Protocol
# XOR Autokey Cipher with starting key = 171
def encrypt(string):
key = 171
result = "\0\0\0\0"
for i in string:
a = key ^ ord(i)
key = a
result += chr(a)
return result
def decrypt(string):
key = 171
result = ""
for i in string:
a = key ^ ord(i)
key = ord(i)
result += chr(a)
return result
# Parse commandline arguments
parser = argparse.ArgumentParser(description="TP-Link Wi-Fi Smart Plug Client v" + str(version))
parser.add_argument("-t", "--target", metavar="<ip>", required=True, help="Target IP Address", type=validIP)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-c", "--command", metavar="<command>", help="Preset command to send. Choices are: "+", ".join(commands), choices=commands)
group.add_argument("-j", "--json", metavar="<JSON string>", help="Full JSON string of command to send")
args = parser.parse_args()
# Set target IP, port and command to send
ip = args.target
port = 9999
if args.command is None:
cmd = args.json
else:
cmd = commands[args.command]
# Send command and receive reply
try:
sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_tcp.connect((ip, port))
sock_tcp.send(encrypt(cmd))
data = sock_tcp.recv(2048)
sock_tcp.close()
print "Sent:     ", cmd
print "Received: ", decrypt(data[4:])
except socket.error:
quit("Cound not connect to host " + ip + ":" + str(port))

Ora potete impostare un’automazione che esegua lo script di controllo del consumo e che aggiorni l’IDX corrispettivo.

Per comodità ho messo come IP della presa 172.24.1.123 e come IDX 456 (cercateli nei due script e modificateli).

Se non volete creare l’automazione che controlli il consumo, semplicemente create un altro sensore virtuale che al tasto on abbia come parametro:

script:///home/pi/domoticz/scripts/HS110.py

Abbastanza semplice no?

Dopo che avrete monitorato i consumi per qualche mese avrete a disposizione un bel grafico su cui poter lavorare:

Come monitorare la temperatura della CPU con Domoticz

Se volete controllare la temperatura della CPU del vostro Raspberry Pi e avere un grafico riportato nel vostro pannello Domoticz, vi basterà usare questo script:

sudo nano /home/pi/domoticz/scripts/cputemp.sh

E incollare (cambiate 123 in base all’IDX del sensore che avete su Domoticz)

#!/bin/bash

milcel=$(cat /sys/class/thermal/thermal_zone0/temp)

MEMUSG=`echo "scale=3;$milcel/1000" | bc`

curl -s -k "http://127.1.1.1:8080/json.htm?type=command&param=udevice&idx=123&nvalue=0&svalue=$MEMUSG" > /dev/null

Ora aggiungete a sudo crontab -e questo (controllerà ogni 5 minuti la temperatura, salvandovela nel sensore virtuale e facendovi poi un grafico):

5 * * * * /home/pi/domoticz/scripts/cputemp.sh

Come creare un sensore virtuale su Domoticz

Se volete creare un sensore virtuale per monitorare delle risorse che possono essere la temperatura della CPU, piuttosto che un bottone o tasto che esegue qualche script/applicativo, vi basterà aprire Domoticz e andare su HARDWARE. Selezionate Dummy (Does nothings, use for virtual switches only):

E dategli il nome che preferite (anche Dummy va bene). Ora cliccate su CREATE VIRTUAL SENSOR alla riga Dummy e aggiungete quello che preferite, ad esempio uno di temperatura:

Adesso spostatevi su DEVICE e segnatevi l’IDX che potrà servirvi per accedervi. Potrete semplicemente aggiornare il dato facendo una chiamata tipo (presupponendo IDX=123 e valore da aggiornare 99):

http://127.1.1.1:8080/json.htm?type=command&param=udevice&idx=123&nvalue=0&svalue=99</>

Semplice no?

Come tenere Domoticz sempre attivo

Dato che molto spesso tra sensori vari o thread aperti da plugin non troppo funzionanti Domoticz può smettere di funzionare da un punto all’altro, il mio suggerimento è quello di crearvi uno script gestito dal crontab e fare in modo che controlli ogni minuto se è attivo. E nel caso, lo riattivi. Presupponendo che l’abbiate installato nella home del vostro Raspberry Pi (nel caso cambiate semplicemente path):

sudo nano /home/pi/domoticz/scripts/checkdomoticz.sh

Incollate:

#!/bin/bash

ip=127.0.0.1
port=8080
idx=1

function jsonValue() {
KEY=$1
num=$2
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$KEY'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}

DOMOTICZ=`curl -s --connect-timeout 2 --max-time 5 "http://$ip:$port/json.htm?type=devices&rid=$idx"`
STATUS=$(echo $DOMOTICZ | jsonValue status 1)
OK="OK"

echo "Domoticz status = $STATUS"

if [ "$STATUS" == "" ] ; then

echo Domoticz status NOK1, retrying in 5 seconds...
sleep 5
DOMOTICZ=`curl -s --connect-timeout 2 --max-time 5 "http://$ip:$port/json.htm?type=devices&rid=$idx"`
STATUS2=$(echo $DOMOTICZ | jsonValue status 1)
echo Domoticz status = $STATUS2

if [ "$STATUS2" == "" ] ; then
echo Domoticz status NOK2, retrying in 5 seconds...
sleep 5
DOMOTICZ=`curl -s --connect-timeout 2 --max-time 5 "http://$ip:$port/json.htm?type=devices&rid=$idx"`
STATUS3=$(echo $DOMOTICZ | jsonValue status 1)
echo Domoticz status = $STATUS3

if [ "$STATUS3" == "" ] ; then
echo Domoticz status NOK3, stopping service, killing process, starting service...
sudo service domoticz stop
sleep 5
sudo service domoticz start
fi
fi
fi

Ora eseguite: sudo crontab -e

E aggiungete in fondo:

* * * * * /home/pi/domoticz/scripts/checkdomoticz.sh

Questo controllerà ogni minuto se è attivo, così male che vada (e nel caso non ci siano ovviamente problemi gravi) Domoticz vi rimarrà disattivato al massimo per 1 minuto.