GithubHelp home page GithubHelp logo

Comments (14)

danpeig avatar danpeig commented on August 20, 2024

Hi,

Did you tried inverting the direction of the current sensor for P3?

from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

I didn't turn the sensor because during the calibration process it was in the same direction as it is now and it worked like that, so I suspected that it might not be a problem in the code...

from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

how does the Curen P3 measure me and it won't count the Real Power P3...???

from esp32energymonitor.

danpeig avatar danpeig commented on August 20, 2024

Can you run the calibration script again replacing this code block:
Serial.print("V3: "); Serial.print(supplyVoltage3); Serial.print(", I3: "); Serial.println(Irms3);

with this

Serial.print("V3: "); Serial.print(supplyVoltage3); Serial.print("PF3: "); Serial.print(powerFactor3); Serial.print(", I3: "); Serial.println(Irms3);

What we are looking for is a negative power factor.

from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

with no load:

V1: 229.00, I1: 0.92
V2: 225.42, I2: 0.88
V3: 226.79PF3: -0.02, I3: 1.02

with load:
V1: 221.39, I1: 13.11
V2: 218.49, I2: 13.28
V3: 220.35PF3: 0.85, I3: 12.92

from esp32energymonitor.

danpeig avatar danpeig commented on August 20, 2024

The hardware appears to be working well. 3 positive parameters.
Now we must check ESPHome and Home Assistant.
When you run the ESPHome console/terminal, do you get similar results in the output variables (voltage, current, and PF)?

from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

This is report from pc terminal directly connected to ESP32 (red square is with no load) next is with load
file

from esp32energymonitor.

danpeig avatar danpeig commented on August 20, 2024

The problem appears to be at HomeAssistant side.

The P3 values with loads are as expected (2414W, 2836W and PF of 0.85). This information is exactly what was posted in Home Assistant.

from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

esp32emon.yaml

esphome:
  name: esp32emon
  name_add_mac_suffix: true
  includes:
    - emonlib/EmonLib.h
    - emonlib/EmonLib.cpp
    - esp32emon.h
  project:
    name: danpeig.esp32emon
    version: "1.3.0"

# Board configuration
esp32:
  board: esp32doit-devkit-v1
  framework:
    type: arduino

# Sets up Bluetooth LE (Only on ESP32) to allow the user
# to provision wifi credentials to the device.
esp32_improv:
  authorizer: none

# Sets up the improv via serial client for Wi-Fi provisioning
improv_serial:

# Enable logging
logger:

# Enable Home Assistant API
api:

# Enable OTA updates
ota:
  password: !secret ota_password

# Wifi configuration
wifi:
  networks:
    # Main network
   - ssid: !secret wifi_ssid
     password: !secret wifi_password
    # Alternative network
    # - ssid: !secret wifi_ssid2
      # password: !secret wifi_password2

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  # ap:
    # ssid: "Esp32EnergyMeter"
    # password: !secret wifi_ap_password

captive_portal:

# MQTT Integration
#mqtt:
#  broker: !secret mqtt_broker
#  port: !secret mqtt_port
#  username: !secret mqtt_user
#  password: !secret mqtt_password
#  discovery: false #We are using the default API for Home Assistant discovery, no need for MQTT

# Timers configuration
time:
  - platform: sntp
    id: sntp_time1
    on_time:
      # Every Month at specified day
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_month: 1
        then:
          - sensor.integration.reset: total_energy_month #Reset power integrator
      # Every Week at specified day
      - seconds: 0
        minutes: 0
        hours: 0
        days_of_week: MON
        then:
          - sensor.integration.reset: total_energy_week #Reset power integrator
      # Every Day at specified hour
      - seconds: 0
        minutes: 0
        hours: 0
        then:
          - sensor.integration.reset: total_energy_day #Reset power integrator

sensor:
  #Custom sensors from EMon
  - platform: custom
    lambda: |-
      auto my_sensor = new MyPowerSensor();
      App.register_component(my_sensor);

      // 1-Phase - - uncomment only the following line for 1 phase measurements
      //return {my_sensor->realpower_sensor1, my_sensor->apparentpower_sensor1, my_sensor->powerfactor_sensor1, my_sensor->supplyvoltage_sensor1, my_sensor->current_sensor1, my_sensor->realpower_sensor_total, my_sensor->apparentpower_sensor_total, my_sensor->current_sensor_total};

      // 2-Phases - uncomment only the following line for 2 phase measurements
      //return {my_sensor->realpower_sensor1, my_sensor->apparentpower_sensor1, my_sensor->powerfactor_sensor1, my_sensor->supplyvoltage_sensor1, my_sensor->current_sensor1, my_sensor->realpower_sensor2, my_sensor->apparentpower_sensor2, my_sensor->powerfactor_sensor2, my_sensor->supplyvoltage_sensor2, my_sensor->current_sensor2, my_sensor->realpower_sensor_total, my_sensor->apparentpower_sensor_total, my_sensor->current_sensor_total};

      // 3-Phases - uncomment only the following line for 3 phase measurements
      return {my_sensor->realpower_sensor1, my_sensor->apparentpower_sensor1, my_sensor->powerfactor_sensor1, my_sensor->supplyvoltage_sensor1, my_sensor->current_sensor1, my_sensor->realpower_sensor2, my_sensor->apparentpower_sensor2, my_sensor->powerfactor_sensor2, my_sensor->supplyvoltage_sensor2, my_sensor->current_sensor2, my_sensor->realpower_sensor3, my_sensor->apparentpower_sensor3, my_sensor->powerfactor_sensor3, my_sensor->supplyvoltage_sensor3, my_sensor->current_sensor3, my_sensor->realpower_sensor_total, my_sensor->apparentpower_sensor_total, my_sensor->current_sensor_total};
    sensors:
      #Phase 1 sensors
      - name: "Real Power P1"
        device_class: "power"
        unit_of_measurement: W
        state_class: "measurement"
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }
      - name: "Apparent Power P1"
        device_class: "apparent_power"
        unit_of_measurement: VA
        state_class: "measurement"
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }
      - name: "Power Factor P1"
        device_class: "power_factor"
        state_class: "measurement"
        accuracy_decimals: 2
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }        
      - name: "Voltage P1"
        device_class: "voltage"
        unit_of_measurement: V
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Current P1"
        device_class: "current"
        unit_of_measurement: A
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   

        #Phase 2 sensors
      - name: "Real Power P2"
        device_class: "power"
        unit_of_measurement: W
        state_class: "measurement"
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Apparent Power P2"
        device_class: "apparent_power"
        unit_of_measurement: VA
        state_class: "measurement"
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Power Factor P2"
        device_class: "power_factor"
        state_class: "measurement"
        accuracy_decimals: 2
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Voltage P2"
        device_class: "voltage"
        unit_of_measurement: V
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Current P2"
        device_class: "current"
        unit_of_measurement: A
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   

        #Phase 3 sensors
      - name: "Real Power P3"
        device_class: "power"
        unit_of_measurement: W
        state_class: "measurement"
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Apparent Power P3"
        device_class: "apparent_power"
        unit_of_measurement: VA
        state_class: "measurement"
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Power Factor P3"
        device_class: "power_factor"
        state_class: "measurement"
        accuracy_decimals: 2
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Voltage P3"
        device_class: "voltage"
        unit_of_measurement: V
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }   
      - name: "Current P3"
        device_class: "current"
        unit_of_measurement: A
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }  

      #Total sensors
      - name: "Total Real Power"
        id: "real_power_sensor_total"
        device_class: "power"
        state_class: "measurement"
        unit_of_measurement: W
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }
      - name: "Total Apparent Power"
        device_class: "apparent_power"
        state_class: "measurement"
        unit_of_measurement: VA
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }
      - name: "Total Current"
        device_class: "current"
        state_class: "measurement"
        unit_of_measurement: A
        accuracy_decimals: 1
        internal: false
        filters:
          - lambda: |-
              //Avoid corrupting integration sensors
              if(!isinf(x) && !isnan(x) && x >= 0 && x <= 10e6)
                {
                return x;
                }
              else
                {
                return 0;
                }

  - platform: integration
    name: "Daily Consumption"
    id: "total_energy_day"
    sensor: real_power_sensor_total
    time_unit: h
    device_class: "energy"
    state_class: "total_increasing"
    unit_of_measurement: kWh
    accuracy_decimals: 2
    restore: false #If true, save the reading to the flash memory to prevent data loss in case of power loss
    filters:
      - multiply: 0.001

  - platform: integration
    name: "Weekly Consumption"
    id: "total_energy_week"
    sensor: real_power_sensor_total
    time_unit: h
    device_class: "energy"
    state_class: "total_increasing"
    unit_of_measurement: kWh
    accuracy_decimals: 2
    restore: false #If true, save the reading to the flash memory to prevent data loss in case of power loss
    filters:
      - multiply: 0.001

  - platform: integration
    name: "Monthly Consumption"
    id: "total_energy_month"
    sensor: real_power_sensor_total
    time_unit: h
    device_class: "energy"
    state_class: "total_increasing"
    unit_of_measurement: kWh
    accuracy_decimals: 2
    restore: false #If true, save the reading to the flash memory to prevent data loss in case of power loss
    filters:
      - multiply: 0.001

  # Wifi signal sensors
  - platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
    name: "WiFi signal dB"
    id: wifi_signal_db
    update_interval: 60s
    entity_category: "diagnostic"

  - platform: copy # Reports the WiFi signal strength in %
    source_id: wifi_signal_db
    name: "WiFi signal"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: "diagnostic"

# Other information
text_sensor:
  - platform: wifi_info
    ip_address:
      name: ESP32 IP Address
    ssid:
      name: ESP32 SSID```



from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

esp32emon.h

#include "EmonLib.h"
#include "esp_task_wdt.h" //Watchdog control features
#define ESP32

// Watchdog timeout in seconds
#define WDT_TIMEOUT 5 

// The Sample window length is defined by the number of half wavelengths or crossings we choose to measure.
// 120 is quite conservative for two phases
#define CROSSINGS 120

// Polling interval
#define POLLING_INTERVAL 30000 //Every 30s will perform a read and publish the data. Do not go under 5s to prevent crashes.

// Pin configuration
#define V1 34
#define V2 34 //Set to V1 if using only one voltage meter
#define V3 34 //Set to V1 if using only one voltage meter

#define I1 35
#define I2 32
#define I3 33

// Calibration for voltage sensors CV and current sensors CI
#define CV1 350.31
#define CV2 346.5 //Set to CV1 if using only one voltage meter
#define CV3 347.23 //Set to CV1 if using only one voltage meter

#define CI1 64.92
#define CI2 65.65
#define CI3 64.41

class MyPowerSensor : public PollingComponent, public Sensor
{
public:
  MyPowerSensor() : PollingComponent(POLLING_INTERVAL) {}

  float get_setup_priority() const override { return esphome::setup_priority::LATE; }

  EnergyMonitor emon1; // Phase 1
  EnergyMonitor emon2; // Phase 2
  EnergyMonitor emon3; // Phase 3

  // Phase 1 sensors
  Sensor *realpower_sensor1 = new Sensor();
  Sensor *apparentpower_sensor1 = new Sensor();
  Sensor *powerfactor_sensor1 = new Sensor();
  Sensor *supplyvoltage_sensor1 = new Sensor();
  Sensor *current_sensor1 = new Sensor();

  // Phase 2 sensors
  Sensor *realpower_sensor2 = new Sensor();
  Sensor *apparentpower_sensor2 = new Sensor();
  Sensor *powerfactor_sensor2 = new Sensor();
  Sensor *supplyvoltage_sensor2 = new Sensor();
  Sensor *current_sensor2 = new Sensor();

  // Phase 3 sensors
   Sensor *realpower_sensor3 = new Sensor();
   Sensor *apparentpower_sensor3 = new Sensor();
   Sensor *powerfactor_sensor3 = new Sensor();
   Sensor *supplyvoltage_sensor3 = new Sensor();
   Sensor *current_sensor3 = new Sensor();

  // Total sensors
  Sensor *realpower_sensor_total = new Sensor();
  Sensor *apparentpower_sensor_total = new Sensor();
  Sensor *current_sensor_total = new Sensor();

  void setup() override
  {

    esp_task_wdt_init(WDT_TIMEOUT, true); // enable panic so ESP32 restarts
    esp_task_wdt_add(NULL);               // add current thread to WDT watch

    /*
    Analog attenuation: When using 0-1V sensors the attenuation should be decreased to improve accuracy.

    ADC_0db: sets no attenuation. ADC can measure up to approximately 800 mV (1V input = ADC reading of 1088).
    ADC_2_5db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1100 mV. (1V input = ADC reading of 3722).
    ADC_6db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1350 mV. (1V input = ADC reading of 3033).
    ADC_11db (default): The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 2600 mV. (1V input = ADC reading of 1575).

    */
    analogSetPinAttenuation(V1, ADC_11db);
    analogSetPinAttenuation(V2, ADC_11db);
    analogSetPinAttenuation(V3, ADC_11db);

    analogSetPinAttenuation(I1, ADC_11db);
    analogSetPinAttenuation(I2, ADC_11db);
    analogSetPinAttenuation(I3, ADC_11db);

    // Phase 1 sensors
    emon1.voltage(V1, CV1, 1.732); // Voltage: input pin, calibration, phase_shift
    emon1.current(I1, CI1);        // Current: input pin, calibration.

    // Phase 2 sensors
    emon2.voltage(V2, CV2, 1.732); // Voltage: input pin, calibration, phase_shift
    emon2.current(I2, CI2);        // Current: input pin, calibration.

    
    //Phase 3 sensors
    emon3.voltage(V3, CV3, 1.732);  // Voltage: input pin, calibration, phase_shift
    emon3.current(I3, CI3);       // Current: input pin, calibration.
    
  }

  void update() override
  {

    // Phase 1
    emon1.calcVI(CROSSINGS, 2000);
    float realPower1 = emon1.realPower;
    realpower_sensor1->publish_state(realPower1);
    float apparentPower1 = emon1.apparentPower;
    apparentpower_sensor1->publish_state(apparentPower1);
    float powerFactor1 = emon1.powerFactor;
    powerfactor_sensor1->publish_state(powerFactor1);
    float supplyVoltage1 = emon1.Vrms;
    supplyvoltage_sensor1->publish_state(supplyVoltage1);
    float current1 = emon1.Irms;
    current_sensor1->publish_state(current1);

    esp_task_wdt_reset(); // Things can take some time... this ensures the watchdog is aware

    // Phase 2
    emon2.calcVI(CROSSINGS, 2000);
    float realPower2 = emon2.realPower;
    realpower_sensor2->publish_state(realPower2);
    float apparentPower2 = emon2.apparentPower;
    apparentpower_sensor2->publish_state(apparentPower2);
    float powerFactor2 = emon2.powerFactor;
    powerfactor_sensor2->publish_state(powerFactor2);
    float supplyVoltage2 = emon2.Vrms;
    supplyvoltage_sensor2->publish_state(supplyVoltage2);
    float current2 = emon2.Irms;
    current_sensor2->publish_state(current2);

    esp_task_wdt_reset(); // Things can take some time... this ensures the watchdog is aware

    
     // Phase 3
     emon3.calcVI(CROSSINGS,2000);
     float realPower3 = emon3.realPower;
     realpower_sensor3->publish_state(realPower3);
     float apparentPower3 = emon3.apparentPower;
     apparentpower_sensor3->publish_state(apparentPower3);
     float powerFactor3 = emon3.powerFactor;
     powerfactor_sensor3->publish_state(powerFactor3);
     float supplyVoltage3 = emon3.Vrms;
     supplyvoltage_sensor3->publish_state(supplyVoltage3);
     float current3 = emon3.Irms;
     current_sensor3->publish_state(current3);
     

    /*
    // Totals 1 phase - uncomment only this block if you are reading one phase
    float realPower_total = emon1.realPower;
    realpower_sensor_total->publish_state(realPower_total);
    float apparentPower_total = emon1.apparentPower;
    apparentpower_sensor_total->publish_state(apparentPower_total);
    float current_total = emon1.Irms;
    current_sensor_total->publish_state(current_total);
    */
	
	/*
    // Totals 2 phases - uncomment only this block if you are reading two phases
    float realPower_total = emon1.realPower + emon2.realPower;
    realpower_sensor_total->publish_state(realPower_total);
    float apparentPower_total = emon1.apparentPower + emon2.apparentPower;
    apparentpower_sensor_total->publish_state(apparentPower_total);
    float current_total = emon1.Irms + emon2.Irms;
    current_sensor_total->publish_state(current_total);
	*/
    
     // Totals 3 phases - uncomment only this block if you are reading three phases
     float realPower_total = emon1.realPower + emon2.realPower + emon3.realPower;
     realpower_sensor_total->publish_state(realPower_total);
     float apparentPower_total = emon1.apparentPower + emon2.apparentPower + emon3.apparentPower;
     apparentpower_sensor_total->publish_state(apparentPower_total);
     float current_total = emon1.Irms + emon2.Irms + emon3.Irms;
     current_sensor_total->publish_state(current_total);
     
  }
};

from esp32energymonitor.

danpeig avatar danpeig commented on August 20, 2024

Thank you, your code is compiling and working. The problem appears to be on Home Assistant end.

from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

thanks for your time, I'll try flashing again and see if it works.
thanks again

from esp32energymonitor.

vladakru avatar vladakru commented on August 20, 2024

As you saw on the test table, everything worked as it should, when I connected it to the mains, one phase read amperes again, but not PF and RP, when I turned the CT sensor in the opposite direction, that phase worked with the readings. I don't know how it's like the current is flowing in the opposite direction or whatever... I hope that now with that setup the reading will be fine.

from esp32energymonitor.

danpeig avatar danpeig commented on August 20, 2024

Here is the explanation from OpenEnergyMonitor:

Does the direction the CT is clipped on the wire, matter?

If you are interested in reading only apparent power, and you don’t have an AC-AC adapter, it does not matter. The power reading will always be positive.

If you want to read real power, and you want to know in which direction power is flowing – e.g. when you generate your own electricity, and want to know whether you are importing or exporting – then the C.T. must face the correct direction. Our convention is: imported and generated powers are positive. If the C.T. faces the wrong way, it means that the power you expect to be positive will be shown as negative. [Note: Robin Emley has adopted the opposite convention for his Mk 2 energy diverter – he regards exported power as positive.]

For the UK ac-ac adapter and the YHDC C.T. purchased from the shop and when the C.T. is on the line conductor, the printing on the face of the C.T. should face in the direction of positive power, i.e. in the picture above, positive power flow is from left to right. If the C.T. is on the neutral conductor (this is only valid on a single-phase installation) it should face in the opposite direction. For any other combination of ac-ac adapter and C.T. it is possible, if the phasing of each is known, to determine the correct orientation, but the easiest and quickest method is probably by trial and error. Reversing the C.T. will change the sign of that input. Reversing the ac-ac adapter (where the plug design allows this) will change the sign of all inputs.

from esp32energymonitor.

Related Issues (12)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.