【mbed OS5対応バージョン】データの保存、更新、取得ができるWebサービス「milkcocoa」に接続し、データのプッシュ、送信、取得ができるライブラリです。 https://mlkcca.com/
Dependents: mbed-os-example-wifi-milkcocoa MilkcocoaOsSample_Eth MilkcocoaOsSample_ESP8266 MilkcocoaOsSample_Eth_DigitalIn
Milkcocoa.cpp@2:63228ec79756, 2017-05-02 (annotated)
- Committer:
- jksoft
- Date:
- Tue May 02 01:25:10 2017 +0000
- Revision:
- 2:63228ec79756
- Parent:
- 1:8e4149b53a8a
debug off
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jksoft | 0:0a2f634d3324 | 1 | #include "Milkcocoa.h" |
jksoft | 0:0a2f634d3324 | 2 | |
jksoft | 2:63228ec79756 | 3 | #if 0 |
jksoft | 0:0a2f634d3324 | 4 | extern RawSerial pc; |
jksoft | 0:0a2f634d3324 | 5 | |
jksoft | 0:0a2f634d3324 | 6 | #define DBG(x) x |
jksoft | 0:0a2f634d3324 | 7 | #else |
jksoft | 0:0a2f634d3324 | 8 | #define DBG(x) |
jksoft | 0:0a2f634d3324 | 9 | #endif |
jksoft | 0:0a2f634d3324 | 10 | |
jksoft | 0:0a2f634d3324 | 11 | DataElement::DataElement() { |
jksoft | 0:0a2f634d3324 | 12 | json_msg[0] = '\0'; |
jksoft | 0:0a2f634d3324 | 13 | strcpy(json_msg,"{\"params\":{"); |
jksoft | 0:0a2f634d3324 | 14 | } |
jksoft | 0:0a2f634d3324 | 15 | |
jksoft | 0:0a2f634d3324 | 16 | DataElement::DataElement(char *json_string) { |
jksoft | 0:0a2f634d3324 | 17 | json_msg[0] = '\0'; |
jksoft | 0:0a2f634d3324 | 18 | strcpy(json_msg,json_string); |
jksoft | 0:0a2f634d3324 | 19 | } |
jksoft | 0:0a2f634d3324 | 20 | |
jksoft | 0:0a2f634d3324 | 21 | void DataElement::setValue(const char *key, const char *v) { |
jksoft | 0:0a2f634d3324 | 22 | char json_string[64]; |
jksoft | 0:0a2f634d3324 | 23 | if( json_msg[strlen(json_msg)-1] != '{' ) |
jksoft | 0:0a2f634d3324 | 24 | { |
jksoft | 0:0a2f634d3324 | 25 | strcat(json_msg,","); |
jksoft | 0:0a2f634d3324 | 26 | } |
jksoft | 0:0a2f634d3324 | 27 | sprintf(json_string,"\"%s\":\"%s\"",key,v); |
jksoft | 0:0a2f634d3324 | 28 | strcat(json_msg,json_string); |
jksoft | 0:0a2f634d3324 | 29 | } |
jksoft | 0:0a2f634d3324 | 30 | |
jksoft | 0:0a2f634d3324 | 31 | void DataElement::setValue(const char *key, int v) { |
jksoft | 0:0a2f634d3324 | 32 | char json_string[64]; |
jksoft | 0:0a2f634d3324 | 33 | if( json_msg[strlen(json_msg)-1] != '{' ) |
jksoft | 0:0a2f634d3324 | 34 | { |
jksoft | 0:0a2f634d3324 | 35 | strcat(json_msg,","); |
jksoft | 0:0a2f634d3324 | 36 | } |
jksoft | 0:0a2f634d3324 | 37 | sprintf(json_string,"\"%s\":\"%d\"",key,v); |
jksoft | 0:0a2f634d3324 | 38 | strcat(json_msg,json_string); |
jksoft | 0:0a2f634d3324 | 39 | } |
jksoft | 0:0a2f634d3324 | 40 | |
jksoft | 0:0a2f634d3324 | 41 | void DataElement::setValue(const char *key, double v) { |
jksoft | 0:0a2f634d3324 | 42 | char json_string[64]; |
jksoft | 0:0a2f634d3324 | 43 | if( json_msg[strlen(json_msg)-1] != '{' ) |
jksoft | 0:0a2f634d3324 | 44 | { |
jksoft | 0:0a2f634d3324 | 45 | strcat(json_msg,","); |
jksoft | 0:0a2f634d3324 | 46 | } |
jksoft | 0:0a2f634d3324 | 47 | sprintf(json_string,"\"%s\":\"%f\"",key,v); |
jksoft | 0:0a2f634d3324 | 48 | strcat(json_msg,json_string); |
jksoft | 0:0a2f634d3324 | 49 | } |
jksoft | 0:0a2f634d3324 | 50 | |
jksoft | 0:0a2f634d3324 | 51 | char *DataElement::getString(const char *key) { |
jksoft | 0:0a2f634d3324 | 52 | static char _word[64]; |
jksoft | 0:0a2f634d3324 | 53 | char *p; |
jksoft | 0:0a2f634d3324 | 54 | int i=0; |
jksoft | 0:0a2f634d3324 | 55 | |
jksoft | 0:0a2f634d3324 | 56 | strcpy(_word , "\"\0"); |
jksoft | 0:0a2f634d3324 | 57 | strcat(_word , key ); |
jksoft | 0:0a2f634d3324 | 58 | strcat(_word , "\"" ); |
jksoft | 0:0a2f634d3324 | 59 | |
jksoft | 0:0a2f634d3324 | 60 | p = strstr( (char*)json_msg , _word ) + 2 + strlen(_word); |
jksoft | 0:0a2f634d3324 | 61 | |
jksoft | 0:0a2f634d3324 | 62 | while( (p[i] != ',')&&(p[i] != '\n')&&(p[i] != '\"') ) |
jksoft | 0:0a2f634d3324 | 63 | { |
jksoft | 0:0a2f634d3324 | 64 | _word[i] = p[i]; |
jksoft | 0:0a2f634d3324 | 65 | i++; |
jksoft | 0:0a2f634d3324 | 66 | } |
jksoft | 0:0a2f634d3324 | 67 | _word[i] = '\0'; |
jksoft | 0:0a2f634d3324 | 68 | |
jksoft | 0:0a2f634d3324 | 69 | return _word; |
jksoft | 0:0a2f634d3324 | 70 | } |
jksoft | 0:0a2f634d3324 | 71 | |
jksoft | 0:0a2f634d3324 | 72 | int DataElement::getInt(const char *key) { |
jksoft | 0:0a2f634d3324 | 73 | return atoi(getString(key)); |
jksoft | 0:0a2f634d3324 | 74 | } |
jksoft | 0:0a2f634d3324 | 75 | |
jksoft | 0:0a2f634d3324 | 76 | float DataElement::getFloat(const char *key) { |
jksoft | 0:0a2f634d3324 | 77 | return atof(getString(key)); |
jksoft | 0:0a2f634d3324 | 78 | } |
jksoft | 0:0a2f634d3324 | 79 | |
jksoft | 0:0a2f634d3324 | 80 | char *DataElement::toCharArray() { |
jksoft | 0:0a2f634d3324 | 81 | if( json_msg[strlen(json_msg)-1] != '{' ) |
jksoft | 0:0a2f634d3324 | 82 | { |
jksoft | 0:0a2f634d3324 | 83 | strcat(json_msg,"}"); |
jksoft | 0:0a2f634d3324 | 84 | } |
jksoft | 0:0a2f634d3324 | 85 | strcat(json_msg,"}"); |
jksoft | 0:0a2f634d3324 | 86 | |
jksoft | 0:0a2f634d3324 | 87 | return(json_msg); |
jksoft | 0:0a2f634d3324 | 88 | } |
jksoft | 0:0a2f634d3324 | 89 | |
jksoft | 0:0a2f634d3324 | 90 | Milkcocoa::Milkcocoa(NetworkInterface* nif, const char *host, uint16_t port, const char *_app_id, const char *client_id){ |
jksoft | 0:0a2f634d3324 | 91 | ipstack = new MQTTInterface(nif); |
jksoft | 0:0a2f634d3324 | 92 | client = new MClient(ipstack); |
jksoft | 0:0a2f634d3324 | 93 | strcpy(servername,host); |
jksoft | 0:0a2f634d3324 | 94 | portnum = port; |
jksoft | 0:0a2f634d3324 | 95 | app_id = _app_id; |
jksoft | 0:0a2f634d3324 | 96 | strcpy(_clientid,client_id); |
jksoft | 0:0a2f634d3324 | 97 | strcpy(username,"sdammy"); |
jksoft | 0:0a2f634d3324 | 98 | strcpy(password,app_id); |
jksoft | 0:0a2f634d3324 | 99 | setLoopCycle(5000); |
jksoft | 0:0a2f634d3324 | 100 | |
jksoft | 1:8e4149b53a8a | 101 | cycleThread1.start(Milkcocoa::threadStarter1,this); |
jksoft | 1:8e4149b53a8a | 102 | cycleThread2.start(Milkcocoa::threadStarter2,this); |
jksoft | 0:0a2f634d3324 | 103 | } |
jksoft | 0:0a2f634d3324 | 104 | |
jksoft | 0:0a2f634d3324 | 105 | Milkcocoa::Milkcocoa(NetworkInterface* nif, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *_session){ |
jksoft | 0:0a2f634d3324 | 106 | ipstack = new MQTTInterface(nif); |
jksoft | 0:0a2f634d3324 | 107 | client = new MClient(ipstack); |
jksoft | 0:0a2f634d3324 | 108 | strcpy(servername,host); |
jksoft | 0:0a2f634d3324 | 109 | portnum = port; |
jksoft | 0:0a2f634d3324 | 110 | app_id = _app_id; |
jksoft | 0:0a2f634d3324 | 111 | strcpy(_clientid,client_id); |
jksoft | 0:0a2f634d3324 | 112 | strcpy(username,_session); |
jksoft | 0:0a2f634d3324 | 113 | strcpy(password,app_id); |
jksoft | 0:0a2f634d3324 | 114 | setLoopCycle(5000); |
jksoft | 0:0a2f634d3324 | 115 | |
jksoft | 1:8e4149b53a8a | 116 | cycleThread1.start(Milkcocoa::threadStarter1,this); |
jksoft | 1:8e4149b53a8a | 117 | cycleThread2.start(Milkcocoa::threadStarter2,this); |
jksoft | 0:0a2f634d3324 | 118 | } |
jksoft | 0:0a2f634d3324 | 119 | |
jksoft | 0:0a2f634d3324 | 120 | Milkcocoa* Milkcocoa::createWithApiKey(NetworkInterface* nif, const char *host, uint16_t port, const char *_app_id, const char *client_id, char *key, char *secret) { |
jksoft | 0:0a2f634d3324 | 121 | char session[60]; |
jksoft | 0:0a2f634d3324 | 122 | sprintf(session, "k%s:%s", key, secret); |
jksoft | 0:0a2f634d3324 | 123 | return new Milkcocoa(nif, host, port, _app_id, client_id, session); |
jksoft | 0:0a2f634d3324 | 124 | } |
jksoft | 0:0a2f634d3324 | 125 | |
jksoft | 0:0a2f634d3324 | 126 | void Milkcocoa::connect() { |
jksoft | 0:0a2f634d3324 | 127 | |
jksoft | 0:0a2f634d3324 | 128 | if(client->isConnected()) |
jksoft | 0:0a2f634d3324 | 129 | return; |
jksoft | 0:0a2f634d3324 | 130 | |
jksoft | 0:0a2f634d3324 | 131 | if(client->connect(servername, portnum)!=0) { |
jksoft | 0:0a2f634d3324 | 132 | DBG(pc.printf("Network connect err\r\n");) |
jksoft | 0:0a2f634d3324 | 133 | return; |
jksoft | 0:0a2f634d3324 | 134 | } |
jksoft | 0:0a2f634d3324 | 135 | |
jksoft | 0:0a2f634d3324 | 136 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; |
jksoft | 0:0a2f634d3324 | 137 | data.keepAliveInterval = 20; |
jksoft | 0:0a2f634d3324 | 138 | data.cleansession = 1; |
jksoft | 0:0a2f634d3324 | 139 | data.MQTTVersion = 4; |
jksoft | 0:0a2f634d3324 | 140 | data.clientID.cstring = _clientid; |
jksoft | 0:0a2f634d3324 | 141 | data.username.cstring = username; |
jksoft | 0:0a2f634d3324 | 142 | data.password.cstring = password; |
jksoft | 0:0a2f634d3324 | 143 | |
jksoft | 0:0a2f634d3324 | 144 | if (client->connect(data) != 0) { |
jksoft | 0:0a2f634d3324 | 145 | DBG(pc.printf("Milkcocoa connect err\r\n");) |
jksoft | 0:0a2f634d3324 | 146 | return; |
jksoft | 0:0a2f634d3324 | 147 | } |
jksoft | 0:0a2f634d3324 | 148 | |
jksoft | 0:0a2f634d3324 | 149 | } |
jksoft | 0:0a2f634d3324 | 150 | |
jksoft | 0:0a2f634d3324 | 151 | bool Milkcocoa::push(const char *path, DataElement dataelement) { |
jksoft | 0:0a2f634d3324 | 152 | milkcocoa_message_t *message = message_box.alloc(); |
jksoft | 0:0a2f634d3324 | 153 | char *buf; |
jksoft | 0:0a2f634d3324 | 154 | |
jksoft | 0:0a2f634d3324 | 155 | if(message == NULL) return false; |
jksoft | 0:0a2f634d3324 | 156 | |
jksoft | 0:0a2f634d3324 | 157 | sprintf(message->topic, "%s/%s/push", app_id, path); |
jksoft | 0:0a2f634d3324 | 158 | buf = dataelement.toCharArray(); |
jksoft | 0:0a2f634d3324 | 159 | strcpy(message->message , buf); |
jksoft | 0:0a2f634d3324 | 160 | |
jksoft | 0:0a2f634d3324 | 161 | osStatus stat = message_box.put(message); |
jksoft | 0:0a2f634d3324 | 162 | |
jksoft | 0:0a2f634d3324 | 163 | if( stat != osOK ) return false; |
jksoft | 0:0a2f634d3324 | 164 | |
jksoft | 0:0a2f634d3324 | 165 | return true; |
jksoft | 0:0a2f634d3324 | 166 | } |
jksoft | 0:0a2f634d3324 | 167 | |
jksoft | 0:0a2f634d3324 | 168 | bool Milkcocoa::send(const char *path, DataElement dataelement) { |
jksoft | 0:0a2f634d3324 | 169 | milkcocoa_message_t *message = message_box.alloc(); |
jksoft | 0:0a2f634d3324 | 170 | char *buf; |
jksoft | 0:0a2f634d3324 | 171 | |
jksoft | 0:0a2f634d3324 | 172 | if(message == NULL) return false; |
jksoft | 0:0a2f634d3324 | 173 | |
jksoft | 0:0a2f634d3324 | 174 | sprintf(message->topic, "%s/%s/send", app_id, path); |
jksoft | 0:0a2f634d3324 | 175 | buf = dataelement.toCharArray(); |
jksoft | 0:0a2f634d3324 | 176 | strcpy(message->message , buf); |
jksoft | 0:0a2f634d3324 | 177 | |
jksoft | 0:0a2f634d3324 | 178 | osStatus stat = message_box.put(message); |
jksoft | 0:0a2f634d3324 | 179 | |
jksoft | 0:0a2f634d3324 | 180 | if( stat != osOK ) return false; |
jksoft | 0:0a2f634d3324 | 181 | |
jksoft | 0:0a2f634d3324 | 182 | return true; |
jksoft | 0:0a2f634d3324 | 183 | } |
jksoft | 0:0a2f634d3324 | 184 | |
jksoft | 0:0a2f634d3324 | 185 | void Milkcocoa::loop() { |
jksoft | 0:0a2f634d3324 | 186 | connect(); |
jksoft | 0:0a2f634d3324 | 187 | client->yield(RECV_TIMEOUT); |
jksoft | 0:0a2f634d3324 | 188 | } |
jksoft | 0:0a2f634d3324 | 189 | |
jksoft | 0:0a2f634d3324 | 190 | bool Milkcocoa::on(const char *path, const char *event, GeneralFunction cb) { |
jksoft | 0:0a2f634d3324 | 191 | MilkcocoaSubscriber *sub = new MilkcocoaSubscriber(cb); |
jksoft | 0:0a2f634d3324 | 192 | sprintf(sub->topic, "%s/%s/%s", app_id, path, event); |
jksoft | 0:0a2f634d3324 | 193 | |
jksoft | 0:0a2f634d3324 | 194 | if (client->subscribe(sub->topic, MQTT::QOS0, cb) != 0) { |
jksoft | 0:0a2f634d3324 | 195 | DBG(pc.printf("Milkcocoa subscribe err\r\n");) |
jksoft | 0:0a2f634d3324 | 196 | return false; |
jksoft | 0:0a2f634d3324 | 197 | } |
jksoft | 0:0a2f634d3324 | 198 | for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) { |
jksoft | 0:0a2f634d3324 | 199 | if (milkcocoaSubscribers[i] == sub) { |
jksoft | 0:0a2f634d3324 | 200 | return false; |
jksoft | 0:0a2f634d3324 | 201 | } |
jksoft | 0:0a2f634d3324 | 202 | } |
jksoft | 0:0a2f634d3324 | 203 | for (int i=0; i<MILKCOCOA_SUBSCRIBERS; i++) { |
jksoft | 0:0a2f634d3324 | 204 | if (milkcocoaSubscribers[i] == 0) { |
jksoft | 0:0a2f634d3324 | 205 | milkcocoaSubscribers[i] = sub; |
jksoft | 0:0a2f634d3324 | 206 | return true; |
jksoft | 0:0a2f634d3324 | 207 | } |
jksoft | 0:0a2f634d3324 | 208 | } |
jksoft | 0:0a2f634d3324 | 209 | return true; |
jksoft | 0:0a2f634d3324 | 210 | } |
jksoft | 0:0a2f634d3324 | 211 | |
jksoft | 0:0a2f634d3324 | 212 | void Milkcocoa::setLoopCycle(int cycle) { |
jksoft | 0:0a2f634d3324 | 213 | loop_cycle = cycle; |
jksoft | 0:0a2f634d3324 | 214 | } |
jksoft | 0:0a2f634d3324 | 215 | |
jksoft | 0:0a2f634d3324 | 216 | void Milkcocoa::start() { |
jksoft | 1:8e4149b53a8a | 217 | cycleThread1.signal_set(START_THREAD); |
jksoft | 1:8e4149b53a8a | 218 | cycleThread2.signal_set(START_THREAD); |
jksoft | 0:0a2f634d3324 | 219 | } |
jksoft | 0:0a2f634d3324 | 220 | |
jksoft | 1:8e4149b53a8a | 221 | void Milkcocoa::cycle_Thread1(void) { |
jksoft | 1:8e4149b53a8a | 222 | cycleThread1.signal_wait(START_THREAD); |
jksoft | 0:0a2f634d3324 | 223 | while(1) { |
jksoft | 0:0a2f634d3324 | 224 | Timer timer; |
jksoft | 0:0a2f634d3324 | 225 | timer.start(); |
jksoft | 0:0a2f634d3324 | 226 | connect(); |
jksoft | 1:8e4149b53a8a | 227 | |
jksoft | 1:8e4149b53a8a | 228 | client->yield(RECV_TIMEOUT); |
jksoft | 0:0a2f634d3324 | 229 | |
jksoft | 1:8e4149b53a8a | 230 | int sub_time = loop_cycle - timer.read(); |
jksoft | 1:8e4149b53a8a | 231 | if( sub_time > 0 ){ |
jksoft | 1:8e4149b53a8a | 232 | Thread::wait(sub_time); |
jksoft | 1:8e4149b53a8a | 233 | } |
jksoft | 1:8e4149b53a8a | 234 | timer.stop(); |
jksoft | 1:8e4149b53a8a | 235 | } |
jksoft | 1:8e4149b53a8a | 236 | } |
jksoft | 1:8e4149b53a8a | 237 | void Milkcocoa::cycle_Thread2(void) { |
jksoft | 1:8e4149b53a8a | 238 | cycleThread2.signal_wait(START_THREAD); |
jksoft | 1:8e4149b53a8a | 239 | while(1) { |
jksoft | 1:8e4149b53a8a | 240 | |
jksoft | 0:0a2f634d3324 | 241 | osEvent evt = message_box.get(); |
jksoft | 0:0a2f634d3324 | 242 | if (evt.status == osEventMail) { |
jksoft | 0:0a2f634d3324 | 243 | milkcocoa_message_t *message = (milkcocoa_message_t*)evt.value.p; |
jksoft | 0:0a2f634d3324 | 244 | MQTT::Message mq_message; |
jksoft | 0:0a2f634d3324 | 245 | |
jksoft | 0:0a2f634d3324 | 246 | if(message == NULL) break; |
jksoft | 0:0a2f634d3324 | 247 | |
jksoft | 0:0a2f634d3324 | 248 | mq_message.qos = MQTT::QOS0; |
jksoft | 0:0a2f634d3324 | 249 | mq_message.retained = 0; |
jksoft | 0:0a2f634d3324 | 250 | mq_message.dup = false; |
jksoft | 0:0a2f634d3324 | 251 | mq_message.payload = (void*)message->message; |
jksoft | 0:0a2f634d3324 | 252 | mq_message.payloadlen = strlen(message->message); |
jksoft | 0:0a2f634d3324 | 253 | |
jksoft | 0:0a2f634d3324 | 254 | client->publish(message->topic, mq_message); |
jksoft | 0:0a2f634d3324 | 255 | |
jksoft | 0:0a2f634d3324 | 256 | message_box.free(message); |
jksoft | 1:8e4149b53a8a | 257 | } |
jksoft | 1:8e4149b53a8a | 258 | Thread::wait(1000); |
jksoft | 0:0a2f634d3324 | 259 | } |
jksoft | 0:0a2f634d3324 | 260 | } |
jksoft | 0:0a2f634d3324 | 261 | |
jksoft | 1:8e4149b53a8a | 262 | void Milkcocoa::threadStarter1(void const *p) { |
jksoft | 0:0a2f634d3324 | 263 | Milkcocoa *instance = (Milkcocoa*)p; |
jksoft | 1:8e4149b53a8a | 264 | instance->cycle_Thread1(); |
jksoft | 1:8e4149b53a8a | 265 | } |
jksoft | 1:8e4149b53a8a | 266 | void Milkcocoa::threadStarter2(void const *p) { |
jksoft | 1:8e4149b53a8a | 267 | Milkcocoa *instance = (Milkcocoa*)p; |
jksoft | 1:8e4149b53a8a | 268 | instance->cycle_Thread2(); |
jksoft | 0:0a2f634d3324 | 269 | } |
jksoft | 0:0a2f634d3324 | 270 | |
jksoft | 0:0a2f634d3324 | 271 | MilkcocoaSubscriber::MilkcocoaSubscriber(GeneralFunction _cb) { |
jksoft | 0:0a2f634d3324 | 272 | cb = _cb; |
jksoft | 0:0a2f634d3324 | 273 | } |
jksoft | 0:0a2f634d3324 | 274 |