iPhone 6s Battery Replacement

Hi, πŸ‘‹

I usually write about technical stuff and tutorials, but this article is more about repair and the right to repair.

It’s important for companies to offer their customers the ability to repair devices that they bought. I’m not saying that they should make all parts and tools available, but they should at least try to offer some help for common repair operations, like storage change, broken screen change, battery change and so on. Perhaps some upgrades as well.

My old Apple iPhone 6s got a new life yesterday thanks to iFixit’s tools and guides.

The phone is ~5 years old at the time of me writing this and it works flawlessly on the latest iOS 15.2.

I thought that once the battery dies, I need to get a new phone and that felt normal to me.

In my country there’s no Apple Store. Getting a battery replacement may involve shipping my phone to a third-party shop in a different city and waiting for it to come back, even though the price of a battery replacement is affordable compared to getting a new phone, for some reason, the idea of fixing my phone instead of getting a new one felt a bit weird. And even if I pay a third-party repair shop, I don’t have any guarantee that the battery is quality. I’m imagining that most of the shops sell old low-quality batteries to make more money.

Thanks to Louis Rossman, (this guy has some incredible and entertaining videos) I was motivated to repair the phone by myself! And thanks to iFixit I found a step-by-step guide and all the tools necessary for me to do the repair.

I’m a software guy, I did not receive repair training and if there weren’t any guides or tools available, I’ll probably never figure how to do the battery change repair by myself without breaking the phone.

The repair was a success and even though I’m not going to use the phone, I’m going to gift to someone that will be very happy to use it for a few more years.

Read more about the right to repair:

BME680 Home Assistant Integration

Hi πŸ‘‹,

In this short article I will highlight how to use the BME680 Home Assistant integration with a BME680 Sensor.

Please note that I’m running Home Assistant core on Raspbian OS.

Raspberry Pi Setup

Before connecting the sensor, you will need to enable the I2C interface on your Raspberry Pi and install some additional tools that are useful for debugging.

To enable the I2C interface execute:

sudo raspi-config

Then go to Interfacing options->I2C and select yes.

Next, install the following packages:

sudo apt-get install build-essential libi2c-dev i2c-tools python-dev libffi-dev

Sensor Setup

The first step is to buy the sensor, get one with headers already soldered if you can otherwise, you’ll need to solder them.

I got mine from Pimoroni and I’ve never was disappointed by them, they deliver to EU.

BME680 sensor. Pimoroni screen capture 2022-01-16

Next depending on which headers you’ve chosen; you will need four male-to-female jumper wires to connect the BME680 to the Raspberry Pi.

To connect the sensor to the Raspberry PI, refer to the following diagram:

You will need to connect the wires to the following buses:

  • Sensor Power -> Raspberry PI 3.3V
  • Sensor GND -> Raspberry PI GND
  • Sensor SCL -> Raspberry PI SCL
  • Sensor SDA -> Raspberry PI SDA

Check that the sensor is detected using the following command on the Raspberry Pi.

/usr/sbin/i2cdetect -y 1

You should get an ouput like this:

0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 76

The sensor’s I2C address can be 0x76 or 0x77. According to the above output, the sensor address in our case is 0x76, keep this in mind.

Home Assistant Setup

Add your homeassistant user to the I2C group by running:

sudo addgroup homeassistant i2c

Next, open configuration.yaml and modify the sensor and homeassistant.customize sections according to:

Don’t forget to replace i2c_address : 0x76 with your i2c address if it’s different.

homeassistant:
  name: HomeKit NucuLabs
  unit_system: metric
  time_zone: Europe/Bucharest
  customize:
    sensor.bme680_sensor_temperature:
      icon: mdi:thermometer
      friendly_name: Temperature
    sensor.bme680_sensor_humidity:
      icon: mdi:water
      friendly_name: Humidity
      device_class: humidity
      unit_of_measurement: "%"
    sensor.bme680_sensor_pressure:
      icon: mdi:gauge
      friendly_name: Pressure
    sensor.bme680_sensor_air_quality:
      icon: mdi:blur
      friendly_name: Air Quality
      device_class: pm25
      unit_of_measurement: "%"

sensor:
  - platform: bme680
    i2c_address: 0x76
    monitored_conditions:
      - temperature
      - humidity
      - pressure
      - gas
      - airquality

Reboot the device after you’ve modified configuration.yaml by running sudo reboot.

Note: The customize section sensor.bme680_sensor_air_quality sets the device class of BME680 air quality measurement to pm25, but this isn’t a pm25 measurement, it’s a proprietary algorithm according BME680 Datasheet. High values indicate good air quality while low values indicate low air quality. On the other hand, in pm25 measurements high values indicate bad air quality and low values good air quality.

This is a hack and it’s up to you if you want to keep it. If you don’t set the device class to pm25 then the measurement won’t be visible in Apple Homekit because Homekit is not aware of this kind of measurement. If you know any other way of making it visible in Homekit let me know. πŸ˜€

After home assistant reboots, the following entities should be available in the Lovelace UI:

Thanks for reading! 🍻

Home automation with Home Assistant on Raspberry PI – Getting Started

Hi πŸ‘‹

The purpose of this article is to get you started quickly with a Home Assistant on a Raspberry Pi. It’s a simple walkthrough on how to install Home Assistant and configure it so it will boot with your PI.

I will use my old Raspberry PI V3 board.

Flashing the Raspberry PI OS

You will need a microSD card of reasonable size, I’m using a 16GB one and a USB Adapter to connect it with my PC.

Head over to Raspberry Pi OS website and download your preferred image, for my Home Assistant I’ve chosen Raspberry Pi OS with desktop and recommended software. After the download is completed, unzip the file and prepare to flash it.

To flash the OS image on the SD card I will use a program called balenaEtcher.

Download it, select your OS image, select the SD card, and hit flash.

After SD card flashing finishes, it is time to setup the Wi-Fi connection. If you’re using an ethernet cable you can skip this step, however, remember to enable SSH.

Setting up the Wi-Fi and enabling SSH

Unplug the SD card from the computer and plug it back. You should see two new drives D: and E:

  1. Open your favorite text editor and create an empty file called ssh in drive E:. This will enable SSH access.
  2. Create a new file called wpa_supplicant.conf using your text editor and paste the following contents in it:
country=us
update_config=1
ctrl_interface=/var/run/wpa_supplicant

network={
   scan_ssid=1
   ssid="YOUR_WIFI_SSID"
   psk="YOUR_WIFI_PASSWORD"
}

Don’t forget to replace YOUR_WIFI_SSID and YOUR_WIFI_PASSWORD with the corresponding values regarding your Wi-Fi network.

Eject the SD card from your computer and plug it into the PI. At boot, the PI should automatically connect to your Wi-Fi network.

Installing Home Assistant Core

Find your Raspberry PI’s IP address and connect to it via ssh. You can run the command ssh pi@192.168.0.XXX. The password for the pi user should be raspberry.

After getting a shell, follow the instructions for installing Home Assistant from the official website.

Ensure that you run each command on its own line. Don’t directly copy the entire code block, copy each line individually.

Starting Home Assistant on boot

If you can access the Home Assistant web GUI using http://192.168.0.XXX:8123 then the next step would be to create a new systemd service so that some assistant starts at boot. Please replace XXX with your Raspberry PI’s IP address.

To create a new service:

  1. Start a new shell on the Raspberry or ensure that you’re using the pi user. We will execute commands with sudo.
  2. Use sudo nano /etc/systemd/system/hass.service to create a new file and paste the following contents into it:
[Unit]
Description=HomeAssistant Service
After=network.target

[Service]
User=homeassistant
WorkingDirectory=/home/homeassistant
Environment="PATH=$PATH:/srv/homeassistant/bin"
ExecStart=/srv/homeassistant/bin/hass

[Install]
WantedBy=multi-user.target

Stop hass command if it’s running and enables the service by executing:

sudo systemctl start hass.service
sudo systemctl enable hass.service
sudo systemctl status hass.service

If the service is running normally, everything is set up. You can safely reboot your PI and the Home Assistant service will run after boot.

Configuring Home Assistant

When visiting the Home Assistant’s web interface for the first time, you will be prompted to create a new user. You may also download the Home Assistant application for your mobile device if you wish to track things like battery, storage, steps, location and so on, in Home Assistant.

In future articles I will show you how to configure the BME680 enviromental sensor and how to activate the Apple Homekit integration. Until then, have fun exploring Home Assistant docs.

Things to do further:

Unattended Upgrades – Enable unattended upgrades for your Raspbian OS. Ensures that your OS’s is always patched and up to date.

UFW – Secure your Home Assistant server with the uncomplicated firewall.

Change default passwords or disable SSH login via password.

Thanks for reading and happy automations! πŸ“š

Pytest Fixtures and Yield

Hi πŸ‘‹

In this short article I want to explain the use of the yield keyword in pytest fixtures.

What is pytest?

Pytest is a complex python framework used for writing tests. It has lots of advanced features and it supports plugins. Many projects prefer pytest in addition to Python’s unitttest library.

What is a fixture?

A test fixture is a piece of code that fixes some common functionality that is required for writing the unit tests. This functionality can be

  • a connection to the database
  • a testing http server or client
  • creation of a complex object

You can read more about test fixtures on Wikipedia.

What does yield keyword do?

In Python, the yield keyword is used for writing generator functions, in pytest, the yield can be used to finalize (clean-up) after the fixture code is executed. Pytest’s documentation states the following.

β€œYield” fixtures yield instead of return. With these fixtures, we can run some code and pass an object back to the requesting fixture/test, just like with the other fixtures.

https://docs.pytest.org/en/6.2.x/fixture.html

An example code could be the following:

@pytest.fixture()
def my_object_fixture():
    print("1. fixture code.")
    yield MyObjectThatRequiresCleanUp()
    print("4. fixture code after yield.")

Running a sample test which utilizes the fixture will output:

collected 1 item                                                                                                                                                                       

tests\test_my_object.py 1. fixture code.
2. Initializing MyObjectThatRequiresCleanUp
3. test code.
.4. fixture code after yield.

Running the same test but now with the fixture my_object_fixture2, will output:

tests\test_my_object.py 1. fixture code.
2. Initializing MyObjectThatRequiresCleanUp
2.1 Entering
3. test code.
.3.1 Exiting
Clean exit
4. fixture code after yield.

I hope I could successfully ilustrate with these examples the order in which the testing and fixture code is run.

To run the tests, I’ve used pytest --capture=tee-sys . in the project root. The file contents are attached to the end of this article. The --capture parameter is used to capture and print the tests stdout. Pytest will only output stdout of failed tests and since our example test always passes this parameter was required.

Conclusion

Pytest is a python testing framework that contains lots of features and scales well with large projects.

Test fixtures is a piece of code for fixing the test environment, for example a database connection or an object that requires a specific set of parameters when built. Instead of duplicating code, fixing the object’s creation into a fixture makes the tests easier to maintain and write.

yield is a python keyword and when it is used in conjunction with pytest fixtures it gives you a nice pythonic way of cleaning up the fixtures.

Thanks for reading! πŸ“š


Contents of the Pytest fixtures placed in tests/__init__.py

import pytest

from my_object import MyObjectThatRequiresCleanUp


@pytest.fixture()
def my_object_fixture():
    print("1. fixture code.")
    yield MyObjectThatRequiresCleanUp()
    print("4. fixture code after yield.")


@pytest.fixture()
def my_object_fixture2():
    print("1. fixture code.")
    with MyObjectThatRequiresCleanUp() as obj:
        yield obj
    print("4. fixture code after yield.")

Contents of my_object.py

class MyObjectThatRequiresCleanUp:
    def __init__(self):
        print("2. Initializing MyObjectThatRequiresCleanUp")

    def __enter__(self):
        print("2.1 Entering")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("3.1 Exiting")
        if exc_type is None:
            print("Clean exit")
        else:
            print("Exception occurred: {}".format(exc_type))

Contents of test_my_object.py placed in tests/test_my_object.py

from tests import my_object_fixture


def test_my_object(my_object_fixture):
    print("3. test code.")