⬆️ Upgrade compiled pb wrappers

This commit is contained in:
brentru 2024-09-03 16:48:03 -04:00
parent 1534649f92
commit 3acd2bc6d9
27 changed files with 79 additions and 54 deletions

View file

@ -1,5 +1,5 @@
/*!
* @file model.cpp
* @file controller.cpp
*
* Controller for the digitalio.proto API
*
@ -27,12 +27,13 @@ bool DigitalIOController::AddDigitalPin(pb_istream_t *stream) {
// Get the DigitalIOAdd message
wippersnapper_digitalio_DigitalIOAdd *dio_add =
WsV2.digital_io_model->GetDigitalIOAdd();
// Strip the D/A prefix off the pin name and convert to a uint8_t pin number
int pin_name = atoi(dio_add->pin_name + 1);
// Configure the pin based on the direction
if (dio_add->gpio_direction ==
wippersnapper_digitalio_DigitalIODirection_DIGITAL_IO_DIRECTION_OUTPUT) {
DigitalOutputPin new_pin = DigitalOutputPin(
dio_add->pin_name, dio_add->value); // TODO: This is pb_callback type
DigitalOutputPin new_pin = DigitalOutputPin(pin_name, dio_add->value);
_digital_output_pins.push_back(new_pin);
} else if (
dio_add->gpio_direction ==

View file

@ -33,11 +33,31 @@ DigitalIOModel::DigitalIOModel() {
/***********************************************************************/
DigitalIOModel::~DigitalIOModel() {}
/***********************************************************************/
/*!
@brief Decodes a DigitalIOAdd message into the _msg_dio_add object
from a nanopb stream.
@param stream
The nanopb input stream.
@return True if the DigitalIOAdd message was successfully decoded.
*/
/***********************************************************************/
bool DigitalIOModel::DecodeDigitalIOAdd(pb_istream_t *stream) {
return pb_decode(stream, wippersnapper_digitalio_DigitalIOAdd_fields,
&_msg_dio_add);
}
/***********************************************************************/
/*!
@brief Clears the DigitalIOAdd message and resets it to default
values.
*/
/***********************************************************************/
void DigitalIOModel::ClearDigitalIOAdd() {
_msg_dio_add = wippersnapper_digitalio_DigitalIOAdd_init_default;
}
// TODO: It feels like this method should be in the controller!
void DigitalIOModel::ParseDigitalIOAdd() {
// TODO
}

View file

@ -25,6 +25,7 @@ public:
wippersnapper_digitalio_DigitalIOAdd *GetDigitalIOAdd() {
return &_msg_dio_add;
}
void ClearDigitalIOAdd();
void ParseDigitalIORemove();
wippersnapper_digitalio_DigitalIORemove *GetDigitalIORemove() {
return &_msg_dio_remove;

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "analogio.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_ANALOGIO_ANALOGIO_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_ANALOGIO_ANALOGIO_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "checkin.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_CHECKIN_CHECKIN_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_CHECKIN_CHECKIN_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "digitalio.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_DIGITALIO_DIGITALIO_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_DIGITALIO_DIGITALIO_PB_H_INCLUDED
@ -32,7 +32,7 @@ typedef enum _wippersnapper_digitalio_DigitalIODirection {
/* *
DigitalIOAdd adds a digital pin to the device. */
typedef struct _wippersnapper_digitalio_DigitalIOAdd {
pb_callback_t pin_name; /* * The pin's name. */
char pin_name[64]; /* * The pin's name. */
wippersnapper_digitalio_DigitalIODirection gpio_direction; /* * The pin's direction. */
wippersnapper_digitalio_DigitalIOSampleMode sample_mode; /* * Specifies the pin's sample mode. */
float period; /* * Time between measurements in seconds, if MODE_TIMER. */
@ -42,13 +42,13 @@ typedef struct _wippersnapper_digitalio_DigitalIOAdd {
/* *
DigitalIORemove removes a digital pin from the device. */
typedef struct _wippersnapper_digitalio_DigitalIORemove {
pb_callback_t pin_name; /* * The pin's name. */
char pin_name[64]; /* * The pin's name. */
} wippersnapper_digitalio_DigitalIORemove;
/* *
DigitalIOEvent is sent from the device to the broker when a digital pin's value changes. */
typedef struct _wippersnapper_digitalio_DigitalIOEvent {
pb_callback_t pin_name; /* * The pin's name. */
char pin_name[64]; /* * The pin's name. */
bool has_value;
wippersnapper_sensor_SensorEvent value; /* * The pin's value. */
} wippersnapper_digitalio_DigitalIOEvent;
@ -56,7 +56,7 @@ typedef struct _wippersnapper_digitalio_DigitalIOEvent {
/* *
DigitalIOWrite writes a boolean value to a digital pin. */
typedef struct _wippersnapper_digitalio_DigitalIOWrite {
pb_callback_t pin_name; /* * The pin's name. */
char pin_name[64]; /* * The pin's name. */
bool has_value;
wippersnapper_sensor_SensorEvent value; /* * The pin's value. */
} wippersnapper_digitalio_DigitalIOWrite;
@ -83,14 +83,14 @@ extern "C" {
/* Initializer values for message structs */
#define wippersnapper_digitalio_DigitalIOAdd_init_default {{{NULL}, NULL}, _wippersnapper_digitalio_DigitalIODirection_MIN, _wippersnapper_digitalio_DigitalIOSampleMode_MIN, 0, 0}
#define wippersnapper_digitalio_DigitalIORemove_init_default {{{NULL}, NULL}}
#define wippersnapper_digitalio_DigitalIOEvent_init_default {{{NULL}, NULL}, false, wippersnapper_sensor_SensorEvent_init_default}
#define wippersnapper_digitalio_DigitalIOWrite_init_default {{{NULL}, NULL}, false, wippersnapper_sensor_SensorEvent_init_default}
#define wippersnapper_digitalio_DigitalIOAdd_init_zero {{{NULL}, NULL}, _wippersnapper_digitalio_DigitalIODirection_MIN, _wippersnapper_digitalio_DigitalIOSampleMode_MIN, 0, 0}
#define wippersnapper_digitalio_DigitalIORemove_init_zero {{{NULL}, NULL}}
#define wippersnapper_digitalio_DigitalIOEvent_init_zero {{{NULL}, NULL}, false, wippersnapper_sensor_SensorEvent_init_zero}
#define wippersnapper_digitalio_DigitalIOWrite_init_zero {{{NULL}, NULL}, false, wippersnapper_sensor_SensorEvent_init_zero}
#define wippersnapper_digitalio_DigitalIOAdd_init_default {"", _wippersnapper_digitalio_DigitalIODirection_MIN, _wippersnapper_digitalio_DigitalIOSampleMode_MIN, 0, 0}
#define wippersnapper_digitalio_DigitalIORemove_init_default {""}
#define wippersnapper_digitalio_DigitalIOEvent_init_default {"", false, wippersnapper_sensor_SensorEvent_init_default}
#define wippersnapper_digitalio_DigitalIOWrite_init_default {"", false, wippersnapper_sensor_SensorEvent_init_default}
#define wippersnapper_digitalio_DigitalIOAdd_init_zero {"", _wippersnapper_digitalio_DigitalIODirection_MIN, _wippersnapper_digitalio_DigitalIOSampleMode_MIN, 0, 0}
#define wippersnapper_digitalio_DigitalIORemove_init_zero {""}
#define wippersnapper_digitalio_DigitalIOEvent_init_zero {"", false, wippersnapper_sensor_SensorEvent_init_zero}
#define wippersnapper_digitalio_DigitalIOWrite_init_zero {"", false, wippersnapper_sensor_SensorEvent_init_zero}
/* Field tags (for use in manual encoding/decoding) */
#define wippersnapper_digitalio_DigitalIOAdd_pin_name_tag 1
@ -106,30 +106,30 @@ extern "C" {
/* Struct field encoding specification for nanopb */
#define wippersnapper_digitalio_DigitalIOAdd_FIELDLIST(X, a) \
X(a, CALLBACK, SINGULAR, STRING, pin_name, 1) \
X(a, STATIC, SINGULAR, STRING, pin_name, 1) \
X(a, STATIC, SINGULAR, UENUM, gpio_direction, 2) \
X(a, STATIC, SINGULAR, UENUM, sample_mode, 3) \
X(a, STATIC, SINGULAR, FLOAT, period, 4) \
X(a, STATIC, SINGULAR, BOOL, value, 5)
#define wippersnapper_digitalio_DigitalIOAdd_CALLBACK pb_default_field_callback
#define wippersnapper_digitalio_DigitalIOAdd_CALLBACK NULL
#define wippersnapper_digitalio_DigitalIOAdd_DEFAULT NULL
#define wippersnapper_digitalio_DigitalIORemove_FIELDLIST(X, a) \
X(a, CALLBACK, SINGULAR, STRING, pin_name, 1)
#define wippersnapper_digitalio_DigitalIORemove_CALLBACK pb_default_field_callback
X(a, STATIC, SINGULAR, STRING, pin_name, 1)
#define wippersnapper_digitalio_DigitalIORemove_CALLBACK NULL
#define wippersnapper_digitalio_DigitalIORemove_DEFAULT NULL
#define wippersnapper_digitalio_DigitalIOEvent_FIELDLIST(X, a) \
X(a, CALLBACK, SINGULAR, STRING, pin_name, 1) \
X(a, STATIC, SINGULAR, STRING, pin_name, 1) \
X(a, STATIC, OPTIONAL, MESSAGE, value, 2)
#define wippersnapper_digitalio_DigitalIOEvent_CALLBACK pb_default_field_callback
#define wippersnapper_digitalio_DigitalIOEvent_CALLBACK NULL
#define wippersnapper_digitalio_DigitalIOEvent_DEFAULT NULL
#define wippersnapper_digitalio_DigitalIOEvent_value_MSGTYPE wippersnapper_sensor_SensorEvent
#define wippersnapper_digitalio_DigitalIOWrite_FIELDLIST(X, a) \
X(a, CALLBACK, SINGULAR, STRING, pin_name, 1) \
X(a, STATIC, SINGULAR, STRING, pin_name, 1) \
X(a, STATIC, OPTIONAL, MESSAGE, value, 2)
#define wippersnapper_digitalio_DigitalIOWrite_CALLBACK pb_default_field_callback
#define wippersnapper_digitalio_DigitalIOWrite_CALLBACK NULL
#define wippersnapper_digitalio_DigitalIOWrite_DEFAULT NULL
#define wippersnapper_digitalio_DigitalIOWrite_value_MSGTYPE wippersnapper_sensor_SensorEvent
@ -145,10 +145,13 @@ extern const pb_msgdesc_t wippersnapper_digitalio_DigitalIOWrite_msg;
#define wippersnapper_digitalio_DigitalIOWrite_fields &wippersnapper_digitalio_DigitalIOWrite_msg
/* Maximum encoded size of messages (where known) */
/* wippersnapper_digitalio_DigitalIOAdd_size depends on runtime parameters */
/* wippersnapper_digitalio_DigitalIORemove_size depends on runtime parameters */
/* wippersnapper_digitalio_DigitalIOEvent_size depends on runtime parameters */
/* wippersnapper_digitalio_DigitalIOWrite_size depends on runtime parameters */
#define WIPPERSNAPPER_DIGITALIO_DIGITALIO_PB_H_MAX_SIZE wippersnapper_digitalio_DigitalIOAdd_size
#define wippersnapper_digitalio_DigitalIOAdd_size 76
#define wippersnapper_digitalio_DigitalIORemove_size 65
#if defined(wippersnapper_sensor_SensorEvent_size)
#define wippersnapper_digitalio_DigitalIOEvent_size (71 + wippersnapper_sensor_SensorEvent_size)
#define wippersnapper_digitalio_DigitalIOWrite_size (71 + wippersnapper_sensor_SensorEvent_size)
#endif
#ifdef __cplusplus
} /* extern "C" */

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "ds18x20.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_DS18X20_DS18X20_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_DS18X20_DS18X20_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "error.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_ERROR_ERROR_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_ERROR_ERROR_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "i2c.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_I2C_I2C_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_I2C_I2C_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "pixels.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_PIXELS_PIXELS_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_PIXELS_PIXELS_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "pwm.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_PWM_PWM_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_PWM_PWM_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "sensor.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_SENSOR_SENSOR_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_SENSOR_SENSOR_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "servo.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_SERVO_SERVO_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_SERVO_SERVO_PB_H_INCLUDED

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "signal.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_SIGNAL_SIGNAL_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_SIGNAL_SIGNAL_PB_H_INCLUDED
@ -251,13 +251,13 @@ extern const pb_msgdesc_t wippersnapper_signal_DeviceToBroker_msg;
#define wippersnapper_signal_DeviceToBroker_fields &wippersnapper_signal_DeviceToBroker_msg
/* Maximum encoded size of messages (where known) */
#if defined(wippersnapper_digitalio_DigitalIOAdd_size) && defined(wippersnapper_digitalio_DigitalIORemove_size) && defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_digitalio_DigitalIOWrite_size) && defined(wippersnapper_analogio_AnalogIOAdd_size) && defined(wippersnapper_analogio_AnalogIORemove_size) && defined(wippersnapper_uart_UARTAdd_size) && defined(wippersnapper_uart_UARTRemove_size)
union wippersnapper_signal_BrokerToDevice_payload_size_union {char f10[(6 + wippersnapper_digitalio_DigitalIOAdd_size)]; char f11[(6 + wippersnapper_digitalio_DigitalIORemove_size)]; char f12[(6 + wippersnapper_digitalio_DigitalIOEvent_size)]; char f13[(6 + wippersnapper_digitalio_DigitalIOWrite_size)]; char f20[(7 + wippersnapper_analogio_AnalogIOAdd_size)]; char f21[(7 + wippersnapper_analogio_AnalogIORemove_size)]; char f80[(7 + wippersnapper_uart_UARTAdd_size)]; char f81[(7 + wippersnapper_uart_UARTRemove_size)]; char f0[83];};
#if defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_digitalio_DigitalIOWrite_size) && defined(wippersnapper_analogio_AnalogIOAdd_size) && defined(wippersnapper_analogio_AnalogIORemove_size) && defined(wippersnapper_uart_UARTAdd_size) && defined(wippersnapper_uart_UARTRemove_size)
union wippersnapper_signal_BrokerToDevice_payload_size_union {char f12[(6 + wippersnapper_digitalio_DigitalIOEvent_size)]; char f13[(6 + wippersnapper_digitalio_DigitalIOWrite_size)]; char f20[(7 + wippersnapper_analogio_AnalogIOAdd_size)]; char f21[(7 + wippersnapper_analogio_AnalogIORemove_size)]; char f80[(7 + wippersnapper_uart_UARTAdd_size)]; char f81[(7 + wippersnapper_uart_UARTRemove_size)]; char f0[83];};
#endif
#if defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_analogio_AnalogIOEvent_size) && defined(wippersnapper_ds18x20_Ds18x20Event_size) && defined(wippersnapper_uart_UARTAdded_size) && defined(wippersnapper_uart_UARTEvent_size) && defined(wippersnapper_i2c_I2cDeviceEvent_size)
union wippersnapper_signal_DeviceToBroker_payload_size_union {char f10[(6 + wippersnapper_digitalio_DigitalIOEvent_size)]; char f20[(7 + wippersnapper_analogio_AnalogIOEvent_size)]; char f80[(7 + wippersnapper_ds18x20_Ds18x20Event_size)]; char f90[(7 + wippersnapper_uart_UARTAdded_size)]; char f100[(7 + wippersnapper_uart_UARTEvent_size)]; char f113[(7 + wippersnapper_i2c_I2cDeviceEvent_size)]; char f0[2406];};
#endif
#if defined(wippersnapper_digitalio_DigitalIOAdd_size) && defined(wippersnapper_digitalio_DigitalIORemove_size) && defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_digitalio_DigitalIOWrite_size) && defined(wippersnapper_analogio_AnalogIOAdd_size) && defined(wippersnapper_analogio_AnalogIORemove_size) && defined(wippersnapper_uart_UARTAdd_size) && defined(wippersnapper_uart_UARTRemove_size)
#if defined(wippersnapper_digitalio_DigitalIOEvent_size) && defined(wippersnapper_digitalio_DigitalIOWrite_size) && defined(wippersnapper_analogio_AnalogIOAdd_size) && defined(wippersnapper_analogio_AnalogIORemove_size) && defined(wippersnapper_uart_UARTAdd_size) && defined(wippersnapper_uart_UARTRemove_size)
#define WIPPERSNAPPER_SIGNAL_SIGNAL_PB_H_MAX_SIZE wippersnapper_signal_BrokerToDevice_size
#define wippersnapper_signal_BrokerToDevice_size (0 + sizeof(union wippersnapper_signal_BrokerToDevice_payload_size_union))
#endif

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#include "uart.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -1,5 +1,5 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.8 at Wed Aug 21 15:48:44 2024. */
/* Generated by nanopb-0.4.8 */
#ifndef PB_WIPPERSNAPPER_UART_UART_PB_H_INCLUDED
#define PB_WIPPERSNAPPER_UART_UART_PB_H_INCLUDED