I made an app to tweet the weather and temperature of a specific area in Go language, and made it run automatically with cron from Raspberry Pi 4. We use OpenWeatherMap and Twitter API.
・ MacOS Catalina 10.15.7 (at the time of development and operation check) ・ Raspbian 10.6 (Raspberry Pi 4B) ・ Go 1.15.2
Apply for a developer and create a Twitter application from the Developer page, and get the API key & secret and Access token & secret.
I referred to the following article. Detailed explanation from the example sentence of the 2020 version Twitter API usage application to the acquisition of the API key Twitter Developer application (with example sentences) and API key acquisition method summary [2019 version]
If the App permissions setting of the created Twitter app is set to "Read Only", a permission error will occur when trying to tweet, so change it to "Read and Write".
First, create an account from the following page. http://home.openweathermap.org/users/sign_up
After signing in, select the API keys tab to see the API keys.
Get the weather information from OpenWeatherMap and create an app to tweet with Twitter API.
I referred to the following article. Tweet regularly with the Go language Twitter API [Go] Get current weather information using OpenWeatherMap API
The folder structure is as follows.
tenkiapp
├── keys
│ └── keys.go
├── getweather
│ └── getweather.go
├── text
│ └── text.go
└── main.go
First, write the code for Twitter authentication. Apply the API key & secret and Access token & secret obtained in "1. Twitter API account application & App creation" to the corresponding part of the code below.
keys.go
package keys
import (
"github.com/ChimeraCoder/anaconda"
)
func GetTwitterApi() *anaconda.TwitterApi {
anaconda.SetConsumerKey("API_KEY")
anaconda.SetConsumerSecret("API_KEY_SECRET")
api := anaconda.NewTwitterApi("ACCESS_TOKEN", "ACCESS_TOKEN_SECRET")
return api
}
Next, write the code to get the weather from OpenWeatherMap. For the API request parameter appid, specify the API key obtained in "3. Creating an OpenWeatherMap account & Obtaining an API key".
getweather.go
package getweather
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
)
type OpenWeatherMapAPIResponse struct {
Main Main `json:"main"`
Weather []Weather `json:"weather"`
Coord Coord `json:"coord"`
Wind Wind `json:"wind"`
Dt int64 `json:"dt"`
}
type Main struct {
Temp float64 `json:"temp"`
TempMin float64 `json:"temp_min"`
TempMax float64 `json:"temp_max"`
Pressuer int `json:"pressure"`
Humidity int `json:"humidity"`
}
type Coord struct {
Lon float64 `json:"lon"`
Lat float64 `json:"lat"`
}
type Weather struct {
Main string `json:"main"`
Description string `json:"description"`
Icon string `json:"icon"`
}
type Wind struct {
Speed float64 `json:"speed"`
Deg int `json:"deg"`
}
func GetWeather() OpenWeatherMapAPIResponse {
endPoint := "https://api.openweathermap.org/data/2.5/weather" //API endpoint
//Set parameters
values := url.Values{}
values.Set("q", "Tokyo,jp") //Specify the area (here, Tokyo)
values.Set("units", "metric") //Get the unit of temperature in Celsius
values.Set("lang", "ja") //Get Description in Japanese
values.Set("appid", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") //API key
//Throw a request
res, err := http.Get(endPoint + "?" + values.Encode())
if err != nil {
panic(err)
}
defer res.Body.Close()
//Read the response
bytes, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
//JSON perspective
var apiRes OpenWeatherMapAPIResponse
if err := json.Unmarshal(bytes, &apiRes); err != nil {
panic(err)
}
return apiRes
}
Write the code to create the text you want to tweet.
text.go
package text
import (
. "tenkiapp/getweather"
"fmt"
"time"
)
func GetTweetText() string {
weather := GetWeather()
tweetText := fmt.Sprintf("%s\n", time.Unix(weather.Dt, 0).Format("2006/01/02 15:04"))
tweetText += fmt.Sprintf("%s\n", weather.Weather[0].Main)
tweetText += fmt.Sprintf("%s\n", weather.Weather[0].Description)
tweetText += fmt.Sprintf("%.1f%s\n", weather.Main.Temp, "℃")
return tweetText
}
Finally, create main.go.
main.go
package main
import (
. "tenkiapp/keys"
. "tenkiapp/text"
)
func main() {
api := GetTwitterApi()
_, err := api.PostTweet(GetTweetText(), nil)
if err != nil {
panic(err)
}
}
I will try it once.
$ go run main.go
It is OK if you can tweet the following with the created Twitter account.
2021/01/01 12:00
Clouds
Tends to be cloudy
6.8℃
I referred to the following article. go build and cross-compile
When I ran go env on Raspberry Pi 4, GOARCH and GOOS were as follows. (If you just want to run the go binary on the Raspberry Pi, you don't need to install go on the Raspberry Pi, but it's done for confirmation)
GOARCH="arm"
GOOS="linux"
Go to the app directory and run the following command.
$ env GOOS=linux GOARCH=arm go build main.go
Transfer the resulting binary file onto the Raspberry Pi.
$ scp [App directory]/main [email protected]:/home/pi/tenkiapp/
I referred to the following article. Run cron on Raspberry Pi 4
Ssh connect to Raspberry Pi.
$ ssh [email protected]
From here, it's work on the Raspberry Pi. First, enable cron logging.
/etc/rsyslog.conf
#Uncomment the following
cron.* /var/log/cron.log
//Reflect changes
$ sudo /etc/init.d/rsyslog restart
//Check cron status active(running)If it is OK
$ sudo /etc/init.d/cron status
//Restart cron (if needed)
$ sudo /etc/init.d/cron restart
Next, set up cron.
$ crontab -e
//Tweet every day at 6:00, 12:00, and 18:00
0 6 * * * /home/pi/tenkiapp/main
0 12 * * * /home/pi/tenkiapp/main
0 18 * * * /home/pi/tenkiapp/main
It's OK if you can tweet at the set time.
Thank you to the creator of the article for your reference.
Detailed explanation from the example sentence of the 2020 version Twitter API usage application to the acquisition of the API key Twitter Developer application (with example sentences) and API key acquisition method summary [2019 version] Tweet regularly with the Go language Twitter API [Go] Get current weather information using OpenWeatherMap API go build and cross-compile Run cron on Raspberry Pi 4
Recommended Posts