Blog
Projects
Docs, Tips & tricks
Freebsd tips
GNU/Linux tips
November 2024 | ||||||
M | T | W | T | F | S | S |
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
Mitsubishi HVAC managed from Home Assistant using MQTT and ESP32 with WiFi | Sun, 29 Sep 24 |
I got installed three Mitsubishi HVAC, and I needed a way to control them from a central point and remotely. I have already an Home Assistant solution, based on custom Debian over a Raspberry Pi 4. The first idea was to connect the Mitsubishi HVAC to the Home Assistant using two wire to activate them. But then I found a lot of already work done to completely manage the Mitsubishi HVAC using an ESP MCU connected to the internal CN105 serial connector. The first code and guide I found were from SwiCago. But I have a lot of ESP32 MCU available, that has bigger size but is powered with 5 V available from the CN105, so no need for a powering circuit. Then I came accross the gysmo38 mitsubishi2MQTT project: fantastic! it is based on ESP32 MCU, it includes a local web interface on the ESP to control the HVAC, and has implemented a complete control of the HVAC using a MQTT client over WiFi. So I've used this mitsubishi2MQTT and adjusted Home Assistant on Debian to get the job done. == LIST OF MATERIALS ==Prerequisites:
== SETUP HVAC USING mitsubishi2MQTT ==
Connect the ESP32 device to the CN105 connector using the cable. CN105 has a serial TTL and power 5 V supply. Pins are in the following order: 1: +12 V <- do not connect (in MFZKT35VG model placed at bottom) 2: GND <- connect to GND of ESP32 3: +5 V <- connect to 5V of ESP32 4: TX <- connect to RX of ESP32 5: RX <- connect to TX of ESP32I placed the ESP32 device just outside the carter of the HVAC control card. == SETUP HOME ASSISTANT TO COMMUNICATE WITH mitsubishi2MQTT ===== SETUP MOSQUITTO ===Setup the compatible MQTT broker, that is mosquitto. Then configure Home Assistant to connect to mosquitto.If not present, install mosquitto service on the Debian system where Home Assistant is running. As root, execute: root@pi:~# apt-get install mosquitto Note, the following packets are needed on my system: mosquitto_1.6.12-1, libdlt2_2.18.5-0.4, libwebsockets16_4.0.20-1, libev4. Configure mosquitto username and password. Replace USER with your MQTT username. root@pi:~# mosquitto_passwd -c /etc/mosquitto/passwd USERSetup mosquitto to include login: root@pi:~# vi /etc/mosquitto/conf.d/default.conf # add the following text: allow_anonymous false password_file /etc/mosquitto/passwdAnd restart service. root@pi:~# systemctl restart mosquitto === SETUP MQTT IN HOME ASSISTANT ===In the Home Assistant configuration file, add the MQTT broker informations. Set IP of broker 192.168.0.123 with your IP of mosquitto; set username and password as set before.root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml # add the following section [...] mqtt: broker: 192.168.0.123 client_id: 'hass' username: 'USER' password: 'PASS' Using the web interface of Home Assistant, go to Configuration, then Integrations and click MQTT. There is a window where is it possible to "Publish a packet" and "Listen to a topic". Check that the communication between mosquitto, Home Assistant and ESP mitsubishi2MQTT is working. In the "listen to a topic" field, indicate the wildcard topic mitsubishi2mqtt/#and start listening. The ESP mitsubishi2MQTT should sent periodically a state message. It is possible to send a query message to the ESP mitsubishi2MQTT, such as (replace NAME-OF-HVAC with name previously set) mitsubishi2mqtt/NAME-OF-HVAC/state # you should receive something like mitsubishi2mqtt/NAME-OF-HVAC/state { "roomTemperature": 21.5, "temperature": 20, "fan": "auto", "vane": "AUTO", "wideVane": "|", "mode": "off", "action": "off", "compressorFrequency": 0 } If that works, good. You now only have to setup an entity for each Mitsubishi HVAC. === SETUP HVAC DEVICE IN HOME ASSISTANT ===To add an entity to control the Mitsubishi HVAC, I added in the configuration file a climate thermostat for each one.Under climate section add the following subsection for each heat pump. Modify NAME-OF-HVAC with name previously set. root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml [...] climate: [...] - platform: mqtt name: USER-FRIENDLY-NAME mode_command_topic: "mitsubishi2mqtt/NAME-OF-HVAC/mode/set" current_temperature_topic: "mitsubishi2mqtt/NAME-OF-HVAC/state" current_temperature_template: "{{ value_json.roomTemperature }}" temperature_command_topic: "mitsubishi2mqtt/NAME-OF-HVAC/temp/set" temperature_unit: C max_temp: 30 min_temp: 16 mode_state_topic: "mitsubishi2mqtt/NAME-OF-HVAC/state" mode_state_template: "{{ value_json.mode }}" mode_command_topic: "mitsubishi2mqtt/NAME-OF-HVAC/mode/set" modes: ["off", "cool", "heat", "dry", "on"] Restart Home Assistant service (can be done also from webpage). Add on the web interface a thermostat panel: you now can choose a climate.USER-FRIENDLY-NAME entity. Enjoy == MQTT TOPIC OF ESP mitsubishi2MQTT ==For reference reported heretopic/power/set OFF topic/mode/set AUTO HEAT COOL DRY FAN_ONLY OFF ON topic/temp/set 16-31 topic/remote_temp/set also called "room_temp", the implementation defined in "HeatPump" seems not work in some models topic/fan/set 1-4 AUTO QUIET topic/vane/set 1-5 SWING AUTO topic/wideVane/set << < | > >> topic/settings topic/state topic/debug/packets topic/debug/packets/set on off topic/debug/logs topic/debug/logs/set on off topic/custom/send custom see https://github.com/SwiCago/HeatPump/blob/master/src/HeatPump.h topic/system/set reboot == USEFUL LINKS ==https://github.com/gysmo38/mitsubishi2MQTThttps://chrdavis.github.io/hacking-a-mitsubishi-heat-pump-Part-2/ https://www.home-assistant.io/integrations/climate.mqtt/ https://www.home-assistant.io/integrations/mqtt#manual-configured-mqtt-items |
Home control with local touchscreen, HTTP remote control, analog and digital IO | Wed, 4 Aug 21 |
My need was for an unified device to locally and remotely control home and garden. You'll find a lot of stuff based on Raspberry, so I went that way.
Device is based on Raspberry Pi 4 with touch screen display and some custom hardware. About the software platform I choosed "Home Assistant Core", installed on Raspbian Debian on ARM that I know quite well. The choice has these pros:
== LIST OF MATERIALS ==The Rasperry Pi
The interface board
Sensors and actuators
For the boxing
Tools needed
=== HARDWARE SETUP ===The Raspberry Pi 4 is fixed on the back of touchscreen display 7". The display is connected to the Pi using his DSI display flat cable.There is a custom board with some components, IC, fuses and screw connectors, fixed over the Raspberry Pi 4 and directly connected on the GPIO header. The connectors represent the external interface, where are attached input devices (sensors and contact) and output control using a relay board. The external interface has the following specification: OUTPUTS - n.4 isolated digital output using a ready board including optocoupler and relay with both N.O. and N.C (max 10A 250VAC). My usage will be to control a boiler, a well pump, an irrigation valve, and some lights. INPUTS - n.1 1-wire protocol interface on 3.3V, can manage a number of sensors connected on the bus identified by serial ID. My usage will be to connect two temperature sensor. - n.1 I2C protocol interface on 3.3V, can manage a number of sensor connected on the bus identified by programmed ID. My usage will be to connect a humidity/pressure/temperature sensor. - n.3 Analog input, reading values in voltage, powered at 3,3V. My usage will be to connect two AC power sensor and a water pressure meter. - n.1 Digital input, optoisolated with variable resistor, input is high when input is closed to 5V. My usage will be to connect a boiler status indicator. - n.2 Digital input, protected with schottky diode, with input that have to go from GND to 5V and back. My usage will be to connect a hall water flow meter generating a square wave. POWER AVAILABLE - The available voltages are 3,3V and 5V, depending on the input type. - Total maximum current allowed is 0.5A for 3,3V and 1A for 5V, they are fused. NOTE ON I2C - Using a Pi version 4, on the DSI cable is passing video combined with touch commands using I2C protocol with address 0x38. - The I2C used is dedicated and is leaving free the I2C on the GPIO header. == CALCULATING ELECTRIC POWER ==I made an approximative calculation about needed current to size correctly the power supply.For the 5V I divide the power supply line for the Raspberry Pi 4 and for the external interface, so that I am using the Raspberry internal circuitry and fuse to protect itself and the display, and a new fuse for the sensors and devices. For the 3.3V I use the internal Raspberry Pi 4 regulator but I add a new fuse toward external devices. Raspberry Pi 4 700mA @ 5V 7" touchscreen display 550mA @ 5V 4 channel relay board each relay when activated 60mA @ 5V, near 0 otherwise. Total from 0 to 240mA 1-wire pullup resistor 1mA @ 3.3V 1-wire temperature sensor 2* 1mA @ 3.3V I2C humidity/bar/temp sensor 1mA @ 3.3V Analog to digital circuit 1mA @ 3.3V AC power sensor (n.2) <1mA @ 3.3V Water pressure meter <1mA @ 5V Digital input circuits <10mA @ 5V Hall water flow meter <10mA @ 5V Length of input sensor lines The length of input sensor lines depends mainly on the bus caracteristic and kind of wire. Expecting to use UTP cable with AWG24 (0.5 mm2) wires, the voltage loss of an input sensor that is consuming 10mA placed with lines 50 meters long is about 0.1V. For the 1-wire temperature sensor the bus length on this kind of wire still works 50 m away. 1-wire should use a star topology when using long wire wire more than one sensor. If needed, it could be necessary to add a low value resistors (under 100Ohm) on the data wire near the sensors to prevent ringing of signal. The Raspberry Pi 4 internal fuse should allow 1250 mA + at least 45 mA from the GPIO header 3.3V The external fuse for 5V should allow 500 mA. So I choosed for a 1 A. The external fuse for 3.3V should allow 45 mA. So I choosed for a 0.5 A. Summing all, the power supply should deliver at least 9W. == OUTPUT ACTUATORS ==Devices commands (output GPIO + relay)- 4 channel relay board with optocoupler and indicator led (I am in fact using an 8 channel board because I have that one available, but connect only 4 relays) Used to control:
If it's the case REMOVE JD-VCC to VCC jumper from the board. This jumper connects the input VCC with the relay VCC supply: we are using VCC of 3.3V for GPIO connections and 5V for relay supply. The GND is connected only with the 5V supply, NOT toward the Raspberry GPIO. To activate the relay coil, the gpio should go to 0 (GND). See this relay board as sample schematic reference == INPUT SENSORS === Internal temperature board =Nothing to be done externally of the board.= 1-wire data protocol =Works on 3 pin: VCC, GND, DQPull-up resistor 4.7k Ohm 4.7k between positive and data wire protocol positive to the +3.3 Used for: - Outdoor temperature sensor DS18B20 Temperature range -55°C e +125°C Power supply +3 - +5.5Vdc , negative ground Cable length should be maximum 10 meters; 1-wire protocol is capacitive, so don't use shielded cables to ground. More sensors can be added in parallel and shares the same pull-up resistor. 1-wire on Raspberry Pi 4 uses as default the pin 7 - GPIO 4 = I2C bus =Works on 4 pin: VCC, GND, SCL, SDA Directly connected to the Raspberry GPIO header. Using only sensors locally placed with short wires. Used for:- Sensor BME280 Indoor temperature, humidity, barometer sensor (I2C) I2C uses on Raspberry Pi 4 the pin 3 - GPIO 2 for SDA and pin 5 - GPIO 3 for SCL. Works on 3.3V. = Analog inputs =The Raspberry Pi 4 has only digital GPIO, as an input you can measure if the pin is connected to a 3.3V or 0V, no intermediate values are readeable. The analog inputs are based on a MCP3004/MCP3008 chip, measure voltage levels from 0 to 3.3V. The chip is connected to the Raspberry using SPI bus.My circuit can manage 3 inputs: n.2 AC current consumption and n.1 water pressure. MCP3008 Analog to Digital converterUsed for:- AC current consumption with sensor SCT-013-30, up to 30A that corresponds to 1V. The sensor includes burden resistor, and comes with two wire connection on 3.5 audio jack (L and K). The AC wire to be measured is one, so the hot wire OR the neutral wire, never both. As the voltage output is a sine wave corresponding of the AC current, and is centered on 0V, I need to adjust it to be readeable from the MCP3008. Using the SCT013-030 30A model, the maximum 30A is 6.5 kW on 220 VAC line, and outputs 1V RMS on the sensor. 1V RMS is 1.414 Vpp, so on a oscilloscope between the L and K wires you will see a wave going from -1.42V to +1.42V if you measures a load consuming 6.5 kW at 220VAC. The scale is linear, so i.e. you see a wave between -0.21V to +0.21V measuring a load consuming 1kW at 220VAC. The MCP3008 measures positive voltage values, and the range is from 0V to 3.3V as it is powered at 3.3V. I need a simple voltage divider to get a reference voltage. Dividing the half of 3.3V is alright as it is +1.65V, so that the measured sine wave will go from +0.23V to +3.07V (+1.65 -1.42 and +1.65 +1.42), a range that can be easily read from the MCP3008. Note: For the AC load I really need only to measure only peak value. I evalutated using a rectifier circuit with diode and capacitor, but the input signal can have very low amplitude so it's not a good option. I could use a precision rectifier introducing an operational amplifier. But finally I decided to not modify the wave more than changing the reference voltage and to work on software side, to simplify and more flexibility on the board circuit. - Water pressure sensor for home distribution pressure that should be 3 bar (0.3 MPa (Mega Pascal)) The sensor I choosed has following specs: Max. 0.5 MPa = 5 bar Powered at 5V Thread G1/4 Reading value: 0-0.5 MPa Maximum value: 1.5 MPa Damaging value: 3.0 MPa Temperature: 0-85 C Output Voltage: 0.5V = 0 MPa, 4.5V = 0.5 MPa The sensor has 3 pin connection: VCC, GND, analog voltage. The sensor works with +5V, so I need some voltage divider to match the 3.3V required for the MCP3008. The analog voltage ranges approximely from 0.5V to 4.5V. It is needed a simple voltage divider 2:1 to match the maximum 3.3V voltage reading of MCP3008 and GPIO, so I put a 2K / 1K Ohm on the analog voltage pin. Note that some 5V power supply are not exactly this value, but some more. For example 5.5V; in that case, the voltage divider 2:1 with an input of 5.5V gives 3.7V. But it's not an issue with the maximum input voltage of the MCP3008, as the sensor output at max pressure 0.5 MPa (5 bar) is 4.5V, that is 3V after the voltage divider. SPI uses on Raspberry Pi 4 the pin 19 - GPIO 10, pin 21 - GPIO 9, pin 23 - GPIO 11 and pin 24 GPIO 8. = Digital inputs =The Raspberry Pi GPIO are 3.3V based. The inputs I am using are 5V based, so for powering the sensor it's not an issue, but some work has to be done to adapt to the Pi GPIO input.Remembering that all the Raspberry inputs are digital, so they can read 0V or 3.3V, there are some alternatives:
I implemented the solution 1. and 2., to be more generic and have some degree of protection. Fast diode input circuitNeeded:- Schottky diode 1N5711 - Resistors 10k, 1k Schottky diode I am needing a schottky diode for the fast switching speed. I am working with low voltages so there are no inconveniences. Hereafter you can see the difference between using a diode 1N4001 and a Schottky 1N5711 as seen on an oscilloscope. Step using general purpose diode: Step using 1N5711 diode: Used for: - Hall effect water flow meter sensor (pulse) The sensor works with 3 pin: VCC, GND, pulse The sensor is pulled to ground to signal a pulse and float high to the external voltage. Optocoupler input circuitThe optocoupler circuit has a variable resistor on the base to filter noise inputs and trigger the optocoupler transistor for some degree of input signals. It has to be regulated after input line installation.- 4N35 chip - Resistors - Capacitor In the circuit diagram the variable resistor is the 1k between the optocoupler and GND with the capacitor in parallel. The circuit shown set the GPIO input to 3.3V when the switch is opened. On the board construction, for extra flexibility I put the GND side of the eccitating LED (pin 2) on a input connector, and added a jumper on the board. This way I can close the line to 5V or close it to GND, according to the jumper and wire setup. Moreover, I have the possibility to connect the line before and after the LED in the 4N35 chip toward an external powered line as input, removing the jumper. Used for: - Generic input, actually a simple switch closed on signalling boiler event == OUTPUT AND INPUT BOARD ==Here is a schematic of the board:And finally the board looks like this: Final board: == MECHANICAL ASSEMBLING ==Follow these steps:
Putting it over the Raspberry Pi Connecting display Cabling Boxing ABS box with size 200 x 120 x 75 mm , you'll find it in beige or black variant. Modify the box to make a display support and making some vent holes and cable passage. == SUMMARY OF GPIO ==pin 3 - GPIO 02 - i2c bus SDA pin 5 - GPIO 03 - i2c bus SCL pin 7 - GPIO 04 - 1-wire externally pullup'd pin 11 - GPIO 17 - digital input 3 closed to 5V or closed to GND (according to the jumper, GPIO goes low; if opened, GPIO goes high) pin 13 - GPIO 27 - digital input 1 GND or 5V pin 15 - GPIO 22 - digital input 2 GND or 5V pin 19 - GPIO 10 - SPI MOSI analog input 1 (from 0 to 4.5V), analog input 2 and 3 (from -1,5V to +1,5V) pin 21 - GPIO 09 - SPI MISO pin 23 - GPIO 11 - SPI CLK pin 24 - GPIO 08 - SPI CE pin 35 - GPIO 19 - digital output 4 (relay NO, NC) pin 37 - GPIO 26 - digital output 3 (relay NO, NC) pin 38 - GPIO 20 - digital output 2 (relay NO, NC) pin 40 - GPIO 21 - digital output 1 (relay NO, NC) === OS BASE SETUP ===Starts from raspbian image.I started with version 10.7 Buster, but later I add testing repository (Bullseye 11) to fix Python 3.8 requirement (I installed 3.9.1). See software installation part about it. The initial setup is not covered in this guide. We need a very small installation of armbian with a read-only root partition and writable home. We start without any graphical interface, I will install a simple window manager hereafter. Some notes about the base setup are reported hereafter. Partitioning with read only root / is ro size ~6 GB /boot is ro size 256 MB /home is rw size the rest of the microSD (in my case ~24 GB)Note: the partitions should be aligned for the microSD to maximise leveling on the read/write partition, considering first 4MiB and so on. Note: all following setup commands are done from root (i.e. "su -" or "sudo su" ) As we are in readonly filesystem, before anything mount as readwrite: root@pi:~# mount -oremount,rw / root@pi:~# mount -oremount,rw /boot tmpfs /tmp cd /var ln -s /tmp log ln -s /tmp tmp root@pi:~# vi /etc/fstab proc /proc proc defaults 0 0 /dev/mmcblk0p1 /boot vfat defaults,ro 0 2 /dev/mmcblk0p2 / ext4 defaults,ro 0 1 /dev/mmcblk0p3 /home ext4 defaults,noatime 0 0 tmpfs /tmp tmpfs nosuid,nodev,mode=1777,size=400M 0 0fix some temporary dir cd /var rm -R log rm -R tmp ln -s /tmp log ln -s /tmp tmpFinal setup is something like this root@pi:~# df -h Filesystem Size Used Avail Use% Mounted on /dev/root 5.3G 2.3G 2.8G 45% / devtmpfs 805M 0 805M 0% /dev tmpfs 934M 0 934M 0% /dev/shm tmpfs 934M 8.5M 926M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 934M 0 934M 0% /sys/fs/cgroup tmpfs 200M 52K 400M 1% /tmp /dev/mmcblk0p3 24G 45M 23G 1% /home /dev/mmcblk0p1 253M 54M 199M 22% /boot tmpfs 187M 0 187M 0% /run/user/1000 I have a user called "user", plus the root account. = Debian testing Bullseye =On Buster I have some issue with matchbox, midori and python versions.I opted to add Bullseye version 11 repository in apt, adding following lines: root@pi:~# vi /etc/apt/sources.list deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi deb http://raspbian.raspberrypi.org/raspbian/ testing main contrib non-free rpiUpgrade with commands root@pi:~# apt-get update root@pi:~# apt-get upgrade root@pi:~# apt-get dist-upgrade root@pi:~# apt-get upgrade root@pi:~# apt-get cleanTake some time. Choose upgrade settings according to your preferences. I had to solve some kept-back packages and purge libc6-dev for conflicts: root@pi:~# apt-get purge libc6-dev root@pi:~# apt-get --with-new-pkgs upgrade Update eventually installed pip modules root@pi:~# pip3 list --outdated --format=freeze | grep -v '^-e' | cut -d = -f 1 | xargs -n1 pip3 install -U After that we have installed raspbian 11 Bullseye, along with python3.9.1 === ENVIRONMENT CONFIGURATION ===Note: all following setup commands are done from root (i.e. "su -" or "sudo su" )As we are in readonly filesystem, before anything mount as readwrite: root@pi:~# mount -oremount,rw / root@pi:~# mount -oremount,rw /bootLet's load at boot io modules, uncommenting root@pi:~# vi /boot/config.txt dtparam=i2c_arm=on dtparam=spi=on dtoverlay=spi0-1cs dtoverlay=w1-gpio,gpiopin=4 To rotate display if necessary, uncomment line: lcd_rotate=2 You also need the following line in /etc/modules root@pi:~# vi /etc/modules i2c-dev == HOME ASSISTANT ==Home Assistant is installed manually, as a Python 3 virtual env using a "homeassistant" user and group.I follow the manual guide here https://www.home-assistant.io/docs/installation/raspberry-pi/ but installed it to self home in /home/homeassistant instead of /srv/homeassistant, because in my setup /home is on the only writable partition. Still as root, install required libraries root@pi:~# apt-get install python3 python3-dev python3-venv python3-pip root@pi:~# apt-get install libffi-dev libssl-dev libjpeg-dev zlib1g-dev root@pi:~# apt-get install autoconf build-essential libopenjp2-7 libtiff5 I was unable to build inside the venv the RPi.GPIO pip module, so I install it from apt repository apt-get install python3-rpi.gpio Create user homeassistant and folders useradd -rm homeassistant -G dialout,gpio,i2cSet virtual env. I uses the flag "--system-site-packages" because I was unable to build inside the venv the RPi.GPIO pip module. sudo -u homeassistant -H -s cd /home/homeassistant python3 -m venv . --system-site-packages source bin/activateThe prompt changes to (homeassistant) homeassistant@raspberrypi:~ $ Install packages. It will take some time. python3 -m pip install wheel pip3 install homeassistantStart home assistant for the first time. It will take some time because it installs required pip3 packages. hassCheck to be able the reach the webpage at address. Do nothing for now. http://RASPBERRYPI_IP_ADDRESS:8123 Check using another terminal that is not installing depencies anymore, i.e.: root@pi:~# ps -fax 8142 pts/1 S 0:00 | _ sudo -u homeassistant -H -s 8143 pts/1 S 0:00 | _ /bin/bash 8402 pts/1 Sl+ 0:07 | _ /home/homeassistant/bin/python3 /home/homeassistant/bin/hass 1177 pts/2 Ss 0:00 _ /bin/bash 22206 pts/2 R+ 0:00 _ ps -faxPress Ctrl-C in the command line to exit hass Create the service file to start home assistant at boot: root@pi:~# cd /etc/systemd/system/ root@pi:/etc/systemd/system# vi home-assistant.service [Unit] Description=Home Assistant After=network.target [Service] Type=simple User=homeassistant Environment=VIRTUAL_ENV="/home/homeassistant" Environment=PATH="$VIRTUAL_ENV/bin:$PATH" ExecStart=/home/homeassistant/bin/hass -c "/home/homeassistant/.homeassistant" [Install] WantedBy=multi-user.targetNow you will need to restart the systemctl and read the file with the following commands root@pi:~# systemctl --system daemon-reload root@pi:~# systemctl enable home-assistant root@pi:~# systemctl start home-assistantVerify root@pi:~# systemctl status home-assistantHome assistant logfile is located here: less /home/homeassistant/.homeassistant/home-assistant.log == LOCAL TOUCHSCREEN USER INTERFACE ==Install a minimal window manager, Matchbox, intended for mobile devices and that only shows one window at a time.root@pi:~# apt-get install matchboxInstall a fast browser, I choosed midori root@pi:~# apt-get install midoriInstall some required Xorg utilities root@pi:~# apt-get install x11-xserver-utils xinit root@pi:~# adduser user videoCreate a xinit configuration file in user home directory to start window manager and browser root@pi:~# vi /home/user/.xinitrc #!/bin/sh /usr/bin/xset -dpms /usr/bin/xset s off /usr/bin/xset s noblank /usr/bin/matchbox-window-manager -use_cursor no -use_titlebar no & /usr/bin/matchbox-panel --size 20 --orientation north --no-menu --no-session & /usr/bin/mb-applet-launcher /usr/share/pixmaps/matchbox-keyboard.png /usr/bin/matchbox-keyboard & /usr/bin/midori -a http://127.0.0.1:8123/Allow xinit to start as an user from command line root@pi:~# vi /etc/X11/Xwrapper.configModify allowed_users to: allowed_users=anybodyIn start xinit at startup as user "user" using /etc/rc.local root@pi:~# vi /etc/rc.local /bin/su user -c /usr/bin/xinit & exit 0matchbox-keyboard has an xml file to configure the keyboard layout. The included ones from repositories are too bad. I started from the one shared from JimmyN here I made some modification on my keyboard file. You have to place the file in the .matchbox user folder as file keyboard.xml . You can download my configuration keyboard.xml here Check that the graphical installation works using su user -c xinitYou should see the Midori browser with automatic login in Home Assistant, and a top bar with on the left a keyboard icon and on the right a clock. Touching the keyboard opens the on screen virtual keyboard, touching it again hides the keyboard. Here are two screenshot made with scrot. I will set autologin for local access to web interface. You do it from the terminal editing the main configuration file. Set autologin for local access to HTTP interface from localhost. root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yamlAdd following configuration block: # autologin if one user homeassistant: auth_providers: - type: trusted_networks trusted_networks: - 127.0.0.1 - ::1 allow_bypass_login: true - type: homeassistant Setup some settings in both the webpage of home assistant and command line. For simplicity I do it from external PC (not on local graphic user interface). Accessing the page for the first time will create one user (the first one is an administrator) and a wizard. http://RASPBERRYPI_IP_ADDRESS:8123 In my setup, first user (and administrator) will have username admin Graphically, I setup Home Assistant with two panels: the first one is the realtime main operative window; the second one has some historical diagnose and system informations. == DIGITAL INPUT AND OUTPUT ==On/off Digital Input and Digital Output are rapidly set in the Home Assistant configuration file. Note that the number ports are GPIO BCM indexes, not pin.root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yamlAdd following configuration blocks: # Digital Input binary_sensor: - platform: rpi_gpio ports: 17: DI3 Boiler Alert invert_logic: false - platform: rpi_gpio ports: 22: DI2 Free invert_logic: true # Digital Output switch: - platform: rpi_gpio invert_logic: true ports: 21: DO1 Boiler 20: DO2 Outdoor Lights 26: DO3 Light outside the gate 19: DO4 Water Pump = Digital Input used for Water Flow Counter =Digital Input 1 (DI1_Water_Flow_Counter) is used as a pulse counter. The specifications of my sensor says it can measure from 1 L/min to 30 L/min . The pulse frequency to flow rate is: frequency (Hz) / 7.5 = flow in L/min .Moreover using the oscilloscope I saw that the minimum steady value (high or low) was more than 2 ms, and with a duty cyle of 50%. Checking with maths, the maximum frequency can be calculated as 30 L/min * 7.5 = 225 Hz , so the minimum period declared is 1/225 Hz = 0.0044 s = 4.4 ms . So the declared minimum steady value is 2.2 ms, that is corresponding with practical measures. Each seconds there should be a maximum of 7.5 * 30 = 225 square waves, and 1 L corresponds to 450 pulses. The rpi_gpio has a bouncetime of ms. It is not required to campionate completely the signal, but only high and low values, so 2 ms is enough. In Home Assistant, the statistics counter is incremented both when value is high and was low, and is low and was high, so the counter has to to be divided instead by 7.5 * 2 = 14. The maximum value of the counter is the daily one, that can reach a maximum of 24*60*30*450 = 19,440,000 pulses, that is lower than the maximum int value in Python (2147483647). I first tried to configure the flow sensor calculation completely in Home Assistant, using the following configuration blocks root@pi:~# /home/homeassistant/.homeassistant/configuration.yaml binary_sensor: - platform: rpi_gpio ports: 27: DI1 Water Flow Counter bouncetime: 2 sensor: - platform: statistics entity_id: binary_sensor.DI1_Water_Flow_Counter name: "Water Flow Daily Count" sampling_size: 10000000 max_age: hours: 24 - platform: statistics entity_id: binary_sensor.DI1_Water_Flow_Counter name: "Water Flow Second Count" sampling_size: 500 max_age: seconds: 1 - platform: template sensors: water_daily_usage: friendly_name: Water Daily Usage value_template: >- {{ ( states('sensor.water_flow_daily_count') | float / 900 ) | round(0) }} unit_of_measurement: 'L' icon_template: hass:water - platform: template sensors: water_flow_usage: friendly_name: Water Flow Usage value_template: >- {{ ( states('sensor.water_flow_second_count') | float / 14 ) | round(0) }} unit_of_measurement: 'L/min' icon_template: hass:water After doing that and made some testing, I found the shown values were very different from truth. I believe that this solution with statistics on binary_sensor is not fast enough and was losing counts. Python sleep() and time() functions are based on OS accuracy; on a non-realtime Linux kernel like my case, the minimum sleep interval is lower than 1 ms but not deterministic, so enough for my purpose. So I evaluated to create a custom integration for that, but it was too complicated over an external simple python script. I'll propose a simple Python script running from Debian. The script has to always run as a service and communicates with Home Assistant using two temporary files, because I need to always check the square wave to gives near instant value and daily counter. The script is updating values with an interval of 10 seconds, writing some file in temp filesystem to be read from Home Assistant. An update longer than 1 second helps me compensate the delay introduced by file handling. I checked sensor counting and correctness of water flow calculation, and seems to be realistic. Install Python schedule library root@pi:~# pip3 install scheduleCreate a script: root@pi:~# vi /home/homeassistant/water_flow.sh #!/usr/bin/python3 # Raspberri Pi - Hall effect Water Flow counter on GPIO # pip3 install rpi_gpio schedule # http://richiardone.eu import RPi.GPIO as GPIO import time, sys, schedule FLOW_SENSOR = 27 UPDATE_INTERVAL = 10 FILE_OUT_INSTANT = '/tmp/water_flow.instant' FILE_OUT_DAILY = '/tmp/water_flow.daily' GPIO.setmode(GPIO.BCM) GPIO.setup(FLOW_SENSOR, GPIO.IN, pull_up_down = GPIO.PUD_UP) daycounter = 0 lastcount = 0 def countPulse(channel): global daycounter daycounter = daycounter+1 def resetDaily(job): global daycounter daycounter = 0 GPIO.add_event_detect(FLOW_SENSOR, GPIO.RISING, callback=countPulse, bouncetime=2) schedule.every().day.at("00:00").do(resetDaily, '') while True: lastcount = daycounter time.sleep(UPDATE_INTERVAL) lastcount = daycounter - lastcount with open(FILE_OUT_INSTANT, 'w') as file: file.write(str(round(lastcount/UPDATE_INTERVAL/7.5, 1))) with open(FILE_OUT_DAILY, 'w') as file: file.write(str(round(daycounter/450, 1))) schedule.run_pending() Set permission: root@pi:~# chown homeassistant:homeassistant /home/homeassistant/water_flow.sh root@pi:~# chmod +x /home/homeassistant/water_flow.shCreate a systemd service: root@pi:~# vi /etc/systemd/system/water_flow.service [Unit] Description=Water Flow Counter After=multi-user.target [Service] Type=simple User=homeassistant ExecStart=/home/homeassistant/water_flow.sh [Install] WantedBy=home-assistant.service Now you will need to restart the systemctl and read the file with the following commands root@pi:~# systemctl --system daemon-reload root@pi:~# systemctl enable water_flow root@pi:~# systemctl start water_flow Add in configuration.yaml file: root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yamlthe following block: sensor: - platform: command_line name: Water Flow Instant Counter command: /bin/cat /tmp/water_flow.instant unit_of_measurement: "L/min" scan_interval: 10 - platform: command_line name: Water Flow Daily Counter command: /bin/cat /tmp/water_flow.daily unit_of_measurement: "L" scan_interval: 60 = Board status: temperature, uptime, system load, memory =Internal temperature can be read from command line (the value has to be divided by 1000):root@pi:~# cat /sys/class/thermal/thermal_zone0/tempTo use the internal temperature I use Command Line integration. You need to add the following to configuration.yaml root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yamlAdd following configuration block sensor: - platform: command_line name: Board Temperature command: /bin/cat /sys/devices/virtual/thermal/thermal_zone0/temp unit_of_measurement: "°C" value_template: '{{ value | multiply(0.001) | round(1) }}' I also put a simple uptime command in the historic panel, to view system load and uptime. Add following block sensor: - platform: command_line name: Board Uptime command: /usr/bin/uptime With an AWK filter on free command, I also display information about memory of the board. Add following block to /home/homeassistant/.homeassistant/configuration.yaml sensor: - platform: command_line name: Board Memory command: '/usr/bin/free -h | /usr/bin/awk -F " " ''FNR==2{print "Total: "$2" Used: "$3" Free: "$4}'' ' = 1-wire - temperature sensor =From command line, verify that are present wl_gpio and wl_thermroot@pi:~# lsmod | grep -i w1_ w1_therm 24576 0 w1_gpio 16384 0 wire 36864 2 w1_gpio,w1_thermYou should see temperature sensor here root@pi:~# ls /sys/bus/w1/devices/With more sensors, you will see multiple /sys/bus/w1/devices/28-xxxxxxxxxxxxx directories, each one having the unique serial number as the directory name. You can select a sensor entering the directory (xxxxxxxxxxxxx is the serial number): cd /sys/bus/w1/devices/28-xxxxxxxxxxxxx cat w1_slaveCopy the serial numbers. Add to configuration.yaml the entry for the 1-wire sensor and devices. The devices are indicated according their serial numbers: they can be renamed with a more useful friendly name. root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml sensor: - platform: onewire In the documentation it is stated that the sensors can be renamed using the "names" parameter according to the serial number, that should be "sensor.28_012032ca73c6_temperature". However in my setup it seems to not be working. So I used the customize directive to change label. root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml homeassistant: customize: sensor.28_012032ca73c6_temperature: friendly_name: Outside South sensor.28_012032cb2851_temperature: friendly_name: Outside North = i2c - temperature, humidity, pressure sensor =Install i2c programs to analyse the sensor addressing.root@pi:~# apt-get install i2c-toolsShow i2c master adapter root@pi:~# i2cdetect -l i2c-1 i2c bcm2835 (i2c@7e804000) I2C adapterList the i2c sensors detected # i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 -- 1 sensors detected in 0x76So the address of my BME280 sensor is 0x76. In Home Assistant configuration file add: root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml sensor: - platform: bme280 name: Indoor i2c_address: 0x76 operation_mode: 2 time_standby: 2 oversampling_temperature: 2 oversampling_pressure: 4 oversampling_humidity: 1 filter_mode: 4 delta_temperature: -1 monitored_conditions: - temperature - humidity - pressure The BME280 sensor usually is self heating himself and gives higher temperature from the true. The "delta_temperature" parameter can be set to adjust constant error in temperature measuring. Using the two 1-wire themometer plus an external analog one, I considered that around 25 degree it has an approximate error of 1 degrees. So I correct removing 1 degrees. When doing this calibration, made adjustement after enough time the sensor was powered on. I set the oversampling, IIR filter and standby time settings to values that in some testing done seems to give me stable readings. = SPI SETUP =Check that the spi_bcm2835 and spidev modules are loaded. If not, use modprobe spi_bcm2835 spidevroot@pi:~# lsmod | grep spi_bcm2835 spi_bcm2835 24576 0 root@pi:~# lsmod |grep spidev spidev 20480 0You should then have some devices ready root@pi:~# ls -l /dev/spi* crw-rw---- 1 root spi 153, 0 Jan 10 12:31 /dev/spidev0.0 crw-rw---- 1 root spi 153, 1 Jan 10 12:31 /dev/spidev0.1To check if GPIO and wires are correctly wired, you can use this tool, after putting a wire between the MISO pin 19 and MOSI pin 21. The result is some hex values as shown. root@pi:~# wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c root@pi:~# gcc -o spidev_test spidev_test.c root@pi:~# ./spidev_test -D /dev/spidev0.0 spi mode: 4 bits per word: 8 max speed: 500000 Hz (500 KHz) FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DE AD BE EF BA AD F0 0DInstall Python spidev library root@pi:~# pip3 install spidevGive user homeassistant permission to use SPI device: root@pi:~# usermod -a -G spi homeassistant = SPI Channel 0 - Water Pressure =Create the following Python script to get values from the MCP3008 channel 0. It is an instant reading of the pressure value.You have to check the minimum voltage of the sensor at 0 Mpa with a voltmeter on the terminal block and set it to variable VMIN. The PMAX can be set to 0.5 to use the Mpa unit, or 5 to use the Bar unit. root@pi:~# vi /home/homeassistant/spi_mcp3008_wp.sh #!/usr/bin/python3 # Raspberri Pi - Water Pressure reading with MCP3008 over SPI # pip3 install spidev # http://richiardone.eu from spidev import SpiDev # minimum voltage measured on sensor data VMIN = 0.490 # maximum voltage as declared VMAX = 4.5 # maximum pressure as declared, can be set to 0.5 for MPa or 5 for Bar # PMAX = 0.5 # MPa PMAX = 5 # Bar # MCP3008 channel CHANNEL = 0 # VRef of MCP3008 VREF = 3.3 # voltage divider ratio VDIV = 2/3 class MCP3008: def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 def read(self, channel = 0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close() try: mcp = MCP3008() realv = (mcp.read(CHANNEL) * VREF / (VDIV)) / 1024 mcp.close() realv = (realv - VMIN) * PMAX / (VMAX - VMIN) if realv < 0: print(0.000) else: print(round(realv, 3)) except: print('E') Set correct permissions to the file root@pi:~# chmod +x /home/homeassistant/spi_mcp3008_wp.sh root@pi:~# chown homeassistant:homeassistant /home/homeassistant/spi_mcp3008_wp.shAdd in configuration.yaml file: root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml sensor: - platform: command_line name: Water Pressure command: /home/homeassistant/spi_mcp3008_wp.sh unit_of_measurement: "Bar" scan_interval: 60 = Channel 1, 2 - AC power consumption =Also here I am using a Python script. It waits some time to read the consumption from the sine wave peak value.The AC sensor gives a sine waves of the frequency of the line with the amplitude corresponding to the load: I need to get the maximum and the minimum of the wave. I can also calculate the wave period. Considering a frequency of 50Hz, for Nyquist we are needing a sampling of at least 100 sample per second, that is one each 10 ms. But I wanted to be more accurate to don't miss the peak, so I wanted to use a sample each 1 ms, that as explained before with digital counter is also a interval well managed in Python over Linux kernel. With SCT013-030 consumption of 30A (around 6.6 kW at 220VAC) corresponds to 1V RMS, that is -1.42V to +1.42V Using 3.3V voltage divider at +1.65V, so that the measured sine wave will go from +0.23V to +3.07V Scale is linear, so ideally VMAX goes from +1.65V to +3.07V Formula to get W from voltage is: (VMAX - (VREF/2)) * 30 * VOLTAGE / 1.42 VREF_2 can be adjusted manually to reflect value read without any load (for example in my case I read 1.66 V root@pi:~# vi /home/homeassistant/spi_mcp3008_ac.sh #!/usr/bin/python3 # Raspberri Pi - AC power consumption reading with MCP3008 over SPI # pip3 install spidev schedule # http://richiardone.eu from spidev import SpiDev import asyncio import sys import time # MCP3008 channel CHANNEL = int(sys.argv[1]) # VRef on MCP3008 VREF = 3.3 VREF = 3.3 VREF_2 = VREF/2 # adjusted because without load always reading 1.66 VREF_2 = 1.66 # Current scale MAXCURR = 30 # AC Voltage VOLTS = 220 # 1 ms interval SAMPLE_INT = 0.001 # wait for 20 ms to get vmax WAIT_INTERVAL_MS = 0.02 FILE_OUT_INSTANT = '/tmp/ac{}.instant'.format(CHANNEL) class MCP3008: def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 def read(self, channel = 0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close() async def check_ac_task(mychan): global mcp, vmax, flag vmax = VREF_2 vmin = VREF_2 vprec0 = VREF_2 vprec1 = VREF_2 vprec2 = VREF_2 while flag: realv = (int(mcp.read(mychan)) * VREF / 1024) # I'm going down, update the vprec if(realv < vprec0): vprec0 = realv if(realv < vprec1): vprec1 = realv if(realv < vprec2): vprec2 = realv # then update the vmax if(realv > vmax): vmax = realv await asyncio.sleep(SAMPLE_INT) loop.stop() async def run_for_interval(loop, task): global flag await asyncio.sleep(WAIT_INTERVAL_MS) flag = False if __name__ == '__main__': try: vmax = 0 flag = True mcp = MCP3008() loop = asyncio.get_event_loop() task = loop.create_task(check_ac_task(CHANNEL)) loop.create_task(run_for_interval(loop, task)) loop.run_forever() loop.close() mcp.close() # 30A (= 6.6 kW at 220VAC) corresponds to 1V RMS, that is -1.42V to +1.42V # using 3.3V voltage divider at +1.65V, so that the measured sine wave will go from +0.23V to +3.07V # scale is linear, so ideally VMAX goes from +1.65V to +3.07V # formula to get W from voltage is: (vmax - (VREF/2)) * MAXCURR * VOLTS / 1.42 # prints W print(round(((vmax - (VREF_2)) * MAXCURR * VOLTS / 1.42), 3)) except: mcp.close() print('E') Set permissions to the file root@pi:~# chmod +x /home/homeassistant/spi_mcp3008_ac.sh root@pi:~# chown homeassistant:homeassistant /home/homeassistant/spi_mcp3008_ac.shAdd in configuration.yaml file: root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml sensor: - platform: command_line name: AC probe 1 current consumption command: /home/homeassistant/spi_mcp3008_ac.sh 1 unit_of_measurement: "W" scan_interval: 10 - platform: command_line name: AC probe 2 current consumption command: /home/homeassistant/spi_mcp3008_ac.sh 2 unit_of_measurement: "W" scan_interval: 10 == SOME AUTOMATIONS === Climate Thermostat =Home assistant includes automation mechanism. A simple one is a climate thermostat platform to regulate boiler activation according to indoor temperature.Add the following to the Home Assistant configuration file root@pi:~# vi /home/homeassistant/.homeassistant/configuration.yaml climate: - platform: generic_thermostat name: Main Thermostat heater: switch.DO1_Boiler target_sensor: sensor.indoor_temperature min_temp: 10 max_temp: 30 target_temp: 22 away_temp: 10 ac_mode: false initial_hvac_mode: "heat" = Outdoor lights on at nightUser Automation from web interface. I created two automations: first one to light on, second one to light off. Fill the following fields:Name -> "Turn on the lights when the sun is set" Mode -> Single Trigger type -> Sun Event -> Sunset Offset -> -00:30 Action type -> Call service Service -> switch.turn_on Name of entities -> switch.do3_gate_lights Click Save The second automation to turn the lights off: Name -> "Turn off the lights when the sun is rising" Mode -> Single Trigger type -> Sun Event -> Sunrise Action type -> Call service Service -> switch.turn_off Name of entities -> switch.do3_gate_lights Click Save == FINAL RESULT ==Here you can download complete configuration.yaml file for Home Assistant. == MEMORY AND SPACE ANALYSIS ==The RAM memory used on Raspberry Pi is no more that 300 MB, so the version with 2 GB is enough to run this solution, also considering the space allocated for memory filesystems (i.e. /tmp).== IMPROVEMENTS AND FUTURE WORKS ==The device as-is can be rated with IP20 protection. With some improvement on the side holes, adding a fine grating, and adding a custom gasket on the display, could arrive to IP42.This is a base for many other deployment, for example some ideas:
=== REFERENCES ===Can't be able to build the solution without these helps, presented here in no particular order:https://www.home-assistant.io/getting-started/automation/ https://www.home-assistant.io/integrations/onewire/ https://www.home-assistant.io/integrations/rpi_gpio/ https://www.home-assistant.io/docs/installation/raspberry-pi/ https://rc.home-assistant.io/docs/authentication/providers/#skip-login-page-examples https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md https://www.home-assistant.io/integrations/bme280/ https://www.home-assistant.io/integrations/sensor.command_line https://developers.home-assistant.io/docs/creating_integration_file_structure/ https://github.com/home-assistant/example-custom-config/tree/master/custom_components https://www.raspberrypi.org/documentation/hardware/display/troubleshooting.md https://www.raspberrypi.org/forums/viewtopic.php?t=122020 https://www.raspberrypi.org/forums/viewtopic.php?t=167896 https://raspberrypi.stackexchange.com/questions/41234/max-length-of-wire-w-3-3v-or-other-issue https://www.raspberrypi-spy.co.uk/2020/11/raspberry-pi-temperature-monitoring/ https://electronics.stackexchange.com/questions/505318/how-to-properly-use-a-relay-module-with-jd-vcc-from-arduino-raspberry https://www.raspberrypi.org/forums/viewtopic.php?t=118230 https://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/ds18b20 http://nagashur.com/blog/2017/06/25/bme280-sur-raspberry-pi-temperature-pression-et-humidite-en-i2c/ https://github.com/kbrownlees/bme280 https://pypi.org/project/enerpi/ https://www.hackster.io/ShawnHymel/hack-your-home-part-3-power-monitor-16a313 https://www.rototron.info/raspberry-pi-analog-water-sensor-tutorial/ https://www.element14.com/community/community/raspberry-pi/raspberrypi_projects/blog/2018/04/26/remote-home-monitoring-with-raspberry-pi-and-hologram-nova https://www.maximintegrated.com/en/app-notes/index.mvp/id/148/CMP/ELK5 https://www.poweruc.pl/blogs/news/non-invasive-sensor-yhdc-sct013-000-ct-used-with-arduino-sct-013 https://maker-tutorials.com/en/auto-start-midori-browser-in-fullscreen-kiosk-modus-raspberry-pi-linux/ https://www.socsci.ru.nl/wilberth/computer/sleepAccuracy.html https://pypi.org/project/mcp3008/ https://github.com/luxedo/RPi_mcp3008 https://pypi.org/project/spidev/ https://www.raspberryme.com/mcp3008-lecture-des-signaux-analogiques-sur-le-raspberry-pi/ |
phperr 0.7 | Sat, 13 Feb 10 |
Current version of my CMS phperr 0.7 is available. Added web2.0 sharing, multipage as usual without using any database, and RSS fixes. Available upon conditions of GPL v2 license. |
Really simple Javascript RSS parser | Thu, 16 Jul 09 |
I was looking for a javascript parser, that works without frills and was simple.
Not finding it, I write a few lines reported below:
var title = 0; var lines = 0; function parselevel(level, skiptext, maxlines){ if(level.textContent.search(skiptext)==-1){ if(level.nodeName == "title"){ title = '<b>' + level.textContent + '</b><br/>'; } if(level.nodeName == "description"){ if(title != 0){ if(maxlines == lines){ return; } document.write('<a '); if(lines%2){ document.write('style="background-color: #90e090;"'); } document.write('>' + title + '' + level.textContent + '</i></a>'); document.write('<br />'); title = 0; lines = lines + 1; } } } for(var i=0; i < level.childNodes.length; i++){ parselevel(level.childNodes[i], skiptext, maxlines); } } function parserss(rssfile, skiptext, maxlines){ var xmlDoc=document.implementation.createDocument("","",null); xmlDoc.async=false; xmlDoc.load(rssfile); var root = xmlDoc.documentElement; title = 0; lines = 0; parselevel(root, skiptext, maxlines); }You call it from html page with: <script src="rss.js" type="text/javascript"></script> <script language="javascript"><!-- window.onload=parserss("YOURRSS.XML", /TITLE_TO_SKIP/, 5) //--></script>Change YOURRSS.XML with the name of rss file (it must be a local file for Gecko browsers, I download it locally with cron and fetch), TITLE_TO_SKIP is a string that exclude some RSS field to be printed, and the last is the number of RSS field to print. |
phperr 0.6 | Sun, 18 Jan 09 |
New version of this simple CMS, phperr 0.6, is available. Fixed minor graphical details and added RSS capability. As usual, available upon conditions of GPL v2 license. |
Random picture from Picasa | Sat, 9 Aug 08 |
Here I report the simple php code:
$userid = 'errimg'; // set your userid of picasa $thumbsize = '108'; // set resolution of thumbnail among 54, 108 or 216 function startElement($parser, $name, $attrs){ global $record; global $canstart; if($name == 'TITLE' && $attrs["TYPE"] == 'text' && $canstart) $record = true; if($name == 'ENTRY') $canstart = true; } function endElement($parser, $name){ global $tmparray; global $record; global $curfield; global $canstart; $record = false; if($name == 'TITLE' && $canstart){ $tmparray[] = $curfield; $curfield = ''; } } function elementContent($parser, $data){ global $curfield; global $record; if($record) $curfield .= $data; } function startIdElement($parser, $name, $attrs){ global $canstart; global $tmparray; global $thumbsize; if($name == 'MEDIA:THUMBNAIL' && $attrs['HEIGHT'] == '108' && $canstart) $tmparray[] = $attrs['URL']; if($name == 'ENTRY') $canstart = true; } function endIdElement($parser, $name){ } function getAlbums($userId){ global $tmparray; global $canstart; $tmparray = array(); $canstart = false; $url = 'http://picasaweb.google.com/data/feed/api/user/'.urlencode($userId).'?kind=album'; $xml = file_get_contents($url); $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "startElement", "endElement"); xml_set_character_data_handler($xml_parser, 'elementContent'); xml_parse($xml_parser, $xml); xml_parser_free($xml_parser); } function showAlbumContent($userId, $albumName){ global $tmparray; global $canstart; $tmparray = array(); $canstart = false; $url = 'http://picasaweb.google.com/data/feed/api/user/'.urlencode($userId).'/album/'.urlencode($albumName); $xml = file_get_contents($url); $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "startIdElement", "endIdElement"); xml_parse($xml_parser, $xml); xml_parser_free($xml_parser); } getAlbums($userid); if(!empty($tmparray)){ $album_title = $tmparray[array_rand($tmparray, 1)]; $album_title = ereg_replace("[^A-Za-z0-9]", "", $album_title); showAlbumContent($userid, $album_title); if(!empty($tmparray)){ $random_pic = $tmparray[array_rand($tmparray, 1)]; print '<a href="http://picasaweb.google.com/'.$userid.'/'.$album_title .'"><img src="'.$random_pic .'" alt=""></a>'; } } |
phperr | Dec 2007 |
I forgot to link here the humble CMS running this site, called with fantasy phperr.
You can get it here (version 0.5); keep in mind that is very my-site oriented, but the code lines are few and it can be easily more developed. Contents are stored in text files (no database required) and are edited in html stile blog; it support upload and management of remote files. The number of pages are unlimited and created as you access them (in wiki stile). Border menus are are also remotely editable in php. |
WaNDA-tools | Dec 2007 |
The WaNDA Project has reached a stable status. It allows you to generate a multiplatform offline version of Wikipedia. More info are available at the project page on Sourceforge, where you can get it.
There's also a page at Politechnic of Turin, linux@studenti, and my MSc thesis in italian about it, here available in texts section. The code is a mix of PHP for processing and multiplatform ECMAscript for consulting the offline content. |
Ermes | Jun 2006 |
"Ermes" is a Windows multicast network application for video conferencing; using video compressions techniques, it streams a desktop area from a server machine to unlimited numbers of clients.
The communication is done with two streams: the audio stream has priority over video, so position of mouse cursor is included with it for improved clearness of speech. The video stream compression is settable to suit situation needs. The programs should run on all Windows NT family (XP, etc..). It works in either client or server mode. Full sources for Visual Studio 2005 (.NET) are released under GPL v2; the software is mainly written in C# with managed C++. Sources: Ermes_v0.4.5.zip Brief documentation in italian with schemes of components: Ermes.pdf |
zenzero | Jan 2005 |
"zenzero" e` il nome in codice di un breve progetto per il controllo di un autoveicolo. Il veicolo e` costruito con Lego Mindstorms, il software di controllo e` basata su Statetra e LegoStatetra. La documentazione del progetto: zenzero.pdf Il sorgente Statetra del sofware di gestione: zenzero_str.tar.bz2 |
All contents, where applicable and except otherwise specified, are present under GPLv2 or GFDL licenses.
E. Richiardone (e AT richiardone DOT eu)
page viewed 30420 times and generated in 0.008166 s