――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.
(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 |
RaspberryPi --- AWS IoT Core --- AWS Lambda --- Slack --- Smartphone
AWS IoT Core
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.
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.
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.
--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.
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()
dht11 is a library that acquires temperature and humidity values from sensors. It's available from GitHub.
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.
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.
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.
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.
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) |
If I have time, I would like to add a function to control the fan and shorten the drying time as an extension function.