MeterLogger
Macros | Functions | Variables
kmp_request.c File Reference
#include <esp8266.h>
#include "driver/uart.h"
#include "unix_time.h"
#include "mqtt.h"
#include "tinyprintf.h"
#include "utils.h"
#include "kmp.h"
#include "kmp_request.h"
#include "config.h"
#include "crypto/crypto.h"
#include "crypto/aes.h"
Include dependency graph for kmp_request.c:

Go to the source code of this file.

Macros

#define QUEUE_SIZE   256
 

Functions

static ICACHE_FLASH_ATTR void kmp_received_task (os_event_t *events)
 
ICACHE_FLASH_ATTR void kmp_request_init ()
 
ICACHE_FLASH_ATTR void kmp_set_mqtt_client (MQTT_Client *client)
 
ICACHE_FLASH_ATTR void kmp_register_meter_is_ready_cb (meter_is_ready_cb cb)
 
ICACHE_FLASH_ATTR unsigned int kmp_get_received_serial ()
 
ICACHE_FLASH_ATTR unsigned int kmp_get_received_energy_kwh ()
 
ICACHE_FLASH_ATTR static void kmp_get_serial_timer_func ()
 
ICACHE_FLASH_ATTR static void kmp_get_register_timer_func ()
 
ICACHE_FLASH_ATTR static void kmp_receive_timeout_timer_func ()
 
ICACHE_FLASH_ATTR void kmp_request_send ()
 
unsigned int kmp_fifo_in_use ()
 
unsigned char kmp_fifo_put (unsigned char c)
 
unsigned char kmp_fifo_get (unsigned char *c)
 
unsigned char kmp_fifo_snoop (unsigned char *c, unsigned int pos)
 

Variables

uint32_t kmp_serial = 0
 
meter_is_ready_cb kmp_meter_is_ready_cb = NULL
 
bool meter_is_ready_cb_called = false
 
volatile unsigned int fifo_head
 
volatile unsigned int fifo_tail
 
volatile unsigned char fifo_buffer [QUEUE_SIZE]
 
unsigned char frame [KMP_FRAME_L]
 
unsigned int frame_length
 
uint16_t register_list [8]
 
kmp_response_t response
 
static MQTT_Clientmqtt_client = NULL
 
static os_timer_t kmp_get_serial_timer
 
static os_timer_t kmp_get_register_timer
 
static os_timer_t kmp_receive_timeout_timer
 
unsigned int kmp_requests_sent
 

Macro Definition Documentation

◆ QUEUE_SIZE

#define QUEUE_SIZE   256

Definition at line 13 of file kmp_request.c.

Referenced by kmp_fifo_get(), kmp_fifo_put(), and kmp_fifo_snoop().

Function Documentation

◆ kmp_fifo_get()

unsigned char kmp_fifo_get ( unsigned char *  c)

Definition at line 384 of file kmp_request.c.

References fifo_buffer, fifo_tail, kmp_fifo_in_use(), and QUEUE_SIZE.

Referenced by kmp_received_task().

384  {
385  if (kmp_fifo_in_use() != 0) {
386  *c = fifo_buffer[fifo_tail++ % QUEUE_SIZE];
387  // wrap
388  if (fifo_tail == QUEUE_SIZE) {
389  fifo_tail = 0;
390  }
391  return 1;
392  }
393  else {
394  return 0;
395  }
396 }
unsigned int kmp_fifo_in_use()
Definition: kmp_request.c:366
volatile unsigned char fifo_buffer[QUEUE_SIZE]
Definition: kmp_request.c:22
volatile unsigned int fifo_tail
Definition: kmp_request.c:21
#define QUEUE_SIZE
Definition: kmp_request.c:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kmp_fifo_in_use()

unsigned int kmp_fifo_in_use ( )

Definition at line 366 of file kmp_request.c.

References fifo_head, and fifo_tail.

Referenced by kmp_fifo_get(), kmp_fifo_put(), and kmp_fifo_snoop().

366  {
367  return fifo_head - fifo_tail;
368 }
volatile unsigned int fifo_tail
Definition: kmp_request.c:21
volatile unsigned int fifo_head
Definition: kmp_request.c:21
Here is the caller graph for this function:

◆ kmp_fifo_put()

unsigned char kmp_fifo_put ( unsigned char  c)

Definition at line 370 of file kmp_request.c.

References fifo_buffer, fifo_head, kmp_fifo_in_use(), and QUEUE_SIZE.

Referenced by uart0_rx_intr_handler().

370  {
371  if (kmp_fifo_in_use() != QUEUE_SIZE) {
373  // wrap
374  if (fifo_head == QUEUE_SIZE) {
375  fifo_head = 0;
376  }
377  return 1;
378  }
379  else {
380  return 0;
381  }
382 }
unsigned int kmp_fifo_in_use()
Definition: kmp_request.c:366
volatile unsigned char fifo_buffer[QUEUE_SIZE]
Definition: kmp_request.c:22
volatile unsigned int fifo_head
Definition: kmp_request.c:21
#define QUEUE_SIZE
Definition: kmp_request.c:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kmp_fifo_snoop()

unsigned char kmp_fifo_snoop ( unsigned char *  c,
unsigned int  pos 
)

Definition at line 398 of file kmp_request.c.

References fifo_buffer, fifo_tail, kmp_fifo_in_use(), and QUEUE_SIZE.

398  {
399  if (kmp_fifo_in_use() > (pos)) {
400  *c = fifo_buffer[(fifo_tail + pos) % QUEUE_SIZE];
401  return 1;
402  }
403  else {
404  return 0;
405  }
406 }
unsigned int kmp_fifo_in_use()
Definition: kmp_request.c:366
volatile unsigned char fifo_buffer[QUEUE_SIZE]
Definition: kmp_request.c:22
volatile unsigned int fifo_tail
Definition: kmp_request.c:21
#define QUEUE_SIZE
Definition: kmp_request.c:13
Here is the call graph for this function:

◆ kmp_get_received_energy_kwh()

ICACHE_FLASH_ATTR unsigned int kmp_get_received_energy_kwh ( )

Definition at line 209 of file kmp_request.c.

References ICACHE_FLASH_ATTR, kmp_response_t::kmp_response_register_list, kmp_unit_to_string(), kmp_value_to_string(), mw_to_w_str(), and strncmp.

209  {
210  unsigned char kmp_unit_string[16];
211  unsigned char kmp_value_string[64];
212 
213  char e1_kwh[64];
214 
216  kmp_unit_to_string(response.kmp_response_register_list[0].unit, kmp_unit_string);
217 
218  if (strncmp(kmp_unit_string, "MWh", 16) == 0) {
219  mw_to_w_str(kmp_unit_string, e1_kwh);
220  }
221 
222 #ifdef DEBUG_NO_METER
223  return pseudo_data_debug_no_meter;
224 #else
225  return atoi(e1_kwh);
226 #endif
227 }
ICACHE_FLASH_ATTR void kmp_unit_to_string(uint8_t unit, unsigned char *unit_string)
Definition: kmp.c:442
ICACHE_FLASH_ATTR void kmp_value_to_string(int32_t value, uint8_t si_ex, unsigned char *value_string)
Definition: kmp.c:394
kmp_response_register_list_t kmp_response_register_list
Definition: kmp.h:18
#define strncmp(a, b, c)
Definition: platform.h:18
ICACHE_FLASH_ATTR void mw_to_w_str(char *mw, char *w)
Definition: utils.c:105
kmp_response_t response
Definition: kmp_request.c:30
Here is the call graph for this function:

◆ kmp_get_received_serial()

ICACHE_FLASH_ATTR unsigned int kmp_get_received_serial ( )

Definition at line 203 of file kmp_request.c.

References ICACHE_FLASH_ATTR, and kmp_serial.

203  {
204  return kmp_serial;
205 }
uint32_t kmp_serial
Definition: kmp_request.c:15

◆ kmp_get_register_timer_func()

ICACHE_FLASH_ATTR static void kmp_get_register_timer_func ( )
static

Definition at line 238 of file kmp_request.c.

References frame, frame_length, ICACHE_FLASH_ATTR, kmp_get_register(), register_list, and uart0_tx_buffer().

Referenced by kmp_request_send().

238  {
239  // get registers
240  // prepare frame
241  register_list[0] = 0x3c; // heat energy (E1)
242  register_list[1] = 0x44; // volume register (V1)
243  register_list[2] = 0x3EC; // operational hour counter (HR)
244  register_list[3] = 0x56; // current flow temperature (T1)
245  register_list[4] = 0x57; // current return flow temperature (T2)
246  register_list[5] = 0x59; // current temperature difference (T1-T2)
247  register_list[6] = 0x4A; // current flow in flow (FLOW1)
248  register_list[7] = 0x50; // current power calculated on the basis of V1-T1-T2 (EFFEKT1)
250 
251  // send frame
252  uart0_tx_buffer(frame, frame_length); // send kmp request
253 }
void ICACHE_FLASH_ATTR uart0_tx_buffer(uint8 *buf, uint16 len)
Definition: uart.c:163
unsigned int frame_length
Definition: kmp_request.c:26
unsigned char frame[KMP_FRAME_L]
Definition: kmp_request.c:25
uint16_t register_list[8]
Definition: kmp_request.c:27
ICACHE_FLASH_ATTR unsigned int kmp_get_register(unsigned char *frame, uint16_t *register_list, uint16_t register_list_length)
Definition: kmp.c:181
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kmp_get_serial_timer_func()

ICACHE_FLASH_ATTR static void kmp_get_serial_timer_func ( )
static

Definition at line 230 of file kmp_request.c.

References frame, frame_length, ICACHE_FLASH_ATTR, kmp_get_serial(), and uart0_tx_buffer().

Referenced by kmp_request_send().

230  {
231  // get serial
232  // prepare frame
234  uart0_tx_buffer(frame, frame_length); // send kmp request
235 }
void ICACHE_FLASH_ATTR uart0_tx_buffer(uint8 *buf, uint16 len)
Definition: uart.c:163
unsigned int frame_length
Definition: kmp_request.c:26
unsigned char frame[KMP_FRAME_L]
Definition: kmp_request.c:25
ICACHE_FLASH_ATTR unsigned int kmp_get_serial(unsigned char *frame)
Definition: kmp.c:139
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kmp_receive_timeout_timer_func()

ICACHE_FLASH_ATTR static void kmp_receive_timeout_timer_func ( )
static

Definition at line 256 of file kmp_request.c.

References ICACHE_FLASH_ATTR, kmp_request_send(), and kmp_requests_sent.

Referenced by kmp_request_send().

256  {
257  if (kmp_requests_sent > 0) {
258  // if no reply received, retransmit
260  }
261 }
ICACHE_FLASH_ATTR void kmp_request_send()
Definition: kmp_request.c:264
unsigned int kmp_requests_sent
Definition: kmp_request.c:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kmp_received_task()

static ICACHE_FLASH_ATTR void kmp_received_task ( os_event_t events)
static

Definition at line 46 of file kmp_request.c.

References current_unix_time, encrypt_aes_hmac_combined(), get_unix_time(), ICACHE_FLASH_ATTR, kmp_decode_frame(), kmp_fifo_get(), KMP_FRAME_L, kmp_meter_is_ready_cb, kmp_requests_sent, kmp_response_t::kmp_response_register_list, kmp_response_t::kmp_response_serial, kmp_serial, kmp_unit_to_string(), kmp_value_to_string(), memset, meter_is_ready_cb_called, MQTT_Publish(), MQTT_TOPIC_L, os_memset, os_printf, os_strncpy, response, strcat, strlen, system_get_free_heap_size(), and tfp_snprintf().

Referenced by kmp_request_init().

46  {
47  unsigned char c;
48  unsigned int i;
49  uint64_t current_unix_time;
50  char current_unix_time_string[64]; // BUGFIX var
51  char key_value[256];
52  unsigned char topic[MQTT_TOPIC_L];
53  unsigned char message[KMP_FRAME_L];
54  int message_l;
55 
56  // vars for aes encryption
57  uint8_t cleartext[KMP_FRAME_L];
58 
59  // allocate struct for response
61  unsigned char kmp_unit_string[16];
62  unsigned char kmp_value_string[64];
63 
64  //ETS_UART_INTR_DISABLE();
65 
66  memset(message, 0x00, KMP_FRAME_L); // clear message buffer
67  i = 0;
68  while (kmp_fifo_get(&c) && (i <= KMP_FRAME_L)) {
69  message[i++] = c;
70  }
71  message_l = i;
72 
73  // decode kmp frame
74  if (kmp_decode_frame(message, message_l, &response) > 0) {
75  // tell user_main we got a serial
79  }
80 #ifdef DEBUG
81  else {
82  os_printf("tried to call kmp_meter_is_ready_cb() before it was set - should not happen\n");
83  }
84 #endif
85  message_l = 0; // zero it so we can reuse it for mqtt string
86  current_unix_time = (uint32)(get_unix_time()); // TODO before 2038 ,-)
87 
88  if (response.kmp_response_serial) {
89  kmp_serial = response.kmp_response_serial; // save it for later use
90  }
91  else if (current_unix_time) { // only send mqtt if we got current time via ntp
92  // prepare for mqtt transmission if we got serial number from meter
93 
94  // format /sample/v1/serial/unix_time => val1=23&val2=val3&baz=blah
95  //topic_l = os_sprintf(topic, "/sample/v1/%lu/%lu", kmp_serial, current_unix_time);
96  // BUG here. returns 0 -^
97  // this is a fix
98  memset(topic, 0, sizeof(topic)); // clear it
99  tfp_snprintf(current_unix_time_string, 64, "%u", (uint32_t)current_unix_time);
100  tfp_snprintf(topic, MQTT_TOPIC_L, "/sample/v2/%u/%s", kmp_serial, current_unix_time_string);
101 
102  memset(message, 0, sizeof(message)); // clear it
103 
104  // heap size
105  tfp_snprintf(key_value, MQTT_TOPIC_L, "heap=%u&", system_get_free_heap_size());
106  strcat(message, key_value);
107 
108  // heating meter specific
109  // flow temperature
110  kmp_value_to_string(response.kmp_response_register_list[3].value, response.kmp_response_register_list[3].si_ex, kmp_value_string);
111  kmp_unit_to_string(response.kmp_response_register_list[3].unit, kmp_unit_string);
112  tfp_snprintf(key_value, MQTT_TOPIC_L, "t1=%s %s&", kmp_value_string, kmp_unit_string);
113  strcat(message, key_value);
114 
115  // return flow temperature
116  kmp_value_to_string(response.kmp_response_register_list[4].value, response.kmp_response_register_list[4].si_ex, kmp_value_string);
117  kmp_unit_to_string(response.kmp_response_register_list[4].unit, kmp_unit_string);
118  tfp_snprintf(key_value, MQTT_TOPIC_L, "t2=%s %s&", kmp_value_string, kmp_unit_string);
119  strcat(message, key_value);
120 
121  // temperature difference
122  kmp_value_to_string(response.kmp_response_register_list[5].value, response.kmp_response_register_list[5].si_ex, kmp_value_string);
123  kmp_unit_to_string(response.kmp_response_register_list[5].unit, kmp_unit_string);
124  tfp_snprintf(key_value, MQTT_TOPIC_L, "tdif=%s %s&", kmp_value_string, kmp_unit_string);
125  strcat(message, key_value);
126 
127  // flow
128  kmp_value_to_string(response.kmp_response_register_list[6].value, response.kmp_response_register_list[6].si_ex, kmp_value_string);
129  kmp_unit_to_string(response.kmp_response_register_list[6].unit, kmp_unit_string);
130  tfp_snprintf(key_value, MQTT_TOPIC_L, "flow1=%s %s&", kmp_value_string, kmp_unit_string);
131  strcat(message, key_value);
132 
133  // current power
134  kmp_value_to_string(response.kmp_response_register_list[7].value, response.kmp_response_register_list[7].si_ex, kmp_value_string);
135  kmp_unit_to_string(response.kmp_response_register_list[7].unit, kmp_unit_string);
136  tfp_snprintf(key_value, MQTT_TOPIC_L, "effect1=%s %s&", kmp_value_string, kmp_unit_string);
137  strcat(message, key_value);
138 
139  // hours
140  kmp_value_to_string(response.kmp_response_register_list[2].value, response.kmp_response_register_list[2].si_ex, kmp_value_string);
141  kmp_unit_to_string(response.kmp_response_register_list[2].unit, kmp_unit_string);
142  tfp_snprintf(key_value, MQTT_TOPIC_L, "hr=%s %s&", kmp_value_string, kmp_unit_string);
143  strcat(message, key_value);
144 
145  // volume
146  kmp_value_to_string(response.kmp_response_register_list[1].value, response.kmp_response_register_list[1].si_ex, kmp_value_string);
147  kmp_unit_to_string(response.kmp_response_register_list[1].unit, kmp_unit_string);
148  tfp_snprintf(key_value, MQTT_TOPIC_L, "v1=%s %s&", kmp_value_string, kmp_unit_string);
149  strcat(message, key_value);
150 
151  // power
152  kmp_value_to_string(response.kmp_response_register_list[0].value, response.kmp_response_register_list[0].si_ex, kmp_value_string);
153  kmp_unit_to_string(response.kmp_response_register_list[0].unit, kmp_unit_string);
154  tfp_snprintf(key_value, MQTT_TOPIC_L, "e1=%s %s&", kmp_value_string, kmp_unit_string);
155  strcat(message, key_value);
156 
157  memset(cleartext, 0, sizeof(message));
158  os_strncpy(cleartext, message, sizeof(message)); // make a copy of message for later use
159  os_memset(message, 0, sizeof(message)); // ...and clear it
160 
161  // encrypt and send
162  message_l = encrypt_aes_hmac_combined(message, topic, strlen(topic), cleartext, strlen(cleartext) + 1);
163 
164  if (mqtt_client) {
165  // if mqtt_client is initialized
166  if (kmp_serial && (message_l > 1)) {
167  // if we received both serial and registers send it
168  MQTT_Publish(mqtt_client, topic, message, message_l, 2, 0); // QoS level 2
169  }
170  }
171  kmp_requests_sent = 0; // reset retry counter
172  // disable timer
173  }
174  }
175  else {
176  // error decoding frame - kmp_receive_timeout_timer_func() retransmits after timeout
177  }
178 }
ICACHE_FLASH_ATTR int kmp_decode_frame(unsigned char *frame, unsigned char frame_length, kmp_response_t *response)
Definition: kmp.c:239
static MQTT_Client * mqtt_client
Definition: kmp_request.c:32
ICACHE_FLASH_ATTR uint32_t get_unix_time(void)
Definition: unix_time.c:55
#define MQTT_TOPIC_L
Definition: user_config.h:25
#define memset(x, a, b)
Definition: platform.h:21
uint32 system_get_free_heap_size(void)
#define strcat(a, b)
Definition: platform.h:23
#define os_printf
Definition: osapi.h:62
ICACHE_FLASH_ATTR void kmp_unit_to_string(uint8_t unit, unsigned char *unit_string)
Definition: kmp.c:442
#define os_memset
Definition: osapi.h:38
#define os_strncpy
Definition: osapi.h:45
uint32_t kmp_serial
Definition: kmp_request.c:15
ICACHE_FLASH_ATTR void kmp_value_to_string(int32_t value, uint8_t si_ex, unsigned char *value_string)
Definition: kmp.c:394
bool meter_is_ready_cb_called
Definition: kmp_request.c:17
kmp_response_register_list_t kmp_response_register_list
Definition: kmp.h:18
unsigned int kmp_requests_sent
Definition: kmp_request.c:39
ICACHE_FLASH_ATTR size_t encrypt_aes_hmac_combined(uint8_t *dst, uint8_t *topic, size_t topic_l, uint8_t *message, size_t message_l)
Definition: crypto.c:68
meter_is_ready_cb kmp_meter_is_ready_cb
Definition: kmp_request.c:16
unsigned int uint32
Definition: c_types.h:54
ICACHE_FLASH_ATTR int tfp_snprintf(char *str, size_t size, const char *format,...)
Definition: tinyprintf.c:480
BOOL ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client *client, const char *topic, const char *data, int data_length, int qos, int retain)
MQTT publish function.
Definition: mqtt.c:591
unsigned char kmp_fifo_get(unsigned char *c)
Definition: kmp_request.c:384
#define KMP_FRAME_L
Definition: kmp.h:2
#define strlen(a)
Definition: platform.h:25
kmp_response_t response
Definition: kmp_request.c:30
uint32_t current_unix_time
Definition: unix_time.c:9
unsigned int kmp_response_serial
Definition: kmp.h:15
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kmp_register_meter_is_ready_cb()

ICACHE_FLASH_ATTR void kmp_register_meter_is_ready_cb ( meter_is_ready_cb  cb)

Definition at line 197 of file kmp_request.c.

References ICACHE_FLASH_ATTR, and kmp_meter_is_ready_cb.

197  {
199 }
meter_is_ready_cb kmp_meter_is_ready_cb
Definition: kmp_request.c:16

◆ kmp_request_init()

ICACHE_FLASH_ATTR void kmp_request_init ( )

Definition at line 181 of file kmp_request.c.

References fifo_head, fifo_tail, ICACHE_FLASH_ATTR, kmp_received_task(), kmp_received_task_prio, kmp_received_task_queue, kmp_received_task_queue_length, kmp_requests_sent, and system_os_task().

181  {
182  fifo_head = 0;
183  fifo_tail = 0;
184 
185  kmp_requests_sent = 0;
186 
188 }
bool system_os_task(os_task_t task, uint8 prio, os_event_t *queue, uint8 qlen)
volatile unsigned int fifo_tail
Definition: kmp_request.c:21
unsigned int kmp_requests_sent
Definition: kmp_request.c:39
static ICACHE_FLASH_ATTR void kmp_received_task(os_event_t *events)
Definition: kmp_request.c:46
#define kmp_received_task_queue_length
Definition: kmp_request.h:4
os_event_t kmp_received_task_queue[kmp_received_task_queue_length]
Definition: kmp_request.h:8
#define kmp_received_task_prio
Definition: kmp_request.h:3
volatile unsigned int fifo_head
Definition: kmp_request.c:21
Here is the call graph for this function:

◆ kmp_request_send()

ICACHE_FLASH_ATTR void kmp_request_send ( )

Definition at line 264 of file kmp_request.c.

References DEFAULT_METER_SERIAL, encrypt_aes_hmac_combined(), get_unix_time(), KMP_FRAME_L, kmp_get_register_timer, kmp_get_register_timer_func(), kmp_get_serial_timer, kmp_get_serial_timer_func(), kmp_meter_is_ready_cb, kmp_receive_timeout_timer, kmp_receive_timeout_timer_func(), kmp_requests_sent, kmp_serial, memset, meter_is_ready_cb_called, MQTT_MESSAGE_L, MQTT_Publish(), MQTT_TOPIC_L, NULL, os_printf, os_timer_arm, os_timer_disarm, os_timer_func_t, os_timer_setfn, strlen, system_get_free_heap_size(), and tfp_snprintf().

Referenced by kmp_receive_timeout_timer_func().

264  {
265 #ifdef DEBUG_NO_METER
266  char cleartext[MQTT_MESSAGE_L];
267  char topic[MQTT_TOPIC_L];
268  char message[KMP_FRAME_L];
269  int message_l;
270 
271  uint8_t sine_wave[256] = {
272  0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
273  0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
274  0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
275  0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
276  0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
277  0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
278  0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
279  0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
280  0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
281  0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
282  0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
283  0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
284  0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
285  0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
286  0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
287  0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
288  0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
289  0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
290  0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
291  0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
292  0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
293  0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
294  0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
295  0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
296  0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
297  0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
298  0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
299  0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
300  0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
301  0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
302  0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
303  0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
304  };
305 #endif
308  os_timer_arm(&kmp_get_serial_timer, 0, 0); // now
309 
312  os_timer_arm(&kmp_get_register_timer, 400, 0); // after 0.4 seconds
313 
314  // start retransmission timeout timer
317  os_timer_arm(&kmp_receive_timeout_timer, 2000, 0); // after 2 seconds
318 
320 #ifdef DEBUG_NO_METER
321  // clear data
322  memset(message, 0, sizeof(message));
323  memset(topic, 0, sizeof(topic));
324 
325  // fake serial for testing without meter
327 
328  tfp_snprintf(topic, MQTT_TOPIC_L, "/sample/v2/%u/%u", kmp_serial, get_unix_time());
329  memset(cleartext, 0, sizeof(cleartext));
330  tfp_snprintf(cleartext, KMP_FRAME_L, "heap=%u&t1=%u.00 C&t2=%u.00 C&tdif=%u.00 K&flow1=%u l/h&effect1=%u.0 kW&hr=%u h&v1=%u.00 m3&e1=%u kWh&",
332  65 + ((sine_wave[pseudo_data_debug_no_meter] * 10) >> 8), // t1
333  45 + ((sine_wave[(pseudo_data_debug_no_meter + 128) & 0xff] * 10) >> 8), // t2
334  10, // tdif
335  100 + ((sine_wave[((pseudo_data_debug_no_meter + 64) * 7) & 0xff] * 50) >> 8), // flow
336  15 + ((sine_wave[pseudo_data_debug_no_meter] * 10) >> 8), // effect1
337  pseudo_data_debug_no_meter / 60, // hr
338  pseudo_data_debug_no_meter, // v1
339  pseudo_data_debug_no_meter // e1
340  );
341  pseudo_data_debug_no_meter++; // let it wrap around
342 
343  // tell user_main we got a serial
347  }
348 #ifdef DEBUG
349  else {
350  os_printf("tried to call kmp_meter_is_ready_cb() before it was set - should not happen\n");
351  }
352 #endif
353 
354  // encrypt and send
355  message_l = encrypt_aes_hmac_combined(message, topic, strlen(topic), cleartext, strlen(cleartext) + 1);
356 
357  if (mqtt_client) {
358  // if mqtt_client is initialized
359  MQTT_Publish(mqtt_client, topic, message, message_l, 2, 0); // QoS level 2
360  }
361 #endif
362  kmp_requests_sent = 0; // reset retry counter
363 }
static MQTT_Client * mqtt_client
Definition: kmp_request.c:32
ICACHE_FLASH_ATTR uint32_t get_unix_time(void)
Definition: unix_time.c:55
#define MQTT_TOPIC_L
Definition: user_config.h:25
ICACHE_FLASH_ATTR static void kmp_receive_timeout_timer_func()
Definition: kmp_request.c:256
#define os_timer_disarm
Definition: osapi.h:51
#define memset(x, a, b)
Definition: platform.h:21
uint32 system_get_free_heap_size(void)
#define NULL
Definition: def.h:47
#define os_timer_func_t
Definition: os_type.h:35
ICACHE_FLASH_ATTR static void kmp_get_serial_timer_func()
Definition: kmp_request.c:230
#define os_printf
Definition: osapi.h:62
#define os_timer_setfn
Definition: osapi.h:52
ICACHE_FLASH_ATTR static void kmp_get_register_timer_func()
Definition: kmp_request.c:238
#define DEFAULT_METER_SERIAL
Definition: user_config.h:21
uint32_t kmp_serial
Definition: kmp_request.c:15
bool meter_is_ready_cb_called
Definition: kmp_request.c:17
unsigned int kmp_requests_sent
Definition: kmp_request.c:39
static os_timer_t kmp_receive_timeout_timer
Definition: kmp_request.c:37
ICACHE_FLASH_ATTR size_t encrypt_aes_hmac_combined(uint8_t *dst, uint8_t *topic, size_t topic_l, uint8_t *message, size_t message_l)
Definition: crypto.c:68
meter_is_ready_cb kmp_meter_is_ready_cb
Definition: kmp_request.c:16
ICACHE_FLASH_ATTR int tfp_snprintf(char *str, size_t size, const char *format,...)
Definition: tinyprintf.c:480
static os_timer_t kmp_get_register_timer
Definition: kmp_request.c:35
BOOL ICACHE_FLASH_ATTR MQTT_Publish(MQTT_Client *client, const char *topic, const char *data, int data_length, int qos, int retain)
MQTT publish function.
Definition: mqtt.c:591
#define os_timer_arm(a, b, c)
Definition: osapi.h:50
static os_timer_t kmp_get_serial_timer
Definition: kmp_request.c:34
#define MQTT_MESSAGE_L
Definition: user_config.h:26
#define KMP_FRAME_L
Definition: kmp.h:2
#define strlen(a)
Definition: platform.h:25
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kmp_set_mqtt_client()

ICACHE_FLASH_ATTR void kmp_set_mqtt_client ( MQTT_Client client)

Definition at line 192 of file kmp_request.c.

References ICACHE_FLASH_ATTR.

192  {
193  mqtt_client = client;
194 }
static MQTT_Client * mqtt_client
Definition: kmp_request.c:32

Variable Documentation

◆ fifo_buffer

volatile unsigned char fifo_buffer[QUEUE_SIZE]

Definition at line 22 of file kmp_request.c.

Referenced by kmp_fifo_get(), kmp_fifo_put(), and kmp_fifo_snoop().

◆ fifo_head

volatile unsigned int fifo_head

Definition at line 21 of file kmp_request.c.

Referenced by kmp_fifo_in_use(), kmp_fifo_put(), and kmp_request_init().

◆ fifo_tail

volatile unsigned int fifo_tail

Definition at line 21 of file kmp_request.c.

Referenced by kmp_fifo_get(), kmp_fifo_in_use(), kmp_fifo_snoop(), and kmp_request_init().

◆ frame

unsigned char frame[KMP_FRAME_L]

Definition at line 25 of file kmp_request.c.

Referenced by kmp_get_register_timer_func(), and kmp_get_serial_timer_func().

◆ frame_length

unsigned int frame_length

Definition at line 26 of file kmp_request.c.

Referenced by kmp_get_register_timer_func(), and kmp_get_serial_timer_func().

◆ kmp_get_register_timer

os_timer_t kmp_get_register_timer
static

Definition at line 35 of file kmp_request.c.

Referenced by kmp_request_send().

◆ kmp_get_serial_timer

os_timer_t kmp_get_serial_timer
static

Definition at line 34 of file kmp_request.c.

Referenced by kmp_request_send().

◆ kmp_meter_is_ready_cb

meter_is_ready_cb kmp_meter_is_ready_cb = NULL

◆ kmp_receive_timeout_timer

os_timer_t kmp_receive_timeout_timer
static

Definition at line 37 of file kmp_request.c.

Referenced by kmp_request_send().

◆ kmp_requests_sent

unsigned int kmp_requests_sent

◆ kmp_serial

uint32_t kmp_serial = 0

Definition at line 15 of file kmp_request.c.

Referenced by kmp_get_received_serial(), kmp_received_task(), and kmp_request_send().

◆ meter_is_ready_cb_called

bool meter_is_ready_cb_called = false

Definition at line 17 of file kmp_request.c.

Referenced by kmp_received_task(), and kmp_request_send().

◆ mqtt_client

MQTT_Client* mqtt_client = NULL
static

Definition at line 32 of file kmp_request.c.

◆ register_list

uint16_t register_list[8]

Definition at line 27 of file kmp_request.c.

Referenced by kmp_get_register_timer_func().

◆ response

kmp_response_t response

Definition at line 30 of file kmp_request.c.

Referenced by kmp_received_task().