[PYTHON] Make a wash-drying timer with a Raspberry Pi

Make a wash-drying timer with a Raspberry Pi

Introduction (Purpose of production)

――Because I work for a company, I am often absent during the day, and I cannot take in the laundry when it rains. For this reason, laundry is basically dried indoors. ――However, the clothes-drying room is not sunny enough, and the drying does not proceed as expected in winter, so the timing of taking in the clothes may be missed, and the laundry accumulates in a snowball style, creating a vicious cycle. ――In order to break this vicious cycle (?), We have created a mechanism to calculate the drying completion time of laundry and notify it to your smartphone.

What to prepare

(1) What is necessary for building the environment on the device side. It can be purchased at Akizuki Denshi. http://akizukidenshi.com/catalog/top.aspx

(2) Necessary for building an environment on the server side. You need an AWS and Slack account. AWS: https://aws.amazon.com/jp/ Slack: https://slack.com/intl/ja-jp/

Product name quantity Use
① RaspberryPi ZeroWH 1 Control microcomputer
① Breadboard 1 For circuit construction
① DHT11 1 Temperature / humidity sensor
① Resistance (4.7kΩ) 2
① Resistance (1kΩ) 1
① Tact switch 1 Start / stop switch
① LED 1 Lights up at startup (for visual confirmation)
② AWS IoT Core Terminate communication with the terminal. The role of the MQTT broker.
② AWS Lambda IoT Core backend. Mediate communication with Slack.
② Slack Used for notification to smartphones

System overview

RaspberryPi --- AWS IoT Core --- AWS Lambda --- Slack --- Smartphone

Environment construction (server)

AWS IoT Core

Creating a certificate

Create an X.509 certificate required to authenticate your connection with AWS IoT Core. As a creation procedure, first create a policy (authorization information for AWS resources) in advance, and then attach the policy to the certificate.

--Select the AWS IoT Core service on the AWS Management Console and create a policy from "Safety"-> "Policies". Set any value for the policy name. Create a policy with any name, with the action "iot: " and the resource ARN "".

--Create a certificate from "Security"-> "Certificate". Create a certificate from the 1-Click certificate creation menu and download "Certificate of this thing" and "Private key" to your PC. You will need this certificate and private key later in the AWS IoT SDK configuration. Also, for the required root CA certificate, see here to RSA 2048. Save the contents of the bitkey in a text editor to create it. --Press "Activate" to activate the certificate, then use "Attach Policy" to attach the policy you just created to the certificate.

Device (thing) registration

Register the device that connects to AWS IoT Core.

--Select the AWS IoT Core service from the AWS Management Console, select "Management"-> "Things"-> "Create"-> "Create a single thing", and follow the on-screen instructions to register the device (thing). .. You will be prompted to create a new certificate, but since you will be using the certificate you created earlier, select "Create thing without certificate". --Click "Attach thing" in the submenu on the upper right of the certificate card created earlier in "Security"-> "Certificate" to attach the device (thing) created earlier to the certificate.

This completes the settings required to connect to AWS IoT Core.

Creating rules

Next, configure the settings to transfer the data received by AWS IoT Core to AWS Lambda.

--Select the AWS IoT Core service from the AWS Management Console, select "ACT"-> "Rules"-> "Create Rule", and follow the on-screen instructions to create a forwarding rule. --In the rule query statement, specify the conditions to apply the action to the received MQTT message in SQL. In this case, the Lambda function is called under the condition of topic name = "condition" and notice = 1, so (SELECT * FROM'condition' WHERE notice = 1). --Set to call the Lambda function from "Set one or more actions"-> "Add action".

AWS Lambda From the AWS Management Console, select your Lambda service and define your Lambda function to be called from AWS IoT Core. Notification to Slack creates text data in the format of "payload =" + json.dumps (send_data)) and POSTs it to the Incoming Webhook URL.

import json
import urllib.request

def lambda_handler(event, context):

    d = json.dumps(event)
    post_slack(event)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

def post_slack(event):
    
    t = event["remaining_time"]
    
    #Message composition
    if t < 0:
        message = "The laundry is dry!"
    else:
        message = "after%-The laundry dries in 2i minutes." % t
    
    send_data = {
        "username" : "dry_notice",
        "text" : message,
    }
    
    send_text = "payload=" + json.dumps(send_data)
    
    #Notification to slack
    request = urllib.request.Request(
        "URL of Slack's Incomming Webhook", 
        data=send_text.encode('utf-8'), 
        method="POST"
    )
    with urllib.request.urlopen(request) as response:
        response_body = response.read().decode('utf-8')
    

Slack Create an account in Slack and add any channel. After that, register the Incoming Webhook for the added channel.

This completes the server-side environment construction.

Environment construction (device)

Hardware design

--Use a breadboard to wire the Raspberry Pi and each part of ①. For the pin layout of Raspberry Pi, here is organized in an easy-to-understand manner for your reference. --The light blue square box is DHT11. From the left, 5V power supply, DATA, NC (unused), GND. DATA connects to any GPIO (14Pin in the figure below). Also, connect a 4.7kΩ resistor to the DATA line and pull it up with 5v. --In addition, the LED and tact switch can be connected to any GPIO (23,24Pin in the figure below) with 1kΩ and 4.7kΩ resistors.

kairozu.PNG

Software design

The overall processing flow is as follows.

--Start the monitor triggered by the Pull_UP event of GPIO24. --Obtain temperature / humidity values from dht11 every 10 seconds. --Calculate the remaining time to dry from the weight, temperature and humidity of the laundry. -(When the remaining time is 10 minutes or less) Notify the remaining time 10 minutes via AWS IoT Core. -Notify the completion of drying via AWS IoT Core (when the remaining time becomes 0). --Stop monitoring due to drying completion or GPIO24 Pull_UP event.

#!/usr/bin/python3
# coding: UTF-8

# Import SDK packages
import RPi.GPIO as GPIO
import dht11 #・ ・ ・ 1
import time
import datetime
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient,AWSIoTMQTTClient
from AWSIoTPythonSDK.exception import AWSIoTExceptions
import json
import logging

# Init logging
logging.basicConfig(filename="Log file path",level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# Init AWSIoTMQTTClient #・ ・ ・ 2
myAWSIoTMQTTClient = None
myAWSIoTMQTTClient = AWSIoTMQTTClient("AWS IoT Core Things Name")
myAWSIoTMQTTClient.configureEndpoint("AWS IoT Core Endpoint URL", 8883)
myAWSIoTMQTTClient.configureCredentials("Root certificate path", "Private key path", "Client certificate path")

# AWSIoTMQTTClient connection configuration
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1)  # Infinite offline Publish queueing
myAWSIoTMQTTClient.configureDrainingFrequency(2)  # Draining: 2 Hz
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)  # 10 sec
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)  # 5 sec

# Connect to AWS IoT
myAWSIoTMQTTClient.connect()
logging.info('connect to AWS IoT')

# MQTT topic #・ ・ ・ 3
topic_1 = "condition"
topic_2 = "monitermode"

# Variable
modeState = False # Operating state(True:ON False:OFF)
v = 3000 # Laundry weight
delta_v = 0 # Delta of Laundry weight
notice = 0 # Notification to Slack
flg_1 = True
flg_2 = True
starttime = datetime.datetime.now()
lasttime = starttime

# Init GPIO
LED = 23
SWITCH = 24
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED,GPIO.OUT)
GPIO.setup(SWITCH,GPIO.IN)

# Read data using pin 14
instance = dht11.DHT11(pin=14)

# Action when switch is pressed
def switch_on(self):

    # When it is running
    if modeState:
        GPIO.output(LED,0)
        modeState = False
        logging.info("Stop drying monitor")
        payload = { "mode": 0}

    # When stopped
    else:
        GPIO.output(LED,1)
        modeState = True
        v = 3000
        delta_v = 0
        notice = 0
        flg_1 = True
        flg_2 = True
        starttime = datetime.datetime.now()
        lasttime = starttime
        logging.info("Start drying monitor")
        payload = { "mode": 1}

    myAWSIoTMQTTClient.publish(topic_2, json.dumps(payload), 1)

# GPIO event setting #・ ・ ・ 4
GPIO.add_event_detect(SWITCH,GPIO.RISING,callback=switch_on,bouncetime=200)


while True:
    try:
        # When it is running
        if modeState:
            result = instance.read()
            if result.is_valid():
                logging.info("Temperature: %-3.1f C" % result.temperature)
                logging.info("Humidity: %-3.1f %%" % result.humidity)

                now = datetime.datetime.now()
                delta = now - lasttime
                logging.info("delta_time: %-2i sec" % delta.seconds)
                lasttime = now

                #・ ・ ・ 5
                ps = 6.11 * 10 ** (7.5 * result.temperature / (result.temperature + 237.3))
                delta_v += (-0.45 * ps * (1-result.humidity / 100) + 0.25) * delta.seconds / 60
                logging.info("delta_v: %-3i g" % int(delta_v))

                elapsed_time = lasttime - starttime
                estimate_time = elapsed_time.seconds * v / (-1 * delta_v) / 60
                remaining_time = elapsed_time.seconds * (v / (-1 * delta_v) - 1) / 60
                logging.info("estimate_time: %-3.1f minutes" % estimate_time)
                logging.info("remaining_time: %-3.1f minutes" % remaining_time)

                #・ ・ ・ 6
                if remaining_time < 10:
                    if flg_1:
                        notice = 1
                        flg_1 = False
                    else:
                        notice = 0

                if remaining_time < 0:
                    if flg_2:
                        notice = 1
                        flg_2 = False
                        modeState = False
                    else:
                        notice = 0

                payload = { "time":str(datetime.datetime.now()),\
                            "temperature":round(result.temperature,1),\
                            "humidity":round(result.humidity,1),\
                            "estimate_time":round(estimate_time,1),\
                            "remaining_time":round(remaining_time,1),\
                            "notice":notice}

                myAWSIoTMQTTClient.publish(topic_1, json.dumps(payload), 1)
        
        # When stopped
        else:
            GPIO.output(LED,0)

        time.sleep(6)

    except KeyboardInterrupt:
        break

    except:
        pass

logging.warning("Exception detected. Finish application.")
GPIO.cleanup()
myAWSIoTMQTTClient.disconnect()
  1. dht11 is a library that acquires temperature and humidity values from sensors. It's available from GitHub.

  2. Setting up an MQTT client that connects to AWS IoT Core. In each case, set the contents referenced in the AWS Iot Core menu. --Item name: Device name registered in "Management" → "Item" --Endpoint: URL displayed in "Settings" → "Custom Endpoint" --Various certificates: Download the certificate attached to "Things" from "Security"-> "Certificate" and store it in the Raspberry Pi.

  3. MQTT topic name. topic_1 (condition) is a topic for posting sensor values such as temperature and humidity, and topic_2 (monitermode) is a topic for posting monitor status.

  4. Monitoring settings of GPIO24 to which the tact switch is connected. Pressing the switch (Lo → Hi) activates the switch_on function. The switch_on function controls the LED and initializes the parameters. The monitor state is held in modeState, and the state (OFF / ON) is changed each time the switch is pressed.

  5. This is a processing unit that calculates the drying time. The formula for drying time is based on this site. v is the weight when the laundry basket is filled with laundry (before drying-after drying → moisture weight), and delta_v is the moisture weight after starting with the switch.

  6. When the remaining time (remaining_time) is (1) 10 minutes or less and (2) 0 minutes or less, we will post to topic_1. The following data will be posted to topic_1.

item name Contents
time Current time
temperature Temperature (℃)
humidity Humidity (%)
estimate_time Time required to complete drying (minutes)
remaining_time Remaining time (minutes)
notice Notification flag to Slack (1:Notify 0:Do not notify)

in conclusion

If I have time, I would like to add a function to control the fan and shorten the drying time as an extension function.

Recommended Posts

Make a wash-drying timer with a Raspberry Pi
Using a webcam with Raspberry Pi
Build a Tensorflow environment with Raspberry Pi [2020]
Operate an oscilloscope with a Raspberry Pi
Create a car meter with raspberry pi
Let's make a cycle computer with Raspberry Pi Zero (W, WH)
Make a thermometer with Raspberry Pi and make it viewable with a browser Part 4
Make a Kanji display compass with Raspberry Pi and Sense Hat
GPGPU with Raspberry Pi
DigitalSignage with Raspberry Pi
Make a wireless LAN Ethernet converter and simple router with Raspberry Pi
[Python + PHP] Make a temperature / humidity / barometric pressure monitor with Raspberry Pi
I tried to make a traffic light-like with Raspberry Pi 4 (Python edition)
Mutter plants with Raspberry Pi
Make a thermometer with Raspberry Pi and make it visible on the browser Part 3
Make a fortune with Python
Make an umbrella reminder with Raspberry Pi Zero W
A memorandum when making a surveillance camera with Raspberry Pi
Make a fire with kdeplot
Create a web surveillance camera with Raspberry Pi and OpenCV
Make an air conditioner integrated PC "airpi" with Raspberry Pi 3!
I made a resource monitor for Raspberry Pi with a spreadsheet
getrpimodel: Recognize Raspberry Pi model (A, B, B +, B2, B3, etc) with python
I made a surveillance camera with my first Raspberry PI.
Creating a temperature / humidity monitor with Raspberry Pi (pigpio version)
[Raspberry Pi] Stepping motor control with Raspberry Pi
Use vl53l0x with Raspberry Pi (python)
Let's make a GUI with python.
Make a sound with Jupyter notebook
Serial communication with Raspberry Pi + PySerial
Let's make a breakout with wxPython
OS setup with Raspberry Pi Imager
VPN server construction with Raspberry Pi
Make a filter with a django template
Try moving 3 servos with Raspberry Pi
Let's make a graph with python! !!
Let's make a supercomputer with xCAT
Make a model iterator with PySide
Make a nice graph with plotly
Make a note of what you want to do in the future with Raspberry Pi
Easily make a TweetBot that notifies you of temperature and humidity with Raspberry Pi + DHT11.
I tried to make a motion detection surveillance camera with OpenCV using a WEB camera with Raspberry Pi
Control the motor with a motor driver using python on Raspberry Pi 3!
I made a web server with Raspberry Pi to watch anime
Make a simple CO2 incubator using Raspberry PI and CO2 sensor (MH-Z14A)
Christmas classic (?) Lighting a Christmas tree with Raspberry Pi and Philips Hue
[Note] Using 16x2-digit character LCD (1602A) from Python with Raspberry Pi
Let's make an IoT shirt with Lambda, Kinesis, Raspberry Pi [Part 1]
How to upload a file to Cloud Storage using Python [Make a fixed point camera with Raspberry PI # 1]
Measure SIM signal strength with Raspberry Pi
Pet monitoring with Rekognition and Raspberry pi
Let's make a shiritori game with Python
Make a video player with PySimpleGUI + OpenCV
[Raspberry Pi] Add a thermometer and a hygrometer
Hello World with Raspberry Pi + Minecraft Pi Edition
Make a rare gacha simulator with Flask
Make a Notebook Pipeline with Kedro + Papermill
Get BITCOIN LTP information with Raspberry PI
Make a partially zoomed figure with matplotlib
Try fishing for smelt with Raspberry Pi
Programming normally with Node-RED programming on Raspberry Pi 3