NSTH-Home Automation Raspberry Google Python
NSTH-Home Automation Raspberry Google Python
with Raspberry,
Google & Python
(English Edition)
TABLE OF CONTENTS
Pag:
Dedicated to 9
1. Introduction 10
2. Copyright 14
3. General description 16
Hardware elements 17
Software elements 19
Automatic actions 20
4. Sensors 24
Temperature & humidity: DHT22* 25
Air quality alarm: MQ135* 26
Gas leaks alarm: AE09/GM* 27
Flood alarm: AE98/iN220* 28
Smoke & fire alarm: AE085/R220B* 29
Electric supply alarm 30
Garage gate alarm 31
Doorbell alarm 32
Reset & alarm simulation buttons 33
Internet connectivity 34
2
Home Automation with Raspberry, Google & Python
6. Actuators 49
LED 50
Audio buzz 51
Relays module 52
Window blinds, lighting, thermostat,
valves & LCD control display 55
Watchdog 58
Other actuators 60
8. Power supply 65
Systems that need +5v 67
Systems that need +3.3v 68
Other power supply systems 69
3
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
the Raspberry* 96
Installation from zero 98
Use of external disks 100
Upgrading the system 101
Bluetooth* settings 102
Package installation 103
Assign fixed IP to Raspberry* 104
Startup configuration 105
Boot from disks by FSTAB 107
Raspberry* HDMI* resolution 108
Main screen settings 109
4
Home Automation with Raspberry, Google & Python
5
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
6
Home Automation with Raspberry, Google & Python
7
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
VNC* 412
PLEX* 412
Google Home* 413
IFTTT* 413
Edimax* 413
Various 414
⊝⊝⊝
8
Home Automation with Raspberry, Google & Python
Dedicated to my wife
to you, gorgeous,
thank you for your love,
thank you for your patience,
thank you for your company,
thank you for your collaboration,
please never change.
9
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
1.-INTRODUCTION
W
ith the massive incorporation, in the last
decades, of the great majority of the
components of the family unit, to the work
life and the culture of the leisure, the
houses have undergone a desertification process that
extends to the majority of the working day and which
generates the need for automatic multiple control and
more and more parameters that affect the comfort of
the home.
10
Home Automation with Raspberry, Google & Python
11
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
12
Home Automation with Raspberry, Google & Python
⊝⊝⊝
13
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
2.-COPYRIGHT
T
he author of this book is Gregorio Chenlo
Romero, who reserves the rights granted by
Law in each region where this book is
published.
14
Home Automation with Raspberry, Google & Python
⊝⊝⊝
15
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
3.-GENERAL DESCRIPTION
T
he general structure of the home automation
project described in this book is extremely
simple and only consists of three basic
pillars:
• Hardware.
• Software.
• Automatic actions.
16
Home Automation with Raspberry, Google & Python
*Hardware Elements
17
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
18
Home Automation with Raspberry, Google & Python
*Software Elements
1. A c u s t o m c o n t r o l s o f t w a r e , p_global.py,
developed in a friendly programming language,
Python* and supported by a simple and easy
operating system, Raspbian*. This language and
operating system is used in both Raspberry*.
6. O t h e r s o f t w a r e a n d A P P , t h a t h e l p t h e
configuration of the whole system (iCircuit*,
Pycharm*, VirtualBox*, IPScanner*, Eagle*, Etcher*,
Home*, Kasa*, EdiLife*, Tadoº*, Speedtest*, Ihc*,
etc.).
19
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Automatic Actions
20
Home Automation with Raspberry, Google & Python
21
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
22
Home Automation with Raspberry, Google & Python
gregochenlo.blogspot.com
⊝⊝⊝
23
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
4.-SENSORS
T
he are many sensors on the market that
could be used for this or other similar
projects. The choice of sensors used is a
personal matter and will depend on the
objectives of each project
24
Home Automation with Raspberry, Google & Python
25
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
26
Home Automation with Raspberry, Google & Python
27
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Flood Alarm:
AE98/iN220*
It is composed of a
probe and a detector
that has power and
alarm light indicators,
acoustic alarm, relay
with voltage-free contacts and integrated power
supply.
28
Home Automation with Raspberry, Google & Python
29
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
30
Home Automation with Raspberry, Google & Python
31
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Doorbell Alarm
Sensor based on an
int er fa ce , a ls o i ts
own, that detects the
+18v generated by the
interface bus that
feeds the doorbell to
access the general
entrance of the house,
attacks a retriggerable
monostable adjusted to
a pulse of a certain
duration and that
finally adapts to the
necessary +3.3v levels
o f t h e GPIO* of the
Raspberry*_home
automation.
As we will see
later, this sensor
detects each press of
the bell, as long as it
is done in a certain
time and filters
noises, electrical
parasites, bounces,
etc.
32
Home Automation with Raspberry, Google & Python
33
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Internet Connectivity
⊝⊝⊝
34
Home Automation with Raspberry, Google & Python
5.-DETAIL OF
SOME SENSORS
W
e have already briefly described the
sensors used in this project, some of them
can be easily acquired in the market
(electronics stores or specialised
websites) and others have had to be created, or at
least build the electronic interfaces, both analog and
digital corresponding to adapt its electrical output
signals to the electrical signals required by the
centralised control system located in the Raspberry*_
home automation.
35
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
3. U s e t h e s o f t w a r e - m a n a g e d
b i d i r e c t i o n a l s e r i a l DAT*
protocol via pin 1-Wire* (must be enabled in the
ip-config of the Raspberry*_home automation) and
with the following structure:
For example:
36
Home Automation with Raspberry, Google & Python
37
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
38
Home Automation with Raspberry, Google & Python
10. T h i s s e n s o r m u s t b e
connected to a logic level
converter, for example a
SODIAL* or equivalent, which
uses several Mosfet BSS138*
and 10kΩ resistors to adapt
the +5v output to the +3,3v
needed for the Raspberry*_
home automation.
39
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
40
Home Automation with Raspberry, Google & Python
41
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
42
Home Automation with Raspberry, Google & Python
43
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Garage Gate
Status
44
Home Automation with Raspberry, Google & Python
45
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
46
Home Automation with Raspberry, Google & Python
*Doorbell Interface
47
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
⊝⊝⊝
48
Home Automation with Raspberry, Google & Python
6.-ACTUATORS
T
his s ection desc ribes in d etail the
mission, the performance, construction and
operation of all actuators (control,
special, etc.) used in this project.
49
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*LED
50
Home Automation with Raspberry, Google & Python
*Audio Buzz
51
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Relays Module
52
Home Automation with Raspberry, Google & Python
In Out GPIO*
H 220v 0,3v L 3,5v H
L 0v 3,4v H 0,1v L
P_on Ov L 3,5v H
53
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
54
Home Automation with Raspberry, Google & Python
55
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
ADUM_1201*.
56
Home Automation with Raspberry, Google & Python
An in te re s ti ng KNX* device,
although not essential, is the
LCD control display.
57
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Watchdog
2. T h i s CK signal
attacks an integrated
NE555*, in monostable
configuration,
adjusted by the R+C=
39kΩ+220uF pair at a
pulse activation, T1,
of 10 seconds,
calculated as: T1=1.1
*39k*220u = 9.5
seconds, see (1).
58
Home Automation with Raspberry, Google & Python
4. If th e p ul se si gn al T1 , of 10 se co nd s,
disappears, a pulse, T2, of +5v is generated by
the second NE555*, adjusted by the pair R+C=
8k2Ω+220uF at 2 seconds, calculated as: T2 = 1.1
*8k2*220u = 2 seconds, see (2).
59
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Other Actuators
⊝⊝⊝
60
Home Automation with Raspberry, Google & Python
7.-SUMMARY
INPUTS vs OUTPUTS
I
n summary: so far we have described most of
the hardware of the inputs and outputs of
the system, being the p_global.py software
in charge of relating them according to
various situations, variables, functions and
algorithms that we will go describing.
61
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Inputs
62
Home Automation with Raspberry, Google & Python
*Outputs
63
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Temperature X X X
Garage gate X X X X X
Smoke X X X X X (*)
Flood X X X (*)
Leak X X X X (*)
Presence X X
Twilight X X X X X
Reset X X X
Power X X X
Doorbell X X X X
CO2 X X X X (*)
Online X X
KNX* X X X X
Keyboard X X
Thermostat X X X
IFTTT* X X X X X
Voice X X X X
BOT* X X X X X
LCD display X X
Screen X X X X X
(*) priority 1
⊝⊝⊝
64
Home Automation with Raspberry, Google & Python
8.-POWER SUPPLY
I
n the system there are components that need
+5v and others +3.3v, so a dual power
supply is needed as indicated below. This
power supply is very easy to build because
the system consumption is very low and therefore many
electronic components are not necessary.
65
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
66
Home Automation with Raspberry, Google & Python
*Systems that
need +5v
7. L o g i c l e v e l c o n v e r t e r SODIAL* 20mA of
consumption.
67
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Systems that
need +3.3v
68
Home Automation with Raspberry, Google & Python
*Other power
supply systems
69
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
⊝⊝⊝
70
Home Automation with Raspberry, Google & Python
9.-HOME CONNECTIVITY
STRUCTURE
I
n order to communicate the different
elements of the system: central control
with Raspberry*_home automation, screen
access control to the system, with
Raspberry*_screen, sensors, actuators, etc., a series
of elements are needed interconnected with each other,
either by physical LAN (Gigabit* type 100/1000Mbs or
10/100Mbs), or by WIFI, as well as an external
connection by Fiber Optic (it can also be by DSL* or
even by mobile data type 3G/4G*).
71
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Service Configuration
WAN Internet IP, etc.
Administration User, pass (customise recommended)
WIRELESS SSID, wap2-psk and custom password
LAN Gateway, IGMP enabled, static DHCP
*
NAT /portforwarding TCP/UDP accessible from outside
72
Home Automation with Raspberry, Google & Python
*Bridges Configuration
73
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
74
Home Automation with Raspberry, Google & Python
*HGU* Router
Configuration
75
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Network Topology:
Router, Switches & Bridges
76
Home Automation with Raspberry, Google & Python
*Protection of the
Router & Bridges
77
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Assignment of
IP Addresses
78
Home Automation with Raspberry, Google & Python
IP
Device 192.168.1.x
Obs MAC Maker
79
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
IP
Device 192.168.1.x
Obs MAC Maker
80
Home Automation with Raspberry, Google & Python
81
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Important Issues
interface wlan0
inform 192.168.1.[IP WIFI]
interface eth0
inform 192.178.1.[IP LAN]
82
Home Automation with Raspberry, Google & Python
6x garage
7x main floor
8x 1st floor
9x 2nd floor
x0 iMac*-LAN
x1 iMac*-WIFI
x2 Raspberry*-LAN
x3 Raspberry*-WIFI
x4 TV_a
x5 TV_b
x6 PS4*
x7 Edimax*
x8 WIFI bulb
x9 TP-Link* WIFI extender
https://www.adminsub.net/mac-address-finder
⊝⊝⊝
83
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
10.-OTHER ASPECTS
OF THE HARDWARE
N
ext we will see other hardware issues
(HDMI, decoders, Ethernet*, Tadoº*, etc.),
they are not essential but they are
interesting. For example:
84
Home Automation with Raspberry, Google & Python
*HDMI-CEC* Activation
85
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Connection of
two decoders
86
Home Automation with Raspberry, Google & Python
For example:
87
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Gigabit Ethernet
1Gb connection
88
Home Automation with Raspberry, Google & Python
89
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Troubleshooting
of Tadoº Thermostat
S o m e t i m e s t h e Tadoº* B r i d g e i s
randomly disconnected from the network
(punctual Internet cutting, interference
with the multicasting of decoders,
punctual power cuts, cuts in
communication with the Tadoº* server,
Router problems, etc.) & it doesn't work.
90
Home Automation with Raspberry, Google & Python
91
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
4. Run: ./LCD35_v
cd LCD_show_v6_1_3
7. Run: ./LCD_hdmi
92
Home Automation with Raspberry, Google & Python
⊝⊝⊝
93
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
11.-RASPBERRY*_HOME
AUTOMATION
CENTRALISED SYSTEM
F
or the centralised
control of the
s y s t e m , a Raspberry*
Pi 3, model B+, is
used with the following
functionalities and parameters:
1. Raspbian* Stretch
operating system over
Linux9*.
6. P r i v a t e a n d p u b l i c k e y
generation with command:
94
Home Automation with Raspberry, Google & Python
11. GPIO* 4 0- p in to c o n tr o l h o me a ut o m at i on
systems.
95
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
96
Home Automation with Raspberry, Google & Python
https://raspberrypi.org
97
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Installation
from Zero
Be lo w ar e a l l r ec o mm en de d op er a ti on s to
configure this Raspberry*, most are common with the
configuration of the Raspberry*_screen, although some
specific to the latter are described below.
username=pi password=raspberry
98
Home Automation with Raspberry, Google & Python
sudo raspi-config
Raspberry*_home automation:
192.168.1.a0 for LAN and 192.168.1.a1 for WIFI
Raspberry*_screen:
192.168.1.b0 for LAN and 192.168.1.b1 for WIFI
Sudo crontab -e
@reboot /usr/local/bin/pigpiod
99
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Use of External
Disks
Command Description
sudo fdisk -l lists the partitions
sudo mkfs.ext3 formats partition in
ext3
sudo mkdir /media/[disk] creates [disk] in
directory: /media/
sudo nano /etc/fstab edits initial
configuration and add:
/dev/sdb/media/[disk] ext3 defaults 0
sudo chown pi /media/[disk] gives permissions and
owner
sudo mount -a mounts [disk]
df -h sees size disk installed
100
Home Automation with Raspberry, Google & Python
Command Description
hostnamectl knows the installed
version
sudo apt-get update downloads the software
to update
sudo apt-get upgrade upgrades to the
downloaded version
sudo apt-get dis-upgrade updates the firmware
sudo apt-get autoclean deletes temporary files
sudo apt-get autoremove deletes unnecessary
packages
101
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Bluetooth settings
102
Home Automation with Raspberry, Google & Python
*Package Installation
Command Description
sudo dpkg-get-selections sees which packages are
installed
sudo apt-get remove [package] uninstalls the desired
[packaged]
sudo apt-get purge [package] deletes the uninstalled
[package]
sudo apt-get autoclean deletes orphaned
packages
sudo apt-get autoremove deletes unnecessary
packages
103
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Assign Fixed IP
to Raspberry*
To e a s i ly a c c e ss t h e b ot h Raspberry*, f o r
example by VNC* or by SSH*, or to access from outside
the installation, the Raspberry* IP must be fixed and
static. Maintaining Raspberry* with fixed and known IP
saves a lot of search time and prevents multiple
errors in access. To do this:
4. I t c a n a l s o b e d o n e b y accessing the
configuration files such as:
104
Home Automation with Raspberry, Google & Python
*Startup Configuration
/home/pi/home_auto/[*].sh:
105
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#! /bin/bash
echo 'Booting p_logfile.py...'
cd /home/pi/home_auto
lxterminal --command='sudo python p_logfile.py'
--geometry=105x25 –title = 'Logfile'
And add:
To check if it works:
106
Home Automation with Raspberry, Google & Python
~/.config/lxsession/LXDE-pi/autostart
107
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Raspberry*
HDMI Resolution
The re so lu ti on de fi ne d i n t he Raspberry*
configuration affects, on the one hand, the resolution
applied to its HDMI output, but also the resolution
displayed in remote mode from VNC*.
108
Home Automation with Raspberry, Google & Python
*Main Screen
Settings
lxterminal --command=
'sudo python /home/pi/home_auto/p_telegram.py'
--geometry=30x3 -–title='Telegram'
lxterminal --command=
'sudo python /home/pi/home_auto/p_logfile.py'
--geometry=105x25 –-title='Logfile'
⊝⊝⊝
109
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
12.-MANAGEMENT SYSTEM
RASPBERRY*_SCREEN
T
his second Raspberry*
is not essential but
has been added to the
project to see how
management and information can
be shared between two Raspberry*
and have more and better control
over home automation.
110
Home Automation with Raspberry, Google & Python
111
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Home Automation
Command Management Screen
112
Home Automation with Raspberry, Google & Python
*Support of a
PLEX* Server
https://www.plex.tv/
113
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Simulation of
a Photo Frame
114
Home Automation with Raspberry, Google & Python
*Various
1. See http://www.waveshare.com/wiki/
115
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Network and
Boot Disks
# Network disks
//192.168.1.[IP]/public/home/pi/disks/public
cifs username=1,password=1 0 0
//192.168.1.[IP]/pi_home_auto/home_auto/home/
pi/DISKS/home_auto cifs file_mode=0777,
dir_mode=0777, username=1,password=1 0 0
//192.168.1.[IP]/sirio/home/pi/disks/sirio
cifs username=1,password=1,vers=1.0 0 0
116
Home Automation with Raspberry, Google & Python
*Startup Configuration
and add:
117
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
118
Home Automation with Raspberry, Google & Python
*Screen Saver
Settings
And configure:
119
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Configure the
Touch Screen
# 7” screen configuration
max_usb_current =1
hdmi_group =2
hdmi_mode =1
hdmi_mode =87
hdmi_cvt 1024 600 60 6 0 0 0
hdmi_drive =1
See:
http://www.waveshare.com/wiki/
120
Home Automation with Raspberry, Google & Python
*PLEX* Server
Installation
121
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
1. See: https://www.codedonut.com/raspberry-pi/
raspberry-pi-plex-media-server/
And change:
PLEX_MEDIA_SERVER_USER=pi
122
Home Automation with Raspberry, Google & Python
*Home Automation
Action Buttons
Button Description
Open window blinds Opens all window blinds
Close window blinds Closes all window blinds
Turns off all lights
Turn off all lights
(both KNX* and WIFI)
Activates MOVIE=ON (closes
Movie ambient some window blinds, turns off
some lights & turns on others)
Activates HOLIDAYS=ON
(performs some automatic
Holidays ON procedures with some window
blinds & lights at certain
times)
Holidays OFF Activates HOLIDAYS=OFF
Gas ON Opens the gas solenoid valve
Gas OFF Closes the gas solenoid valve
Water ON Opens the water electro valve
Water OFF Closes the water electro valve
Reset ROUTER Resets Router 192.168.1.[IP]
Reset NAS Resets NAS 192.168.1.[IP]
123
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
⊝⊝⊝
124
Home Automation with Raspberry, Google & Python
13.-ADDITIONAL DEVICE
SOFTWARE
I
n addition to containing the necessary and
specified hardware, it is necessary to
configure the software that is needed for
each of the devices that complement the set
of sensors and actuators.
125
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Temperature and
Humidity Sensor
wget abyz.co.uk/rpi/pigpio/code/DHT22_py.zip
@reboot /usr/local/bin/pigpiod
126
Home Automation with Raspberry, Google & Python
*Edimax*
127
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
smartplug_digest_auth.py
5. B e f o r e i n t e g r a t i n g p_smartplug.py into
p_global.py, it is highly recommended to start
it in a test program, for example, p_edimax.py
that is located in the /home/pi/home_auto/
folder.
128
Home Automation with Raspberry, Google & Python
129
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*TP-LINK* WIFI
Bulb LB100*
130
Home Automation with Raspberry, Google & Python
T h i s c h a t i s i n t e g r a t e d i n t o t h e Python*
p_telegram.py program and it needs to know the status
of the TP-Link* LB_100 bulb.
1. See https://github.com/konsumer/tplink-lightbub
131
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
fbombilla='/home/pi/home_auto/p_bulb.txt'
#capture the state of light bulb
file=open(f_bulb, 'r')
text=file.readlines()[19][14] #line 19, pos 14
text=='0' #WIFI bulb OFF
text=='1' #WIFI bulb ON
132
Home Automation with Raspberry, Google & Python
*TP-LINK* WIFI
Extender
133
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
134
Home Automation with Raspberry, Google & Python
*RM-MINI 3*
Broadlink Converter
For it:
1. L o c a t e t h e RM* n e a r t h e d e v i c e s t o b e
controlled: TV, decoder, colour lamp (in this
c a s e a TAO-GLOW* m o d e l ) , Apple* TV, audio
amplifier, etc.
135
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
✓ See https://forum.pimatic.org/topic/3074/
python-how-to-integrate-cheap-broadlink
-rm3-mini-ir-blaster-with-pimatic
136
Home Automation with Raspberry, Google & Python
[General]
IPAddress=192.168.1.[IP]
Port=80
MACAddress=78:0f:77:xx:xx:xx
Timeout=10
[Commands]
6. In the directory:
/home/pi/home_auto/infrared/ BlackBeanControl.py
RM3Device=broadlink.rm((RealIPAddress,RealPort),
RealMACAddress,RealTimeout)
137
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
138
Home Automation with Raspberry, Google & Python
Source and
Right source p_tv_s_right TV
select right
Source and
Left source p_tv_s_left TV
select left
Turn on Apple*
Turn on Apple* p_apple_on TV
Apple*
Turn off
Turn off Apple* p_apple_off Apple*
Apple* TV
T h e f o l l o w i n g Webhooks* w i t h o r i g i n in
Raspberry*_home automation are also defined:
139
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
/home/pi/home_auto/[*].py:
http://[user]:[pass]@[URL]/p_bulb_{{TextField}}.php
Where:
Parameter Description
Apache* server (*) user in
[user] Raspberry*_home automation
(we will see it)
[pass] Idem for the password
Address of he public page, hosted in
[URL]
NO-IP* (we will see)
File name [*].php captured by the $
{{TextField}}
symbol
140
Home Automation with Raspberry, Google & Python
141
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
142
Home Automation with Raspberry, Google & Python
1) Direct method:
◦ Unplug and plug the power switch.
◦ Press the Sonoff* button, 6 seconds (it will
start to flash slowly).
◦ Start the eWelink* APP on your mobile or
tablet and select the WIFI (only 2.4Ghz, it does
not work with 5Ghz) that covers the switch.
◦ Detected the switch, follow the rest of the
steps. If this does not work go to method 2
described below.
2) AP method:
◦ Unplug and plug the switch into the mains.
◦ Press its button for 6 seconds and release it
(the LED flashes slowly).
◦ Press the button again for another 6 seconds
(the LED should flash quickly).
◦ Connect the mobile to the WIFI generated by
switch, of the type ITEAD*-1000xxx and initial
password 12345678
◦ E n t e r t h e A P P eWelink* a n d w a i t f o r
connection.
◦ Detected the switch, follow the rest of the
steps and finish its configuration.
◦ If there are problems, deactivate the 5GHz
WI FI of th e R ou te r o r Br id ge , t o a vo id
interference and try pairing again.
143
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
sudo cp /home/pi/.local/lib/python2.7/site-packages
/sonoff /home/pi/home_auto
sss=sonoff.Sonoff('[user]','[pass]','[rr]')
Where:
devices=sss.get_devices()
dispo=devices[x]['deviceid']
sss.switch(action,dispo,None)
Where:
⊝⊝⊝
144
Home Automation with Raspberry, Google & Python
14.-LINUX
RASPBIAN*
T
h e Raspberry* integrates a
complete operating system
of t h e Linux* f a m i l y ,
called Raspbian* and which
we have already mentioned
previously.
www.raspbian.org
145
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Basic Instructions
146
Home Automation with Raspberry, Google & Python
/home/pi/home_auto/system_home_auto/save_home.sh
#!/bin/bash
echo "Copying files..."
sudo cp ~/.config/lxsession/LXDE-pi/autostart
/home/pi/home_auto/system_home_auto/autostart
sudo cp /boot/config.txt
/home/pi/home_auto/system_home_auto/config.txt
sudo cp /etc/fstab
/home/pi/home_auto/system_home_auto/fstab
sudo cp /home/pi/.config/openbox/lxde-pi-rc.xml
/home/pi/home_auto/system_home_auto/lxde-pi-rc.xml
sudo cp /etc/rc.local
/home/pi/home_auto/system_home_auto/rc.local
sudo cp /etc/samba/smb.conf
/home/pi/home_auto/system_home_auto/smb.conf
sudo cp /home/pi/home_auto/save_home.sh
/home/pi/home_autos/system_home_auto/save_home.sh
echo "...copy made"
147
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
/home/pi/home_auto/system_rasp_screen/save_screen.sh
#!/bin/bash
echo "Copying files..."
sudo cp ~/.config/lxsession/LXDE-pi/autostart
/home/pi/home_auto/system_rasp_screen/autostart
sudo cp /boot/config.txt
/home/pi/home_auto/system_rasp_screen/config.txt
sudo cp /etc/fstab
/home/pi/home_auto/system_rasp_screen/fstab
sudo cp /home/pi/.config/openbox/lxde-pi-rc.xml
/home/pi/home_auto/system_rasp_screen/lxde-pi-rc.xml
sudo cp /etc/rc.local
/home/pi/home_auto/system_rasp_screen/rc.local
sudo cp /etc/samba/smb.conf
/home/pi/home_auto/system_rasp_screen/smb.conf
sudo cp /home/pi/home_auto/save_screen.sh
/home/pi/home_auto/system_home_auto/save_screen.sh
echo "...copy made"
bash save_[*].sh
148
Home Automation with Raspberry, Google & Python
*Use of External
Disks
Command Description
sudo fdisk -l List of existing disks
Formats partition in
sudo mkfs.ext3
ext3 filesystem
Creates access to
sudo mkdir /media/[disk] [di sk ] i n d ir ec to ry
/media/
Edit configuration
sudo nano /etc/fstab initial mount of disks
and add:
/dev/[partition]/media/[disk] ext3 defaults 0
Assign owner user pi to
sudo chown pi /media/[disk]
disk [disk]
Mount all disks
sudo mount -a
(defined in fstab)
Unmount the disk in
sudo umount /dev/[partition]
[partition]
⊝⊝⊝
149
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
15.-VNC*
F
or more convenience in
a c c e s s i n g t h e Raspbian*
operating system of both
Raspberry*, all its con-
tent and the home automation
system and not to block other
resources such as a TV (via
HDMI-CEC*) , t h e n e e d f o r a
keyboard, a mouse, having to
locate the Raspberry* very close
to the TV, etc., it is recommended to use a remote
connection via the VNC* software (local application or
Chrome* plugin), which allows access to the Raspberry*
from the mobile, a tablet, a computer, etc. and not
only from the internal network of the home, it also
allows access from outside the home.
150
Home Automation with Raspberry, Google & Python
151
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*General
#!/bin/sh
vncserver:0 -geometry 1920x1080 -depth 24 -dpi 96
chmod +x svnc.sh
./svnc.sh to run
vncpasswd to change or edit password or
from <vnc server>
<change password>
152
Home Automation with Raspberry, Google & Python
*VNC* pointer
153
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Virtual Desks
1. Start:
4. See:
www.librebit.github.io
154
Home Automation with Raspberry, Google & Python
155
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*VNC* on Another
Tablet-Screen
We do the following:
/sdcard/Android/data
156
Home Automation with Raspberry, Google & Python
⊝⊝⊝
157
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
16.-LXTERMINAL*
W
e have already spoken that
the Raspbian* o p e rating
sys tem , wh ich su ppo rts
both Raspberry*, contains a
terminal emulator: LXTerminal*.
158
Home Automation with Raspberry, Google & Python
*General
And change:
Or also:
And add:
geometry_columns =60
geometry_rows =25
@/home/pi/home_auto/[*.sh]
159
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Script Description
p_start_global.sh Starts p_global.py
p_start_telegram.sh Starts p_telegram.py
p_start_logfile.sh Starts p_logfile.py
#!/bin/bash
echo 'Booting p_logfile.py ...'
cd /home/pi/home_auto
lxterminal --command='sudo python p_logfile.py'
--geometry=105x25 –title='Logfile'
160
Home Automation with Raspberry, Google & Python
*Other Options
in LXTerminal*
And change:
And add:
<applications>
<application name="*">
<decor>no</decor>
</application>
</applications>
⊝⊝⊝
161
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
17.-NO-IP*
W
e have already commented
that every time we turn
off and on the main
Router (unless we have a
fixed public IP contracted with
the telecommunications operator
and usually has a monthly fee),
the public IP of our main
Router will change. This is a
problem when we want to access
our Router remotely because we do not know, if we are
outside the home, what is that IP.
162
Home Automation with Raspberry, Google & Python
163
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*General
<my accounts>
service: no-ip.com
name: [our URL]
username: [our e-mail]
password: [our password]
<my hostnames>
service: [our URL]
hostname: [our URL]
<auto update> <refresh>
http://[URL].hopto.org
Or also:
164
Home Automation with Raspberry, Google & Python
Or also:
http://[user]:[pass]@[URL].hopto.org If username
and password are used.
165
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Installation
mkdir noip
cd no ip
wget http://www.no-ip.com/client/linux/
noip-duc-linux.tar.gz
tar vzxf noip-duc-linux.tar.gz
sudo apt-get install build-essential
make
sudo make install
sudo nano /etc/rc.local and add:
/usr/local/bin/noip2
166
Home Automation with Raspberry, Google & Python
For example:
167
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
168
Home Automation with Raspberry, Google & Python
*Important
www.no-ip.com as:
169
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
www.no-ip.com>
⊝⊝⊝
170
Home Automation with Raspberry, Google & Python
18.-COLORAMA*
N
ext we talk about Colorama*, an additional
Python* software module and that allows to
improve the presentation of the screens of
the home automation program, p_global.py,
making it more attractive, readable, clear and
friendly.
Specifically, this
module, which is only valid in
the environment of the
Raspbian* terminal emulator,
this is in LXTerminal*, allows
it to position text in a
specific and fixed place in a
window, assigning it a series
of attributes: colour of the text, colour of the
background, font, brightness, flickering, etc.
171
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Installation and
Commands
See: http://nullege.com/
Instruction Action
Fore.GREEN+'Text' Displays 'Text' with green letter
Back.RED+'Text' Displays 'Text' with red background
Displays 'Text' with normal
Style.NORMAL+'Text' brightness
Displays 'Text' with high
Style.BRIGHT+'Text' brightness
Style.RESET_ALL Restores all settings
Style.BLINK Blinks text
Style.UNDERLINED Underlines text
init(autoreset=True) Restores style after writing
Cursor.BACK(x) Goes back x characters
Cursor.FORWARD(x) Goes forward x characters
Cursor.UP(x) Goes up x characters
Cursor.DOWN(x) Goes down x characters
Positions the cursor on
Cursor.POS(c,r)
c=column & r=row
172
Home Automation with Raspberry, Google & Python
*Examples
print (Cursor.POS(48,23)+Fore.YELLOW+'Hello')
print (Cursor.POS(1,2)+Style.BRIGHT+Fore.RED+'Start:')
print (Cursor.POS(2,5)+Fore.WHITE+Back.GREEN+write(x))
print (Cursor.POS(10, 5)+''*27)
print (Cursor.POS(10.5)+Fore.BLUE+Back.WHITE+
time.strftime('%X'))
trace (Cursor.BACK(20.30)+'P'+str(write(5)))
⊝⊝⊝
173
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
19.-TKINTER*
A
nother very interesting
Python* module and that in
this project is used in
t h e p_screen.py program
(which we will see later), is
Tkinter*, which basically allows
to create and locate buttons on
the screen, with different
formats, colours, sizes, fonts,
associated gifs, motion effects,
etc. and that pressing them can execute additional
Python* scripts.
174
Home Automation with Raspberry, Google & Python
*General Information
See www.guia-tkinter.readthedocs.io
175
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Buttons Creation
176
Home Automation with Raspberry, Google & Python
We would do:
window=Tk()
source=tkFont.Font(family='Helvetic',size=20,)
#the height and width are in lines
window.geometry('800x600+100+0')
#width and height adjustment and right-hand shift
window.resizable(width=False,height=False)
#to avoid changing screen size
window.config(cursor="none")
#to avoid displaying the cursor in the screen
window.config(background='cyan')
# background screen colour
button_open.pack()
button_open.place(x=left,y=height+offset,
width=width_short,height=height_short)
image1=PhotoImage(file='/home/pi/home automation/
photos/blinds.gif')
button_open.config(image=image1)
mainloop()
177
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Use of Images
on Buttons
178
Home Automation with Raspberry, Google & Python
*Hide Cursor
on Screen
Do the next:
And add:
<applications>
<application name="*">
<decor>no</decor>
</application>
</applications>
179
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
180
Home Automation with Raspberry, Google & Python
And select:
sudo raspi-config
<advance options> <audio> <AUTO>
If it wants to do it by BT (Bluetooth*), it is
only necessary to activate the BT speaker and put it
in pairing mode, enter the top bar of Raspbian* and
select the BT icon:
⊝⊝⊝
181
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
20.-SAMBA*
W
e had already commented
previously, that to manage
home automation commands
from the Raspberry* touch
screen, it is necessary to have
information exchange files
between both Raspberry*.
182
Home Automation with Raspberry, Google & Python
*General
#Network disks
//192.168.1.[IP[/public /home/pi/disks/public
cifs username=1,password=1 0 0
//192.168.1.[IP[/pi_home_auto/home_auto /home/pi/
disks/home_auto cifs file_mode=0777,
dir_mode=0777,username=1,password=1 0 0
//192.168.1.[IP]/sirio /home/pi/disks/sirio
cifs username=1,password=1,vers=1.0 0 0
sudo su
python /home/pi/home_auto/p_screen.py
And add:
183
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Action Description
Turn off lights Turns off all lights
Lights the living room lamp
Lights living room sofa
in the sofa area
Watch movie Actives movie mode
Closes a group of
Close window blinds
window blinds
Opens a group of
Open window blinds
window blinds
Open living room window Opens living room window
blinds blinds
Open all window blinds Opens all window blinds
Holidays ON Activates Holidays mode
Holidays OFF Deactivates Holidays mode
Opens the electro valve of
Water ON
the water
Closes the electro valve of
Water OFF
the water
184
Home Automation with Raspberry, Google & Python
Action Description
Gas ON Opens the gas electro valve
Gas OFF Closes the gas electro valve
Heating ON Sets thermostat in PRESENCE
Heating OFF Sets thermostat in ABSENCE
Resets
Clear screen
the p_global.py screen
Reset NAS Resets de home NAS
Reset ONT *
Resets ONT* communication
Reset ROUTER Resets the main ROUTER
Resets
Reset RASPBERRY*
Raspberry*_home automation
185
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Samba Installation
workgroup =WORKGROUP
wins support =yes
and at the end, in section [pi], add:
[pi_home_auto]
comment =user directory
path =/home/pi
browseable =Yes
writeable =Yes
read only =no
only guest =no
create mask =0777
directory mask =0777
public =Yes
186
Home Automation with Raspberry, Google & Python
⊝⊝⊝
187
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
21.-TELEGRAM*
I
n order to interact with the
home automation of the house, in
addition to using VNC* or acting
with the buttons of the
Raspberry*_ screen, a Telegram BOT* has
been added, which with the execution
of a sim ple Python* module in the
Raspberry*_home automation allows to
execute a series of commands to
perform the most important and fundamental home
automation actions. To do so, both from home and from
outside it, we only need an Internet access.
188
Home Automation with Raspberry, Google & Python
*General
https://geekytheory.com/tutorial-raspberry
-pi-use-of-telegram-with-python
https://www.fwhibbit.es/controla-tu-raspberry
-pi-via-telegram
189
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Install
System Features
token in @BotFather
rasp in @Rasp [user]Bot
Finally:
190
Home Automation with Raspberry, Google & Python
191
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Change Type
of Text in the BOT*
bold bot.send_message(cid,'*text*',
parse_mode='Markdown')
italic bot.send_message(cid,'_text_',
parse_mode='Markdown')
192
Home Automation with Raspberry, Google & Python
*Device List
pid =Popen(["arp","-n",host],stdout=PIPE)
s =pid.communicate()[0]
193
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
mac =re.search(r”(([a-f\d]{1,2}\:){5}[a-f\d]
{1,2})”,s).groups()[0]
Where:
Where:
194
Home Automation with Raspberry, Google & Python
Living room TV
Bedroom TV
PS4* WIFI
Main Router
Each Bridge
Edimax*
Tadoº*
WIFI bulbs
RM* mini
Google Home*
Alexa*
Both Raspberry*
iMac*
195
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Public and
Local IP Detection
http://miip.es
https: //www.cual-es-mi-ip.net/
http://www.cualesmiip.com/
import urllib2
ip=urllib2.urlopen(url_ip).read()[a:b]
196
Home Automation with Raspberry, Google & Python
22.-IFTTT*
W
ith the emergence of
multiple home automation
hardware manufacturers,
with diverse parameters
and protocols, various action
integrators have also appeared.
197
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*General
T o c o n f i g u r e a c c e s s t o IFTTT* f r o m the
Raspberry*_home automation, do the following:
Enter at:
https://ifttt.com/maker_webhooks
https://ifttt.com/maker_webhooks
Or from Python*:
To add it in Python*:
import requests
requests.post('https://maker.ifttt.com/
trigger/'+[webhook]+'/with/key/'+/[key])
-H “Content - Type:application/json”
-d'{“value[1]”:“[parameter]”}
...-d'{“value[n]”:“[parameter]”}
198
Home Automation with Raspberry, Google & Python
199
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Webhooks* Created
Webhook* Description
ambient_on/off On/off switch Sonoff* ambient
bridge_on/off On/off switch Sonoff* Tadoº*
bulb_on/off On/off lamp TP-Link* WIFI
kitchen_on/off On/off switch Sonoff*+RF kitchen
colours_on/off On/off colours lamp
deco_on/off On/off living room decoder
tv_on/off On/off living room TV
screen_on/off On/off switch Sonoff* screen
tado_auto Tadoº* goes to automatic mode
Tadoº* goes to 18°C (64,4°F)
tado_on_18
setpoint
Tadoº* goes to 22°C (71,6°F)
tado_on_22
setpoint
tado_off Tadoº* turns off heating
Adds /home/pi/home_auto/
log_dropbox
p_logfile.txt to DropBox*
send_sms Send an SMS
rasp_calendar Adds specific event to calendar
⊝⊝⊝
200
Home Automation with Raspberry, Google & Python
23.-GOOGLE
ASSISTANT*
I
n this section we will see
how, using Artificial
Intelligence integrated in
a speaker with a personal
assistant, we can provide the
entire system with much more
added value.
201
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
202
Home Automation with Raspberry, Google & Python
*General
www.sistemasorp.es
203
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Important
204
Home Automation with Raspberry, Google & Python
*Script Creation
*.PHP Description
p_open.php Opens all window blinds
Opens living room window
p_open_living.php
blinds
Adds/removes ambient to
p_ambient_on/off.php
p_devices.txt
p_turn_off.php Turns off all the lights
p_turn_on/off_sofa.php Turns on/off sofa lamp
p_apple_on/off.php Turns on/off Apple* TV
Increases/decreases +5dB
p_audio_more/less.php
audio amplifier volume
p_audio_mute.php Puts mute in the amplifier
p_audio_on/off.php Turns on/off amplifier
p_close.php Closes all window blinds
p_colours_auto.php Puts colour lamp in auto
Puts colour lamp in a
p_colours_[colour].php
concrete colour
205
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*.PHP Description
Puts colours lamp with
p_colours_more/less_br.php
maximum/minimum brightness
p_colours_on/off.php Turns on/off colours lamp
p_deco_back.php Goes back decoder screen
p_deco_more/less.php Advances/goes back program
p_deco_mute.php Decoder mute
p_turn_on_sofa.php Turns on the sofa lamp
Adds/removes bridge Tadoº*
p_bridge_on/off.php
to p_devices.txt
Puts desco on channel
p_put_[number].php
number [number]
Puts desco con channel
p_put_[name].php
name [name]
Adds/removes screen to
p_screen_on/off.php
p_devices.txt
Adds/removes Tadoº*
p_tado_away/home.php
away/home to p_devices.txt
A d d s Tadoº* >22°C, <22°C
p_tado_more/less22.php
to p_devices.txt (71,6°F)
Adds Tadoº* >50%, <50% HR
p_tado_more/less50.php
to p_devices.txt
Advances/goes back living
p_tv_more/less.php
room TV channel
Activates input sources
p_tv_source.php
from the living room TV
Advances right in the
p_tv_source_right.php
source selection
Advances left in the
p_tv_source_left.php
source selection
p_watch_movie.php Activates movie ambient
206
Home Automation with Raspberry, Google & Python
*Topics to Review
sudo ls -l
/var/www/html/index.html
207
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
208
Home Automation with Raspberry, Google & Python
*Protect Apache*
with User & Password
To do this:
<Directory “/var/www/html”>
AuthType Basic
AuthName “For administrators only”
AuthUserFile /etc/apache2/.htpasswd
Requires valid-user
</Directory>
209
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
http://[user]:[password]@[URL].hopto.org:80/[x]
p_turn_off.php
p_close.php
p_open.php
p_open_living.php
p_turn_on/off_sofa.php
p_[*].php
any *.php defined in the previous tables
210
Home Automation with Raspberry, Google & Python
*Applets Created
in IFTTT*
211
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Turn on/off
screen
Google* eWelink* On/off screen switch
On/off WIFI
Turn on/off bulb Google* TP-link* bulb
Turns on WIFI bulb to
Bulb to 10% Google* TP-link* 10% of brightness
Open living room Opens blinds of
window blinds
Google* KNX* living room
212
Home Automation with Raspberry, Google & Python
Turns on heating on
tado_on_22/18 Raspberry* Tadoº* 22/18°C (71,6/64,4°F)
Set Tadoº* thermostat
tado_auto Raspberry* Tadoº* on auto mode
Button
Close widget KNX* Closes all blinds
213
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
214
Home Automation with Raspberry, Google & Python
*Routines in
Google Home*
Routine Description
Turns on/off the amplifier
via RM* (infrared) and
[turn on/off the TV]
turns on the TV via
Chromecast*
Activates movie ambient
[watch movie] and runs [turn on the TV]
routine
Announces weather
forecast, agenda, the
[good morning]
reminders for today and
opens all blinds.
Runs [turn off the TV]
routine, announces the
weather forecast & agenda
[good evening]
for tomorrow, closes all
the blinds and turns off
all the lights
215
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Routine Description
Turns off Raspberry*_
screen & all the lights
[good bye]
and runs [turn off the TV]
routine
Turns on Raspberry*_
screen, reads the
[i'm home]
reminders and runs [turn
on the TV] routine
216
Home Automation with Raspberry, Google & Python
217
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Room Devices
Kitchen eWelink*
Ewelink*, Tadoº*
Room
bridge
Tp-Link* bulb,
Chrome*, Google*
Mini, eWelink*
Living Room ambient,
Raspberry*_screen,
Tadoº* thermostat,
TV, decoder etc.
Act with:
218
Home Automation with Raspberry, Google & Python
*Google* Broadcasting
219
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
220
Home Automation with Raspberry, Google & Python
221
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
10. To e x e c u t e th e s c r i p t we will do fr o m
p_global.py the following:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www
<Location /html>
AuthType basic
AuthName "Authorisation is required"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Location>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log
combined
</VirtualHost>
222
Home Automation with Raspberry, Google & Python
*Previous situation:
http://[user]:[password]@[URL].hopto.org/[*].php
*New situation:
http://[user]:[password]@[URL].hopto.org/html/[*].php
223
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Alarm: power/smoke/gas/flood/C02/bell.
Recovered from Internet shutdown.
KNX* thermostat absence/presence.
Lights off.
Living room lamp off/on.
Window blinds/gate opened/closed.
Water/gas valve opened/closed.
Movie/holiday atmosphere on/off.
System screen cleared.
NAS/ONT/Raspberry* reset.
Reset/Delete/Send key pressed.
Long/Short reset pressed.
Barks de guard dog (or other *.mp3 sound)
$ Status information
Water Open/Closed water valve
Gas Open/Closed gas valve
Holidays Holidays on/off
Ambient Ambient scene on/off
Garage Garage gate open/closed
NAS DHT22* temperature and humidity
Raspberry* CPU and GPU temperatures
Summary Summarise all the above
⊝⊝⊝
224
Home Automation with Raspberry, Google & Python
24.-PYTHON 2.7*
F
or programming control
modules, management,
monitoring, reports, etc. of
this home automation system,
in the two Raspberry*, the most
f a m o u s e v e r y d a y , Python 2.7*
programming language has been used,
running on the Raspbian* operating
system, especially for being a
modern, powerful language, for its
greater ease of implementation, for the existence of
multiple libraries, manuals, tutorials, forums,
integration with home systems, easy integration with
Raspberry* hardware, etc.
225
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*General
226
Home Automation with Raspberry, Google & Python
*Added Libraries
227
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
228
Home Automation with Raspberry, Google & Python
*Summary Python*
Commands
https://www.python.org/
Command Description
# Comments 1 line
'''…''' Comments several lines
print text Displays text on screen
print '%s'%var Var formats print in %s
var=raw(input) Enters text & load variable var
Assigns int, real, boolean
=
variables
+,-,*,/ Basic operations
** Exponent
% Module, residue
229
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Command Description
// Entire division
Escape character, example '\n'
\
line break
Retrieves position x in variable
var[x]
var, counts from 0
len(x) Length string x
string.isalpha() Sees if variable is string
x.lower() Passes string x to lowercase
x.upper() Passes string x to uppercase
str(x) Converts x to a string
x+y Concatenates the strings x & y
Compares in if statements.
==
Do not confuse with =
!= Not equal in if statements
Operates & assigns in the same
-=,+=,*=
function
and, or, not Basic logical operations
a>>b Shifts 1 bit to the right
a<<b Shifts 1 bit to the left
a&b AND operation between bytes
a|b OR operation between bytes
a^b XOR operation between bytes
~a NOT operation
0bx Transforms x to binary
bin(x) Transforms string x to binary
oct(x) Transforms string x to octal
hex(x) Transforms string x to hexadecimal
int(x) Transforms string x to integer
Transforms string x to integer
int(x,s)
into base s
230
Home Automation with Raspberry, Google & Python
Command Description
If expression [exp] is true, the
if[exp]:
following instruction is executed
Else if following instruction is
elif[exp]:
executed
else: Other instructions are executed
Extracts from the string s from i
s[i:j]
to j-1. Counts form 0
s[i:] String s from i to the end
s[:j] String s from the beginning to j-1
Defines de fn function with
def fn(a,b):
arguments a & b
Returns the local variable x of
return(x)
the function fn
Calls the function fn with
fn(a,b,c)
parameters a, b & c
import x Imports library x
from m import f Imports f function from library m
dir(m) Sees libraries included in m
math.sqrt(x) Invokes the square root of x
type(x) Returns data type of x
Defines list as a data list from x
list=[x,...,z]
to z
list.append(e) Adds the element e to list
list.remove(e) Deletes item e from list
len(list) Number of list items
Truncates the list from position a
list[a:b]
to position b-1. Counts from 0
list.index(x) Position of x in list
Inserts the string s in the x
list.insert(x,s)
position
Sorts the list items and creates
list.sort()
an ordered list
231
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Command Description
sum(list) Adds elements of the list
Creates a list with pair of lists
zip(l_1,l_2)
l_1 & l_2
for x in list: Cycle through the list
while condition: Executes while condition is true
break Exits loop for or while
Creates dic dictionary with keys
dic={x:a,...,z:b}
x...z and values a...b
Returns value of the key x in the
dic[x]
dictionary dic
Deletes the key a & its value in
del dic[a]
dictionary dic
dic={} Empty dictionary
dic[x]=a Adds key x and value a to dic
Returns value_key from dic,
dic.items()
unordered
dic.keys() Returns keys from dic
dic.values() Returns values from dic
print dic[x] Prints key value x in dic
range(x) Element x of the list
Range from x to y with increment 1
range(x,y)
by default
range(x,y,z) Range from x to y and increase z
Imports random number management
import random
library
Generates random between integers
random.randint(x,y)
x & y
round(x,y) Rounds x to y decimals
s.split() Transforms string s into list
pass Does nothing
open([file],'w') Opens file [file] for writing
232
Home Automation with Raspberry, Google & Python
Command Description
open([file],'r') Opens file [file] for reading
open([file],'a') Opens file [file] for append
Opens file [file] for reading and
open([file],'r+')
writing
Reads a line in file [file]
[file].readline()
('\' included)
[file].close() Closes de file [file]
with
Automatically opens/closes [file]
open([file],'r') as
var in var object
233
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Error Handling
with try...except
import logging
logging.basicConfig(filename='/home/pi/home_auto
/p_global.py',level=logging.INFO)
try:
[…]
except Exception as e:
logging.exception(str(e))
print sys.exec_info()
234
Home Automation with Raspberry, Google & Python
Keyboard interrupt,
System error
I/O error
Import error
Value error
EOF error
OS error
General exception,
Etc.,
⊝⊝⊝
235
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
25.-KNX*
T
h e KNX* interface may not
be used in many home
automation developments,
because it is more
oriented to the office
environment than to the home
environment due to its high
price, the complexity of
installation and maintenance,
the need for a dependency on professional experts
integrators and officials, because of the difficulty
in obtaining devices, because it is a very closed and
proprietary system, with little or no security,
nothing friendly, very difficult to integrate with
other solutions, expensive, etc.
• Dimmer lamps.
236
Home Automation with Raspberry, Google & Python
• Twilight sensors.
237
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Configuration
http://michlstechblog.info/blog/raspberry-pi
-eibknx -ip-gateway-or-router-with-the-pi/
https://github.com/ThingType/KNX_Python_library/blob
/master/example_script.py
238
Home Automation with Raspberry, Google & Python
4. Examples:
239
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Parameters in
the Raspberry*
dtoverlay=pi3-disable-bt
240
Home Automation with Raspberry, Google & Python
*KNX* connection to
Raspberry* UART
241
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Serial* Installation
1. sudo rpi-config
enable_uart=1
https://github.com/ThingType/KNX_Python_library.git
https://github.com/atdt/monotonic.git
242
Home Automation with Raspberry, Google & Python
*Communication with
the UART*
ser=serial.Serial(port='/dev/ttyAMA0',
#for Raspberry* PI 3 without BT
port='/dev/serial0', #for Raspberry* PI 3 with BT
243
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Various
See www.knx.org
244
Home Automation with Raspberry, Google & Python
*Structure of the
KNX* Telegrams
Examples:
control: =BC
source: 1.1.10 =11-10
245
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
246
Home Automation with Raspberry, Google & Python
*Detail in the
Telegram Fields
247
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Examples:
248
Home Automation with Raspberry, Google & Python
BC-11-1F-28-02-E1-00-81-07
249
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
250
Home Automation with Raspberry, Google & Python
*Communication
Sequence
7. t2=13bits=1.35ms
8. d0+...+d7+parity=0
251
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
x Description x Description
1 2_room_b1 2 2_stair landing
3 2_room_a1 4 2_bathroom
5 1_room_a1 6 1_room_b1
7 1_stair landing 8 Free
9 Free 10 1_bathroom
11 0_entry 12 Free
13 0_living room terrace 14 -1_garage
0_living room lamp &
15 -1_laundry 16
blind
17 0_bathroom 18 -1_cellar
19 2_room_b2 20 2_room_a2
21 Free 22 1_room_a2
23 1_room_b2 24 Free
27 0_kitchen 28 0_thermostat
31 0_garage stairs up 32 Free
55 -1_Raspberry*_home 56 Free
75 0_all 76 0_all
77 0_twilight sensor 78 2_LCD display
0_living room wall 0_living room little
124 125
lights blinds
x Description x Description
7 2_stair landing 8 2_room_b1
252
Home Automation with Raspberry, Google & Python
x Description x Description
9 Free 10 2_bathroom ceiling
11 2_room_a1 12 Free
13 Free 14 1_bathroom ceiling
15 Free 16 1_stair landing
17 1_room_b1 18 1_room_a1
19 Free 20 0_kitchen
23 -1_garage 24 0_garage stairs up
25 Free 26 -1_garage stairs down
27 Free 28 0_entry
31 Free 32 0_bathroom ceiling
x Description x Description
1 2_room_b1 2 2_stairs landing
3 2_room_a1 4 Free
5 Free 6 2_bathroom ceiling
7 2_bathroom mirror 8 1_room_a1
9 1_room_b1 10 1_stairs landing
0_living room sofa 0_living room table
11 12
wall wall
13 1_bathroom ceiling 14 1_bathroom mirror
15 0_kitchen 16 0_entry
17 0_garage stairs up 18 0_bathroom ceiling
19 0_terrace 20 -1_cellar
21 -1_garage 22 -1_garage stairs down
23 -1_laundry 24 0_all
253
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
x Description x Description
25 -1_gym 26 0_hall
29 Free 30 0_bath mirror
x Description x Description
0_living room table 0_living room table
1 2
lamp lamp dimmer
0_living room room 0_living room sofa
3 4
sofa lamp lamp dimmer
0_living room all
5 0_living all lamps 6
lamps dimmer
x Description x Description
1 2_room_b1 2 2_stairs landing
3 2_room_a1 4 2_bathroom ceiling
5 1_room_a1 6 1_room_b1
7 1_stairs landing 8 Free
9 Free 10 1_bathroom ceiling
11 0_entry 12 Free
13 Free 14 -1_garage
15 0_garage stairs up 16 0_kitchen
17 0_bathroom ceiling 18 0_living room lamps
254
Home Automation with Raspberry, Google & Python
x Description x Description
15 1_room_a1 17 1_room_b1
0_living room small 0_living room small
19 21
left right
0_living room large
25 0_kitchen 27
right
0_living room large
29 0_all blinds 31
left
x Description x Description
1 0_right lamp 2 0_right dimmer lamp
3 0_left lamp 4 0_left dimmer lamp
5 0_both lamps 6 0_both dimmer lamps
x Description x Description
1 0_heater 2 0_presence/absence
255
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
x Description x Description
3 0_real temperature 4 0_setpoint temperature
x Description x Description
9 -1_gas 10 -1_water
For example:
• In closet 0_2:
62 A: sofa wall light B: table wall light
67 living room small right window blind
68 living room small left window blind
87 living room large left window blind
64 living room large right window blind
256
Home Automation with Raspberry, Google & Python
• In closet 1_1:
71 A: room_a1 light B: room_b1 light
72 A: room_a1 blind B: room_b1 blind
• In closet 2_1:
73 A: room_b1 light B: room_b2 light
74 A: ceiling bathr. light B: mirror bathroom light
• In closet 2_2:
75 A: 2_stairs landing B: 1_stairs landing
76 A: 2_room_b2
257
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
258
Home Automation with Raspberry, Google & Python
*Configuration in
p_global.py
Group Devices
Window_blinds_without Living room, kitchen,
alarm room_1/2
Window_blinds_living Living room small/larger
Living room small,
Window_blinds_auto
room_1/2
Window_blinds_movie Living room small
ambient & larger_50%
Window_blinds_holiday even Living room small,
days room_1
259
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Group Devices
Window_blinds_holiday odd
Living room small & room_2
days
Living room right,
lights_holiday even days
kitchen, room_1
Living room left, kitchen,
lights_holiday odd days
room_2
⊝⊝⊝
260
Home Automation with Raspberry, Google & Python
26.-ETS3/4*
T
o configure KNX* devices,
the o f f i c i a l ETS*
software, version 3, 4 or
5 could be used.
It is recommended to access:
www.knx.org
261
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*KNX* Work
Sequence with ETS*
262
Home Automation with Raspberry, Google & Python
263
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Various
3. Activate SERIALPEI16-COM1*
4. Mask $0012 in physical address a.b.c reserved.
264
Home Automation with Raspberry, Google & Python
*USB-Serial* Converter
1. T o v i e w t h e R S 2 3 2 - U S B
adapter on the iMac*:
2. In terminal:
cd /dev
ls tty.usbserial*
3. <Preferences><NET> <USB-SerialController>
(9600|E|1|8|xo=F|rts=F|dsr=F)
265
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
-Check that:
/dev/cu.serial exists
/dev/tty.usbserial exists
in lsof|grep usbserial no session started
(exit or restart)
with null-modem bypass the DB9
in CoolTerm (in MAC*) see TxD-RxD
⊝⊝⊝
266
Home Automation with Raspberry, Google & Python
27.-ADDITIONAL
SOFTWARE
T
o optimise the process of creating
software, design and testing of electronic
circuits, it is proposed to use the
software detailed below and which helps in:
267
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Applepi-Baker* and
Etcher*
268
Home Automation with Raspberry, Google & Python
*LXTerminal* and
Terminal*
269
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Pycharm*
270
Home Automation with Raspberry, Google & Python
*Icircuit*
271
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Eagle*
272
Home Automation with Raspberry, Google & Python
*NO-IP Duc*
273
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*VirtualBox*
It is interesting to use it
for when we have an operating
system, for example MAC OSX*, but
we need to try some management
software of a device in a different operating system,
for example the KNX* ETS* device management software
th a t i s n o t a v a i l a b l e f o r MAC OSX*, USB-RS232*
interface drivers, etc.
274
Home Automation with Raspberry, Google & Python
*Ipscanner Home*
⊝⊝⊝
275
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
28.-EXCHANGE
FILES
A
s it has said in previous chapters, for the
correct communication of parameters between
t h e Raspberry*_home automation and the
Raspberry*_screen, a series of information
exchange files are used, which allow writing and
reading the commands that are generated on the
Raspberry*_screen, Telegram* or Google Home* and run on
the Raspberry*_home automation.
• p_sensors.txt
• p_actuators.txt
• p_blinds.txt
• p_lights.txt
• p_devices.txt
• p_logfile.txt
276
Home Automation with Raspberry, Google & Python
*P_Sensors.txt
Located at:
Raspberry*_home automation:
/home/pi/home_auto/p_sensors.txt
Parameter Description
NAS temperature: xx °C/°F External NAS temperature
NAS humidity xx %RH External NAS humidity
There is or not 220v power
Power: yes/no
supply in the house
There is or not Internet
Internet: yes/no
access
Garage gate: open/close Garage gate status
Doorbell: on/off Doorbell rings or not
Sm o k e a l a r m s t a t u s of
Smoke: yes/no
floors with sensor
Flood alarm status of wet
Water: yes/no
areas
Leak alarm status of the
Gas: yes/no
kitchen
Al a r m s t a t u s b y t o x i c
CO2: normal/danger
gases of the garage
277
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Parameter Description
Heater status by schedule
Heater: on/off
or thermostat
Holidays: on/off Holidays mode status
Movie: on/off Movie ambient mode status
Thermostat: presence/absence KNX* thermostat status
Water_valve: open/close Valve of the water status
Gas_valve: open/close Valve of the gas status
Origin of the alarm or
Origin: xx action:
Telegram*, Google*, etc.
Setpoint temperature in
Setpoint temperature:
t h e l i v i n g r o o m KNX*
xx °C/°F
thermostat
Real temperature in the
Real temperature:
living r o o m KNX*
xx °C/°F
thermostat
278
Home Automation with Raspberry, Google & Python
*P_Actuators.txt
Located at:
Raspberry*_home automation:
/home/pi/home_auto/p_actuators.txt
279
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
280
Home Automation with Raspberry, Google & Python
*P_blinds.txt
Located at:
Raspberry*_home automation:
/home/pi/home_auto/p_blinds.txt
281
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*P_lights.txt
Located at:
Raspberry*_home automation:
/home/pi/home_auto/p_lights.txt
Light ON Description
Led focus on terrace, main
Terrace
floor
Lamp near table of living
Living room table lamp room, main floor
Lamp near sofa of living
Living room sofa lamp
room, main floor
Wall light table of living
Living room wall table room, main floor
Wall light sofa of living
Living room wall sofa room, main floor
LED ceiling entry house,
Entry
main floor
Hall Lamp outside, main door
Bathroom ceiling, main
Entrance bathroom ceiling
floor
282
Home Automation with Raspberry, Google & Python
Light ON Description
Bathroom mirror, main
Entrance bathroom mirror
floor
Garage stairs up Garage stairs, main floor
Gym Garage, gym area
Laundry Garage, laundry area
Garage Garage, cars area
Cellar Garage, cellar area
Stairs landing 1 st
Stairs landing 1st floor
Bathroom 1st ceiling Bathroom ceiling 1st floor
Bathroom 1st mirror Bathroom mirror 1st floor
Room_1a Bedroom_a 1st floor
Room_1b Bedroom_b 1st floor
Stairs landing 2nd Stairs landing 2nd floor
Room_2a Bedroom_a 2nd floor
Room_2b Bedroom_b 2nd floor
Bathroom 2nd ceiling Bathroom ceiling 2nd floor
Bathroom 2nd mirror Bathroom mirror 2nd floor
283
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*P_devices.txt
Located at:
Raspberry*_home automation:
/home/pi/home_auto/p_devices.txt
284
Home Automation with Raspberry, Google & Python
*P_logfile.txt
Located at:
Raspberry*_home automation:
/home/pi/home_auto/p_logfile.txt
⊝⊝⊝
285
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
29.-PYTHON*
MODULES
T
his chapter describes the Python* modules
that make up the entire system: home
automation, control, messaging and event
viewer.
286
Home Automation with Raspberry, Google & Python
*P_global.py
287
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*P_telegram.py
288
Home Automation with Raspberry, Google & Python
*P_logfile.py
289
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*P_screen.py
⊝⊝⊝
290
Home Automation with Raspberry, Google & Python
30.-DETAIL OF
PYTHON* MODULES
B
elow is a summary of the most important
functions that make up the Python* modules
described above and that allow this project
to work properly.
291
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*P_global.py
#==================================================================
# P_BLOBAL v.09 January 2019 with home automation actions
# in KNX* WIFI devices, Tadoº* & RM*
# verbal announcements & status questions by Google Home*
# Home Automation-Raspberry Integration Modules
# @ address_1rio Chenlo
#==================================================================
# GENERAL CONFIGURATION
#!/usr/bin/env python -u
# -*- coding: utf-8 -*-
version='v.09'
# IMPORT BODY
import sonoff #Sonoff devices management
import RPi.GPIO as GPIO
from colorama import init, Style, Fore, Back, Cursor
init(autoreset=True) #reset colorama style after writing
from datetime import datetime #to know the month
import time,random
time.strftime("%H:%M:%S") #24 hours format
import locale #for local names
locale.setlocale(locale.LC_ALL,'en_EN.UTF-8')
import os, sys, serial #system & UART control
os.system('setterm -cursor off') #hidden cursor in terminal screen
import termios, fcntl #key press capture
import requests #direct use of curl -X POST in IFTTT()
import KnxComObject #KNX actuation modules
import KnxDevice #for bulbs and window blinds
import KnxDPT
import KnxTelegram
import traceback #ejection line visualisation
import logging #mistakes management
from func_timeout import func_timeout, FunctionTimedOut #timeout
function controller
try: #on error in p_global.log da error,
creates it again
logging.basicConfig(filename='/home/pi/home_auto/
p_global.log',level=logging.ERROR)
except:
os.system('sudo rm /home/pi/home_auto/p_global.log')
logging.basicConfig(filename='/home/pi/home_auto/p_global.log',
level=logging.ERROR)
292
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# Delete these instructions and keys() to run program
# in interpreter mode
#------------------------------------------------------------------
#------------------------------------------------------------------
from email.mime.text import MIMEText #to send email
from email.mime.multipart import MIMEMultipart
from smtplib import SMTP
import smtplib, socket, getpass
from email.MIMEBase import MIMEBase #to send files by email
from email import encoders #to encrypt files
import pigpio # to DHT22 temperature sensor, daemon must be started
import DHT22 # DHT22 module should be in same folder as program
293
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#PUSH BUTTON KNX BLOCKERS 17-x -> 56/a, type where a can be:
blocker={
7: 'stair landing 2nd floor ',8: 'billiard ',
...
28:'entry ',32: 'bathroom main floor ceiling '}
#LIGHTS KNX 8/x type, simple & double push button, where x can be:
bulb_A={
1: 'billiard ',2: 'stair landing 2nd floor ',
...
30:'bathroom main floor mirror '}
#LIGHTS KNX 48/x type double push buttons, where x can be:
bulb_B={
1: 'billiard ',2: 'stairs landing 2nd floor ',
...
17:'bath. main f. ceiling ',18: 'living room lamps '}
#WINDOW BLINDS 24/x type, simple push buttons, where x can be:
blind= {
15: 'room_b 2nd floor ',16: 'room_b 2nd floor-stop ',
...
31: 'living large left ',32: 'living large left-stop '}
#
OTHER ACTUATORS 32/x type, where x can be:
others= {1: 'Heater'}
#------------------------------------------------------------------
# Configuration off KnxDevice.G_ADDR for home automation actuation
# see https://thingtype.com/blog/hacking-a-knx-network-with-
# a-raspberry-pi/
#------------------------------------------------------------------
# LIGHTS 1,0,X (1:on, 0:off)
#------------------------------------------------------------------
# LIVING LAMPS 2,0,X (1:on, 0:off)
294
Home Automation with Raspberry, Google & Python
# DIM: do 5 successive on
#------------------------------------------------------------------
# BLINDS 3,0,X (1:close, 0:open) (X+1=one pulse)
#------------------------------------------------------------------
blinds_without_alarm =[15,17,19,21,25]
...
lights_holidays_odd =[15,9,11]
#------------------------------------------------------------------
# THERMOSTAT KNX 4,0,2 type absence/presence with:
# KnxComObject(KnxDevice.G_ADDR(4,0,2),1,0x2E/0x2C)
#------------------------------------------------------------------
# VALVES 5,0,X type (1:close, 0:open)
#------------------------------------------------------------------
#GMAIL parameters
origin = "[email protected]"
address1 = "[email protected]" #addresses
address2 = "[email protected]"
smtp_server = 'smtp.gmail.com'
smtp_user = '[email protected]'
smtp_pass = 'pass'
server = smtplib.SMTP(smtp_server)
diary='/home/pi/home_auto/p_logfile.txt' #log file storage
try:
outfile=open(diary,'a')
295
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
except:
os.system('sudo cp /home/pi/home_auto/p_logfile.ok
/home/pi/home_auto/p_logfile.txt')
outfile=open(diary,'a')
outfile.write('DAY: HOUR: ALARM:'+' '*54+'ORIGIN:\n') #add
#file header
outfile.write(separator)
outfile.close()
#------------------------------------------------------------------
# COLOUR CLASS: Acts with colours lamp
# INPUTS: on, off, brightness & colour
# OUTPUTS: turn on/off, set colour
# add > /dev/null 2>&1 to avoid error messages on the screen
#------------------------------------------------------------------
class colour:
global orig
try: #don't change the green text
on= order_colour+'on > /dev/null 2>&1'
...
less_bright= order_colour+'less_bright > /dev/null 2>&1 '
except:
orig='Class colour'
line(traceback.extract_stack()) #set num_line with current line
write_outfile('Colours isn't available, review NO_IP')
#------------------------------------------------------------------
# MODULE ON_OFF_SONOFF() turns on/off un sonoff switch
# INPUTS: on/off, switch
# OUTPUTS: on/off Sonoff switch
#------------------------------------------------------------------
def on_off_sonoff(accion,device):
global y_on
try:
if accion=='on' and device=='screen':
y_on=True
if accion=='off' and device=='screen':
y_on=False
dispo=devices[switch[device]]['deviceid']
sss.switch(accion,dispo,None)
orig='on_off_sonoff()'
line(traceback.extract_stack())
write_outfile('Set '+device+' in '+accion)
except:
orig='on_off_sonoff()'
line(traceback.extract_stack())
write_outfile('Sonoff isn't available, review eWelink')
#------------------------------------------------------------------
# MODULE SEE_MONTH(): look if is summer or winter
# INPUTS: datetime.now()
# OUTPUTS: variable dia2 to "21:00:00" or "22:00" for automatic()
# April-August closes at 22:30, September at 21:30 & 21:00
# the rest of the months
#------------------------------------------------------------------
296
Home Automation with Raspberry, Google & Python
def see_month():
global day2
month=datetime.now().month
if month>=4 and month<=8:
day2='22:30:00'
elif month==9:
day2='21:30:00'
else:
day2='21:00:00'
#------------------------------------------------------------------
# MODULE LINE(): take the current line of execution
# takes into account he level on nesting: main, function, function
# in function, etc...
# INPUTS: stack situation
# OUTPUTS: num_line from function call is
#------------------------------------------------------------------
def line(x):
global num_line #function output
level=len(x) #nesting level
line=str(x) #find line number
for j in range(0,level): #repeat as level
line=line[line.find('p_global.py')+13:] #& set format
num_line=line[line.find(' ')+1:line.find(',')]
num_line=str(int(num_line)+1)
num_line='#'+('000'+num_line)[len(num_line)-1:]+' '
return (num_line)
#------------------------------------------------------------------
# MODULE SEE_COLOUR(): turns on colours with the select colour
# INPUTS: select colour
# OUTPUTS: if is possible, colours turns on
#------------------------------------------------------------------
def see_colour(x):
global orig
orig='see_colour()'
try:
if '&&' in x: #look for several actions
j1=x[x.find('colours_')+8:x.find('/dev')-3]
#1st action in j1
j2=x[x.find('&&'):]
j2=j2[j2.find('colours_')+8:j2.find('/dev')-3]
#2nd action in j2
jf=j1+' & in: '+j2
else:
jf=x[x.find('colours_')+8:x.find('/dev')-3] #only one
write_outfile('Set Colours in: '+jf)
os.system(x) #acts with Colours and action x
except:
line(traceback.extract_stack())
write_outfile('Colours isn't review NO_IP')
#------------------------------------------------------------------
# MODULE START_EDIMAX(): act with Edimax SP1101W plug
# Based on smartplug.py script (available SP1101W FW 2.02)
297
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE START_SONOFF(): acts with Sonoff switches
# INPUTS: Sonoff parameters
# OUTPUTS: Sonoff detected switches are init
#------------------------------------------------------------------
def start_sonoff():
global sss,switch,devices,orig
try:
sss=sonoff.Sonoff('[user]','[password]','us')
switch={'screen':0,'ambient':1,'kitchen':2,'bridge':3}
devices=sss.get_devices()
orig='start_sonoff()'
line(traceback.extract_stack())
write_outfile('Sonoff started successfully')
except:
orig='start_sonoff()'
line(traceback.extract_stack())
write_outfile('Sonoff isn't available, review eWelink')
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE SETUP_GRAL(): starts el GPIO
# INPUTS: any
# OUTPUTS: GPIO configuration & warnings
#------------------------------------------------------------------
def setup_gral():
global orig
try:
GPIO.setmode(GPIO.BOARD) #GPIO numbers by physical location
298
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE TRACE(): display GPIO status
# INPUTS: GPIO pin situation
# OUTPUTS: GPIO pin formatted situation
#------------------------------------------------------------------
def trace(x_trace):
print (Cursor.POS(48,23)+Fore.YELLOW + str(x_trace))
#------------------------------------------------------------------
# MODULE ENLARGE(): change str to str+blank of a certain length
# INPUTS: x_enlarge, length_text
# OUTPUTS: x_enlarge formatted str
#------------------------------------------------------------------
def enlarge(x_enlarge):
x_enlarge=x_enlarge+' '*(length_text-len(x_enlarge))
return(x_enlarge)
#------------------------------------------------------------------
# MODULE CLEAR_ACTUATORS() Start p_actuators.txt
# INPUTS: p_actuators.txt with actions
# OUTPUTS: p_actuators.txt with actions initiated to NO
#------------------------------------------------------------------
def clear_actuators():
global orig
try:
acts=open(factuators,'w')
acts.write('Turns off lights: NO\n')
...
acts.write('Turns off living room sofa: NO\n')
acts.close()
except:
orig='clear_actuators()'
line(traceback.extract_stack())
say('Attention: ACTUATORS error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE CLEAR_LIGHTS(): empty p_lights.txt
# INPUTS: p_lights.txt
# OUTPUTS: p_lights.txt empty except hall if is on
#------------------------------------------------------------------
def clear_lights():
global switched_on,orig
try:
if 'hall ' in switched_on:
lights=open(flights,'w')
lights.write('hall ')
299
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
switched_on=[]
switched_on.append('hall ')
lights.close()
else:
switched_on=[] #switched on lights
lights=open(flights,'w')
lights.close()
except:
orig='clear_lights()'
line(traceback.extract_stack())
say('Attention: LIGHTS error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODUE CLEAR_BLINDS(): adds open blinds to p_blinds.txt
# INPUTS: p_blinds.txt
# OUTPUTS: p_blinds.txt full with open blinds
#------------------------------------------------------------------
def clear_blinds():
global open,orig
try:
open=[] #open blinds, alphabetical order
blinds=open(fblinds,'w')
for x in [25,15,27,31,21,19,17]: #starts with all open
open.append(blind[x])
blinds.write(blind[x]+'\n')
blinds.close()
except:
orig='clear_blinds()'
line(traceback.extract_stack())
say('Attention: BLINDS error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE RECORD_LIGHTS(): switched_on[] to p_lights.txt transfer
# INPUTS: p_lights.txt & switched_on[]
# OUTPUTS: p_lights.txt
#------------------------------------------------------------------
def record_lights(switched_on):
global orig
try:
switched_on.sort() #switched on lights sort
lights=open(flights,'w')
for x in switched_on:
lights.write(x+'\n')
lights.close()
except:
orig='record_lights()'
line(traceback.extract_stack())
say('Attention: LIGHTS error')
line(traceback.extract_stack())
see_colour(colour.red)
300
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE RECORD_BLINDS(): open[] to p_blinds.txt transfer
# INPUTS: p_blinds.txt & open[]
# OUTPUTS: p_blinds.txt
#------------------------------------------------------------------
def record_blinds(open):
global orig
try:
open.sort()
blinds=open(fpersianas,'w')
for x in open:
if 'stop' not in x: #delete stops
blinds.write(x+'\n')
blinds.close()
except:
orig='record_blinds()'
line(traceback.extract_stack())
say('Attention: BLINDS error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE RECORD_SENSORS(): states[] to p_sensors.txt transfer
# INPUTS: states[] y p_sensors.txt
# OUTPUTS: p_sensors.txt
#------------------------------------------------------------------
def record_sensors(states):
global orig
try:
sensors=open(fsensors,'r')
k=[] #to save data
while True: #record states[] except states[16]
x=sensors.readline()
if x!='':
k.append(x)
else:
break
sensors.close()
if len(k)<18:
os.system('sudo cp /home/pi/home_auto/p_sensors.ok
/home/pi/home_auto/p_sensors.txt')
sensors=open(fsensors,'r')
k=[]
while True:
x=sensors.readline()
if x!='':
k.append(x)
else:
break
sensors.close()
sensors=open(fsensors,'w')
for x in range (0,16):
sensors.write(states[x]+'\n')
sensors.write(k[16])
sensors.write(states[17]+'\n')
301
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
sensors.write(states[18]+'\n')
sensors.close()
except:
orig='record_sensors()'
line(traceback.extract_stack())
say('Attention: SENSORS error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE RECORD_open(): p_blinds.txt to open[] transfer
# INPUTS: p_blinds.txt y open[]
# OUTPUTS: open[]
#------------------------------------------------------------------
def record_open():
global open,orig
try:
open=[]
blinds=open(fblinds,'r')
while True:
x=blinds.readline()
if x!='':
open.append(x[:len(x)-1]) #watch out with \n
else:
break
blinds.close()
except:
orig='record_open()'
line(traceback.extract_stack())
say('Attention: BLINDS error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE RECORD_SWITCHED_ON(): p_lights.txt, switched_on[] transfer
# INPUTS: p_lights.txt & switched_on[]
# OUTPUTS: switched_on[]
#------------------------------------------------------------------
def record_switched_on():
global switched_on,orig
try:
switched_on=[]
lights=open(flights,'r')
while True:
x=lights.readline()
if x!='':
switched_on.append(x[:len(x)-1]) #watch out with \n
else:
break
lights.close()
except:
orig='record_switched_on()'
line(traceback.extract_stack())
say('Attention: LIGHTS error')
line(traceback.extract_stack())
302
Home Automation with Raspberry, Google & Python
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE RECORD_ACTIVTED(): p_devices.txt to activated[] transfer
# INPUTS: p_devices.txt
# OUTPUTS: activated[]
#------------------------------------------------------------------
def record_activated():
global activated,orig
try:
activated=[]
devices=open(fdevices,'r')
while True:
x=devices.readline()
if x!='':
activated.append(x[:len(x)-1]) #watch out with \n
else:
break
devices.close()
except:
orig='record_activated()'
line(traceback.extract_stack())
say('Attention: DEVICES error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE RECORD_STATES(): updates current sensor status
# INPUTS: each sensor status by GPIO & p_sensors.txt
# OUTPUTS: p_sensors.txt y states[]
#------------------------------------------------------------------
def record_states():
global states,tempo,orig
try:
tempo=[]
inter=open(fsensores,'r')
while True:
x=inter.readline()
if x!='':
tempo.append(x[:len(x)-1])
else:
break
inter.close()
except:
orig='record_states()'
line(traceback.extract_stack())
say('Attention: SENSORS error')
line(traceback.extract_stack())
see_colour(colour.red)
303
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
while True:
x=inter.readline()
if x!='':
tempo.append(x[:len(x)-1])
else:
break
inter.close()
states=[]
states.append ('Temp NAS: '+str(tem)+' °C')
states.append ('Hum NAS: '+str(hum)+' %HR')
if GPIO.input(pin_power)=='0': #POWER
states.append('Power: No')
else:
...
if GPIO.input(pin_co2)=='1': #CO2
states.append('Co2: Excessive')
#------------------------------------------------------------------
# MODULE UPDATE_STATES(): updates states[] with real data
# INPUTS: sensor, gpio, connected, garage_gate, heater
# OUTPUTS: states[]
#------------------------------------------------------------------
def update_states():
global states
states[0]='Temp NAS: '+str(tem)+' °C'
states[1]='Hum NAS: '+str(hum)+' %HR'
if GPIO.input(pin_power)=='0': #POWER
states[2]='Power: No'
else:
states[2]='Power: Yes'
...
#------------------------------------------------------------------
# MODULE KNXEVENTS(): read knx bus
# INPUTS: KNX bus telegrams
# OUTPUTS: information load into KnxDevice script
#------------------------------------------------------------------
#Function called from previous (KnxDevice) to allow the script
# to be notified of a telegram event.
def KnxEvents(index):
pass
#------------------------------------------------------------------
# MODULE KNX_ONOFF(): acts with KNX bus with several parameters
# INPUTS: (x,0,y),z,0x2E/0x2C (x,0,y) group addresses, z flag &
# k='ON' or k='OFF'
# OUTPUTS: action with KNX bus
#------------------------------------------------------------------
def knx_onoff(x,y,z,k):
global orig
try:
Knx=KnxDevice.KnxDevice()
Knx._comObjectsList=[KnxComObject.KnxComObject(
KnxDevice.G_ADDR(x,0,y),z,0x2E),KnxComObject.KnxComObject(
KnxDevice.G_ADDR(x,0,y),z,0x2C)]
Knx._comObjectsNb=len(Knx._comObjectsList)
304
Home Automation with Raspberry, Google & Python
except:
orig='knx_onoff()'
line(traceback.extract_stack())
say('Attention: KNX error')
#------------------------------------------------------------------
# MODULE SAY(): announces by Google Home text with 15s timeout
# INPUTS: text/[*].mp3
# OUTPUTS: announces text by Google Home
# Call to p_ghome_say.py script that runs in Python 3.5 who needs
# PHP 7.0, Apache & Mysql to management *.mp3 URL
# generated with gTTS. The *.mp3 are in /var/www/cache on
# MD5 format & without protection with user/pass
#------------------------------------------------------------------
def say(text):
global orig
orig='say()'
try:
line(traceback.extract_stack())
value=func_timeout(15,talk,args=(text)) #15s
#watch out: this function sends text as a list, it has convert
#it as str with: ''.join(text)
time.sleep(3) #wait to avoid problems
except FunctionTimedOut:
line(traceback.extract_stack())
write_outfile('Function say() error, Google Home resets')
location='/home/pi/home_auto/gTTS/'
os.system(location+'./p_ghome_reset.py '+' > /dev/null 2>&1')
#------------------------------------------------------------------
# MODULE TALK(): called by say() with timeout
# INPUTS: text
# OUTPUTS: text to talk on Google Home
#------------------------------------------------------------------
def talk(*text):
global orig
orig='talk()'
ttt=''.join(text) #*text parameter to one variable
ip_google='192.168.1.xx'
location='/home/pi/home_auto/gTTS/'
write_outfile('Announce: '+ttt)
os.system(location+'./p_ghome_say.py '+ip_google+' "'+ttt+'"
> /dev/null 2>&1')
305
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE IFTTT(): acts with IFTTT widgets
# INPUTS: name=widget name. Available are:
# log_dropbox, WIFI_bulb_on/off, ambient_on/off, screen_on/off,
# bridge_on/off, colours_on/off, tv_on/off, desco_4k_on/off,
# tado_off, tado_auto, tado_on_22, tado_on_18
# Adds: +'> /dev/null 2>&1' to avoid screen messages
# OUTPUTS: turns on/off select widget
# In terminal use: curl -X POST https://maker.ifttt.com/trigger
# /[webhook]/with/key/[clave]
# See key en www.ifttt.com->select: webhooks->webhooks->settings
#------------------------------------------------------------------
def ifttt(name):
global orig
orig='ifttt()'
error_ifttt=False
line(traceback.extract_stack())
write_outfile('Acts on WIFI with '+name)
if name=='tv_on': #look if tv is off to switch it on
res=os.system("ping -w 1 "+ip_tv+'> /dev/null 2>&1')
if res!=0: #tv is OFF
try:
requests.post('https://maker.ifttt.com/trigger/
'+name+'/with/key/'+key_ifttt)
except:
error_ifttt=True
elif name=='tv_off':
res=os.system("ping -w 1 "+ip_tv+'> /dev/null 2>&1')
if res==0: #tv is ON
try:
requests.post('https://maker.ifttt.com/trigger/
'+name+'/with/key/'+key_ifttt)
except:
error_ifttt=True
...
try:
requests.post('https://maker.ifttt.com/trigger/
'+name+'/with/key/'+key_ifttt)
except:
error_ifttt=True
if error_ifttt:
line(traceback.extract_stack())
say('Attention: REQUESTS error')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
#------------------------------------------------------------------
# MODULE LOG_DROP(): upload on Dropbox p_logfile.txt
# INPUTS: p_logfile.txt
# OUTPUTS: p_logfile.txt on Dropbox in /logfile
# It has record in www/cache/ and invoke in IFTTT only with:
# [URL].hopto.org/cache/p_logfile.txt (NO-IP URL)
#------------------------------------------------------------------
def log_drop():
306
Home Automation with Raspberry, Google & Python
global orig
orig='log_drop()'
try:
os.system('sudo cp /home/pi/home_auto/p_logfile.txt
/var/www/cache/p_logfile.txt')
except:
line(traceback.extract_stack())
say('Attention: SYSTEM error')
ifttt('log_dropbox') #upload p_logfile.txt on DROPBOX/logfile/
line(traceback.extract_stack())
write_outfile('Upload p_logfile.txt on DROPBOX/logfile/')
#-----------------------------------------------------------------
# MODULE AUTOMATIC(): acts, every day except HOLIDAYS=ON
# INPUTS: holidays mode true/false, movie mode true/false
# OUTPUTS: acts with blinds like:
# At 11:00-21:00(22:30 summer) opens: room_a/b & living room small
# At 21:00 (22:30 summer)-11:00 closes room_a/b % living room small
#------------------------------------------------------------------
def automatic():
x=states[12]
global orig,open,close_high
if (not holidays and x=='Movie: OFF'):
global acts_a
if y_on==False and 'tado home ' in activated:
if devices[0].get('params').get(u'switch')=='off':
on_off_sonoff('on','screen')
orig='automatic()'
line(traceback.extract_stack())
write_outfile('Switch on screen')
say('Tadoº is in Home mode, switch on screen')
if y_on==True and 'tado away ' in activated:
if devices[0].get('params').get(u'switch')=='on':
on_off_sonoff('off','screen')
orig='automatic()'
line(traceback.extract_stack())
write_outfile('Switch off screen')
say('Tadoº is in Away mode, switch off screen')
t=time.strftime("%X") #look the time
if ((t>=day1 and t<=day2) and 'hall ' not in
switched_on):#is day
if acts_a and closes_high: #it has to open blinds
see_colour(colour.on+' && '+colour.red)
orig='automatic()'
ifttt('ambient_off') #switch off ambient
ifttt('WIFI_bulb_off') #switch off WIFI bulb
ifttt('colours_off') #switch off colours
307
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE INITIAL_TEST(): initial test on start or after RESET
# INPUTS: start o RESET
# OUTPUTS: LED R,A,V, blink, sounds, sensors values, send mail
# adds event to p_logfile.txt
#------------------------------------------------------------------
def initial_test():
global orig
line(traceback.extract_stack())
try:
os.system('clear') #clear main screen
orig='initial_test()'
write_outfile('Do the initial test')
print (Cursor.POS(10, 2)+Style.BRIGHT+Fore.RED+'INITIAL TEST:')
print (Cursor.POS(25,3)+Fore.GREEN +'Temperature: ')
print (Cursor.POS(25,4)+Fore.GREEN +'Humidity: ')
print (Cursor.POS(25,6)+Fore.RED +'Red LED: ')
print (Cursor.POS(25,7)+Fore.YELLOW +'Yellow LED: ')
308
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE SETUP_RELAYS(): nas, ont, router, hub
# Acts with 8 RELAY-kkmoon
# L=OFF (C+NC), H=ON (C+NA) with 74ls14 inverter
# power RELAY x8 module, whit external power
# INPUTS: pin, time ON, time OFF
# OUTPUTS: on/off, display pin on/off & screen messages
#------------------------------------------------------------------
def setup_relays():
global orig
orig='setup_relays()'
try:
for i in pins_relays:
GPIO.setup(i, GPIO.OUT) # Set i mode is output
GPIO.output (pin_nas, GPIO.LOW)
...
write_outfile('Switch off all relays')
except:
line(traceback.extract_stack())
say('Attention: GPIO error')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
#------------------------------------------------------------------
# MODULE SETUP_LED(): start led, reset button & buzz
# INPUTS: led (R:red, Y:yellow, G:green) E/A(on/off), reset button
# OUTPUTS: sounds buzz x seconds, LED status on the screen
#------------------------------------------------------------------
def setup_led():
global orig,num_line
orig='setup_led()'
try:
nom_LED=[ledR,ledY,ledG]
for i in nom_LED:
GPIO.setup(i, GPIO.OUT) # output mode for led
GPIO.output(i,GPIO.LOW) # switch off led
GPIO.setup(pin_buzz, GPIO.OUT) # output mode
GPIO.output(pin_buzz, GPIO.LOW) # switch off buzz
GPIO.setup(boton_reset, GPIO.IN, pull_up_down=GPIO.PUD_UP)
line(traceback.extract_stack())
write_outfile('Starts LED')
except:
line(traceback.extract_stack())
309
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE SETUP_ALARMS(): house alarms detection
# INPUTS: Garage(12), Smoke(13), Water(15), Gas(18), Power(37),
# Doorbell(40), CO2(31)
# OUTPUTS: sound, screen messages & email
#------------------------------------------------------------------
def setup_alarms():
global orig
try:
orig='setup_alarms()'
for i in pines_alarms:
GPIO.setup(i, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_power, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
...
GPIO.add_event_detect(pin_garage, GPIO.BOTH,
callback=ac_alarm_garage, bouncetime=bounce*4)
...
write_outfile('Starts GPIO of alarms')
except:
line(traceback.extract_stack())
say('Attention: GPIO error')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
#------------------------------------------------------------------
# MODULE START_ALARMS(): start variables to False
# INPUTS: variables to start
# OUTPUTS: variables started to False
#------------------------------------------------------------------
def start_alarms():
global error,reset_pressed,reset_long,wait,
cut_internet,a_sensor_bad,t_wait
v=[]
i=0
while i<8:
v.append(False)
i+=1 (error,reset_pressed,reset_long,wait,cut_internet,
a_sensor_bad,a_reset,t_wait)=v
#------------------------------------------------------------------
# MODULE AE_LED(): on/off specified LED
# INPUTS: LED (R:red, Y:yellow, G:green), E/A(on/off), time
# OUTPUTS: on/off LED
#------------------------------------------------------------------
def ae_LED(LED, action, time):
global error,cur,orig,jj
if accion == 'E':
accion = GPIO.HIGH # LED on with HIGH
n_accion='Switched_on'
elif accion == 'A':
accion = GPIO.LOW # LED off with LOW
n_accion='Switched_off'
310
Home Automation with Raspberry, Google & Python
else:
print (Cursor.POS(10, 20) + Fore.RED + enlarge('ERROR: action
'+str(accion)+' wrong'))
orig='ae_LED()'
line(traceback.extract_stack())
write_outfile('ERROR: action '+str(accion)+' wrong')
error = True
destroy()
if LED == 'R':
GPIO.output(ledR, accion)
n_LED='Red'
if accion==GPIO.HIGH:
print (Cursor.POS(40, 6) + Fore.RED + 'Yes')
else:
print (Cursor.POS(40, 6) + Fore.RED + 'No')
print (Cursor.POS(10, 19) + Fore.GREEN + enlarge('LED: '
+n_LED+' is: '+n_accion))
...
else:
print (Cursor.POS(10, 20) + Fore.RED + enlarge('ERROR:
LED'+str(LED)+' wrong'))
orig='ae_LED()'
line(traceback.extract_stack())
write_outfile('ERROR: LED'+str(LED)+' wrong')
error = True
destroy()
time.sleep(time) #Don't delete, it's ck speed controller
#------------------------------------------------------------------
# MODULE ON_DEVICE(): set ON on GPIO & time
# INPUTS: pin & time to on
# OUTPUTS: pin of GPIO activation
#------------------------------------------------------------------
def on_device(pin,time):
global orig
n_pin=pin
if pin== 'NAS':
pin=pin_nas
fil=10
...
else:
print (Cursor.POS(10, 18) + Fore.RED + enlarge('ERROR: relay
'+str(n_pin)+' wrong'))
orig='on_device()'
line(traceback.extract_stack())
write_outfile('ERROR: relay '+str(n_pin)+' wrong')
return()
try:
if (pin==pin_ont or pin==pin_nas or pin==pin_router):
GPIO.output(pin, GPIO.LOW)
else:
GPIO.output(pin, GPIO.HIGH)
except:
orig='on_device()'
line(traceback.extract_stack())
311
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE OFF_DEVICE(): OFF on GPIO with time
# INPUTS: pin & off time
# OUTPUTS: switched off specified GPIO pin
#------------------------------------------------------------------
def off_device(pin,time):
global orig
n_pin=pin
if pin== 'NAS':
pin=pin_nas
fil=10
...
else:
print (Cursor.POS(10, 18) + Fore.RED + enlarge('ERROR: relay
'+str(n_pin)+' wrong'))
orig='off_device()'
line(traceback.extract_stack())
write_outfile('ERROR: relay '+str(n_pin)+' wrong')
return()
try:
if (pin==pin_ont or pin==pin_nas or pin==pin_router):
GPIO.output(pin, GPIO.HIGH)
else:
GPIO.output(pin, GPIO.LOW)
except:
orig='off_device()'
line(traceback.extract_stack())
say('Attention: GPIO error')
see_colour(colour.red)
time.sleep(time)
print (Cursor.POS(10, 17) + Fore.GREEN + enlarge('Switch off
relay: ' + str(n_pin)))
orig=ori
line(traceback.extract_stack())
write_outfile('Switch off relay: ' + str(n_pin))
print (Cursor.POS(51, fil) + Fore.RED + 'OFF')
#------------------------------------------------------------------
# MODULE MESSAGE(): send e-mail with gmail
# INPUTS: topic, message_see (screen), message_rest (full) address
# OUTPUTS: message to address with topic and message_see/rest
#------------------------------------------------------------------
def message(topic, message_see, message_rest, address):
global orig
312
Home Automation with Raspberry, Google & Python
orig='Gmail'
try:
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.green)
message = message_see + message_rest + '\n' * 3
+ 'Message of XX House'
mime_message = MIMEText(message)
mime_message["From"] = origin
mime_message["To"] = address
mime_message["Subject"] = topic+' '+time.strftime("%X ")
smtp = SMTP("smtp.gmail.com", 587)
smtp.ehlo()
smtp.starttls()
smtp.login(smtp_user, smtp_pass)
smtp.sendmail(origin, address, mime_message.as_string())
smtp.quit()
print (Cursor.POS(10, 21) + Fore.GREEN + enlarge('Wrong
message:'))
print (Cursor.POS(10, 22) + Fore.GREEN + enlarge(topic+':
'+message_see[:26]))
if address==address_1:
line(traceback.extract_stack())
write_outfile(message_ver)
write_outfile(separator)
see_colour(colour.off)
except:
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
line(traceback.extract_stack())
say('Attention: SMTP error')
#------------------------------------------------------------------
# MODULE SEND_DAILY(): daily send with p_logfile.txt summary
# INPUTS: origin, address, file, day_1
# OUTPUTS: gmail message with topic, message, file
#------------------------------------------------------------------
def send_daily():
global orig,y_on
try:
# mail build
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.green)
msg = MIMEMultipart()
msg['To'] = address_1
msg['From'] = origin
msg['Subject'] = 'HOME AUTOMATION SUMMARY'+time.strftime(
"%X ")
#message body:
msg.attach(MIMEText('Daily summary at '+day_1+' Home','plain'))
fp = open(daily,'rb')
attached = MIMEBase('multipart', 'encrypted')
attached.set_payload(fp.read())
fp.close()
encoders.encode_base64(attached) #base64 encrypted
attached.add_header('Content-Disposition', 'attachment',
313
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
filename='p_logfile.txt')
msg.attach(attached)
#stmp start
smtp = SMTP("smtp.gmail.com", 587)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(smtp_user,smtp_pass)
smtp.sendmail(origin,address_1,msg.as_string())
log_drop() #p_logfile.txt to DROPBOX/lofile/
orig='send_daily()'
line(traceback.extract_stack())
say('En of the day, send summary')
line(traceback.extract_stack())
see_colour(colour.off)
y_on=False
except:
orig='sen_daily()'
line(traceback.extract_stack())
say('Attention: SMTP error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE SEND_SUMMARY(): send daily summary
# INPUTS: day1 & day2 for change of day & p_logfile.txt
# OUTPUTS: send the file p_logfile.txt
#------------------------------------------------------------------
def send_summary():
global day_1,day_2,t_2,orig
try:
if day_2!=day_1: #other day?
orig='send_summary()'
line(traceback.extract_stack())
write_outfile('Send & delete summary at '+dia_1)
print (Cursor.POS(10, 21) + Fore.GREEN + enlarge(
'Send & delete summary at '+dia_1))
send_daily() #send mail with summary
os.remove(daily) #delete & create new summary file
outfile=open(daily,'w') #open p_logfile.txt
outfile.write('DAY: HOUR: ALARM:'+' '*54+'ORIGIN:\n')
outfile.write(separator)
outfile.close()
orig='send_summary()'
write_outfile(jump)
write_outfile(separator)
line(traceback.extract_stack())
write_outfile('HOME AUTOMATIO CONTROL START')
write_outfile(separator)
write_outfile(title)
write_outfile(separator)
day_1=day_2
else:
t_2=time.localtime() #day of the week
day_2=time.strftime('%A',t_2)
314
Home Automation with Raspberry, Google & Python
except:
orig='send_summary()'
line(traceback.extract_stack())
say('Attention: LOGFILE error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE SOUND(): buzz sound & ck signal
# INPUTS: program activated
# OUTPUTS: x seconds pulse en la base del NPN, direct logic
#------------------------------------------------------------------
def sound(x): # x seconds
try:
GPIO.output(pin_buzz, GPIO.HIGH) # turn on buzz
time.sleep(x)
GPIO.output(pin_buzz, GPIO.LOW) # turn off buzz
if x!=ck:
print (Cursor.POS(10, 16) + Fore.GREEN + enlarge('Beep
'+str(x)+' seconds'))
except:
orig='sound()'
line(traceback.extract_stack())
say('Attention: GPIO error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE AC_RESET():push button RESET, to clear screen/total reset
# INPUTS: reset button
# OUTPUTS: reset_long variable
#------------------------------------------------------------------
def ac_reset(ev=None):
global reset_pressed,reset_long,orig
time.sleep(1)
if GPIO.input(button_reset)==0:
reset_pressed=True
time.sleep(pause_reset_long)
if GPIO.input(button_reset)==0: # reverse logic
reset_long=True
print (Cursor.POS(42, 13) + Fore.RED + 'YES')
orig='ac_reset()'
line(traceback.extract_stack())
write_outfile('LONG RESET button pressed')
else:
reset_long=False
print (Cursor.POS(42, 13) + Fore.GREEN + 'YES')
orig='ac_reset()'
line(traceback.extract_stack())
write_outfile('SHORT RESET button pressed')
else:
reset_pressed=reset_largo=False
orig='ac_reset()'
line(traceback.extract_stack())
315
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
316
Home Automation with Raspberry, Google & Python
line(traceback.extract_stack())
see_colour(colour.off)
#------------------------------------------------------------------
# MODULE SENSOR(): read temperature & humidity in DHT22 sensor
# INPUTS: sensor DHT22 inputs
# OUTPUTS: tem (temperature) & hum (humidity)
#------------------------------------------------------------------
def sensor():
global orig,tem,hum
try:
# this connects to pigpio daemon which must be started first
# run: sudo pgpiod
pigpio.exceptions = False #pigpio errors ignored
global pi
s.trigger()
tem = s.temperature() / 1.
hum = s.humidity() / 1.
except:
line(traceback.extract_stack())
say('Attention: TRIGGER error')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
if tem>=tmax:
print (Cursor.POS(40, 3) + Fore.RED + ('{:3.1f}'.format(tem)) +
' °C '+Fore.RED+'('+str(tmax)+')')
orig='sensor()'
line(traceback.extract_stack())
say('Attention: NAS temperature excessive')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
else:
if tem<-100: #sensor error
print (Cursor.POS(40, 3) + Fore.RED+ ('Sensor is missing '))
if not start:
orig='sensor()'
line(traceback.extract_stack())
write_outfile('NAS tem & hum sensor is missing')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
else:
print (Cursor.POS(40, 3) + Fore.GREEN+('{:3.1f}'.format(tem))
+ ' °C '+Fore.RED+'('+str(tmax)+')')
if hum>=hmax:
print (Cursor.POS(40, 4) + Fore.RED + ('{:3.1f}'.format(hum))
+ ' %HR '+Fore.RED+'('+str(hmax)+')')
orig='sensor()'
line(traceback.extract_stack())
say('Attention: excessive NAS humidity')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
else:
if hum<-100:
print (Cursor.POS(40, 4) + Fore.RED+ ('Sensor is missing'))
317
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
if not start:
orig='sensor()'
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
write_outfile('NAS sensor is missing')
else:
print (Cursor.POS(40, 4) + Fore.GREEN+('{:3.1f}'.format(hum))
+ ' %HR '+Fore.RED+'('+str(hmax)+')')
pigpio.exceptions = True #pigpio errors
return(tem,hum)
#------------------------------------------------------------------
# MODULE SEE_SENSOR(): look & acts with tem & hum NAS sensor
# INPUTS: yes_sensor, sensor() & maxims
# OUTPUTS: devices off & send messages
#------------------------------------------------------------------
def see_sensor():
global yes_sensor,a_sensor_bad,a_sensor_bien,orig
if yes_sensor==0:
sensor()
if ((tem>=tmax or hum>=hmax) and a_sensor_bad==False):
off_device('NAS', 2)
ae_LED('Y', 'E',largo)
print (Cursor.POS(10,23)+Fore.RED+enlarge('Excessive tem or
hum: '+str(tem)+'°C '+str(hum)+'%HR'))
time.sleep(long)
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
line(traceback.extract_stack())
message('TEMPERATURE ALARM','Excessive Temperature or
Humidity: '+str(tem)+'°C '+str(hum)+'%HR.','\n'+
'Check: \n-Real Temperature & Humidity.\n-NAS
status.',address_1)
message('NAS','NAS is off, until RESET or correct
parameters','',address_1)
orig='sensor()'
line(traceback.extract_stack())
write_outfile('EXCESSIVE Temperature or Humidity: '+str(tem)
+'°C '+str(hum)+'%HR.')
a_sensor_bad=True
a_sensor_good=False
318
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE ONOFF(): Check if Raspberry is online or offline
# INPUTS: GMAIL server answer
# OUTPUTS: online ON or OFF variables
#------------------------------------------------------------------
def onoff():
global connected,orig
try:
smtpserver = smtplib.SMTP("smtp.gmail.com", 587) #look Gmail
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
connected = 'ON'
except (socket.gaierror, socket.error, socket.herror,
smtplib.SMTPException):
connected = 'OFF'
return(connected)
#------------------------------------------------------------------
# MODULE SEE_ONOFF(): acts with Internet connection status
# INPUTS: connected or not to Internet by onoff()
# OUTPUTS: messages & variables fo Internet status
#------------------------------------------------------------------
def see_onoff():
global cut_internet,t_off,hour_cut,counter,to_wait,orig
if (connected=='OFF' and t_off>t_off_max):
cut_internet=True
t_off=0
hour_cut=time.strftime("%d-%m-%y ")+time.strftime("%X")
elif (connected=='OFF' and t_off<=t_off_max):
t_off+=1
cut_internet=False
if (connected=='ON' and cut_internet==True):
print (Cursor.POS(10, 5) + Fore.GREEN + 'Internet: ON ')
line(traceback.extract_stack())
message('INTERNET','OK Internet after cut: '+hour_cut,
'. Check: \n'+'-ONT & ROUTER status.
\n-Internet access.\n-Decoder',address_1)
orig='onoff()'
line(traceback.extract_stack())
say('Recovered from Internet cutting')
line(traceback.extract_stack())
write_outfile('INTERNET OK after cut at: '+hour_cut)
cut_internet=False
319
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
ae_LED('Y','A',largo)
elif (connected=='OFF' and cut_internet==True
and to_wait==False):
print (Cursor.POS(10, 5) + Fore.RED + Style.BRIGHT
+ 'Internet: OFF')
print (Cursor.POS(10, 23) + Fore.RED + enlarge('Internet
connection is OFF'))
hour_cut=time.strftime("%d-%m-%y ")+time.strftime("%X")
orig='onoff()'
line(traceback.extract_stack())
write_outfile('Internet connection is OFF')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
write_outfile(separator)
off_device('ONT',2)
...
cut_internet=True
if (counter<600 and connected=='OFF'): #600 cycles wait
counter+=1
to_wait=True
elif (counter>=600 and connected=='ON'):
to_wait=False
counter=0
#------------------------------------------------------------------
# MODULE HEATER(): Check if heater is ON/OFF
# INPUTS: time, schedule, activated[]
# OUTPUTS: is_heater
#------------------------------------------------------------------
def heater():
global is_heater,see_heater,fhome,error_edimax,tado_state,
tado_temp,tado_hum,y_on
if error_edimax==False:
try:
is_heater=str(edimax.state+' ')[:3] #Edimax status
except:
orig='heater()'
line(traceback.extract_stack())
say('Attention: Edimax error')
see_colour(colour.on+' && '+colour.red)
error_edimax=True
is_heater='OFF'
if (is_heater!='ON ' and is_heater!='OFF'):
now=time.localtime()
day=time.strftime('%w',now)
h1i=schedule[int(day)][0 : 8] #on morning
h1f=schedule[int(day)][9 :17] #off morning
h2i=schedule[int(day)][18:26] #on afternoon
h2f=schedule[int(day)][27:35] #off afternoon
t=time.strftime("%X")
if ((t>=h1i and t<=h1f) or (t>=h2i and t<=h2f)):
is_heater='ON '
else:
is_heater='OFF'
else:
320
Home Automation with Raspberry, Google & Python
is_heater='---'
try:
is_heater=str(edimax.state+' ')[:3]
error_edimax=False
orig='heater()'
line(traceback.extract_stack())
say('Edimax is OK')
see_colour(colour.off)
except:
pass
#------------------------------------------------------------------
# MODULE SEE_HEATER(): look to heater status (Edimax) cyclically
# INPUTS: yes_heater, cycles_heater
# OUTPUTS: heater(), yes_heater
#------------------------------------------------------------------
def see_heater():
global yes_heater
if yes_heater==cycles_heater:
print (Cursor.POS(10,5)+' '*27)
if is_heater=='ON ':
print (Cursor.POS(10,5) + Fore.RED + see_heater)
else:
print (Cursor.POS(10,5) + Fore.CYAN + see_heater)
heater()
yes_heater=0
else:
yes_heater+=1
321
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE SEE_START(): update KNX thermostat on start
# INPUTS: start, states[]
# OUTPUTS:KNX thermostat updating doing: absence/presence
#------------------------------------------------------------------
def see_start():
global start,orig
if start==True:
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.verde)
if states[13]=='KNX thermostat: ABSENCE':
knx_onoff(4,2,1,'ON')
for x in range(0,4):
time.sleep(1)
knx_onoff(4,2,1,'OFF')
if states[13]=='KNX thermostat: PRESENCE':
knx_onoff(4,2,1,'OFF')
for x in range(0,4):
time.sleep(1)
knx_onoff(4,2,1,'ON')
orig='start=True'
line(traceback.extract_stack())
say('KNX Thermostat started')
start=False
see_colour(colour.off)
#------------------------------------------------------------------
# MODULE SEE_ORIGIN(): origin update with p_sensors.txt actions
# INPUTS: p_sensors.txt
# OUTPUTS: ori
#------------------------------------------------------------------
def see_origin():
global ori,orig
try:
xx=[]
inter=open(fsensors,'r') #xx[] with p_sensors.txt
while True:
xj=inter.readline()
if xj!='':
xx.append(xj[:len(xj)-1]) #watch out with \n
else:
break
inter.close()
except:
orig='see_origin()'
line(traceback.extract_stack())
say('Attention: SENSORS error')
see_colour(colour.red)
if len(xx)<19: #p_sensors.txt corrupt?
os.system('sudo cp /home/pi/home_auto/p_sensors.ok
/home/pi/home_auto/p_sensors.txt')
xx=[]
inter=open(fsensors,'r') #xx[] with p_sensors.txt
while True:
xj=inter.readline()
322
Home Automation with Raspberry, Google & Python
if xj!='':
xx.append(xj[:len(xj)-1])
else:
break
inter.close()
try:
if xx[16] =='Origin: GOOGLE':
ori='GOOGLE'
...
except:
ori='Unknown'
#------------------------------------------------------------------
# MODULE SEE_TRACE(): display alarms
# INPUTS: GPIO
# OUTPUTS: GPIO alarms display
#------------------------------------------------------------------
def see_trace():
global orig
try:
trace(Cursor.BACK(11)+'P'+str(GPIO.input(pin_power))
+'h'+str(GPIO.input(pin_smoke))+'g'+str(GPIO.input(pin_gas))
+'a'+str(GPIO.input(pin_water))+'p'+str(GPIO.input(pin_garage))
+'t'+str(GPIO.input(pin_doorbell))+'c'+str(GPIO.input(pin_co2))
+'R'+str(GPIO.input(button_reset)))
except:
orig='see_trace()'
say('Attention: GPIO error')
#------------------------------------------------------------------
# MODULE SEE_EFFECTORS(): acts with effectors[]
# INPUTS: effectors[] with actions to do
# OUTPUTS: ifttt,knx,movie,lights,blinds,holiday,valves
# IMPORTANT: tex actions must be the same as p_actuators.txt
#------------------------------------------------------------------
def see_effectors():
global effectors,movie,holidays,states,switched_on,open,
tele,orig,error_edimax
try:
actions=open(factuators,'r')
effectors=[]
while True:
x=actions.readline()
if (x!='' and x!='\n' and x!=' '):
effectors.append(x)
else:
break
acciones.close()
except:
orig='see_effectors()'
line(traceback.extract_stack())
say('Attention: ACTUATORS error')
see_colour(colour.red)
if len(effectors)>=22: #effectors[] full?
323
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
324
Home Automation with Raspberry, Google & Python
#HOLIDAYS ON-------------------------------------------------------
if effectors[7]=='Holidays ON: YES\n':
holidays=True
states[11]='Holidays: ON'
orig=ori
line(traceback.extract_stack())
write_outfile('Holidays status ON')
message('TELEGRAM ALARM','Holidays status ON. ',
'Check:\n-All is ok.',address_1)
movie=False
line(traceback.extract_stack())
write_outfile('Movie ambient is OFF')
states[12]='Movie: OFF'
ifttt('ambient_off')
...
say('Holidays status is ON')
#HOLIDAYS OFF------------------------------------------------------
if effectors[8]=='Holidays OFF: YES\n':
holidays=False
states[11]='Holidays: OFF'
orig=ori
325
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
ifttt('tado_auto')
ifttt('deco_4k_on')
...
say('Holidays status is OFF')
326
Home Automation with Raspberry, Google & Python
#HEATER ON---------------------------------------------------------
if effectors[13]=='Heater ON: YES\n':
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
knx_onoff(4,2,1,'ON')
orig=ori
line(traceback.extract_stack())
states[13]='Thermostat: PRESENCE'
...
say('KNX thermostat in presence')
#HEATER OFF--------------------------------------------------------
if effectors[14]=='Heater OFF: YES\n':
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.blue)
knx_onoff(4,2,1,'OFF')
orig=ori
states[13]='KNX thermostat: ABSENCE'
...
say('KNX thermostat in absence')
#CLEAR SCREEN------------------------------------------------------
if effectors[15]=='Clear screen: YES\n':
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.green)
print (Cursor.POS(44, 7) + Fore.WHITE + Back.GREEN
+ 'CLEAR (C)')
sound(short)
ae_LED('R','E',short)
...
orig=ori
line(traceback.extract_stack())
write_outfile('Crear screen & exchange files')
os.system('clear')
see_titles()
if 'hall ' in switched_on:
switched_on='hall '
else:
switched_on=[]
clear_lights()
clear_blinds()
record_states()
print (Cursor.POS(10,5) + Fore.RED + see_heater)
tele=save_tele
see_thermostat()
print (Cursor.POS(44, 7) + Fore.GREEN + Back.WHITE
+ 'CLEAR (C)')
line(traceback.extract_stack())
see_colour(colour.off)
say('System screen is clear')
327
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#NAS RESET---------------------------------------------------------
if effectors[16]=='Reset NAS: YES\n':
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.green)
ae_LED('R','E',short)
off_device('NAS',2)
on_device('NAS',2)
ae_LED('R','A',short)
orig=ori
write_outfile('Switch off & on the NAS')
message('TELEGRAM','NAS reset. ',
'Check:\n-NAS OK.',address_1)
...
say('NAS reset')
#ONT RESET---------------------------------------------------------
if effectors[17]=='Reset ONT: YES\n':
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.green)
ae_LED('R','E',short)
off_device('ONT',2)
on_device('ONT',2)
ae_LED('R','A',short)
orig=ori
write_outfile('Switch off/on ONT')
message('TELEGRAM ALARM','ONT reset. ',
'Check:\n-Internet access ok.',address_1)
...
say('ONT reset')
#ROUTER RESET------------------------------------------------------
if effectors[18]=='Reset ROUTER: YES\n':
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.green)
ae_LED('R','E',short)
off_device('ROUTER',2)
on_device('ROUTER',2)
...
message('TELEGRAM ALARM','ROUTER reset.',
'Check:\n-Internet access ok.'+
'\n-Routers in 1st & 2nd are ok.'
+'\n-Tadoº Bridge is ok',address_1)
...
say('Router reset')
#RESET RASPBERRY---------------------------------------------------
if effectors[19]=='RASPBERRY Reset: YES\n':
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
ae_LED('R','E',short)
orig=ori
message('TELEGRAM ALARM','RASPBERRY reset. ',
'Check:\n-Sistema is OK.',address_1)
acciones.close()
clear_actuators()
ae_LED('R','A',short)
328
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE SEE_THERMOSTAT(): Display KNX thermostat data
# INPUTS: telegram sent by KNX thermostat
# OUTPUTS: display t_s variable & states[] to
# p_sensors.txt transfer
#------------------------------------------------------------------
def see_thermostat():
global t_s,t_sa,t_sp,t_r,states,open,orig,
is_heater,close_high,error_edimax
offset=-7.4 #KNX thermostat adjust
orig='see_thermostat()'
if j4==1: #on/off KNX relay
if error_edimax==False:
try:
ss=edimax.state
except:
error_edimax=True
orig='see_thermostat()'
line(traceback.extract_stack())
say('Attention: Edimax error')
ss='OFF'
if (j7==129 and ss=='ON'): #heater is on
is_heater='ON '
if (j7==128 or ss=='OFF'): #heater is off
is_heater='OFF'
else:
is_heater='---'
line(traceback.extract_stack())
write_outfile('Heater status unknown')
error_edimax=False
elif j4==2: #absence/presence status
if j7==128: #absence KNX
329
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
330
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE TELEGRAM(): KNX telegram reader
# INPUTS: bus KNX
# OUTPUTS: tele[] with KNX telegram
#------------------------------------------------------------------
def telegram():
global tele,received
while ser.inWaiting()>0: #something on the bus?
received+=str(ser.readline())
if len(received)>9:
x=0
for j in received: #telegram structure
if ord(j)==188: #start telegram=188
tele=received[x:]
break
else:
x+=1
if len(tele)>4:
lon=ord(tele[5:6])-225+9 #telegram length
tele=tele[:lon] #length=9+octet LSB from [5]
received=received[lon:] #exclude part one
crc=255 #check crc=0
for i in tele: #XOR must be 0
crc=crc^ord(i)
if crc!=0:
ser.flushInput() #with error empty buffer
#------------------------------------------------------------------
# MODULE SEE_TELEGRAM(): acts with devices according KNX
# INPUTS: KNX telegram
# OUTPUTS: actuations
#------------------------------------------------------------------
def see_telegram():
global save_tele,j1,j2,j3,j4,j7,tele,light,per,open,
switched_on,is_heater,text_tele,orig
if len(tele[2:3])>0:
for x in tele:
text_tele+=str(ord(x))+'-'
j=ord(tele[2:3]) #telegram origin direction
if (j not in button and (tele[0:1]==128 and tele[1:2]==17)):
print (Cursor.POS(9,23)+Fore.RED+'['+str(j)+']
does not exists')
line(traceback.extract_stack())
message('KNX SENSOR','['+text_tele+'] does not exists.
','Check:\n-New sensor or error.',address_1)
orig='telegram()'
line(traceback.extract_stack())
write_outfile('KNX SENSOR ['+text_tele+'] does not exists. ')
...
elif j in button:
331
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#----------------------------------------------------------------
# KNX THERMOSTAT DISPLAY
#----------------------------------------------------------------
if button[j]=='thermostat ':
save_tele=tele
j4=ord(tele[4:5]) #destination
j7=ord(tele[7:8]) #presence/absence
see_thermostat()
record_sensors(states) #states[] to p_sensors.txt transfer
#----------------------------------------------------------------
# RECORD TO FILES
#----------------------------------------------------------------
if len(tele[0:8])==8:
j1=ord(tele[1:2]) #origin
j2=ord(tele[2:3]) #origin
j3=ord(tele[3:4]) #destination
j4=ord(tele[4:5]) #destination
j7=ord(tele[7:8]) #light on/off or blind open/close
tele=light=per=''
if j7==129: #light on
if light not in switched_on:
print (Cursor.POS(9,23) + Fore.RED + light + ' ')
switched_on.append(light)
...
if j7==128: #light off
if light=='all ':
if 'hall ' in switched_on:
switched_on='hall '
else:
switched_on=[]
clear_lights()
...
#look for a blind
#add to opened file if are open (total or partial)
#remove from opened file if are total close
if (j3==24 and j4 in blind):
per=blind[j4]
if (j7==128 and j4 not in [29,30]):
if j4 in [31,32]:
332
Home Automation with Raspberry, Google & Python
movie=False
if per not in open:
print (Cursor.POS(9,23) + Fore.RED + per)
if ('stop' in per and blind[j4-1] in open):
open.remove(blind[j4-1])
else:
open.append(per)
if ((j7==128 and j4==29) or (j7==129 and j4==30)):
clear_blinds()
movie=False
if (j7==129 and j4 not in [29,30]):
...
blinds.close()
#------------------------------------------------------------------
# MODULE SEE_GARAGE(): acts with con lights according garage
# INPUTS: off_garage, switched_on[]
# OUTPUTS: off_garage, switched_on[]
#------------------------------------------------------------------
def see_garage():
global switched_on,off_garage,orig
if off_garage:
loff=[20,25] #cellar & gym lights
for j in loff:
knx_onoff(1,j,0,'OFF')
time.sleep(.5)
...
orig='ac_alarm_porton()'
line(traceback.extract_stack())
say('Garage lights off')
off_garage=False
#------------------------------------------------------------------
# MODULE AC_ALARM_POWER(): 0->1 power off, 1->0 power on
# INPUTS: GPIO
# OUTPUTS: LED,ck,message,variables
#------------------------------------------------------------------
def ac_alarm_power(Ev=None):
global a_power_yes,a_power_no,orig
if (GPIO.input(pin_power)==1 and a_power_no==True):
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.red)
ae_LED('R', 'E',largo)
333
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
ae_LED('G', 'A',largo)
sound(long)
print (Cursor.POS(42, 10) + Fore.RED + 'NO')
print (Cursor.POS(10, 15) + Fore.RED + enlarge('Power is off'))
line(traceback.extract_stack())
message('POWER ALARM','Power is off. ','Check:\n
-Distribution panel.\n'+'-Refrigerators status.',address_1)
orig='ac_alarm_power()'
a_power_yes=True
a_power_no=False
line(traceback.extract_stack())
write_outfile('Saves [*].txt on /home/pi/home_auto/safe/')
try:
os.mkdir('/home/pi/home_auto/safe')
except:
os.system('sudo cp /home/pi/home_auto/*.txt
/home/pi/home_auto/safe')
#------------------------------------------------------------------
# MODULE AC_ALARM_GARAGE(): 1->0 garage open, 0->1 garage close
# INPUTS: GPIO
# OUTPUTS: LED,ck,message,variables
#------------------------------------------------------------------
def ac_alarm_porton(Ev=None):
global still_open,f_open,garage_open,garage_close,
state_garage,orig,off_garage
if GPIO.input(pin_porton)==0 and GPIO.input(pin_power)==0:#open?
if still_a==False and f_open==True:
...
print (Cursor.POS(10, 15) + Fore.GREEN + enlarge('Alarm:
GARAGE STILL OPEN'))
still_open=True
orig='ac_alarm_porton()'
f_open=False
state_garage='Garage: Still open\n'
say('Attention: garage still open')
334
Home Automation with Raspberry, Google & Python
if porton_cerrado-porton_open<=(3*60+10) and
still_open==False and f_open==True and GPIO.input(pin_power)==0:
...
print (Cursor.POS(23, 10) + Fore.RED + 'AB')
print (Cursor.POS(10, 15) + Fore.GREEN +
enlarge('Alarm GARAGE STILL OPEN'))
message('GARAGE ALARM','Garage STILL OPEN. ','Check: \n'
+'-Garage open or close.\n-Power.',address_1)
...
say('Attention: garage still open')
#------------------------------------------------------------------
# MODULE AC_ALARM_SMOKE(): 1->0 smoke alarm, 0->1 no smoke
# INPUTS: GPIO
# OUTPUTS: LED,ck,message,variables
#------------------------------------------------------------------
def ac_alarm_smoke(Ev=None):
global a_smoke_yes,a_smoke_no,orig
if (GPIO.input(pin_smoke)==0 and a_smoke_no==True and
GPIO.input(pin_power)==0):
...
message('SMOKE ALARM', 'Smoke alarm in Kitchen or Roof. ',
'Check:\n'+'-Real alarm?.\n-Gas valve.',address_1)
...
say('Attention: smoke alarm')
335
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
'-Gas valve.',address_1)
...
say('There isn't smoke alarm')
#------------------------------------------------------------------
# MODULE AC_ALARM_WATER(): 1->0 flood alarm, 0->1 no flood
# INPUTS: GPIO
# OUTPUTS: LED,ck,message,variables
#------------------------------------------------------------------
def ac_alarm_water(Ev=None):
global a_water_yes,a_water_no,orig
if (GPIO.input(pin_water)==0 and a_water_no==True and
GPIO.input(pin_power)==0):
...
message('WATER ALARM', 'Flood alarm in Kitchen, Garage or Bath.
','Check:\n'+'-Where is the flood.',address_1)
...
say('Attention: flood alarm')
#------------------------------------------------------------------
# MODULE AC_ALARM_GAS(): 1->0 gas leakage, 0->1 no leakage
# INPUTS: GPIO
# OUTPUTS: LED,ck,message,variables
#------------------------------------------------------------------
def ac_alarm_gas(Ev=None):
global a_gas_yes,a_gas_no,orig
if (GPIO.input(pin_gas)==0 and a_gas_no==True and
GPIO.input(pin_power)==0):
...
message('GAS ALARM', 'Gas leakage in Kitchen. ','Check:\n
-If the alarm is real.\n'+'-Open doors and windows to
ventilate.',address_1)
...
say('Attention: gas leakage alarm')
#-----------------------------------------------------------------
# MODULE AC_ALARM_DOORBELL(): direct logic, bouncetime=2s
# INPUTS: GPIO
# OUTPUTS: LED,ck,message,variables
#------------------------------------------------------------------
def ac_alarm_doorbell(Ev=None):
336
Home Automation with Raspberry, Google & Python
global a_doorbell_yes,a_doorbell_no,orig
if (GPIO.input(pin_doorbell)==1 and a_doorbell_no==True and
a_doorbell_yes==False and GPIO.input(pin_power)==0):
say('*dog') #dog barking simulation
...
print (Cursor.POS(10, 15) + Fore.RED + enlarge('Doorbell has
rang'))
message('DOORBELL ALARM', 'Doorbell has rang. ','Check:\n
-Mobile calls.\n'+'-Delivery notices.',address_1)
...
say('Attention: Doorbell has rang')
#------------------------------------------------------------------
# MODULE AC_ALARM_CO2(): L alarm, H no alarm, reverse logic
# INPUTS: GPIO
# OUTPUTS: LED,ck,message,variables
#------------------------------------------------------------------
def ac_alarm_co2(Ev=None):
global a_co2_yes,a_co2_no,orig
if (GPIO.input(pin_co2)==0 and a_co2_no==True and
GPIO.input(pin_power)==0):
...
message('Co2 ALARM', 'HIGH level Co2. ','Check:\n
-If there is people or car in the garage.\n'+
'-Open garage gate util alarm goes off.',address_1)
...
say('Attention: toxic gas in the garage')
#------------------------------------------------------------------
# MODULE WRITE_OUTFILE(): record messages to en [daily] file
# INPUTS: program messages and origin of the action
# OUTPUTS: p_logfile.txt with program messages
#------------------------------------------------------------------
def write_outfile(men):
time.sleep(.2) #wait for event viewer
outfile=open(daily,'a')
if men==title or men==separator or men==jump:
outfile.write(men)
else:
changes=(('á','a'),('é','e'),('í','i'),('ó','o'),('ú','u')
337
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
,('º',''))
for a,b in changes:
men=men.replace(a,b).replace(a,b) #delete invalid characters
men=num_line+men
outfile.write(time.strftime("%d-%m-%y ")+time.strftime("%X ")
+enlarge(men)+' '+orig+'\n')
outfile.close()
#------------------------------------------------------------------
# MODULE SEE_TITLES(): write main titles of program
# INPUTS: any
# OUTPUTS: titles on screen
#------------------------------------------------------------------
def see_titulos():
global orig
os.system('clear')
print (Cursor.POS(10, 2) + Style.BRIGHT + Fore.RED + 'RASPBERRY
-HOME AUTOMATION CONTROL')
for i in range(15,23):
print (Cursor.POS(8,i) + Fore.WHITE + enlarge('->'))
orig='see_titulos()'
line(traceback.extract_stack())
write_outfile('Start Titles')
338
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE KESY(): red pressed keys
# INPUTS: keyboard
# OUTPUTS: tec: pressed key
#------------------------------------------------------------------
def keys():
global tec,orig
keys=['R','r','B','b','E','e']
try:
tec=sys.stdin.read(1) #key pressed?
except IOError: pass
if tec in keys:
orig='keys()'
line(traceback.extract_stack())
write_outfile('Key '+tec+' pressed')
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.greed)
elif tec!='':
ae_LED('R','E',short)
sound(ck)
ae_LED('R','A',short)
return(tec)
#------------------------------------------------------------------
# MODULE SEE_KEYS(): keys pressed management
# INPUTS: tec, pressed key
# OUTPUTS: action with devices & variables
#------------------------------------------------------------------
def see_keys():
global reset_pressed,reset_largo,tele,
t_tec,day_tec,tec,orig,switched_on
if (tec=='r' or tec=='R'): #RESET key
line(traceback.extract_stack())
see_colour(colour.on+' && '+colour.lilac)
print (Cursor.POS(44, 6) + Fore.WHITE + Back.RED
+ 'RESET (R)')
sound(short)
reset_pressed=True
reset_long =True
orig='keys()'
say('Reset key pressed')
...
339
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE blink_green(): ck del watchdog & date/time refresh
# INPUTS: any
# OUTPUTS: ae_LED green,ck & date/time refresh
#------------------------------------------------------------------
def blink_green():
ae_LED('G','E',0)
sound(ck)
ae_LED('G','A',0)
print (Cursor.POS(10, 3) + Fore.GREEN + time.strftime("%d-%m-%y")
+' ['+day_1[0:2]+']')
print (Cursor.POS(10, 4) + Fore.GREEN + time.strftime("%X"))
#------------------------------------------------------------------
# MODULE DISKSPACE(): hard disk (USB)
# INPUTS: USB hard disk status
# OUTPUTS: total, used & free diskSpace
#------------------------------------------------------------------
def diskSpace():
global orig
try:
p = os.popen("df -h /")
i = 0
while 1:
i += 1
line = p.readline()
if i == 2:
return(line.split()[1:5])
except:
orig='diskSpace()'
line(traceback.extract_stack())
say('Attention: POPEN error')
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE VAR_CPU(): CPU temperature & HD free space
# INPUTS: any
# OUTPUTS: cpu_temp & cpu_hd variables
#------------------------------------------------------------------
def var_cpu():
global cpu_temp,cpu_hd,orig
340
Home Automation with Raspberry, Google & Python
try:
tempFile = open( "/sys/class/thermal/thermal_zone0/temp" )
cpu_temp = tempFile.read()
tempFile.close()
cpu_temp = round(float(cpu_temp)/1000)
cpu_hd=diskSpace()[2]
except:
orig='var_cpu()'
line(traceback.extract_stack())
say('Attention: TEMPFILE error')
see_colour(colour.red)
#------------------------------------------------------------------
# MODULE SEE_VAR_CPU(): cpu & temperature alarm
# INPUTS: cpu_temp,cpu_temp_max
# OUTPUTS: a_cpu_yes, messages
#------------------------------------------------------------------
def see_var_cpu():
global a_cpu_yes,orig
print (Cursor.POS(10, 8) + Fore.GREEN + 'HD free:'+str(cpu_hd))
if cpu_temp<cpu_temp_max:
print (Cursor.POS(10, 7) + Fore.GREEN +
'CPU(°C):'+str(cpu_temp))
a_cpu_yes=False
else:
print (Cursor.POS(10, 7) + Fore.RED +
'CPU(°C):'+str(cpu_temp))
if a_cpu_yes==False:
line(traceback.extract_stack())
message('CPU ALARM', 'excessive CPU temperature
('+str(cpu_temp)+'/'+str(cpu_temp_max)+'°C). ',
'Check:\n'+'-General system status.\n-Software updated on
Raspberry\n'+'-Correct system start.',address_1)
orig='var_cpu()'
line(traceback.extract_stack())
write_outfile('CPU ALARM: excessive CPU temperature
('+str(cpu_temp)+'/'+str(cpu_temp_max)+'°C)')
a_cpu_yes=True
say('Alarm: excessive CPU temperature')
#------------------------------------------------------------------
# MODULE DESTROY(): stops program
# INPUTS: <ctrl>+<c> on keyboard or vnc
# OUTPUTS: GPIO start, display on screen, send message
#------------------------------------------------------------------
def destroy():
global error,orig
orig='destroy()'
if error == False:
xx = 'Program completed by the user'
else:
xx = 'Program completed by parameters error'
line(traceback.extract_stack())
write_outfile(xx)
print (Cursor.POS(10, 24) + Fore.RED + enlarge(xx))
341
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# Do not delete the following instructions, avoid temperature
# sensor errors
#------------------------------------------------------------------
try:
pi=pigpio.pi()
s = DHT22.sensor(pi, pin_sensor)
s.cancel()
except:
orig='destroy()'
line(traceback.extract_stack())
say('Attention: DHT22 error')
see_colour(colour.red)
#------------------------------------------------------------------
# close key capture
#------------------------------------------------------------------
try:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
GPIO.cleanup() # release resource
outfile.close()
sys.exit(0)
except:
orig='destroy()'
line(traceback.extract_stack())
say('Attention: KEYS error')
line(traceback.extract_stack())
see_colour(colour.red)
#------------------------------------------------------------------
# START OF MAIN PROGRAM EXECUTION
#------------------------------------------------------------------
if __name__ == '__main__': #Program start from here
os.system('clear')
print '-'*50
print 'Starting Home Automation Control Program....'
print 'Version: '+version
print '-'*50
say('Starting Home Automation Control Program')
orig='__main__'
num_line=''
write_outfile(jump)
write_outfile(separator)
write_outfile('Starting Home Automation Control Program')
write_outfile(separator)
write_outfile(title)
write_outfile(separator)
see_colour(colour.on+' && '+colour.red)
342
Home Automation with Raspberry, Google & Python
say('Performing setup')
print 'General setup...'
setup_gral()
print 'Setup LED...'
setup_led()
print 'Setup relays...'
setup_relays()
print 'Setup alarms...'
setup_alarms()
print 'Start alarms...'
start_alarms()
print 'Start Edimax...'
start_edimax()
print 'Start Sonoff...'
start_sonoff()
print 'Start Switched_on[]...'
record_switched_on() #switched_on[] with p_lights.txt
print 'Start Open[]...'
record_open() #switched_on[] with p_blinds.txt
print 'Start States[]...'
record_states() #states[] with p_sensors.txt
print 'Start Pigpio...'
orig='__main__'
write_outfile('Start el GPIO & DHT22')
try:
pi=pigpio.pi()
except:
say('Attention: GPIO error')
see_colour(colour.red)
try:
print 'Start DHT22...'
s=DHT22.sensor(pi,pin_sensor)
except:
say('Attention: DHT22 error')
see_colour(colour.red)
say('Performing the initial test')
test_initial()
os.system('clear')
try:
GPIO.add_event_detect(boton_reset, GPIO.FALLING,
callback=ac_reset, bouncetime=bounce*500)
except:
say('Attention: GPIO error')
see_colour(colour.red)
see_titles()
#------------------------------------------------------------------
# MAIN PROGRAM LOOP
#------------------------------------------------------------------
try:
orig='try:'
write_outfile(jump)
write_outfile(separator)
num_line=''
write_outfile('MAIN PROGRAM LOOP START')
343
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
write_outfile(separator)
say('Program started successfully')
see_colour(colour.verde)
while True: #main loop
#----------------------------------------------------------------
# Alarms jumps falling or rising interruption
# Prioritised processes with yes_polling
#----------------------------------------------------------------
if yes_polling==0: #telegram actions
see_mes() #summer or winter
see_trace() #GPIO trace
record_states() #p_sensors.txt to states[]
record_activated() #p_devices.txt to activated[]
see_heater() #heater status
see_sensor() #sensor status
telegram() #read KNX telegram to tele[]
see_telegram() #acts with devices
if yes_polling==0:
record_lights(switched_on) #p_lights.txt with switched_on[]
record_blinds(open) #p_blinds.txt with open[]
onoff() #Internet connection
see_onoff() #Internet management
var_cpu() #cpu status
see_var_cpu() #cpu status management
update_states() #states[] with real data
record_sensors(states) #p_sensors.txt with states[]
record_switched_on() #switched_on[] with p_lights.txt
automatic() #automatic tasks
see_garage() #garage lights actions
see_origin() #origin with p_sensors.txt
see_effectors() #actions with effectors[]
record_sensors(states) #p_sensors.txt with states[]
record_lights(switched_on) #p_lights.txt with switched_on[]
record_blinds(open) #p_blinds.txt with open[]
key() #key pressed
see_keys() #action with key pressed
see_start() #update thermostat status
see_reset() #reset button
send_summary() #daily activity summary
blink_green() #acoustic/visual/ck traces
if yes_polling==cycles_polling: #not essential tasks
yes_polling=0
else:
yes_polling+=1
#------------------------------------------------------------------
# Here ends main program try loop
#------------------------------------------------------------------
#------------------------------------------------------------------
# Program interruptions, exceptions & errors management
#------------------------------------------------------------------
except KeyboardInterrupt: #ctrl+c stops program
orig='keyboard'
line(traceback.extract_stack())
344
Home Automation with Raspberry, Google & Python
345
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*P_telegram.py
#------------------------------------------------------------------
# P_TELEGRAM.PY: Telegram BOT to Home Automation Control
# Uses two exchange data files with p_global.py to act with sensors
# and effectors. This version acts with lamps, window blinds, gas &
# water valve, heater, holidays status, etc.
# Files:
# p_sensors.txt: sensors status: temperature, humidity, etc.
# p_actuators.txt: actuators, relays, etc.
# commands: /start, /help & /exec
# Botfather Telegram Configuration
# BOT uses polling & can't be included in another program
# and must be run in parallel and share information through files
#------------------------------------------------------------------
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import telebot
from telebot import types
import time,os,sys
import urllib2
import psutil #RAM management
import socket #IP local management
from smartplug import SmartPlug #Edimax status
from subprocess import Popen,PIPE #IP vs MAC mana
import re
import logging #program errors log
try:
logging.basicConfig(filename='/home/pi/home_auto/p_telegram.log'
,level=logging.ERROR)
except:
os.system('sudo rm /home/pi/home_auto/p_telegram.log')
logging.basicConfig(filename='/home/pi/home_auto/p_telegram.log'
,level=logging.ERROR)
url_ip="http://miip.es" #URL to read public IP
#others URL:
#http://miip.es en [4832:4854]
#http://www.mypublicip.com en [144:160]
#http://checkip.dyndns.org en [:]
mac_device={
'86:16:f9:xx:xx:xx':'Edimax','e0:41:36:yy:yy:yy':'Router Fiber',
'7c:2e:bd:zz:zz:zz':'Google','82:16:f9:aa:aa:aa':'TP-Link Exte',
...,
3c:5c:c4:cc:cc:cc':'Alexa ','d0:7f:a0:bb:bb:bb':'Smart Watch'}
346
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULO ERROR(): displays error x
# INPUTS: error x to display
# OUTPUTS: send message with error x
#------------------------------------------------------------------
def error(x):
print(colour.RED + 'Error in: '+x+ colour.ENDC)
exit
#------------------------------------------------------------------
# MODULE START_ACTIONS(): starts actions
# INPUTS: actions[] to blank
# OUTPUTS: actions[] with blank actions (NO)
#------------------------------------------------------------------
def start_actions():
global actions
actions=[]
actions.append('Switch off lights: NO\n')
...
actions.append('Switch off living room sofa: NO\n')
#------------------------------------------------------------------
# MODULE READ(): reads data[] from p_sensors.txt
# INPUTS: p_sensors.txt, exchange file p_global.py & data[]
# OUTPUTS: data[]
#------------------------------------------------------------------
def read():
global data,v_thermostat,v_water,v_gas
exchange_sensors='/home/pi/home_auto/p_sensors.txt'
inter_sensors=open(exchange_sensors,'r')
data=[]
while True:
x=inter_sensors.readline()
if x!='':
datos.append(x[:len(x)-1]) #watch out: \n
else:
break
inter_sensors.close()
347
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE WRITE(): update actions in p_actuators.txt
# INPUTS: actions[]
# OUTPUTS: p_actuators.txt & p_sensors.txt
#------------------------------------------------------------------
def write():
try:
exchange_actuators='/home/pi/home_auto/p_actuators.txt'
inter_actuators=open(exchange_actuators,'w')
for i in actions:
inter_actuators.write(i)
inter_actuators.close()
leer() #read sensor status in data[]
data[16]='Origin: TELEGRAM'
exchange_sensors='/home/pi/home_auto/p_sensors.txt'
inter_sensors=open(exchange_sensors,'w')
for i in data:
inter_sensors.write(i+'\n') #transfer to p_sensors.txt
inter_sensors.close()
except:
error('p_actuators.txt open')
TOKEN = "token_token_token" #see TOKEN on Telegram
idi = 1234567890 #user code on Telegram
userStep = {}
knownUsers = []
commands = { 'start': 'Starts bot',
'help' : 'Available commands',
'exec' : 'Executes one command'}
menu = types.ReplyKeyboardMarkup()
menu.add("Raspberry", 'Home_Auto')
menu.add('System', 'Info')
raspberry_menu = types.ReplyKeyboardMarkup()
raspberry_menu.add('Temperatures', 'HD')
raspberry_menu.add('RAM', 'CPU')
raspberry_menu.add('Back')
home_automation_menu = types.ReplyKeyboardMarkup()
home_automation_menu.add('Status', 'Action')
home_automation_menu.add('Lights/Others', 'Blinds')
home_automation_menu.add('Heater','Devices')
home_automation_menu.add('Holidays','Movie')
home_automation_menu.add('Back')
system_menu = types.ReplyKeyboardMarkup()
system_menu.add('IP','Clear')
system_menu.add('NAS reset','ONT reset')
system_menu.add('ROUTER reset','RASPBERRY reset')
system_menu.add('Back')
state_menu = types.ReplyKeyboardMarkup()
state_menu.add('Temperatures', 'Humidity')
state_menu.add('Power', 'Internet', 'Edimax')
state_menu.add('Garage', 'Doorbell', 'Smoke')
state_menu.add('Water', 'Gas', 'CO2')
state_menu.add('Back')
action_menu = types.ReplyKeyboardMarkup()
action_menu.add('Switch off lights','Back')
action_menu.add('Close blinds', 'Open blinds')
348
Home Automation with Raspberry, Google & Python
# TEXT COLOUR
class colour:
RED = '\033[91m'
BLUE = '\033[94m'
GREEN = '\033[32m'
ENDC = '\033[0m' #end colour
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
#------------------------------------------------------------------
# MODULE: WIFI_BULB(): ON/OFF status of WIFI_bulb
# INPUTS: WIFI bulb details /home/pi/home_auto/p_WIFI_bulb.txt
# OUTPUTS: state='ON/OFF'
#------------------------------------------------------------------
def WIFI_bulb():
global state
try:
fWIFI_bulb='/home/pi/home_auto/p_WIFI_bulb.txt'
except:
os.system('sudo cp /home/pi/home_auto/p_WIFI_bulb.ok
/home/pi/home_auto/p_WIFI_bulb.txt')
error('p_WIFI_bulb.txt opening')
#------------------------------------------------------------------
# MODULE GET_USER_SETP: gets pulsation movement
# INPUTS: uid
# OUTPUTS: userStep
#------------------------------------------------------------------
349
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
def get_user_step(uid):
if uid in userStep:
return userStep[uid]
else:
knownUsers.append(uid)
userStep[uid] = 0
print(colour.RED + "¡¡New user!!" + colour.ENDC)
#------------------------------------------------------------------
# MODULE LISTENER(): receives info from telebot
# INPUTS: bootpolling() of telebot
# OUTPUTS: messages
#------------------------------------------------------------------
def listener(messages):
for m in messages:
if m.content_type == 'text':
print("[" + str(m.chat.id) + "] " +
str(m.chat.first_name) + ": " + m.text)
bot = telebot.TeleBot(TOKEN)
bot.set_update_listener(listener)
#------------------------------------------------------------------
# MODULE START: starts basic menu of bot
# INPUTS: message of bootpolling()
# OUTPUTS: access to main menu
#------------------------------------------------------------------
@bot.message_handler(commands=['start'])
def command_start(m):
cid = m.chat.id
if cid==idi: #user code
userStep[cid] = 0
bot.send_message(cid, "*Home Automation System of " +
str(m.chat.first_name)+'-Other*',parse_mode='Markdown')
time.sleep(1)
bot.send_message(cid, "*Available Commands:*"
,parse_mode='Markdown')
time.sleep(1)
bot.send_message(cid, "/start, /help, /exec, \n"
, reply_markup=menu)
else:
permission_denied()
#------------------------------------------------------------------
# MODULE HELP: displays commands of help
# INPUTS: message of bootpolling()
# OUTPUTS: available commands on help
#------------------------------------------------------------------
@bot.message_handler(commands=['help'])
def command_help(m):
cid = m.chat.id
if cid==idi:
help_text = "*Available Commands: \n*"
for key in commands:
help_text += "/" + key + ": "
help_text += commands[key] + "\n"
350
Home Automation with Raspberry, Google & Python
bot.send_message(cid, help_text,parse_mode='Markdown')
else:
permission_denied()
#------------------------------------------------------------------
# MODULE COMMAND_EXEC(): runs basic Linux commands
# INPUTS: message of bootpolling()
# OUTPUTS: runs these Linux commands
#------------------------------------------------------------------
@bot.message_handler(commands=['exec'])
def command_exec(m):
cid = m.chat.id
if cid == idi:
bot.send_message(cid, "Running: " + m.text[len("/exec"):])
bot.send_chat_action(cid, 'typing')
time.sleep(2)
f = os.popen(m.text[len("/exec"):])
result = f.read()
bot.send_message(cid, "Result: " + result)
else:
permission_denied()
#------------------------------------------------------------------
# MODULE: MAIN_MENU(): main program menu
# INPUTS: bootpolling() options
# OUTPUTS: main menu options
#------------------------------------------------------------------
@bot.message_handler(func=lambda message:
get_user_step(message.chat.id) == 0)
def main_menu(m):
cid = m.chat.id
text = m.text
if cid==idi:
if text == "Raspberry":
bot.send_message(cid, '*Available Information:*'
,parse_mode='Markdown',reply_markup=raspberry_menu)
userStep[cid] = 1
elif text == "Home Automation":
bot.send_message(cid, '*Home Automation options:*'
, parse_mode='Markdown',reply_markup=home_auto_menu)
userStep[cid] = 2
elif text == 'System':
bot.send_message(cid, '*System Options:*',
parse_mode='Markdown',reply_markup=system_menu)
userStep[cid] = 3
elif text == 'Info':
command_start(m)
userStep[cid]=0
else:
command_text(m)
else:
permission_denied()
#------------------------------------------------------------------
# MODULE RASP_OPT(): basic status of Raspberry_home automation
351
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE DOMO_OPT(): main options
# INPUTS: bootpolling() options
# OUTPUTS: main options
#------------------------------------------------------------------
@bot.message_handler(func=lambda message:
get_user_step(message.chat.id) == 2)
def home_auto_opt(m):
global cid
cid = m.chat.id
text = m.text
if cid == idi :
if text == "State":
bot.send_message(cid, "*State Menu:*",parse_mode='Markdown')
print(colour.BLUE + "State Menu: " + colour.ENDC)
bot.send_message(cid, "*Available Options*"
,parse_mode='Markdown',reply_markup=state_menu)
352
Home Automation with Raspberry, Google & Python
userStep[cid] = 4
elif text == "Action":
...
#------------------------------------------
#LIGHTS
#------------------------------------------
elif text == "Lights/Others":
cid = m.chat.id
text=m.text
if cid==idi:
print(colour.BLUE + "LIGHTS ON: " + colour.ENDC)
bot.send_message(cid, "*LIGHTS ON:*",parse_mode='Markdown')
try:
fluces='/home/pi/home_auto/p_lights.txt'
lights=open(flights,'r')
x=lights.readline()
if len(x)==0 or x=='\n':
bot.send_message(cid,'*[24/24] All off*',
parse_mode='Markdown')
print(colour.RED + '[24/24] All off...\n'
+ colour.ENDC)
else:
t=0
while len(x)!=0 and x!='\n' and x[0:1]!=' ':
bot.send_message(cid,x)
print(colour.RED + x + colour.ENDC)
x=lights.readline()
t+=1
bot.send_message(cid,'*['+str(t)
+'/24]...end...*',parse_mode='Markdown')
print(colour.RED+'['+str(t)
+'/24]...end...'+colour.ENDC)
lights.close()
except:
error('Opening p_lights.txt')
print(colour.BLUE + "OTHERS:" + colour.ENDC)
...
userStep[cid] = 2
else:
permission_denied()
#------------------------------------------
#WINDOW BLINDS
#------------------------------------------
elif text == "Blinds":
print(colour.BLUE + "Open blinds: " + colour.ENDC)
bot.send_message(cid, "*Open blinds:*",parse_mode='Markdown')
cid = m.chat.id
text=m.text
if cid==idi:
try:
fblinds='/home/pi/home_auto/p_blinds.txt'
blinds=open(fblinds,'r')
x=blinds.readline()
blinds.close()
353
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
if len(x)==0 or x=='\n':
bot.send_message(cid,'*[7/7] All close...*'
,parse_mode='Markdown')
print(colour.RED + '[7/7] All close...' + colour.ENDC)
else:
blinds=open(fblinds,'r')
x=blinds.readline()
t=0
while len(x)!=0 and x!='\n':
x=blinds.readline()
t+=1
blinds.close()
if t==7:
bot.send_message(cid,'*[7/7] All open...*'
,parse_mode='Markdown')
else:
blinds=open(fblinds,'r')
x=blinds.readline()
t=0
while len(x)!=0 and x!='\n':
bot.send_message(cid,x)
print(colour.RED + x + colour.ENDC)
x=blinds.readline()
t+=1
blinds.close()
if t==0:
bot.send_message(cid,'*[7/7] All close...*'
,parse_mode='Markdown')
else:
bot.send_message(cid,'*['+str(t)
+'/7]...end...*',parse_mode='Markdown')
except:
error('opening of p_blinds.txt')
userStep[cid] = 2
else:
permission_denied()
#------------------------------------------
#HEATER
#------------------------------------------
elif text == "Heater":
...
permission_denied()
#------------------------------------------
#CONNECTED DEVICES
#------------------------------------------
elif text == "Devices":
print(colour.BLUE + "Connected devices: " + colour.ENDC)
bot.send_message(cid, "*Connected devices:*"
,parse_mode='Markdown')
cid = m.chat.id
text=m.text
if cid==idi:
354
Home Automation with Raspberry, Google & Python
#--------------------------------------------------------------
# Connected devices identified in ARP
#--------------------------------------------------------------
bot.send_message(cid,'*...According IP-MAC...*'
,parse_mode='Markdown')
print(colour.RED + '...According IP-MAC...' + colour.ENDC)
bot.send_message(cid,'*...updating arp-scan...*'
,parse_mode='Markdown')
print(colour.RED + '...updating arp-scan...' + colour.ENDC)
bot.send_message(cid,'*...wait 2 seconds...*'
,parse_mode='Markdown')
print(colour.RED + '...wait 2 seconds...' + colour.ENDC)
mac_file='/home/pi/home_auto/p_ip_mac.txt'
try:
os.system('sudo arp-scan -r 1 -I eth0 –localnet
-t 1000 > '+mac_file)
except:
error('arp-scan')
ffile=open(mac_file,'r')
names={}
hostname = '192.168.1.'
while True:
x=ffile.readline()
if x!='':
t=x.find('\t')
host=x[:t]
mac= x[t+1:t+18]
if mac in mac_device:
names[mac_device[mac]]=host
else:
if host.find(hostname)==0:
names['Unknown']=host[:13]
else:
break
list=[]
for j in names: #add device names to sort them
list.append(j)
list.sort()
c=0
for j in list:
jj='['+names[j]+']:\t'+j
bot.send_message(cid,jj)
print(colour.RED+jj+colour.ENDC)
time.sleep(.1) #waiting for bot
c+=1
bot.send_message(cid,'*['+str(c)+'/'+str(len(mac_device))
+']*',parse_mode='Markdown')
print(colour.RED + '['+str(c)+'/'+str(len(mac_device))
+']'+colour.ENDC)
#--------------------------------------------------------------
# Devices that are not connected or are not in ARP list
#--------------------------------------------------------------
missing=[]
ff=0
355
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
bot.send_message(cid,'*...Missing devices...*',
parse_mode='Markdown')
print(colour.RED + '...Missing devices...' + colour.ENDC)
for x in mac_device:
if mac_device[x] not in names:
missing.append(mac_device[x])
missing.sort()
for x in missing:
bot.send_message(cid,x)
print(colour.RED+x+colour.ENDC)
ff+=1
bot.send_message(cid,'*...Missing: *'
+str(ff),parse_mode='Markdown')
print(colour.RED + '...Missing: ' +str(ff)
+ colour.ENDC)
#--------------------------------------------------------------
# Main devices identified by its IP
#--------------------------------------------------------------
any=False
n_device=[]
bot.send_message(cid,'*...According to PING...*',
parse_mode='Markdown')
print(colour.RED + '...According to PING...' + colour.ENDC)
bot.send_message(cid,'*...wait 10 seconds...*'
,parse_mode='Markdown')
print(colour.RED + '...wait 10 seconds...' + colour.ENDC)
for x in device:
print(colour.RED + str(x) + colour.ENDC),
host=hostname+str(x)
try:
response = os.system("ping -w 1 "+host)
except:
error('ping'+host)
if response == 0:
n_device.append(dispo[x])
any=True
n_device.sort() #sort by connected name
for x in n_device:
bot.send_message(cid,x)
print(colour.RED + x + colour.ENDC)
if any==False:
bot.send_message(cid,'*None*',parse_mode='Markdown')
print(colour.RED + 'None' + colour.ENDC)
else:
bot.send_message(cid,'*['+str(len(n_device))+'/'
+str(len(device))+']...end...*',parse_mode='Markdown')
print(colour.RED + '...end...' + colour.ENDC)
userStep[cid] = 2
else:
permission_denied()
elif text == 'Holidays':
read() #read p_sensors.txt to data[]
if len(data)>13: #data[] full?
bot.send_message(cid,data[11])
356
Home Automation with Raspberry, Google & Python
if 'OFF' in data[11]:
print(colour.GREEN+data[11]+colour.ENDC)
else:
print(colour.RED +data[11]+colour.ENDC)
elif text == 'Movie':
leer() #read p_sensors.txt to data[]
if len(data)>13: #data[] full
bot.send_message(cid,data[12])
if 'OFF' in data[12]:
print(colour.GREEN+data[12]+colour.ENDC)
else:
print(colour.RED +data[12]+colour.ENDC)
elif text == "Back":
userStep[cid] = 0
bot.send_message(cid, "*Main Menu:*",parse_mode='Markdown',
reply_markup=menu)
else:
command_text(m)
else:
permission_denied()
#------------------------------------------------------------------
# MODULE SAY(): announces text by Google Home
# INPUTS: text
# OUTPUTS: verbally announce by Google Home
#------------------------------------------------------------------
def say(text):
ip_google='192.168.1.xx'
location='/home/pi/home_auto/gTTS/'
try:
os.system(location+'./p_ghome_say.py '+ip_google+' "'
+text+'" > /dev/null 2>&1')
time.sleep(5)
except:
pass
#------------------------------------------------------------------
# MODULE SIST_MENU(): system status options
# INPUTS: options captured by bootpolling()
# OUTPUTS: system status Raspberry_home automation options
#------------------------------------------------------------------
@bot.message_handler(func=lambda message:
get_user_step(message.chat.id) == 3)
def sist_menu(m):
cid = m.chat.id
text=m.text
start_actions()
if cid==idi:
if text == 'IP':
try:
x=[l for l in ([ip for ip in
socket.gethostbyname_ex(socket.gethostname())[2]
if not ip.startswith("127.")][:1],
[[(s.connect(('8.8.8.8', 53)),
s.getsockname()[0], s.close()) for s in
357
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
[socket.socket(socket.AF_INET,
socket.SOCK_DGRAM)]][0][1]]) if l][0][0]
except:
error('getting local IP')
if x!='' and len(x)<15: #to avoid bot errors
bot.send_message(cid,'*local IP: *'
+x,parse_mode='Markdown')
print(colour.BLUE+x+colour.ENDC)
ip=urllib2.urlopen(url_ip).read()[4832:4854]
ip_ok=''
ip_val=['1','2','3','4','5','6','7','8','9','0','.']
for x in ip: #estrange characters filter
if x in ip_val:
ip_ok=ip_ok+x
bot.send_message(cid, '*public IP: *'
+ip_ok,parse_mode='Markdown')
print(colour.BLUE +ip + colour.ENDC)
elif text == "Clear":
...
elif text == "NAS Reset":
...
elif text == "ONT Reset":
...
elif text == "ROUTER Reset":
...
elif text == "RASPBERRY Reset":
...
elif text == "Back":
userStep[cid]=0
bot.send_message(cid, "*Main Menu:*",parse_mode='Markdown'
, reply_markup=menu)
else:
command_text(m)
else:
permission_denied()
write() #saves actions to exchange files
#------------------------------------------------------------------
# MODULE STATE_OPT(): main menu
# INPUTS: bootpolling() options
# OUTPUTS: main menu options to perform
#------------------------------------------------------------------
@bot.message_handler(func=lambda message:
get_user_step(message.chat.id) == 4)
def state_opt(m):
cid = m.chat.id
text = m.text
if cid == idi :
read()
if len(data)>=18: #to avoid error
if text == "Temperatures":
bot.send_message(cid, '*NAS Temp: *'+
data[0][len(data[0]) -9:],parse_mode='Markdown')
print(colour.BLUE +data[0] +colour.ENDC)
...
358
Home Automation with Raspberry, Google & Python
except:
bot.send_message(cid, '*Edimax
---*',parse_mode='Markdown')
print(colour.BLUE +'---'+colour.ENDC)
elif text == "Garage":
...
elif text == "Back":
userStep[cid] = 2
bot.send_message(cid, "*Options:*"
,parse_mode='Markdown',reply_markup=home_automation_menu)
else:
command_text(m)
else:
permission_denied()
#------------------------------------------------------------------
# MODULE ACCION_OPT(): home automation actions
# INPUTS: options captured by bootpolling()
# OUTPUTS: home automation actions to perform
#------------------------------------------------------------------
@bot.message_handler(func=lambda message:
get_user_step(message.chat.id) == 5)
def accion_opt(m):
global actions,v_water,v_gas,v_thermostat,data
cid = m.chat.id
text = m.text
start_actions()
if cid == idi :
if text == "Lights off":
bot.send_message(cid, "*Switching off lights...*"
,parse_mode='Markdown')
print(colour.BLUE + "Switching off lights..."
+ colour.ENDC)
actions[0]='Switch off lights: YES\n'
359
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE PERMISSION_DENIED(): denies permission for token error
# INPUTS: bot identification & token
# OUTPUTS: permission denied if identity errors
#------------------------------------------------------------------
def permission_denied():
bot.send_message(cid, "*¡¡Permission denied!!*",
parse_mode='Markdown')
print(colour.RED + " ¡¡Permission denied!! " + colour.ENDC)
#------------------------------------------------------------------
# MODULE DISKSPACE(): gets disk space
# INPUTS: Raspbian system on Raspberry_home automation
# OUTPUTS: total and free disk space in float format
#------------------------------------------------------------------
def diskSpace():
global disk
disk=[]
try:
p = os.popen("df -h /")
i = 0
while 1:
i += 1
line = p.readline()
if i == 2:
x=line.split()[1:5]
total=x[0]
available=x[2]
total=total[:total.find('G')]
if ',' in total:
total=total[:total.find(',')]+'.'
+total[total.find(',')+1:]
disk.append(float(total))
available=available[:available.find('G')]
if ',' in available:
available=available[:available.find(',')]
+'.'+available[available.find(',')+1:]
disk.append(float(available))
return
except:
error('popen error')
360
Home Automation with Raspberry, Google & Python
#------------------------------------------------------------------
# MODULE COMMAND_TEXT(): quality bootpolling() messages
# INPUTS: bootpolling() messages
# OUTPUTS: captured messages validation
#------------------------------------------------------------------
@bot.message_handler(func=lambda message: True,
content_types=['text'])
def command_text(m):
cid = m.chat.id
if cid==idi:
if (m.text.lower() in ['hello', 'hi', 'good morning']):
bot.send_message(cid, 'Hi, '
+ str(m.from_user.first_name) + '. How are you?.')
elif (m.text.lower() in ['bye', 'see you', 'end]):
bot.send_message(cid, 'See you, ' +
str(m.from_user.first_name) + '. Bye')
else:
bot.send_message(cid, 'I don't understand, use /start')
else:
permission_denied()
#------------------------------------------------------------------
# MODULE TELEGRAM_POLLING(): to avoid errors in bot.polling
# INPUTS: bootpolling()
# OUTPUTS: received messages from Telegram
#------------------------------------------------------------------
def telegram_polling():
try:
global err
err='Program stopped by '
bot.infinity_polling(True, timeout=500)
bot.stop_polling() #to ensure a single instance
time.sleep(3)
except KeyboardInterrupt: #ctrl+c stops program
err='Program stopped by the user...'
except Exception:
if str(sys.esc_info()[0])=="<class 'requests
.exceptions.ConnectionError'>":
err=err+'Edimax error...'
else:
err=err+'other exception'
except IOError:
err=err+'input/output error'
except TeleBot:
err=err+'Telebot error'
except:
err=traceback.format_exc()
finally:
if err!='' and err!='None\n':
logging.exception('\r\n'+time.strftime("%d-%m-%y ")
+time.strftime("%X ")+'\r\n'+'-'*40+'\n'+err)
bot.stop_polling() #to avoid polling errors
time.sleep(10)
telegram_polling() #start again
361
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MAIN BODY OF BOOTPOLLING() PROGRAM
#------------------------------------------------------------------
if __name__ == '__main__':
os.system('clear')
star_actions()
write()
print (colour.RED+'Running Bot...'+colour.ENDC)
telegram_polling()
362
Home Automation with Raspberry, Google & Python
*P_screen.py
#Background colours
red ='#F50743'
green='#38EB5C'
#Buttons size
width_short =300 #small buttons
height_short =65 #small buttons
width_large =620 #big buttons
height_large =100 #big buttons
left =60 #position x for left buttons
right =460 #position x for right buttons
height =35 #position height buttons separation
offset =30 #up or down all buttons
type_cur ='none' #cursor type over button
363
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# MODULE BEEP(): beep sound by analog output
# INPUTS: file [*].wav in /home/pi/home_auto/
# OUTPUTS: audio by analog jack output
#------------------------------------------------------------------
def beep():
mixer.init()
sounds=mixer.Sound(sound)
sounds.play()
#------------------------------------------------------------------
# MODULE START_ACTIONS(): starts actions list
# INPUTS: actions[]
# OUTPUTS: actions[] filled with initial state NO
#------------------------------------------------------------------
def start_actions():
global actions
actions=[]
actions.append('Switched off lights: NO\n')
...
actions.append('Switched off living room sofa: NO\n')
#------------------------------------------------------------------
# MODULE WRITE(): starts p_actuators with actions[]
# INPUTS: actions[] & p_actuators.txt
# OUTPUTS: p_actuators.txt with con actions
#------------------------------------------------------------------
def write():
global file,actions
inter_actuators=open(file,'w')
for i in actions:
inter_actuators.write(i)
inter_actuators.close()
start_actions()
inter_sensors=open(file2,'r')
a=[]
while True:
x=inter_sensors.readline()
if x!='':
a.append(x[:len(x)-1])
else:
break
inter_sensors.close()
a[16]='Origin: SCREEN'
inter_sensors=open(file2,'w')
for x in a:
inter_sensors.write(x+'\n')
inter_sensors.close()
#------------------------------------------------------------------
# MODULE BLOCK(): blocks/unlocks buttons use
# INPUTS: locked=True/False variable
# OUTPUTS: runs ok() or nook() & updates locked like a flip-flop
#------------------------------------------------------------------
def block():
364
Home Automation with Raspberry, Google & Python
global locked
if locked:
ok()
locked=False
else:
nook()
locked=True
#------------------------------------------------------------------
# MODULE OK(): shows ok button
# INPUTS: button call
# OUTPUTS: shows ok button, sound & pause
#------------------------------------------------------------------
def ok():
global button_ok
button_ok=Button(ven,borderwidth=5,background=green)
button_ok.pack()
button_ok.place(x=left+width_short+17,y=height*7+offset+10
,width=height_short,height=height_short*4)
image0=PhotoImage(file='/home/pi/home_auto/photos/ok.gif')
button_ok.config(image=image0)
beep()
time.sleep(.3)
#------------------------------------------------------------------
# MODULE NOOK(): shows nook button
# INPUTS: button call
# OUTPUTS: shows nook button, sound & pause
#------------------------------------------------------------------
def nook():
global button_nook
button_nook=Button(ven,borderwidth=5,background=red)
button_nook.pack()
button_nook.place(x=left+width_short+17,y=height*7+offset+10
,width=height_short,height=height_short*4)
image0=PhotoImage(file='/home/pi/home_auto/photos/nook.gif')
button_nook.config(image=image0)
beep()
time.sleep(.3)
#------------------------------------------------------------------
# MODULE OPEN(): shows open button
# INPUTS: button call
# OUTPUTS: shows open button & updates actions[]
#------------------------------------------------------------------
def open():
actions[6]='Open all window blinds: YES\n'
write()
ok()
#------------------------------------------------------------------
# MODULE CLOSE(): shows close button
# INPUTS: button call
# OUTPUTS: shows close button & updates actions[]
#------------------------------------------------------------------
365
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
def close():
actions[4]='Close all window blinds: YES\n'
write()
nook()
#------------------------------------------------------------------
# MODULE OFF(): shows off button
# INPUTS: button call
# OUTPUTS: shows off button & updates actions[]
#------------------------------------------------------------------
def off():
actions[0]='Switch off lights: YES\n'
write()
ok()
#------------------------------------------------------------------
# MODULE AMBIENT(): shows ambient button
#------------------------------------------------------------------
# MODULE HOLIDAYS_ON/OFF(): shows holidays_on/off button
#------------------------------------------------------------------
# MODULE GAS_ON/OFF(): shows gas_on/off button
#------------------------------------------------------------------
# MODULE WATER_ON/OFF(): shows water_on/off button
#------------------------------------------------------------------
# MODULE RESET_ROUTER/NAS(): shows reset_router/nas button
#------------------------------------------------------------------
#------------------------------------------------------------------
# MODULE EXIT(): show exit button
# INPUTS: button call
# OUTPUTS: show exit button & updates actions[]
#------------------------------------------------------------------
def exit():
ven.quit()
#------------------------------------------------------------------
# Button definition: 2 instructions with location & content, image
# compound position, relief or overrelief, achor text position,
# run command, activebackground colour, left and upper offset
#------------------------------------------------------------------
button_ok_ini=Label(ven,compound=BOTTOM,relief="raised"
,borderwidth=5)
button_ok_ini.pack()
button_ok_ini.place(x=left+width_short+17,y=height*7+offset+10
,width=height_short,height=height_short*4)
image0=PhotoImage(file='/home/pi/home_auto/photos/ok.gif')
button_ok_ini.config(image=image0)
#------------------------------------------------------------------
# OPEN BUTTON
#------------------------------------------------------------------
button_open=Button(ven,text='Open
Blinds',anchor='w',compound=LEFT,font=font,relief="raised"
,overrelief='sunken',borderwidth=5,command=open
366
Home Automation with Raspberry, Google & Python
,activebackground=green,cursor=type_cur)
button_open.pack()
button_open.place(x=left,y=height+offset,width=width_short
,height=height_short)
image1=PhotoImage(file='/home/pi/home_auto/photos/open blinds.gif')
button_open.config(image=image1)
#------------------------------------------------------------------
# CLOSE BUTTON
#------------------------------------------------------------------
button_close=Button(ven,text='Close blinds',anchor='w'
,compound=LEFT,font=font,relief="raised",overrelief='sunken'
,borderwidth=5,command=close,activebackground=red
,cursor=type_cur)
button_close.pack()
button_close.place(x=right,y=height+offset,width=width_short
,height=height_short)
image2=PhotoImage(file='/home/pi/home_auto/photos
/close blinds.gif')
button_close.config(image=image2)
#------------------------------------------------------------------
# OFF BUTTON
#------------------------------------------------------------------
button_off=Button(ven,text='Switch off All
Lights',anchor='c',compound=LEFT,font=font,relief="raised",
overrelief='sunken',borderwidth=5,command=off
,activebackground=green,cursor=type_cur)
button_off.pack()
button_off.place(x=left+40,y=height*3+offset,width=ancho_largo,heig
ht=height_short)
I
mage3=PhotoImage(file='/home/pi/home_auto/photos/off all.gif')
button_off.config(image=image3)
#------------------------------------------------------------------
# AMBIENT BUTTON
#------------------------------------------------------------------
button_ambient=Button(ven,text='Movie Ambient',anchor='c'
,compound=LEFT,font=font,relief="raised",overrelief='sunken'
,borderwidth=5,command=ambient,activebackground=green
,cursor=type_cur)
button_ambient.pack()
button_ambient.place(x=left+40,y=height*5+offset,width=ancho_largo
,height=height_short)
image4=PhotoImage(file='/home/pi/home_auto/photos
/movie ambient.gif')
button_ambient.config(image=image4)
367
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
#------------------------------------------------------------------
# HOLIDAYS BUTTON
#------------------------------------------------------------------
button_holidays_on/off=Button(ven,text='Holidays ON/OFF',anchor='w'
,compound=LEFT,font=font,relief="raised",overrelief='sunken'
,borderwidth=5,command=holidays_on/off,activebackground=red
,cursor=type_cur)
button_holidays_on/off.pack()
button_holidays_on/off.place(x=left,y=height*7+offset
,width=width_short,height=height_short)
I
mage5=PhotoImage(file='/home/pi/home auto/photos/holidays
on/off.gif')
button_holidays_on/off.config(image=image5)
#------------------------------------------------------------------
#GAS ON/OFF BUTTONS
#------------------------------------------------------------------
button_gas_on/off=Button(ven,text='Gas ON/OFF',anchor='w'
,compound=LEFT,font=font,relief="raised",overrelief='sunken'
,borderwidth=5,command=gas_on/off,activebackground=green
,cursor=type_cur)
button_gas_on/off.pack()
button_gas_on/off.place(x=left,y=height*9+offset,width=width_short
,height=height_short)
image7=PhotoImage(file='/home/pi/home_auto/photos/gas on/off.gif')
button_gas_on/off.config(image=image7)
#------------------------------------------------------------------
# WATER ON/OFF BUTTONS
#------------------------------------------------------------------
button_water_on/off=Button(ven,text='Water ON/OFF',anchor='w'
,compound=LEFT,font=font,relief="raised",overrelief='sunken'
,borderwidth=5,command=water_on/off,activebackground=green
,cursor=type_cur)
button_water_on/off.pack()
button_water_on/off.place(x=left,y=height*11+offset
,width=width_short,height=height_short)
image9=PhotoImage(file='/home/pi/home_auto/photos
/water on/off.gif')
button_water_on/off.config(image=image9)
#------------------------------------------------------------------
# RESET ROUTER/NAS BUTTONS
#------------------------------------------------------------------
button_reset_router/nas=Button(ven,text='Router/NAS Reset'
,anchor='w',compound=LEFT,font=font,relief="raised"
,overrelief='sunken',borderwidth=5,command=reset_router/nas
,activebackground=green,cursor=type_cur)
368
Home Automation with Raspberry, Google & Python
button_reset_router/nas.pack()
button_reset_router/nas.place(x=left,y=height*13+offset
,width=width_short,height=height_short)
image11=PhotoImage(file='/home/pi/home_auto/photos
/reset router/nas.gif')
button_reset_router.config(image=image11)
#------------------------------------------------------------------
# MAIN BODY OF THE PROGRAM
#------------------------------------------------------------------
try:
start_actions()
lock=True #if it can acts control
print 'Waiting '+str(delay)+' seconds to Chrome starts'
time.sleep(delay)
mainloop() #to star buttons actions
except Exception:
logging.exception('\n'+time.strftime("%d-%m-%y ")
+time.strftime("%X ")+'\n'+'-'*40+'\n')
os.system('python /home/pi/domotica/p_pantalla.py')
369
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*P_logfile.py
# TEXT COLOUR
class colour:
RED = '\033[91m'
BLUE = '\033[94m'
GREEN = '\033[32m'
YELLOW = '\033[33m'
PURPLE = '\033[35m'
CYAN = '\033[36m'
SIN = '\033[0m' #without effect
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
CURSIVA = '\033[3m'
while True:
time.sleep(.05) #reduces CPU consumption <10%
fic=open(log,'r')
lines=fic.readlines()
fic.close()
last_line=lines[len(lines)-1] #without character \n
if last_line<>old_line:
date =last_line[:19] #main fields
topic=last_line[19:80]
origin=last_line[80:len(last_line)-1]
print
colour.RED+date+colour.GREEN+topic+colour.BLUE+colour.CYAN+origin
+colour.SIN
old_line=last_line
⊝⊝⊝
370
Home Automation with Raspberry, Google & Python
31.-SCHEMES
I
n this section several simulations made
w i t h iCircuit* are attached to test the
designs made before creating the project
prototype.In these schemes it can see a
project module, adapted to the simulation and temporal
evolution of some critical variables (voltage,
current, frequency, etc.) to ensure that the circuit
works as expected.
5. Watchdog circuit.
371
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*General 220v
Interface
372
Home Automation with Raspberry, Google & Python
*Power Alarm
Interface
373
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Buzz an CK
Circuit
374
Home Automation with Raspberry, Google & Python
*Doorbell
Circuit
375
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
376
Home Automation with Raspberry, Google & Python
*Watchdog
Circuit
377
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Logic Levels
Converter
378
Home Automation with Raspberry, Google & Python
*Other Schemes
gregochenlo.blogspot.com
379
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
380
Home Automation with Raspberry, Google & Python
381
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
382
Home Automation with Raspberry, Google & Python
Thanks so much.
383
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Scheme: General
384
Home Automation with Raspberry, Google & Python
385
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Scheme: Hardware
4. C o n n e c t i o n o f v a r i o u s d e v i c e s t o t h e
corresponding WIFI, both 2.4GHz and 5GHz.
Highlights the Google Home* Mini that allows
bidirectional *.mp3 sounds (bark of the guard
dog simulation, etc.) & voice command management
of the entire system.
386
Home Automation with Raspberry, Google & Python
7. Secondary Raspberry* w i t h t h e 3 f u n c t i o n s
described in the general scheme: touch screen
control for home automation buttons, multimedia
server management with PLEX*, a photo frame
simulator and automatic transition algorithm
between these three functions.
387
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
388
Home Automation with Raspberry, Google & Python
*Scheme: Software
389
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
9. F i n a l l y t h e Python* m o d u l e s a r e l i s t e d :
p_global.py (global home automation control),
p _ t e l e g r a m . p y (Telegram* b o t m a n a g e r ) ,
p_pantalla.py (home automation access buttons,
PLEX* man age r, p hot o fr ame sim ula tor and
automatic transition algorithm) and p_logfile.py
(system event viewer).
390
Home Automation with Raspberry, Google & Python
391
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Scheme: Switches
eWelink*
392
Home Automation with Raspberry, Google & Python
393
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Scheme: KNX* vs
Raspberry*
394
Home Automation with Raspberry, Google & Python
395
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Scheme: Complete
Circuit*
396
Home Automation with Raspberry, Google & Python
397
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
32.-MINIMUM AND
SCALED SOLUTIONS
I
n this section are attached minimum and
scaled proposals schemes (from simpler to
more complex), without the need to
implement all the sensors, actuators,
devices and software described in this book.
398
Home Automation with Raspberry, Google & Python
*OPTION 1:
The Minimum Necessary
399
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
400
Home Automation with Raspberry, Google & Python
*OPTION 2:
With Some Control
401
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
402
Home Automation with Raspberry, Google & Python
*OPTION 2a:
With More Control
403
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
404
Home Automation with Raspberry, Google & Python
*OPTION 3:
Advanced Option
405
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
406
Home Automation with Raspberry, Google & Python
33.-WEB
BIBLIOGRAPHY
A
series of web pages that have helped to
build this project are summarised below. In
them there is the solution to 100% of the
problems sought, perhaps the learning
process is based precisely on the path of information
search, rather than on the information itself, but in
them there is a lot of useful information and a lot of
work for part of many enthusiasts of Home Automation,
Software, Hardware, etc., to which I thank again their
gesture of sharing with everyone, via the Internet,
their experiences, their ideas and their efforts.
407
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Raspberry*
https://www.raspberrypi.org/
https://www.berryterminal.com/doku.php/berryboot
https://azure-samples.github.io/raspberry-pi-web-
simulator/
http://www.kami.es/2016/ejecutar-script-al-inicio-
raspberry-pi/
https://www.cnet.com/how-to/how-to-setup-bluetooth-on-
a-raspberry-pi-3/
https://raspberryparatorpes.net/sistemas-
operativos/nuevo-raspbian-stretch/
https://www.deacosta.com/instrucciones-para-
actualizar-raspbian-8-jessie-raspbian-9-stretch-en-
raspberry-pi/
https://raspberrypi.stackexchange.com/questions/10209/
how-to-disable-mouse-cursor-on-lxde
https://raspberrypi.stackexchange.com/questions/30056/
raspberry-pi-raspbian-multiple-desktops
*Linux*
http://www.raspbian.org
http://www.linux.org
http://ekiketa.es/crear-un-script-ejecutable-por-el-
shell-en-linux/
https://wiki.lxde.org/en/Talk:LXTerminal
https://www.luisllamas.es/tutoriales-de-raspberry-pi-
linux/
https://www.raspberrypi.org/blog/another-update-
raspbian/
https://www.raspberrypi.org/forums/viewtopic.php?
t=99646
408
Home Automation with Raspberry, Google & Python
*Hardware
https://www.cetronic.es
https://www.mouser.es/
https://www.kubii.fr/
https://mydevices.com/
http://kookye.com/category/tutorials/rapsberry-pi-
projects/
http://www.electronicaestudio.com/
https://computers.tutsplus.com/articles/creating-a-
speaker-for-your-raspberry-pi-using-a-piezo-element--
mac-59336
https://www.eibmarkt.com/cgi-
bin/eibmarkt.storefront/DE/Product/NS6512716?
PID=DE_NS6512716
https://www.domotiga.nl/projects/domotiga/wiki/Hardwar
e_RaspberryPi
http://www.eelectron.com/it/prodotto/interfaccia-
raspberry-pi-knx/?lang=en
https://www.hqs.sbt.siemens.com/cps_product_data/data/
produktdb_en.htm
http://www.ugreen.com.cn/product-681-en.html
*Tkinter*
https://github.com/eliluminado/Guia-
Tkinter/blob/master/Interfaz%20grafica%20con
%20Tkinter.wiki
https://guia-tkinter.readthedocs.io/es/develop/
https://python-para-
impacientes.blogspot.com/2016/07/animaciones-con-
pyapng.html
409
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Python*
http://www.python.org
https://www.codecademy.com/catalog/subject/all
https://drive.google.com/drive/folders/0B-
EjJI8oLlmdZDRyMkM0UTNmZ00
https://plot.ly/python/
https://inventwithpython.com/es/7.html
http://acodigo.blogspot.com/2013/11/python-gui-
ventanas.html
https://linuxconfig.org/how-to-change-default-python-
version-on-debian-9-stretch-linux
https://packages.debian.org/stretch/all/python-
pychromecast/download
*Telegram*
https://web.telegram.org/
https://geekytheory.com/tutorial-raspberry-pi-uso-de-
telegram-con-python
https://www.fwhibbit.es/controla-tu-raspberry-pi-
mediante-telegram
https://www.atareao.es/tutorial/crea-tu-propio-bot-
para-telegram/bot-en-python-para-telegram/
https://my.knx.org/
https://raspberrypi.stackexchange.com/questions/45570/
410
Home Automation with Raspberry, Google & Python
how-do-i-make-serial-work-on-the-raspberry-pi3-pi3b-
pizerow
http://jjmilburn.github.io/2016/04/04/ttyUSB-to-
vagrant-virtualbox/
http://vendomotica.com/imgcsv/Guia%20de%20programacion
%20KNX(ES)_MWS3AKNX.pdf
http://www.futurasmus-knxgroup.es/
https://support.industry.siemens.com/cs/products/5wg11
17-2ab12/-?pid=354073&dtp=Certificate&mlfb=5WG1117-
2AB12&mfn=ps&lc=es-ES
https://cursodidacticoknx.wordpress.com/2-12-acuse-de-
recibo/
https://blog.openalfa.com/instalacion-y-uso-de-eibd
https://github.com/weinzierl-engineering/baos
http://perso.wanadoo.es/pictob/comserie.htm
https://www.dehof.de/eib/DE/raspi.htm
https://www.bauwas.eu/?tag=raspberry
http://www.peatonet.com/raspberry-pi-y-los-pinesgpio-
controlando-raspberry-a-traves-del-puerto-serie-de-
consola/
https://pyserial.readthedocs.io/en/latest/pyserial_api
.html
http://es.tldp.org/COMO-INSFLUG/COMOs/Terminales-
Como/Terminales-Como-3.html
http://trasteandounpoco.blogspot.com/2007/12/interfaz-
serie-rs232-knx-ft12-con.html
https://www.mac-usb-serial.com/docs/tutorials/serial-
port-access-virtualbox-machines-running-mac-os-x.html
https://forums.virtualbox.org/viewtopic.php?t=26860
https://www.virtualbox.org/manual/ch03.html#serialport
s
*NO-IP*
https://www.noip.com/
https://www.realdroid.es/2016/10/29/configurar-no-ip-
para-raspberry-pi-y-de-paso-que-es-no-ip/
411
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Samba*
https://www.samba.org/
https://www.naguissa.com/foro/i601/configurar-fstab-
para-montar-unidades-de-windows-o-samba-
automaticamente
https://www.atareao.es/tutorial/raspberry-pi-primeros-
pasos/compartir-archivos-en-red-con-samba/
*VNC*
http://www.vnc.com/
https://geekytheory.com/tutorial-raspberry-pi-7-
escritorio-remoto-vnc-no-ip/
https://www.realvnc.com/es/connect/docs/server-
parameter-ref.html
https://librebit.github.io/raspberry/raspbian/vnc/serv
er/2016/09/14/habilitar-vnc-server-en-raspberry-
pi.html
*PLEX*
https://www.plex.tv/
https://thepi.io/how-to-set-up-a-raspberry-pi-plex-
server/
https://www.codedonut.com/raspberry-pi/raspberry-pi-
plex-media-server/
412
Home Automation with Raspberry, Google & Python
*Google Home*
https://store.google.com/es/product/google_home
https://medium.com/google-cloud/building-your-first-
action-for-google-home-in-30-minutes-ec6c65b7bd32
https://www.instructables.com/id/Google-Home-
Raspberry-Pi-Power-Strip/
https://www.sistemasorp.es/2018/08/07/ordenar-
comandos-a-un-robot-con-tu-propia-voz-y-el-altavoz-de-
google-home/
https://github.com/greghesp/assistant-relay
https://github.com/harperreed/google-home-notifier-
python
*IFTTT*
http://www.ifttt.com
https://ifttt.com/applets/85059471d-if-you-say-
enciende-luz-sofa-then-make-a-web-request
https://ifttt.com/services/maker_webhooks/settings
https://www.xatakahome.com/trucos-y-bricolaje-
smart/the-maker-channel-es-lo-mejor-que-le-ha-pasado-
a-ifttt-y-a-la-internet-de-las-cosas
*Edimax*
http://www.edimax.com/
https://github.com/bablokb/ediplug
https://github.com/wendlers/ediplug-py
413
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
*Various
http://www.portchecktool.com/
http://www.intranet-of-
things.com/smarthome/infrastructure/knx/arduino/
https://www.calculadoraconversor.com/conversor-
binario/
https://image.online-convert.com/convert-to-gif
http://www.findsounds.com/ISAPI/search.dll
https://developer.microsoft.com/en-us/microsoft-
edge/tools/vms/
http://codigodiario.me/proteger-autenticacion-una-
ruta-apache2/
https://www.enmimaquinafunciona.com/pregunta/536/puede
s-pasarpase-de-usuario-para-la-autenticacion-basica-
http-en-parametros-de-url
⊝⊝⊝
414
Home Automation with Raspberry, Google & Python
34.-NEWS OF
THIS EDITION
I
n this new edition of this book, the
following topics have been added and or
corrected and some improvements have been
introduced.
415
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
⊝⊝⊝
416
Home Automation with Raspberry, Google & Python
35.-GLOSSARY
OF TERMS
Term Description
868 Low power consumption transmission system
1-Wire* Serial communications protocol
Circuit supporting transmission in 2
2-Wire*
directions
3rd & 4th generation of mobile technology
3G/4G
transmission system
4K High definition TV format
6LowPAN Low power wireless Personal Area Network
A/D Analog/Digital converter
Alternating Current to Direct Current
AC/DC
converter
A device that causes a machine o other
Actuator
device to operate
ADS Audio Digital System Fermax* protocol
AI Artificial Intelligence
Alexa* Amazon* assistant
Android* Google* mobile operative system
WEB server with open source for several
Apache*
platforms
APCI Aplication Protocol Control Information
APP Application abbreviation
Apple* TV Apple digital multimedia receiver
Development platform based on a free
Arduino*
hardware board
417
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Term Description
ARP Address Resolution Protocol
ARC Audio Return Channel HDMI protocol
ARM* Advanced RISC* Machine
Synchronisation process between sender
Asynchronous
and receiver is performed in each word
Industrial specification for wireless
Bluetooth*
personal area networks
Computer program that automatically
BOT
performs repetitive tasks
Telegram keys, aliases & permissions
BotFather*
management
Procedure connects two networks or groups
Bridge
of clients in cable networks
Broadlink *
RM* mini manufacturer
BTI Bus Transceiver Interface
Digital system that transfers data
Bus
between components
Buzz Audio generator
C-NC Closed-Normally Closed
CEC *
Consumer Electronics Control
Chromecast *
Google* portable device synchroniser
Chromium *
Google* free & open source web browser
Binary signal to coordinate the actions
Clock
of several circuits
CO2 Carbon dioxide
Module for displaying colour texts in
Colorama*
LXTerminal* Raspbian* windows
Electronic device to transform an analog
Converter
signal into a digital signal
Carrier Sense Multiple Access with
CSMA/CA*
Collision Avoidance
Daemon Program running in the background
Software-managed bidirectional serial
DAT
protocol
Decoder Receiver device and TV signal converter
418
Home Automation with Raspberry, Google & Python
Term Description
DHCP Dynamic Host Configuration Protocol
Electro mechanical device for the
Differential
electrical protection of people
Standardised format in electrical
DIN installations
DLNA* Digital Living Network Alliance
DNS* Domain Name System
DSL* Digital Subscriber Line
DUC* Dynamic DNS* Update Client
DVI* Digital Visual Interface (only video)
DYN* Dynamic DNS* or DDNS*
Eagle* Electronic Design Automation software
Edilife* APP to control Edimax* devices
European Installation Bus (currently
EIB*
KNX*)
EIS* EIB* Interworking Standard KNX* protocol
Free & open source APP used to write
Etcher*
image files
Standard of local area networks for
Ethernet*
computers
Engineering Tool Software (software for
ETS*
KNX* installations)
ext3 Third Extended Filesystem format
FAT32* File Allocation Table with 32 bits
Fermax* Electronic intercoms manufacturer
Finder* Relays manufacturer
To quickly know all the equipment
Fing*
connected to a network APP
Multivibrator capable of remaining in one
Flip-flop
of two possible states
FreeDyn* Software to update dynamic DNS*
Device that acts as a connection
Gateway
interface between devices or computers
GIF Graphics Interchange Format
Ethernet* standard that achieves 1
Gigabit
gigabit per second
419
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Term Description
Gmail* *
Google email service
Google* smart speaker with Artificial
Google Home*
Intelligence
GPIO *
General Purpose Input Output
Handshake Communication establishment protocol
HDMI *
High Definition Multimedia Interface
HGU *
Home Gateway Unit
Google* APP to Google Home* Mini
Home*
management
Home Set of techniques aimed at automating a
automation home
http:// Hypertext Transfer Protocol
https:// Hypertext Transfer Protocol Secure
Network element used to connect several
HUB
Ethernet* devices
Inter-Integrated Circuit Raspberry*
I2C*
interface
iCircuit *
Electronic circuit simulation software
Integrated Development Environment for
IDLE*
Python*
IFTTT *
If This Then That integrator software
IGMP *
Internet Group Management Protocol
IHC *
Broadlink RM* mini APP
Apparent resistance of a circuit equipped
Impedance
with capacity & self-induction
Software that manages interactions
Integrator
between applications or devices
Interface Connection between devices or systems
iOS *
Apple* mobile operating system
IP Internet Protocol address
Software to know the IP of the devices
IPScanner*
connected to the network
IR Infrared device
ISO Exact image or copy of a file
Itead *
Sonoff* switches manufacturer
Kasa* APP to control WIFI bulbs of TP-Link*
420
Home Automation with Raspberry, Google & Python
Term Description
Standard open world for the control of
KNX*
houses and buildings (before EIB*)
LAN Local Area Network
LB100 *
TP-Link* WIFI bulb
LED Light-Emitting Diode
LXTerminal *
Terminal software integrated in Raspbian*
MAC Media Access Control address
McAfee *
Antivirus software
Message-Digest Algorithm 5 encryption
MD5*
management
Mesh Wireless network with a single SSID
MHL Mobile High-definition Link
Metal Oxide Semiconductor Field Effect
MOSFET
transistor
NAS Network Attached Storage
NAT Network Address Translation
Netflix *
Multimedia content provider
NFC *
Near Field Communication
Software to access to the local server
NGROK*
from the internet with dynamic URL
Dynamic DNS* Update Client for NO-IP*
NO-IP DUC*
environment
New Out Of Box Software to Raspberry*
NOOBS*
software installation
NPCI Network Protocol Control Information
NPM Node Package Manager
NPN Transistor with N, P & N layers
ONT *
Optical Network Termination
Optocoupler Light activated switch device
OSX* Apple Operating System for computers
PCB Printed Circuit Board
PCM Pulse Code Modulation
Physical External Interface of the Bus
PEI-10*
Coupling Unit with 10 pin on KNX* systems
Hypertext Preprocessor general purpose
PHP
programming language
421
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Term Description
Electroacoustic transducer with
Piezoelectric
piezoelectric crystal
Ping Network diagnostic program
PLEX *
Multimedia content server
PNP Transistor with P, N & P layers
Router channel in which the sending of
Port
information is organised
Pycharm *
Professional Python* script editor
Python *
Interpreted programming language
Micro computer created by the Raspberry*
Raspberry*
Foundation & based on ARM* technology
Distribution of the Debian-based Linux*
Raspbian*
operating system
Relay Electromagnetic switch
Allows to reset the pulse with a new shot
Retriggerable
before completing the timing
Ripples* Screensaver in Raspbian*
RISC* Reduced Instruction Set Computer
RJ11 Connector used in telephone networks
RJ45 Connector used in computer networks
Device to connect computers within a
Router
network
Script that contains a series of
Routine
independent activities or instructions
Serial binary data communication
RS232
interface
Request to Send/Clear to Send flow
RTS/CTS
control signals
RxD Receive Data
Samba *
Microsoft* file sharing protocol
Schmitt *
Special type of electronic comparator and
trigger trigger
Sensor Device that captures physical quantities
Running application capable of responding
Server
to customer requests
Manufacturer of the logical level
Sodial*
converter device ADUM1201*
422
Home Automation with Raspberry, Google & Python
Term Description
Sonoff* *
Itead basic switch
Speedtest Network speed test software
Serial Peripheral Interface in Raspberry*
SPI*
device
Structured Query Language used in
SQL*
programming to manage databases
Secure Shell for remote access to a
SSH*
server
SSID Server Set Identifier
STB Set Top Box connection
Stretch* Raspbian* version operating system
Device that allows diverting or
Switch interrupting the course of an electric
current
Tadoº* Electronic thermostat with geolocation
Tao-Glow* Infrared colours lamp
Transmission Control Protocol/User
TCP/UDP
Datagram Protocol
TCPI Transport Protocol Control Information
Telegram* Personal communication software
Entry text mode application to Raspbian*
Terminal
system
Pre-established maximum time to execute a
Timeout
process
To create and locate software buttons on
Tkinter*
the screen
LB100* WIFI bulb & WIFI extender
TP-Link*
manufacturer
Electronic device to switching or amplify
Transistor
electronic signals
TTL Transistor Transistor Logic
TxD Transmit Data
Universal Asynchronous Receiver-
UART*
Transmitter
Distribution of the Linux* operating
Ubuntu*
system
Ugreen* USB to Serial interface manufacturer
423
Gregorio Chenlo Romero (gregochenlo.blogspot.com)
Term Description
UHD *
Ultra High Definition, similar to 4K
UPS Uninterruptible Power Supply
URL Uniform Resource Locator
uSD Micro Security Digital memory
Valve Fluid regulation and control instrument
VDS** Video Digital System Fermax* protocol
Software for virtualisation several
VirtualBox*
operating systems
VNC* Virtual Network Computing
WAP* Wireless Application Protocol
Watchdog Electronic flow control circuit
WD* Western Digital* manufacturer
Method of altering the operation of a web
Webhook*
page
WIFI Wireless Fidelity
Working group in a Microsoft* network
Workgroup
protocol
x bauds Symbol (1 or more bits) per second
x bps Bits per second
x cm Centimetres
x dB Decibels
x fps Frames per second
x Hz Hertz
x mA Mili amperes
x uF Micro farads
x v Volts
x w Watts
x Ω Ohm
Xscreensaver *
Screensaver on Raspbian*
ZIP Lossless file compression format
⊝⊝⊝
424
Home Automation with Raspberry, Google & Python
gregochenlo.blogspot.com
425