558 * @brief Publish DBIRTH for all active units. If there are no active units, don't |
558 * @brief Publish DBIRTH for all active units. If there are no active units, don't |
559 * publish anything. This function should be called at program start. |
559 * publish anything. This function should be called at program start. |
560 */ |
560 */ |
561 void publishDBirthAll(void) |
561 void publishDBirthAll(void) |
562 { |
562 { |
563 char *payload = NULL; |
563 char *topic = NULL, *payload = NULL, *payloadu = NULL; |
564 units_list *unit; |
564 units_list *unit; |
565 int comma = FALSE; |
565 int comma = FALSE; |
566 |
566 |
567 payload = payload_header(); |
567 payload = payload_header(); |
568 payload = xstrcat(payload, (char *)"{\"units\":["); |
568 payload = xstrcat(payload, (char *)"{\"units\":["); |
569 for (unit = Config.units; unit; unit = unit->next) { |
569 for (unit = Config.units; unit; unit = unit->next) { |
570 if (unit->mode != UNITMODE_OFF) { |
570 if (unit->mode != UNITMODE_OFF) { |
571 if (comma) |
571 if (comma) |
572 payload = xstrcat(payload, (char *)","); |
572 payload = xstrcat(payload, (char *)","); |
573 payload = xstrcat(payload, unit_data(unit, true)); |
573 payloadu = unit_data(unit, true); |
|
574 payload = xstrcat(payload, payloadu); |
574 comma = TRUE; |
575 comma = TRUE; |
|
576 free(payloadu); |
|
577 payloadu = NULL; |
575 } |
578 } |
576 } |
579 } |
577 if (comma) { // Only publish if there is at least one unit active. |
580 if (comma) { // Only publish if there is at least one unit active. |
578 payload = xstrcat(payload, (char *)"]}}"); |
581 payload = xstrcat(payload, (char *)"]}}"); |
579 publisher(mosq, topic_base((char *)"DBIRTH"), payload, true); |
582 topic = topic_base((char *)"DBIRTH"); |
|
583 publisher(mosq, topic, payload, true); |
|
584 free(topic); |
|
585 topic = NULL; |
580 } |
586 } |
581 free(payload); |
587 free(payload); |
582 payload = NULL; |
588 payload = NULL; |
583 } |
589 } |
584 |
590 |
585 |
591 |
586 |
592 |
587 void publishDData(units_list *unit) |
593 void publishDData(units_list *unit) |
588 { |
594 { |
589 char *payload = NULL, *topic = NULL; |
595 char *payload = NULL, *payloadu = NULL, *topic = NULL; |
590 |
596 |
591 if (mqtt_use) { |
597 if (mqtt_use) { |
592 payload = payload_header(); |
598 payload = payload_header(); |
593 payload = xstrcat(payload, unit_data(unit, false)); |
599 payloadu = unit_data(unit, false); |
|
600 payload = xstrcat(payload, payloadu); |
594 payload = xstrcat(payload, (char *)"}"); |
601 payload = xstrcat(payload, (char *)"}"); |
595 topic = xstrcat(topic_base((char *)"DDATA"), (char *)"/"); |
602 topic = xstrcat(topic_base((char *)"DDATA"), (char *)"/"); |
596 topic = xstrcat(topic, unit->alias); |
603 topic = xstrcat(topic, unit->alias); |
597 publisher(mosq, topic, payload, false); |
604 publisher(mosq, topic, payload, false); |
598 free(payload); |
605 free(payload); |
599 payload = NULL; |
606 payload = NULL; |
|
607 free(payloadu); |
|
608 payloadu = NULL; |
600 free(topic); |
609 free(topic); |
601 topic = NULL; |
610 topic = NULL; |
602 } |
611 } |
603 } |
612 } |
604 |
613 |
885 fclose(f); |
894 fclose(f); |
886 } |
895 } |
887 neterr: |
896 neterr: |
888 |
897 |
889 payload = xstrcat(payload, (char *)"}}"); |
898 payload = xstrcat(payload, (char *)"}}"); |
890 if (birth) |
899 if (birth) { |
891 publisher(mosq, topic_base((char *)"NBIRTH"), payload, true); |
900 topic = topic_base((char *)"NBIRTH"); |
892 else |
901 publisher(mosq, topic, payload, true); |
893 publisher(mosq, topic_base((char *)"NDATA"), payload, false); |
902 } else { |
894 |
903 topic = topic_base((char *)"NDATA"); |
|
904 publisher(mosq, topic, payload, false); |
|
905 } |
|
906 free(topic); |
|
907 topic = NULL; |
895 free(payload); |
908 free(payload); |
896 payload = NULL; |
909 payload = NULL; |
897 |
910 |
898 if ((Config.temp_address || Config.hum_address) && Config.temp_hum_idx) { |
911 if ((Config.temp_address || Config.hum_address) && Config.temp_hum_idx) { |
899 sprintf(sidx, "%d", Config.temp_hum_idx); |
912 sprintf(sidx, "%d", Config.temp_hum_idx); |
943 break; |
956 break; |
944 } |
957 } |
945 mosquitto_lib_cleanup(); |
958 mosquitto_lib_cleanup(); |
946 return; |
959 return; |
947 } |
960 } |
|
961 free(id); |
|
962 id = NULL; |
948 |
963 |
949 /* |
964 /* |
950 * Set our will |
965 * Set our will |
951 */ |
966 */ |
952 if ((rc = mosquitto_will_set(mosq, topic_base((char *)"NDEATH"), 0, NULL, mqtt_qos, false))) { |
967 topic = topic_base((char *)"NDEATH"); |
|
968 if ((rc = mosquitto_will_set(mosq, topic, 0, NULL, mqtt_qos, false))) { |
953 if (rc > MOSQ_ERR_SUCCESS) |
969 if (rc > MOSQ_ERR_SUCCESS) |
954 syslog(LOG_NOTICE, "MQTT: mosquitto_will_set: %s", mosquitto_strerror(rc)); |
970 syslog(LOG_NOTICE, "MQTT: mosquitto_will_set: %s", mosquitto_strerror(rc)); |
955 mosquitto_lib_cleanup(); |
971 mosquitto_lib_cleanup(); |
956 return; |
972 return; |
957 } |
973 } |
|
974 free(topic); |
958 |
975 |
959 if (debug) |
976 if (debug) |
960 mosquitto_log_callback_set(mosq, my_log_callback); |
977 mosquitto_log_callback_set(mosq, my_log_callback); |
961 mosquitto_max_inflight_messages_set(mosq, max_inflight); |
978 mosquitto_max_inflight_messages_set(mosq, max_inflight); |
962 mosquitto_connect_callback_set(mosq, my_connect_callback); |
979 mosquitto_connect_callback_set(mosq, my_connect_callback); |
989 |
1006 |
990 |
1007 |
991 void mqtt_disconnect(void) |
1008 void mqtt_disconnect(void) |
992 { |
1009 { |
993 int rc; |
1010 int rc; |
|
1011 char *topic; |
994 |
1012 |
995 if (mqtt_use) { |
1013 if (mqtt_use) { |
996 /* |
1014 /* |
997 * Final publish 0 to clients/<hostname>/thermferm/state |
1015 * Final publish 0 to clients/<hostname>/thermferm/state |
998 * After that, remove the retained topic. |
1016 * After that, remove the retained topic. |
999 */ |
1017 */ |
1000 syslog(LOG_NOTICE, "MQTT disconnecting"); |
1018 syslog(LOG_NOTICE, "MQTT disconnecting"); |
1001 publisher(mosq, topic_base((char *)"DBIRTH"), NULL, true); // Not always needed, but ... |
1019 topic = topic_base((char *)"DBIRTH"); |
1002 publisher(mosq, topic_base((char *)"DDEATH"), NULL, true); |
1020 publisher(mosq, topic, NULL, true); // Not always needed, but ... |
1003 publisher(mosq, topic_base((char *)"NBIRTH"), NULL, true); |
1021 free(topic); |
1004 publisher(mosq, topic_base((char *)"NDEATH"), NULL, true); |
1022 topic = topic_base((char *)"DDEATH"); |
|
1023 publisher(mosq, topic, NULL, true); |
|
1024 free(topic); |
|
1025 topic = topic_base((char *)"NBIRTH"); |
|
1026 publisher(mosq, topic, NULL, true); |
|
1027 free(topic); |
|
1028 topic = topic_base((char *)"NDEATH"); |
|
1029 publisher(mosq, topic, NULL, true); |
|
1030 free(topic); |
1005 mqtt_last_mid = mqtt_mid_sent; |
1031 mqtt_last_mid = mqtt_mid_sent; |
1006 mqtt_status = STATUS_WAITING; |
1032 mqtt_status = STATUS_WAITING; |
1007 mqtt_my_shutdown = TRUE; |
1033 mqtt_my_shutdown = TRUE; |
1008 |
1034 |
1009 do { |
1035 do { |