Created
November 23, 2020 07:54
-
-
Save moyashipan/9440c3c02659d0b1e986c900a2f803be to your computer and use it in GitHub Desktop.
測距センサーをつないだM5ATOM MatrixからAlexaのChangeReportを送る
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
String regenerateAccessToken() { | |
String payload = ""; | |
payload += "grant_type=refresh_token"; | |
payload += "&refresh_token=" + REFRESH_TOKEN; | |
payload += "&client_id=amzn1.application-..."; | |
payload += "&client_secret=..."; | |
HTTPClient client; | |
client.begin("https://api.amazon.com/auth/o2/token"); | |
client.addHeader("Content-Type", "application/x-www-form-urlencoded"); | |
int httpCode = client.POST(payload); | |
Serial.printf("[HTTPS] POST... code: %d\n", httpCode); | |
String response_body = client.getString(); | |
Serial.println(response_body); | |
int str_start = response_body.indexOf("Atza|"); | |
int str_end = response_body.indexOf("\"", str_start); | |
String access_token = response_body.substring(str_start, str_end); | |
client.end(); | |
return access_token; | |
} | |
void postChangeRequst(String access_token, bool state) { | |
String value = state ? "NOT_DETECTED" : "DETECTED"; | |
String payload = ""; | |
payload += "{"; | |
payload += "\"context\": {},"; | |
payload += "\"event\": {"; | |
payload += "\"header\": {"; | |
payload += "\"messageId\": \"abc-123-def-456\","; | |
payload += "\"namespace\": \"Alexa\","; | |
payload += "\"name\": \"ChangeReport\","; | |
payload += "\"payloadVersion\": \"3\""; | |
payload += "},"; | |
payload += "\"endpoint\": {"; | |
payload += "\"scope\": {"; | |
payload += "\"type\": \"BearerToken\","; | |
payload += "\"token\": \"" + access_token +"\""; | |
payload += "},"; | |
payload += "\"endpointId\": \"sensor-001\""; | |
payload += "},"; | |
payload += "\"payload\": {"; | |
payload += "\"change\": {"; | |
payload += "\"cause\": {"; | |
payload += "\"type\": \"PHYSICAL_INTERACTION\""; | |
payload += "},"; | |
payload += "\"properties\": ["; | |
payload += "{"; | |
payload += "\"namespace\": \"Alexa.ContactSensor\","; | |
payload += "\"name\": \"detectionState\","; | |
payload += "\"value\": \"" + value + "\","; | |
payload += "\"timeOfSample\": \"" + DateTime.format("%FT%T.00Z") + "\","; | |
payload += "\"uncertaintyInMilliseconds\": 0"; | |
payload += "}"; | |
payload += "]"; | |
payload += "}"; | |
payload += "}"; | |
payload += "}"; | |
payload += "}"; | |
Serial.println(payload); | |
HTTPClient client; | |
client.begin("https://api.fe.amazonalexa.com/v3/events"); | |
client.addHeader("Content-Type", "application/json"); | |
client.addHeader("Authorization", "Bearer " + access_token); | |
client.addHeader("User-Agent", "M5Stack ATOM Matrix"); | |
client.addHeader("Accept", "*/*"); | |
client.addHeader("Accept-Encoding", "gzip, deflate, br"); | |
int httpCode = client.POST(payload); | |
Serial.printf("[HTTPS] POST... code: %d\n", httpCode); | |
client.end(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <M5Atom.h> | |
#include <HTTPClient.h> | |
#include <DateTime.h> | |
const char SSID[] = ""; | |
const char PASSWORD[] = ""; | |
const String REFRESH_TOKEN = "Atzr|..."; | |
const int RECV_PIN = 33; | |
const int AVE_LENGTH = 100; | |
int MIN_CAT_DISTANCE = 1000; // この値以上なら猫がいる | |
bool last_has_cat = false; // ひとつ前の検出結果 | |
bool stabled_has_cat = false; // チャタリングを無視した現在の状態 | |
int stable_count = 0; | |
const int MAX_STABLE_COUNT = 3; | |
int timer = 0; | |
bool show_led = true; | |
void setup() { | |
M5.begin(true, false, true); | |
delay(50); | |
pinMode(RECV_PIN, INPUT); | |
M5.dis.drawpix(0, 0xf00000); | |
WiFi.mode(WIFI_STA); | |
wifiDisconnect(true); | |
while (!wifiConnect()); | |
DateTime.setTimeZone(0); | |
DateTime.begin(); | |
} | |
void loop() { | |
delay(50); | |
M5.update(); | |
showDistance(); | |
if (M5.Btn.wasPressed()) { | |
show_led = !show_led; | |
} | |
timer++; | |
if (timer >= 20) { | |
timer = 0; | |
} else { | |
return; | |
} | |
int total = 0; | |
for (int i = 0; i < AVE_LENGTH; i++) { | |
total += receiveDistance(); | |
} | |
float ave = (float)total / AVE_LENGTH; | |
Serial.println(ave); | |
bool has_cat = ave >= MIN_CAT_DISTANCE; | |
bool stabled_changed = false; | |
if (has_cat == last_has_cat) { | |
if (stable_count < MAX_STABLE_COUNT) { | |
stable_count++; | |
bool stabled = (stable_count == MAX_STABLE_COUNT); | |
stabled_changed = stabled && (has_cat != stabled_has_cat); | |
} | |
} else { | |
stable_count = 0; | |
} | |
last_has_cat = has_cat; | |
// 安定状態が変化した | |
if (stabled_changed) { | |
Serial.println("Cat state changed"); | |
// 送信する | |
post(has_cat); | |
Serial.println("Completed"); | |
stabled_has_cat = has_cat; | |
} | |
} | |
void showDistance() { | |
M5.dis.clear(); | |
if (!show_led) { | |
return; | |
} | |
int reading = analogRead(RECV_PIN); | |
int m = reading * 25 / 4095; | |
CRGB color = (reading >= MIN_CAT_DISTANCE) ? 0x00ff00 : 0x0000ff; | |
for (int i = 0; i < m; i++) { | |
M5.dis.drawpix(i, color); | |
} | |
} | |
int receiveDistance() { | |
int reading = analogRead(RECV_PIN); | |
return reading; | |
} | |
void led(bool v) { | |
M5.dis.clear(); | |
if (v) { | |
M5.dis.drawpix(0, 0xff0000); | |
} | |
} | |
void post(bool state) { | |
while (!wifiConnect()); | |
String access_token = regenerateAccessToken(); | |
if (access_token.length() > 0) { | |
postChangeRequst(access_token, state); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool wifiConnect() { | |
wifiDisconnect(true); | |
WiFi.begin(SSID, PASSWORD); | |
Serial.print("WiFi connecting"); | |
int count = 0; | |
while (WiFi.status() != WL_CONNECTED) { | |
Serial.print("."); | |
led(true); | |
delay(10); | |
led(false); | |
delay(90); | |
if (++count > 100) { | |
wifiDisconnect(true); | |
WiFi.begin(SSID, PASSWORD); | |
Serial.println(""); | |
Serial.print("reconnecting"); | |
count = 0; | |
} | |
} | |
Serial.println(" connected"); | |
return true; | |
} | |
bool wifiDisconnect(bool val) { | |
WiFi.disconnect(val); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment