//http://homieiot.github.io/homie-esp8266/docs/develop/configuration/json-configuration-file/ //curl -X PUT http://homie.config/config -d @config.json --header "Content-Type: application/json" /*Example data/homie/config.json { "name": "geraet", "device_id": "geraet", "wifi": { "ssid": "blafoo", "password": "password" }, "mqtt": { "host": "mqttbrokerhostname", "port": 1883, "auth": false }, "ota": { "enabled": false } } */ //3M #include #include #include HomieNode homieNode("lamp", "lamp"); //id, type #define PIN_SR_DATA D5 #define PIN_SR_LTCH D6 #define PIN_SR_CLOCK D7 #define OUTPUTS 6 long lastTickMillis; uint8_t out[OUTPUTS]; long lastChange=0; #define STANDBYTIME 5000 //time in ms after lamps switch off if nothing happened boolean standby=false; #define MAXONTIME 1000 //maximum time in ms a lamp should be turned on (for lampoffmillis value) long lampoffmillis[OUTPUTS]; //time (millis()) at which lamp should turn off uint16_t last_data=0; void setup() { pinMode(PIN_SR_DATA, OUTPUT); pinMode(PIN_SR_LTCH, OUTPUT); pinMode(PIN_SR_CLOCK, OUTPUT); shiftRelais(0); Serial.begin(115200); Serial.println(); Homie_setFirmware("lichtorgel", "1.0.0"); Homie.setLoopFunction(loopHandler); homieNode.advertiseRange("duration", 0, OUTPUTS - 1).settable(onSetLamp); // lichtorgel/lamp/duration_n/set Homie.setup(); ArduinoOTA.setHostname("lichtorgel"); /*ArduinoOTA.onStart([]() { }); ArduinoOTA.onEnd([]() { }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { strip.setPixelColor(progress / (total / NUMPIXELS), strip.Color(100, 0, 0)); strip.show(); });*/ ArduinoOTA.begin(); } void loop() { Homie.loop(); ArduinoOTA.handle(); } void loopHandler() { long loopmillis=millis(); uint16_t data=0; for (uint8_t i=0; iloopmillis){ //turn lamp on if offtime is above current time data|=1<=STANDBYTIME && !standby){ Serial.println("Standby"); data=0; shiftRelais(0); standby=true; } if (data!=last_data){ //output changed shiftRelais(mapData(data)); printBinary(data); lastChange=loopmillis; last_data=data; } /* int packetSize = Udp.parsePacket(); if (packetSize) { // receive incoming UDP packets Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort()); int len = Udp.read(incomingPacket, 255); if (len > 0) { incomingPacket[len] = 0; } uint16_t data=incomingPacket[0]<<8 | incomingPacket[1]; Serial.printf("UDP packet contents: %s\n", incomingPacket); printBinary(data); printBinary(mapData(data)); shiftRelais(mapData(data)); lastChange=millis(); standby=false; }*/ } void printBinary(uint16_t value){ for(int i = 15; i >=0; i--) { Serial.print((value & (1 << ((byte)i) )) ? 1 : 0); //Serial.print(!!(value & (1 << i))); //this should also work } Serial.println(); } uint16_t mapData(uint16_t x){ //because shift register pinout is different from actual outlet connection numbering uint16_t d=0; d|=moveByte(x,0,1); d|=moveByte(x,1,2); d|=moveByte(x,2,3); d|=moveByte(x,3,4); d|=moveByte(x,4,5); d|=moveByte(x,5,6); d|=moveByte(x,6,7); d|=moveByte(x,7,0); return d; } uint16_t moveByte(uint16_t x,uint8_t from,uint8_t to){ //example: x=00110101 from=2 to=0 -> 00000001 return ((x&_BV(from))>0) ? _BV(to):0; } void shiftRelais(uint16_t data) { digitalWrite(PIN_SR_LTCH, LOW); shiftOut(PIN_SR_DATA, PIN_SR_CLOCK, MSBFIRST, (data >> 8)); shiftOut(PIN_SR_DATA, PIN_SR_CLOCK, MSBFIRST, data & 0xff); digitalWrite(PIN_SR_LTCH, HIGH); } bool onSetLamp(const HomieRange& range, const String& value) { //lamp index (range) and on time (in ms) standby=false; lastChange=millis(); Serial.print("onSetLamp "); Serial.print(range.index); Serial.print(" value="); Serial.println(value); if (!range.isRange) { //long set_offmillis=value.toInt()); //homieNode.setProperty("duration").send(value); return false; //range must be specified } if (range.index < 0 || range.index >= OUTPUTS) { //out of range return false; } long set_offmillis=value.toInt()+millis(); if (set_offmillis>millis()+MAXONTIME){ set_offmillis=millis()+MAXONTIME; //limit value } lampoffmillis[range.index]=set_offmillis; Serial.print("lampoffmillis["); Serial.print(range.index); Serial.print("]="); Serial.println(lampoffmillis[range.index]); homieNode.setProperty("duration_" + String(range.index)).send(value); }