Advertisement
Guest User

Untitled

a guest
Jul 15th, 2018
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.23 KB | None | 0 0
  1. #include <WiFi.h>
  2. #include <PubSubClient.h>
  3. #include <DHT.h>
  4. #include <ESPmDNS.h>
  5. #include <WiFiUdp.h>
  6. #include <ArduinoOTA.h>
  7. #include <EEPROM.h>
  8. #define PORT_TX 32
  9.  
  10. /*
  11.  
  12. Value Button(s) Description
  13. 0x1 My Stop or move to favourite position
  14. 0x2 Up Move up
  15. 0x3 My + Up Set upper motor limit in initial programming mode
  16. 0x4 Down Move down
  17. 0x5 My + Down Set lower motor limit in initial programming mode
  18. 0x6 Up + Down Change motor limit and initial programming mode
  19. 0x8 Prog Used for (de-)registering remotes, see below
  20. 0x9 Sun + Flag Enable sun and wind detector (SUN and FLAG symbol on the Telis Soliris RC)
  21. 0xA Flag Disable sun detector (FLAG symbol on the Telis Instructor Excellence Award – Expert, čím sa zaradil medzi top 10 % najlepších inštruktorov na celom svete.Soliris RC)
  22.  
  23. */
  24.  
  25. #define SYMBOL 640
  26. #define HAUT 0x2
  27. #define STOP 0x1
  28. #define BAS 0x4
  29. #define PROG 0x8
  30. #define UPS 0x0E
  31. #define EEPROM_ADDRESS 0
  32.  
  33. #define REMOTE 0x121110 //<-- Change it!
  34.  
  35. const char* inTopic = "localcomm/esp32/cmd/+";
  36. const char* outTopic = "localcomm/esp32/data/roll/status";
  37.  
  38. unsigned int newRollingCode = 1; //<-- Change it!
  39. unsigned int rollingCode = 0;
  40. byte frame[7];
  41. byte checksum;
  42.  
  43. /*****************************************************
  44. * LED and doorbel settings
  45. ******************************************************/
  46. int LED_BUILTIN = 2;
  47. byte doorbel = 12;
  48. bool doorbel_status = false;
  49. /*****************************************************
  50. * MQTT settings
  51. * WIFI settings
  52. *****************************************************/
  53. const char* ssid = "w-eki";
  54. const char* password = "Ekino123";
  55. const char* mqttServer = "192.168.25.20";
  56. const int mqttPort = 1883;
  57. const char* mqttUser = "yourMQTTuser";
  58. const char* mqttPassword = "yourMQTTpassword";
  59.  
  60.  
  61. WiFiClient espClient;
  62. PubSubClient client(espClient);
  63.  
  64. /*****************************************************
  65. * ESP32 DHT Reading
  66. * DHT Input
  67. *****************************************************/
  68.  
  69. #define DHTPIN 33
  70. #define DHTTYPE DHT22
  71. DHT dht(DHTPIN, DHTTYPE);
  72. float localHum = 0;
  73. float localTemp = 0;
  74. char temp[35];
  75. char hum[35];
  76.  
  77.  
  78. /*****************************************************
  79. * Global settings
  80. *
  81. *****************************************************/
  82. int LoopCounter = 0;
  83.  
  84. /***************************************************
  85. * Get indoor Temp/Hum data
  86. ****************************************************/
  87. void getDHT()
  88. {
  89. float tempIni = localTemp;
  90. float humIni = localHum;
  91. localTemp = dht.readTemperature();
  92. localHum = dht.readHumidity();
  93. if (isnan(localHum) || isnan(localTemp) || localHum > 100 || localTemp < 15) // Check if any reads failed and exit early (to try again).
  94. {
  95. localTemp = tempIni;
  96. localHum = humIni;
  97. return;
  98. }
  99. }
  100.  
  101. void callback(char* topic, byte* payload, unsigned int length) {
  102. payload[length]='\0'; // Null terminator used to terminate the char array
  103. String message = (char*)payload;
  104.  
  105. Serial.print("Message arrived on topic: [");
  106. Serial.print(topic);
  107. Serial.print("]: ");
  108. Serial.println(message);
  109.  
  110. //get last part of topic
  111. char* cmnd = "test";
  112. char* cmnd_tmp=strtok(topic, "/");
  113.  
  114. while(cmnd_tmp !=NULL) {
  115. cmnd=cmnd_tmp; //take over last not NULL string
  116. cmnd_tmp=strtok(NULL, "/"); //passing Null continues on string
  117. //Serial.println(cmnd_tmp);
  118. }
  119.  
  120. if (!strcmp(cmnd, "control")) {
  121. if (message == "UP") {
  122. Serial.println("Received Somfy Up");
  123. BuildFrame(frame, HAUT);
  124. }
  125. if (message == "UPS") {
  126. Serial.println("Received Somfy Up");
  127. BuildFrame(frame, UPS);
  128. }
  129. else if (message == "DOWN") {
  130. Serial.println("Received Somfy Down");
  131. BuildFrame(frame, BAS);
  132. }
  133. else if (message == "STOP") {
  134. Serial.println("Received Somfy Stop");
  135. BuildFrame(frame, STOP);
  136. }
  137. else if (message == "PROG") {
  138. Serial.println("Received Somfy Prog");
  139. BuildFrame(frame, PROG);
  140. }
  141. //TODO add custom series as send over MQTT
  142. SendCommand(frame, 2);
  143. for(int i = 0; i<2; i++) {
  144. SendCommand(frame, 7);
  145. }
  146. sendSomfyStatus();
  147. }
  148. else if (!strcmp(cmnd, "reset")) {
  149. Serial.println("Received reset command");
  150. //ESP.reset();
  151. }
  152. else if (!strcmp(cmnd, "code")) {
  153. Serial.print("Received new code");
  154. unsigned int code;
  155. //get code from message
  156. code=message.toInt();
  157. Serial.println(code);
  158. //store in EEPROM and set global var
  159. EEPROM.put(EEPROM_ADDRESS, code);
  160. rollingCode=code;
  161. }
  162. else if (!strcmp(cmnd, "status")) {
  163. Serial.println("Printing status");
  164. sendSomfyStatus();
  165. }
  166.  
  167. }
  168.  
  169. void connect_mqtt()
  170. {
  171. while (!client.connected())
  172. {
  173. Serial.println("Connecting to MQTT...");
  174. if (client.connect("ESP32Client", mqttUser, mqttPassword )) {
  175. Serial.println("connected to MQTT");
  176. }
  177. else
  178. {
  179. Serial.print("failed with state ");
  180. Serial.print(client.state());
  181. delay(2000);
  182. }
  183. }
  184. }
  185.  
  186. void connect_wifi()
  187. {
  188. WiFi.begin(ssid, password);
  189. while (WiFi.status() != WL_CONNECTED)
  190. {
  191. delay(500);
  192. Serial.println("Connecting to WiFi..");
  193. }
  194. }
  195.  
  196.  
  197. void sendSomfyStatus() {
  198. char outTopic_status[50];
  199. char msg[50];
  200.  
  201. //IP Address
  202. strcpy(outTopic_status,outTopic);
  203. strcat(outTopic_status,"ip_address");
  204. WiFi.localIP().toString().toCharArray(msg,50);
  205. client.publish(outTopic_status,msg );
  206.  
  207. //Rolling Code
  208. strcpy(outTopic_status,outTopic);
  209. strcat(outTopic_status,"rolling_code");
  210. unsigned int code;
  211. EEPROM.get(EEPROM_ADDRESS, code);
  212. dtostrf(code,2,0,msg);
  213. client.publish(outTopic_status,msg );
  214.  
  215. //Remote number
  216. strcpy(outTopic_status,outTopic);
  217. strcat(outTopic_status,"remote");
  218. dtostrf(REMOTE,2,0,msg);
  219. client.publish(outTopic_status,msg );
  220. }
  221.  
  222. void setup()
  223. {
  224. pinMode(LED_BUILTIN, OUTPUT);
  225. pinMode(doorbel, INPUT_PULLUP);
  226. attachInterrupt(digitalPinToInterrupt(doorbel), doorbel_signal, RISING);
  227. Serial.begin(115200);
  228. connect_wifi();
  229. Serial.println("Connected to the WiFi network");
  230. client.setServer(mqttServer, mqttPort);
  231. connect_mqtt();
  232. client.subscribe("localcomm/esp32/cmd/+");
  233. Serial.println("Setting up DHT");
  234. dht.begin();
  235.  
  236.  
  237. pinMode(PORT_TX,OUTPUT);
  238. digitalWrite(PORT_TX,0);
  239.  
  240. EEPROM.begin(512); //added Smo
  241. if (EEPROM.get(EEPROM_ADDRESS, rollingCode) < newRollingCode) {
  242. EEPROM.put(EEPROM_ADDRESS, newRollingCode);
  243. }
  244. //EEPROM.put(EEPROM_ADDRESS, newRollingCode); //only needed ONCE for init of EEPROM.
  245. Serial.print("Simulated remote number : "); Serial.println(REMOTE, HEX);
  246. Serial.print("Current rolling code : "); Serial.println(rollingCode);
  247.  
  248.  
  249. client.setCallback(callback);
  250. sendSomfyStatus();
  251.  
  252. // OTA settings
  253.  
  254. // Port defaults to 3232
  255. // ArduinoOTA.setPort(3232);
  256.  
  257. // Hostname defaults to esp3232-[MAC]
  258. ArduinoOTA.setHostname("myesp32");
  259.  
  260. // No authentication by default
  261. // ArduinoOTA.setPassword("admin");
  262.  
  263. // Password can be set with it's md5 value as well
  264. // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  265. // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
  266. ArduinoOTA
  267. .onStart([]() {
  268. String type;
  269. if (ArduinoOTA.getCommand() == U_FLASH)
  270. type = "sketch";
  271. else // U_SPIFFS
  272. type = "filesystem";
  273.  
  274. // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
  275. Serial.println("Start updating " + type);
  276. })
  277. .onEnd([]() {
  278. Serial.println("\nEnd");
  279. })
  280. .onProgress([](unsigned int progress, unsigned int total) {
  281. Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  282. })
  283. .onError([](ota_error_t error) {
  284. Serial.printf("Error[%u]: ", error);
  285. if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
  286. else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
  287. else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
  288. else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
  289. else if (error == OTA_END_ERROR) Serial.println("End Failed");
  290. });
  291.  
  292. ArduinoOTA.begin();
  293. }
  294.  
  295.  
  296.  
  297. void loop()
  298. {
  299. ArduinoOTA.handle();
  300. LoopCounter++;
  301. client.loop();
  302. getDHT();
  303. if (LoopCounter > 10)
  304. {
  305. if (!client.connected())
  306. {
  307. connect_mqtt();
  308. }
  309. if (WiFi.status() != WL_CONNECTED)
  310. {
  311. connect_wifi();
  312. }
  313. digitalWrite(LED_BUILTIN, HIGH);
  314. snprintf(temp,10,"%4g",localTemp);
  315. Serial.println(localTemp);
  316. snprintf(hum,10,"%4g",localHum);
  317. Serial.println(localHum);
  318. client.publish("localcomm/esp32/data/hum/status",hum);
  319. //delay(100);
  320. client.publish("localcomm/esp32/data/temp/status",temp);;
  321. LoopCounter = 0;
  322. digitalWrite(LED_BUILTIN, LOW);
  323. }
  324. if (doorbel_status){
  325. client.publish("localcomm/esp32/data/doorbel/status","ON");
  326. delay(1000);
  327. client.publish("localcomm/esp32/data/doorbel/status","OFF");
  328. doorbel_status = false;
  329. }
  330. delay(2000);
  331. }
  332.  
  333. void doorbel_signal(){
  334. Serial.println("Interrupted");
  335. doorbel_status = true;
  336. }
  337.  
  338. void BuildFrame(byte *frame, byte button) {
  339. unsigned int code;
  340. EEPROM.get(EEPROM_ADDRESS, code);
  341. Serial.print("Sending w/ rolling code : "); Serial.println(code);
  342. frame[0] = 0xA7; // Encryption key. Doesn't matter much
  343. frame[1] = button << 4; // Which button did you press? The 4 LSB will be the checksum
  344. frame[2] = code >> 8; // Rolling code (big endian)
  345. frame[3] = code; // Rolling code
  346. frame[4] = REMOTE >> 16; // Remote address
  347. frame[5] = REMOTE >> 8; // Remote address
  348. frame[6] = REMOTE; // Remote address
  349.  
  350. Serial.print("Frame : ");
  351. for(byte i = 0; i < 7; i++) {
  352. if(frame[i] >> 4 == 0) { // Displays leading zero in case the most significant
  353. Serial.print("0"); // nibble is a 0.
  354. }
  355. Serial.print(frame[i],HEX); Serial.print(" ");
  356. }
  357.  
  358. // Checksum calculation: a XOR of all the nibbles
  359. checksum = 0;
  360. for(byte i = 0; i < 7; i++) {
  361. checksum = checksum ^ frame[i] ^ (frame[i] >> 4);
  362. }
  363. checksum &= 0b1111; // We keep the last 4 bits only
  364.  
  365.  
  366. //Checksum integration
  367. frame[1] |= checksum; // If a XOR of all the nibbles is equal to 0, the blinds will
  368. // consider the checksum ok.
  369.  
  370. Serial.println(""); Serial.print("With checksum : ");
  371. for(byte i = 0; i < 7; i++) {
  372. if(frame[i] >> 4 == 0) {
  373. Serial.print("0");
  374. }
  375. Serial.print(frame[i],HEX); Serial.print(" ");
  376. }
  377.  
  378.  
  379. // Obfuscation: a XOR of all the bytes
  380. for(byte i = 1; i < 7; i++) {
  381. frame[i] ^= frame[i-1];
  382. }
  383.  
  384. Serial.println(""); Serial.print("Obfuscated : ");
  385. for(byte i = 0; i < 7; i++) {
  386. if(frame[i] >> 4 == 0) {
  387. Serial.print("0");
  388. }
  389. Serial.print(frame[i],HEX); Serial.print(" ");
  390. }
  391. Serial.println("");
  392. Serial.print("Rolling Code : "); Serial.println(code);
  393. EEPROM.put(EEPROM_ADDRESS, code + 1); // We store the value of the rolling code in the
  394. EEPROM.commit(); // EEPROM. It should take up to 2 adresses but the
  395. // Arduino function takes care of it.
  396. }
  397.  
  398. void SendCommand(byte *frame, byte sync) {
  399. if(sync == 2) { // Only with the first frame.
  400. //Wake-up pulse & Silence
  401. //PORTD |= 1<<PORT_TX;
  402. //GPOS |= 1<<PORT_TX; //wrong usage anyway
  403. digitalWrite(PORT_TX,1);
  404. delayMicroseconds(9415);
  405. //PORTD &= !(1<<PORT_TX);
  406. //GPOS &= !(1<<PORT_TX);
  407. digitalWrite(PORT_TX,0);
  408. delayMicroseconds(89565);
  409. }
  410.  
  411. // Hardware sync: two sync for the first frame, seven for the following ones.
  412. for (int i = 0; i < sync; i++) {
  413. //PORTD |= 1<<PORT_TX;
  414. //GPOS |= 1<<PORT_TX;
  415. digitalWrite(PORT_TX,1);
  416. delayMicroseconds(4*SYMBOL);
  417. //PORTD &= !(1<<PORT_TX);
  418. //GPOS &= !(1<<PORT_TX);
  419. digitalWrite(PORT_TX,0);
  420. delayMicroseconds(4*SYMBOL);
  421. }
  422.  
  423. // Software sync
  424. //PORTD |= 1<<PORT_TX;
  425. //GPOS |= 1<<PORT_TX;
  426. digitalWrite(PORT_TX,1);
  427. delayMicroseconds(4550);
  428. //PORTD &= !(1<<PORT_TX);
  429. //GPOS &= !(1<<PORT_TX);
  430. digitalWrite(PORT_TX,0);
  431. delayMicroseconds(SYMBOL);
  432.  
  433.  
  434. //Data: bits are sent one by one, starting with the MSB.
  435. for(byte i = 0; i < 56; i++) {
  436. if(((frame[i/8] >> (7 - (i%8))) & 1) == 1) {
  437. //PORTD &= !(1<<PORT_TX);
  438. //GPOS &= !(1<<PORT_TX);
  439. digitalWrite(PORT_TX,0);
  440. delayMicroseconds(SYMBOL);
  441. //PORTD ^= 1<<5;
  442. //GPOS ^= 1<<5; //dont need to xor if I know state
  443. digitalWrite(PORT_TX,1);
  444. delayMicroseconds(SYMBOL);
  445. }
  446. else {
  447. //PORTD |= (1<<PORT_TX);
  448. //GPOS |= (1<<PORT_TX);
  449. digitalWrite(PORT_TX,1);
  450. delayMicroseconds(SYMBOL);
  451. //PORTD ^= 1<<5;
  452. //GPOS ^= 1<<5;
  453. digitalWrite(PORT_TX,0);
  454. delayMicroseconds(SYMBOL);
  455. }
  456. }
  457.  
  458. //PORTD &= !(1<<PORT_TX);
  459. //GPOS &= !(1<<PORT_TX);
  460. digitalWrite(PORT_TX,0);
  461. delayMicroseconds(30415); // Inter-frame silence
  462. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement