Giter VIP home page Giter VIP logo

esp8266mqttclient's Introduction

MQTT Client library for ESP8266 Arduino

This is MQTT client library for ESP8266, using mqtt_msg package from MQTT client library for Contiki and use for ESP8266 NON-OS SDK esp_mqtt

Features:

  • Support subscribing, publishing, authentication, will messages, keep alive pings and all 3 QoS levels (it should be a fully functional client).

Requirements

  • ESP8266WiFi
  • WiFiClientSecure

Status

  • Support 3 type of qos (0, 1, 2) and outbox
  • only mqtt over TCP

MQTT URI Scheme

  • mqtt://[username][:password@]hostname[:port][#clientId]
    • mqtt for MQTT over TCP
    • ws for MQTT over Websocket
  • Example:
    • Full mqtt://username:[email protected]:1883#my_client_id
    • Websocket ws://username:[email protected]:1883/mqtt#my_client_id
    • Minimal mqtt://test.mosquitto.org, with user, pass = NULL, port = 1883, client id = "ESP_" + ESP.getChipId()

API

Setup

  • bool begin(String uri);
  • bool begin(String uri, int keepalive, bool clean_session);
  • bool begin(String uri, LwtOptions lwt);
  • bool begin(String uri, LwtOptions lwt, int keepalive, bool clean_session)

Events

  • void onConnect(THandlerFunction fn);
  • void onDisconnect(THandlerFunction fn);
  • void onSubscribe(THandlerFunction_PubSub fn);
  • void onPublish(THandlerFunction_PubSub fn);
  • void onData(THandlerFunction_Data fn);

Pub/Sub

  • int subscribe(String topic);
  • int subscribe(String topic, uint8_t qos);
  • int publish(String topic, String data);
  • int publish(String topic, String data, int qos, int retain);

License

Copyright (c) 2016 Tuan PM (https://twitter.com/tuanpmt) ESP8266 port (c) 2016 Ivan Grokhotkov ([email protected])

License Apache License

esp8266mqttclient's People

Contributors

andreas-ibm avatar cakesifu avatar hieucdtspk avatar samvik avatar tuanpmt avatar unimatrix099 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp8266mqttclient's Issues

error: request for member 'read' in 'source', which is of non-class type 'unsigned char*'

I tried to comply a sketch that i wrote based on the examples, but something went wrong. Here are my sketch:

#include <ESP8266WiFi.h>
#include <ESP8266MQTTClient.h>
MQTTClient mqtt;

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "xxx"
#define WLAN_PASS       "xxx"

/************************* Adafruit.io Setup *********************************/

#define SERVER      "xxx"
#define PORT        "xxx"
#define USERNAME    "xxx"
#define PASS        "xxx"
#define CLIENT_ID   "ESP01" 


#define LWT             {.lwtTopic = "xxx", .lwtMsg = "xxx", .lwtQos = 0, .lwtRetain = 0}
#define KEEP_ALIVE      60000
#define CLEAN_SESSION   1

void setup() {
  WiFi.mode(WIFI_STA);
  Serial.begin(57600);
  Wifi_begin();


  //topic, data, data is continuing
  mqtt.onData([](String topic, String data, bool cont) {
    Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
    mqtt.unSubscribe("/qos0");
  });

  mqtt.onSubscribe([](int sub_id) {
    Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
    mqtt.publish("/qos0", "qos0", 0, 0);
  });
  mqtt.onConnect([]() {
    Serial.printf("MQTT: Connected\r\n");
    Serial.printf("Subscribe id: %d\r\n", mqtt.subscribe("/qos0", 0));
//    mqtt.subscribe("/qos1", 1);
//    mqtt.subscribe("/qos2", 2);
  });


  mqtt.begin("mqtt://" USERNAME ":" PASS "@" SERVER ":" PORT "#" CLIENT_ID , LWT, KEEP_ALIVE, CLEAN_SESSION);
}

void loop() { 
  mqtt.handle();


}


void Wifi_begin() {
  // Connect to WiFi access point.
  Serial.println();
  Serial.print(F("Connecting to "));
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());
}

and this is the error message:
sketch

Am I missing or misunderstanding something?

Support to MQTT, websockets, TSL

Hi,

I test the code "MQTTOverWebsocketClient" and this works fine on ports 8080 and 8090 of "test.mosquitto.org" (without encryption)

But I need to use MQTT over Websockets with TLS and authentication.
I'm using the broker "test.mosquitto.org", port 8091, to test this. But I'm not succeeding.

How can I adapt the code to implement TLS?

I try add (the same of example "MQTTSecureClient") :

String fingerprint = "7E 36 22 01 F9 7E 99 2F C5 DB 3D BE AC 48 67 5B 5D 47 94 D2";

and add :

  configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");

  mqtt.onSecure([](WiFiClientSecure *client, String host) {
        Serial.printf("Verify: %s\r\n", host.c_str());
        return client->verify(fingerprint.c_str(), host.c_str());
    });

but the connection is not established.

can someone help me find a solution to implement MQTT over WebSockets with TLS?

Thank you.
Jorge

publish not send,but no error show

Hi, I am appreciate your Project ,so I want do some contribution, to feedback some question I meet.
I git clone this project to control my ESP8266 board,
if only use mqtt.onData event,it work fine,
but I add a publish call in onData function, the publish not send, other Subscriber can not receive which topic publish. the board also not jump exception.

and the mqtt.onPublish function also not call, I am confused with this, am i use wrong?

  mqtt.onData([](String topic, String data, bool cont) {
    Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
    //mqtt.unSubscribe("/qos0");
    Serial.printf("%s \r\n", data.c_str());
    if (data.compareTo("1") == 0 || data.compareTo("ON") == 0)
    {
      digitalWrite(PIN_RELAY1, HIGH );
      digitalWrite(PIN_RELAY2, HIGH );
      mqtt.publish("homeassistant/switch/irrigation/state", "ON", 0, 0); //**actually not work**
      //mqtt.publish("123", "ON", 0, 0);
      digitalWrite(LED_BUILTIN, LOW); //LED ON
      //delay(200);

    }
    //delay(1000); //delay 1 second
    if (data.compareTo("0") == 0 || data.compareTo("OFF") == 0)
    {
      digitalWrite(PIN_RELAY1, LOW );
      digitalWrite(PIN_RELAY2, LOW );
      mqtt.publish("homeassistant/switch/irrigation/state", "OFF", 0, 0); // **actually not work**
      //mqtt.publish("123", "OFF" , 0, 0);
      digitalWrite(LED_BUILTIN, HIGH); //LED OUT
    }
  });
  Serial.println("mqtt OnSub: ");
  mqtt.onSubscribe([](int sub_id) {
    Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
    mqtt.publish("/qos0", "qos0", 0, 0);                                           // **but this publish WORK FINE!   i am so confused** 
  });

  Serial.println("mqtt OnPub: ");
  mqtt.onPublish([](int pub_id) {                                                   //**this function never call, i don't know why**
    Serial.printf("onPublish return id: %d \r\n", pub_id);
  });

So i use another esp8266 mqtt client PubSubClient, and it work fine.

void callback(char* topic, byte* payload, unsigned int length) {//call back function with PubSubClient
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  String s = "";
  for (int i = 0; i < length; i++) {
    s = s + (char)payload[i];
  }
  Serial.println(s);
  // Switch on the LED if an 1 was received as first character
  if (s == "ON") {
    digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
    client.publish("homeassistant/switch/irrigation/state", (char*)s.c_str());
  } else {
    digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
    client.publish("homeassistant/switch/irrigation/state", (char*)s.c_str());
  }
}

Missing disconnect packet option.

Hi,

I see there's no option for sending a disconnect packet to broker. This can be useful for sharing same broker connections among clients.

My 2 cents:

In ESP8266MQTTClient.cpp add:

bool MQTTClient::disconnect(void)
{
sendDisconnect();
free(_state.in_buffer);
free(_state.out_buffer);
LOG("[MQTT_client] disconnect!\n");
return true;
}

void MQTTClient::sendDisconnect()
{
_state.outbound_message = mqtt_msg_disconnect(&_state.connection);
_state.pending_msg_type = mqtt_get_type(_state.outbound_message->data);
_state.pending_msg_id = mqtt_get_id(_state.outbound_message->data,
_state.outbound_message->length);
LOG("Sending MQTT_MSG_TYPE_DISCONNECT\r\n");
_transportTraits->write(_tcp.get(), _state.outbound_message->data,
_state.outbound_message->length);
}

And their corresponding function declarations in header file:

bool disconnect();
void sendDisconnect();

Rgds,

Richard

onDisconnect not defined

Just forgot to add:
void MQTTClient::onDisconnect(THandlerFunction fn) { _disconnected_cb = fn; }
in file ESP8266MQTTClient.cpp

Expose "connected()"

It could be great to change the "connected()" member to public.
Currently, I have to save the state of the client using the connected and disconnected callbacks.

User exception (panic/abort/assert)

Arduino IDE 1.8.12
Esp8266 Framework 2.7.0
ESP8266MQTTClient 1.0.5

Run Sample MQTTClient.ino

#include <ESP8266MQTTClient.h>
#include <ESP8266WiFi.h>
MQTTClient mqtt;

void setup() {
  Serial.begin(115200);
//  WiFi.begin("ssid", "pass");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  //topic, data, data is continuing
  mqtt.onData([](String topic, String data, bool cont) {
    Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
    mqtt.unSubscribe("/qos0");
  });

  mqtt.onSubscribe([](int sub_id) {
    Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
    mqtt.publish("/qos0", "qos0", 0, 0);
  });
  mqtt.onConnect([]() {
    Serial.printf("MQTT: Connected\r\n");
    Serial.printf("Subscribe id: %d\r\n", mqtt.subscribe("/qos0", 0));
//    mqtt.subscribe("/qos1", 1);
//    mqtt.subscribe("/qos2", 2);
  });

  mqtt.begin("mqtt://test.mosquitto.org:1883");
//  mqtt.begin("mqtt://test.mosquitto.org:1883", {.lwtTopic = "hello", .lwtMsg = "offline", .lwtQos = 0, .lwtRetain = 0});
//  mqtt.begin("mqtt://user:[email protected]:1883");
//  mqtt.begin("mqtt://user:[email protected]:1883#clientId");

}

void loop() {
  mqtt.handle();
}
User exception (panic/abort/assert)
Abort called

>>>stack>>>

ctx: cont
sp: 3fffff00 end: 3fffffc0 offset: 0000
3fffff00:  3fffdad0 3ffee7d8 00000020 401009b7  
3fffff10:  000000fe 00000000 00000000 00000000  
3fffff20:  00000000 00000000 00000000 00000080  
3fffff30:  3ffef6a0 0000001d 00000001 3ffee988  
3fffff40:  3fffdad0 00000000 3ffee7d8 4020723e  
3fffff50:  00000000 40201e94 80ffff90 40207250  
3fffff60:  00000000 8000001e 3fffff90 40211048  
3fffff70:  3fffdad0 00000000 3ffee7d8 401000dc  
3fffff80:  3fffdad0 00000000 3ffee7d8 40202b01  
3fffff90:  3ffef800 00000000 3ffee948 40201ed8  
3fffffa0:  feefeffe 00000000 3ffee948 40206ea8  
3fffffb0:  feefeffe feefeffe 3ffe84e4 40100c79  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

mqtt.begin is not working

mqtt.begin is not working

MQTTClient mqtt;
mqtt.begin("mqtt://test.mosquitto.org:1883");

Hence following command goes to infinite loop. & produces stack
mqtt.handle();

so I added a Boolean flag onConnect() command &

boolean flag = true;
…
mqtt.onConnect([]() {
   ….  ;
   flag=false;
});
…..
void loop()
{
   if(!flag);
   {
    …
    mqtt.handle();
   }
   else
   {
      Serial.println("Mqtt not connected...");
      delay(5000);
   }
}

### stack_traced

Decoding 12 results
0x4010020c: _umm_free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1295
0x401009e8: free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1755
0x402069f8: axTLS::WiFiClientSecure::stop() at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\libraries\ESP8266WiFi\src/WiFiClientSecureAxTLS.cpp line 312 (discriminator 1)
0x40206a14: _GLOBAL__sub_I__ZN7BearSSL16WiFiClientSecure14_bearssl_stackE at WiFiClientSecureBearSSL.cpp line ?
0x4010020c: umm_free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1295
0x401009e8: free at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266\umm_malloc/umm_malloc.c line 1755
0x40207085: MQTTClient::begin(String, LwtOptions, int, bool) at C:\Users\Amit Suani\Documents\Arduino\libraries\ESP8266MQTTClient\src/ESP8266MQTTClient.cpp line 275
0x40203d59: ArduinoJson::Internals::JsonParser ::Reader, ArduinoJson::Internals::StringWriter >::eat(char) at C:\Users\Amit Suani\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/JsonParser.hpp line 42
: (inlined by) ArduinoJson::Internals::JsonParser ::Reader, ArduinoJson::Internals::StringWriter >::parseObject() at C:\Users\Amit Suani\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/JsonParserImpl.hpp line 94
0x40204139: ArduinoJson::Internals::FloatParts ::FloatParts(float) at C:\Users\Amit Suani\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Deserialization/../Serialization/../Serialization/FloatParts.hpp line 34
0x40203550: postTransmission() at D:\php\Modbus Master\mqttclient_esp8266/mqttclient_esp8266.ino line 53
0x40207264: MQTTClient::deliverPublish(unsigned char*) at C:\Users\Amit Suani\Documents\Arduino\libraries\ESP8266MQTTClient\src/ESP8266MQTTClient.cpp line 275
-0x40100a49:
cont_wrapper at C:\Users\Amit Suani\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.4.2\cores\esp8266/cont.S line 81

Compilation error

Hello,

I was trying to test your library and got a compilation error. I tested with your 'MQTTSecureClient.ino' example.

Full Error Log:
ESP8266MQTTClient error log.txt

And I tried compiling only the library with no MQTT functions, and had the same error.

WDT reset

I was getting a constant WDT reset in my application due an endless loop in the function processRead(). There were two problems: an invalid message type (0) following a MQTT_MSG_TYPE_PINGRESP and length = 0 on MQTT_MSG_TYPE_PINGRESP. I don´t know what´s causing that conditions, but the function implementation can lead to an endless loop in case of an unexpected message content. I’m not sure, but I believe that the package may be discarded when a ping response is received. I also believe that´s important to limit the number of times that the loop can be performed. I don´t know if 10 times is enough, but it´s working for me.
To fix, I changed the code (bold) as bellow:

int MQTTClient::processRead()
{
**// change begin aonm
   #define MAXREADRETRY 10   // limit of read retries 
   int retry = 0;            // count read retries
// change end aonm**
*
*
*
        case MQTT_MSG_TYPE_PINGRESP:
            LOG("MQTT_MSG_TYPE_PINGRESP\r\n");
            // Ignore
**// change begin aonm
           return 0;   //discard remaining data
// change end aonm**
            break;
**// change begin aonm
        default: // Trap invalid message types
           LOG("Invalid message type %i\r\n", msg_type);
           return 0;
// change end aonm**
    }
    if(_state.message_length < _state.message_length_read) {
        _state.message_length_read -= _state.message_length;
        _state.in_buffer += _state.message_length;
**// change begin aonm
        retry++;
        if (retry > MAXREADRETRY) {
           return 0;
           }
// change end aonm**
        goto PROCESS_READ_AGAIN;
    }
    return 1;
}


Possible error in out_buffer free memory

Hi, I see in ESP8266MQTTClient.cpp the following memory allocations for in and out buffers:

_state.in_buffer = (uint8_t *)malloc(DEFAULT_MQTT_BUFFER_SIZE_BYTES);
if(_state.in_buffer == NULL) {
    LOG("Not enought memory\r\n");
    return false;
}
_state.in_buffer_length = DEFAULT_MQTT_BUFFER_SIZE_BYTES;
_state.out_buffer = (uint8_t *)malloc(DEFAULT_MQTT_BUFFER_SIZE_BYTES);
if(_state.in_buffer == NULL) {
    free(_state.in_buffer);
    LOG("Not enought memory\r\n");
    return false;
}

I believe the last check over in_buffer should be done over out_buffer, and also both mallocs() should be freed. Please correct me if i'm wrong...

Thanks, rgds,

Richard

Properly Setting up Last Will Message

In example:
https://github.com/tuanpmt/ESP8266MQTTClient/blob/master/examples/MQTTClient/MQTTClient.ino#L32

The last will message is set up without referring to the keepalive argument as specified in:
https://github.com/tuanpmt/ESP8266MQTTClient/blob/master/src/ESP8266MQTTClient.cpp#L72

The example should probably be changed to include the keepalive (& cleansession), so predictable behaviour can be expected with the last will messages. Otherwise, the last will msg seems to be sent and printed in the topic before any other messages, whenever the connection is created.

problem Mqtt client ssl

hello
i have used this libray but the esp8266 go to crash.
can I help me please?

this is the code

`#include <ESP8266MQTTClient.h>
#include <ESP8266WiFi.h>

MQTTClient mqtt;
String fingerprint = "‎finger print ";

String host = "192.168.1.227";

// WiFi card example
char ssid[] = "gdfgdfgg"; // your SSID
char pass[] = "gfdgdfggdfgfdgdgfdgfdgd"; // your SSID Password

void setup() {
Serial.begin(115200);
WiFi.begin(ssid,pass );

while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
}

mqtt.onSecure([](WiFiClientSecure *client, String host) {
    Serial.printf("Verify: %s\r\n", host.c_str());
    return client->verify(fingerprint.c_str(), host.c_str());
});

//topic, data, data is continuing
mqtt.onData([](String topic, String data, bool cont) {
    Serial.printf("Data received, topic: %s, data: %s\r\n", topic.c_str(), data.c_str());
    mqtt.unSubscribe("/qos0");
});

mqtt.onSubscribe([](int sub_id) {
    Serial.printf("Subscribe topic id: %d ok\r\n", sub_id);
    mqtt.publish("/qos0", "qos0", 0, 0);
});
mqtt.onConnect([]() {
    Serial.printf("MQTT: Connected\r\n");
    mqtt.subscribe("/qos0", 0);
});

mqtt.begin("mqtts://davide:[email protected]:8883" , {.lwtTopic = "hello", .lwtMsg = "offline", .lwtQos = 0, .lwtRetain = 0});
//mqtt.begin("mqtts://test.mosquitto.org:8883", {.lwtTopic = "hello", .lwtMsg = "offline", .lwtQos = 0, .lwtRetain = 0});
//mqtt.begin("mqtts://user:[email protected]:8883");
//mqtt.begin("mqtts://user:[email protected]:8883#clientId");

}

void loop() {
mqtt.handle();`

and this the error log

`Panic C:\Users\davide\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266\abi.cpp:92 __throw_bad_function_call

ctx: cont
sp: 3fff0870 end: 3fff0a90 offset: 01b0

stack>>>
3fff0a20: 00000000 00000000 00000000 40206098
3fff0a30: feefeffe 3ffef60c 00000000 40206710
3fff0a40: 00000000 00000000 3ffef60c 4020385d
3fff0a50: 00000000 00000000 3ffef60c 40203c3d
3fff0a60: 00000000 00000000 3ffefa5d 40203048
3fff0a70: feefeffe 00000000 3ffefa5d 402068ac
3fff0a80: feefeffe feefeffe 3ffefa70 4010070c
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v0c897c37
~ld`

thanks in advantage.

Davide

Crash with data len: 0

Just tried a very simple ESP8266 sketch, subscribing to "#", and using MQTT.fx to publish topic "Hello", with an empty payload. It reliably crashes out just after the LOG statement in ESP8266MQTTClient.cpp line 344.

Running on Lolin D1 Mini, ESP8266 libraries 2.4.2.

ws communication headers are compared case sensitive

Http header names are not case sensitive, bool MQTTWSTraits::connect(WiFiClient* clientIn, const char* host, int port, const char *path) does a case sensitive coparison of the headers (temp.startsWith("upgrade: websocket").
If a client sends the header in different casing as expected, the websocket connection will fail.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.