# Autocurtain
### By
Joel Carlsson (jc222mw)
[Result/making video](https://youtu.be/p1m7KBn0kPY)
### Overview
Automated curtains that follows the sun all the way down behind the horizon when the weather is clear.
By unsing solar and weather data from APIs, the server will calculate where the curtains would be. The curtains can be set for both west and east.
If set west, the curtains will only move in the afternoon and follow the sun down, then reset when the sun has passed the horizon.
If set east, the curtain will go down when the sun rizes over the horizon, and then follow up until noon.
Every value that is communicated between thing and server is calculated to percent (0 = all the way up, 100 = all the way down) and runned as instances on the server. This means that many curtains with different motors and different curtains can be runned and show similar results.
The server can run both multiple west and east curtains simultainously, by just connecting new units in the index and setting up a separate MQTT-feed for the other direction.
It is possible to pinpoint the location of the device by both IP-adress or by coordinates.
The REST-API is still under development, the plan with the REST-API is to connect web- and mobile-apps to have the power to add new units by coordinates and controll the units throught the apps.
Knowledge: Medium
Time: 16 hrs
### Things used in this project
[Lopy 4](https://pycom.io/product/lopy4-multipack/) (Any Pycom unit with WiFi will do)
[Expansion Board 3.1](https://pycom.io/product/lopy4-multipack/)
[Stepper motor](https://www.poscope.com/product/nema-17-sy42sth47-1684b-stepper-motor/) (Not enough to controll a 108 cm metallic curtain)
[Stepper motor driver](https://www.electrokit.com/en/product/adapterkort-for-stegmotordrivare/)
[Adaptercard for stepper motor driver](https://www.electrokit.com/en/product/adapterkort-for-stegmotordrivare/)
[BreadBoard](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/velleman-utbildningskit-elektronik-p36303)
[Buttons x2](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/velleman-utbildningskit-elektronik-p36303)
[Capacitor, 10μF](https://www.kjell.com/se/produkter/el-verktyg/elektronik/elektroniklabb/velleman-utbildningskit-elektronik-p36303)
[Net Adapter 3–12 V, 2250 mA](https://www.biltema.se/kontor---teknik/datortillbehor/natadaptrar/natadapter-3-12-v-2000030021)
Cables (Not the thinest ones for the net adapter)
### Story
Every day, in the after noon the sun goes down outside my window. Unfortunately, the sun sets with a clear view from where my computer is and from the livingroom sofa, every day is the same, all year long. Even during the winter. And every day, has the same story. I have to go to the window and lower the curtains, but not to much. Just enough so the flowers get sun and som light comes in, but enough to stop the blinding light. And every nigh, i had to go and lift it up again.
This is something that really can be automated, and with a little bit of patience and some skills, one can make the curtain lower it self, just to cover the sun and follow the sun down untill it dissapears, and then, go back to it's normal state.
### Lopy4
Lopy4 is a device by Pycom that is programmed by Micropython. The lopy4 has Wifi, Bluetooth, Sigfox And LoRa, which means that there are multiple ways to connect the device to internet or other devices. This project will use WiFi for connection, but it wouldn't be a problem to rewrite the code to use LoRa instead. It is easy to connect sensors through the pins on the Lopy4 for both input and output.
### Computer setup
* Download Firmware from Pycom by following [this guide](https://docs.pycom.io/gettingstarted/installation/)
* Follow the guide at Pycom
* Download and install [Node.js](https://nodejs.org/en/)
* The LTS version will cover what you need
* I use Visual Studio Code as IDE which can be found [here](https://code.visualstudio.com/)
* Download
* Install by following the installation guide in the installer
* Open VSCode
* Install the plugin Pymakr by following [these steps](https://i.imgur.com/EMLusR2.png)
*
## Software setup
### Data transmition
The project uses WiFi from the "Thing" and internet connection to the server.
The "Thing" needs external power from adapter, and where i live there is no LoRa connection.
The protocol for communication is MQTT.
The protocol for the REST-API is HTTP (still under construction).
The plan was to use HTTP for all communication, but it is to much trouble to make a two way HTTP connection with the Lopy compared to MQTT. This disabled some functionality because of the small amount of data.
### Platform
This project needs an MQTT broker. I use [adafruit.io](https://io.adafruit.com/). One feed for Automatic height is needed in the broker, that can be subscribed to from both the server and the client. This project won't send that much data, so no paymet plan is needed for Adafruit
### APIs
Two APIs are used for solar position and for weather.
* [OpenWeatherMap](https://openweathermap.org/) for getting clouds
* [Ip Geolocation](https://ipgeolocation.io/) for getting location from ip and for solar position
Both of them are free to a certain amount of monthly requests, which the server in this system is design to stay under. No payment is needed.
### Get the code
The code is available for download on [Github](https://github.com/joelcarlss/IoT-autocurtains)
There are two ways of getting the code locally.
* Use git (If you have it and know how to use it)
* If you know how to use Git you can clone the code to your machine
* Download it as zip-file
* On the Github [repo](https://github.com/joelcarlss/IoT-autocurtains), press "Code" and then "Download ZIP"
* Let the file be downloaded to your computer
* Un-zip the file
* Put the folder where you want it to be
The code inside the folder is structured in two separate folders, Server and Thing. Both the server and the thing is separate from eachother and the server will be executed locally or in the cloud. The thing will be uploaded to the Pycom.
### Thing
The code for the thing is MicroPython code, as the lopy4 requires.
* Open Visual Studio Code.
* Open the "thing" folder as current project.
Now you will have the project loaded in VSCode.
* Create a file in the root folder called "env.json"
* This file should look like this
* But change the data to you credentials
```
{
"wifi": {
"ssid": "nameOfYourWifi",
"password": "passwordToYourWifi"
},
"mqtt": {
"username": "adafruitUsernameIfAdafruitBroker",
"password": "adafruitPasswordIfAdafruitBroker"
}
}
```
* main.py
* The MQTT has adafruit.io as predefined broker. If you want another broker change the second argument in the MQTTClient
* Also change the name of the thing if you like
* Username and password is taken from the env.json file that already is created.
```
client = MQTTClient(
"solarfruit14", "io.adafruit.com",
user=data["mqtt"]["username"],
password=data["mqtt"]["password"], port=1883
)
```
### Server
The server is a Node.js server, that requires a little bit of setup.
* Open a new instance of Visual Studio Code.
* Open the "server" folder as the project
Now you will have the project loaded in VSCode.
* First of all you need to create a new file named ".env" in the server root folder.
* The File shoulld look like this.

* For every variable, enter the required information
* Api key from IpGeolocation API
* API key form OpenWeather API
* Your Adafruit username
* Your Adafruit user password
* URL Isn't needed.
* IP address for locating the device.
* Isn't needed if longitude and latitude is specified.
* Latitude for your thing
* Longitude for you thing
* From the command prompt in VSCode run "npm install"
* This will install all the needed packages to run the server
* Set up MqttHandler.js
* Inside the module, host, username, password and topic need to be set.
* If you're going to run both east and west curtains, topic needs to be set for each instance.
* Check Unit.js
* The variable "milliseconds" is set to "180000" which is 30 minutes. This value is how often updates will be runned.
* Don't worry , updates will only be done between the hours that the sun is up on the specified side. The rest of the day, no requests are done.
* Set the the preferred preferences
* Change to what you prefer
```
this.autoPreferences = {
clouds: 70, // Percent clouds. If more clouds than the set value, no execution will be done.
resetTo: 3, // Percent to go to after sunset for curtains facing west (goDown = true)
solarAltitude: {
top: 50, // Solar altitude where execution has its top. This is the 0% value for the curtain
bottom: 1, // Solar altitude where the execution has its bottom. This is the 100% value for the curtain
resetAt: 0 // For afternoon movement (goDown = true). When the sun passes this altitude, the curtain will go up
}
}
```
* Go to index.js
* Start new instance a thing
```
controller.connectByLatLon(latitude, longitude, goDown)
or
controller.connectByIp(ip, goDown)
```
One of these lines are used to start an instance for a new thing.
If the longitude and latitude are set in the .env file, these can be directly called in as arguments to the functions.
Latitude: `process.env.LATITUDE`
Longitude: `process.env.LONGITUDE`
#### goDown (boolean)
goDown sets the direction that the curtain should go.
True = West. The curtain will follow the sun down
False = East. The curtain will follow the sun up
If curtains in both directions are going to be connected, two connect functions needs to be rendered. One with goDown = false and one with goDown = true.
This means that you need to set to separate feeds in the mqtt-server as well.
### Run the server
Write `npm start` to start the server permanently.
If you are going to do development on the server, use: `npm devStart`
`npm devStart` will run the server through nodemon, which restarts the server at every save. This makes development much easier.
## Hardware setup
[Video of hardware setup](https://youtu.be/p1m7KBn0kPY)


## Presenting the data
Provide visual examples on how the dashboard looks. Pictures needed.
- How often is data saved in the database.
- *Explain your choice of database.
### Adafruit dashboard

Can controll the curtain when other values than the automated messages from the server is desirable.
The "Up" and "Down" can go past the percent and create new percent values. Example. The curtain is at 100 and the "Down" button is pressed, the motor will run one revolution down and set it as the new 100% value. Same when going up over 0.
### Server message

The automated triggers are controlled in the server and the instructions are presented in the server chapter.
### Finalizing the design
[Video of result and hardware setup](https://youtu.be/p1m7KBn0kPY)
I ran in to som complications that needs to be fixed before a final version. The "hand crafted" shaft pin that is made screws, nuts and a drilling machine as tool, makes the curtain roll up unevenly. There are great ways to fix this, that probably doesn't cost that much more. Extenstions for the shaft pin, that can be mounted on and stay permanently. It is actually amazing that this holds as good as it does. The screw that holds the home made shaft with the real shaft, is for wood and is screwed through a drilled hole in a metal nut. I actually thought this one should break, but it holds well, though i think it's probably 65% luck that holds it together.
The motor can't roll a 108 cm metallic curtain all the way up. A smaller one or a blind should work perfect. It is actually a lot of weight to handle with the metalic curtains.
It can be a good idea to use better wiring from the net adapter, there almost was a small fire, just from the two cables touching.
I also fried one lopy4 during the project but that one was my fault. But check where you connect the net adapter ;)
