-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGoProHero4.cpp
More file actions
225 lines (177 loc) · 6.53 KB
/
GoProHero4.cpp
File metadata and controls
225 lines (177 loc) · 6.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
//Library for GOPRO Hero4 silver written with the help of:
//https://github.com/KonradIT/goprowifihack/blob/master/HERO4/WifiCommands.md
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiUdp.h>
#include "GoProHero4.h"
//GOPRO MAC address used only for power on/
//You can get it with http://10.5.5.9/gp/gpControl/info
byte *GoProHero4::mac;
//GOPRO IP address. You normally never have to modify this line
const char* GoProHero4::host = "10.5.5.9"; //GoPro Hero 4 IP Address
GoProHero4::GoProHero4(char* ssid,char* passwd,byte* mac) {
//save mac address pointer
GoProHero4::mac=mac;
//init link status
link=Disconnected;
//Wifi Connect
Serial.print("Connecting to "); Serial.println(ssid);
WiFi.begin(ssid,passwd);
}
//refresh status attributes of the GoPro
void GoProHero4::updateStatus(DynamicJsonDocument GoProStatus) {
//if status array is present
if (GoProStatus.containsKey("status")) {
//update of current mode
if (GoProStatus["status"].containsKey("43")){
currentMode=(ModeValue)GoProStatus["status"]["43"].as<int>();
Serial.print("Current Mode:"); Serial.println(currentMode);
}
//update Recording Processing Status
if (GoProStatus["status"].containsKey("8")){
recordingProcessing=(RecordingProcessingState)GoProStatus["status"]["8"].as<int>();
Serial.print("Recording/Processing :"); Serial.println(recordingProcessing);
}
else Serial.println("Current Mode not found in record status");
} else Serial.println("Status record not found");
if (GoProHero4::link==GoProHero4::Connected) {
}
}
int GoProHero4::ExecGoProCmd(String GoProURL) {
//if the WIFI connection to the GoPro is not established
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi unconnected");
GoProHero4::link=GoProHero4::Disconnected;
//if it is
} else {
//if it was not before
if (GoProHero4::link!=GoProHero4::Connected) {
GoProHero4::link=GoProHero4::Connected;
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
//prepare http request
HTTPClient http;
String url = "http://"+String(GoProHero4::host)+GoProURL;
String HttpAnswer;
http.begin(url);
//execute http request
Serial.println("GET "+url);
int httpCode = http.GET();
//log http code returned
Serial.print("Http code:");Serial.println(httpCode);
//Check the returned code
//If WIFI OK but unable to connect
if (httpCode==HTTPC_ERROR_CONNECTION_REFUSED) {
//GOPRO seems to be OFF
Serial.println("No GOPRO answer, seems to be OFF");
power=Off;
//else if http request result available
} else if (httpCode > 0) {
//if HTTP OK received, GOPRO is ON
if (httpCode==HTTP_CODE_OK) power=On;
HttpAnswer = http.getString(); //Get the request response payload
Serial.println(HttpAnswer); //Print the response payload
//Parse JSON answer in case of need
if (httpCode==HTTP_CODE_OK or httpCode==HTTP_CODE_INTERNAL_SERVER_ERROR){
//allocate memory for json deserialization (with help of http://arduinojson.org/v6/assistant to compute the capacity)
DynamicJsonDocument GoProStatus(3000);
DeserializationError error = deserializeJson(GoProStatus, HttpAnswer);
//incase of error
if (error) {
Serial.print("DeserializeJson() failed: ");
Serial.println(error.c_str());
}
//in case of success, refresh GoPro status
else GoProHero4::updateStatus(GoProStatus);
}
}
http.end();
return httpCode;
}
}
bool GoProHero4::isConnected() {
//get WiFi Status
//if WIFI connection is down
if (WiFi.status()!= WL_CONNECTED){
//if connection was up
if ( link==Connected ) {
link=Disconnected;
Serial.println("Connection lost");
}
}
//else if WIFI connection is up GoPro status still disconnected
else if ( link==Disconnected ){
//update GOPRO link status
link=Connected;
Serial.println("WIFI Connected");
//refresh status (will happen only if GOPRO is On)
refreshStatus();
}
return ((bool)(link==Connected));
}
void GoProHero4::refreshStatus() {
//get Gopro Status
Serial.println("Get Status");
ExecGoProCmd("/gp/gpControl/status");
}
void GoProHero4::photoMode() {
//if video recording in progress
if((currentMode==Video) && (recordingProcessing==Active)) {
Serial.println("Stop Video");
ExecGoProCmd("/gp/gpControl/command/shutter?p=0");
//wait for end of recording before going on
delay(1000);
}
//set mode to Photo
Serial.println("Mode Photo");
ExecGoProCmd("/gp/gpControl/command/mode?p=1");
//refresh status
refreshStatus();
}
void GoProHero4::videoMode() {
//set mode to Video
Serial.println("Mode Video");
ExecGoProCmd("/gp/gpControl/command/mode?p=0");
//refresh status
refreshStatus();
}
void GoProHero4::photoCapture() {
//if mode Photo or video mode and recording Off
if ((currentMode==Video) && (recordingProcessing==NotActive)) {
Serial.println("Capture Video");
ExecGoProCmd("/gp/gpControl/command/shutter?p=1");
}
else if((currentMode==Video) && (recordingProcessing==Active)) {
Serial.println("Stop Video");
ExecGoProCmd("/gp/gpControl/command/shutter?p=0");
//wait for end of recording before going on
delay(1000);
}
else if (currentMode==Photo){
Serial.println("Capture Photo");
ExecGoProCmd("/gp/gpControl/command/shutter?p=1");
}
else {
Serial.println("Capture command not implemented in this mode");
}
//refresh status
refreshStatus();
}
bool GoProHero4::powerOn() {
//send WOL packet to the GOPRO
WiFiUDP udp;
byte preamble[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
byte i;
Serial.println("Sending WOL packet");
udp.beginPacket(GoProHero4::host,9); //sending packet at port 9,
udp.write(preamble, sizeof preamble);
udp.write(GoProHero4::mac, 6);
udp.endPacket();
//wait for GOPRO to wake up. 1 second is sometime too short
delay(1500);
//refresh status
refreshStatus();
return(power==On);
}