Giter VIP home page Giter VIP logo

Comments (50)

mwittig avatar mwittig commented on June 23, 2024

Hi,

Also das wäre keine grosse Sache, aber stehe momentan etwas auf dem Schlauch: Gehört die Abfrage zur Fronius Solar API oder handelt es sich um einen anderen Service?

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

Gehört auch zur Abfrage von Fronius API.
die Ausgabe sieht so aus:

{
    "Head" : {
        "RequestArguments" : {
            "resource" : "5\/0\/",
            "print" : "names"
        },
        "Status" : {
            "Code" : 0,
            "Reason" : "",
            "UserMessage" : "",
            "ErrorDetail" : {
                "Nodes" : []
            }
        },
        "Timestamp" : "2016-02-25T11:23:46+01:00"
    },
    "Body" : {
        "Data" : {
            "TimeStamp" : {
                "value" : 1456395825,
                "unit" : "sec"
            },
            "Enable" : {
                "value" : 1,
                "unit" : "1"
            },
            "Visible" : {
                "value" : 1,
                "unit" : "1"
            },
            "Power_P_Generate" : {
                "value" : 629,
                "unit" : "W"
            },
            "Power_P_Load" : {
                "value" : -2883.25,
                "unit" : "W"
            },
            "Power_P_Grid" : {
                "value" : 2254.25,
                "unit" : "W"
            },
            "Power_Akku_Sum" : {
                "value" : null,
                "unit" : "W"
            },
            "Power_PV_Sum" : {
                "value" : 629,
                "unit" : "W"
            },
            "Relative_Current_SelfConsumption" : {
                "value" : 100,
                "unit" : "%"
            },
            "Relative_Current_Autonomy" : {
                "value" : 21.815659,
                "unit" : "%"
            },
            "Power_P_SelfConsumption" : {
                "value" : -629,
                "unit" : "W"
            }
        }
    }
}

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Das sieht interessant aus! Ich kenne bisher nur die Fronius Solar API V1 - darin konnte ich aber den o.g. Query nicht finden. Ich bräuchte also bitte noch genauere Angaben zum Gerät. Evntl gibt es ja noch eine neuere Version der API ...

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

Der Wechselrichter ist ein Fronius Symo 5.0-3-M Bj. 2015 mit Integriertem Datenlogger und installiertem Smartmeter von Fronius.
Den Query hab ich auch zufällig im Internet gefunden als ich mit FHEM herumgespielt habe.
Mit diesen Daten wäre es einfacher Geräte per Überschuß zu schalten/steuern.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Ah, ok. Ich denke, dass ich den Thread gefunden habe: http://forum.fhem.de/index.php?topic=24614.15

Es handelt sich anscheinend um eine nicht dokumentierte Dienstfunktion des Datenlogger, der im Symo integriert ist. Also ich intgeriere dass gerne, es wir aber schon ein paar Tage dauern und Du musst dann das Versuchskaninchen spielen :)

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

Das wäre toll!
Wenn du mir erklärst was ich machen muss kann ich es gerne probieren!

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

gibts schon neuigkeiten?

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Leider nein. Ich was das ganze WE unterwegs. Ich schaue es mir in den kommenden Tagen an.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Hi, ich habe mal den ersten Wurf implementiert. Bitte probiere es mal aus.

Der Code ist aber noch nicht als npm package veröffentlicht. Du müsstest also bitte das git repository klonen. Wenn Du diesbezüglich weitere Informationen brauchst, sag einfach Bescheid und ich helfe Dir gerne weiter.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

@madison2007 Hattest Du den neuen Call schon ausprobiert? (siehe example.js)

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

Hi ,
Bin noch bis Freitag im urlaub.
Kann es mir erst ansehen wenn ich zu hause bin.
Sonnige grüße von den seychellen

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

^^ Du Glücklicher! Schöne Urlaubstage noch!

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

Danke!
Vielleicht kannst mir in der Zwischenzeit schildern was ich zum testen machen muss.

Lg

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

"Der Code ist aber noch nicht als npm package veröffentlicht. Du müsstest also bitte das git repository klonen. "
wie mache ich das?

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Ich habe ein neues Package gebaut. --> 0.0.5
Ich denke, dass es ist einfacher :)
Beispielcode findest Du in der example.js oder auch im README

In welchem Kontext willst Du das Package eigentlich einsetzen?

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

bin da noch ein neuling auf dem gebiet und steh im moment etwas auf der leitung ;-)
was muss ich mit dem package jetzt machen und was muss ich mit dem beispielcode machen?
sorry für meine dummen fragen ;-)

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Oha, hast Du noch nichts mit Node gemacht? Ich versuche hier mal die Super-Kurzanleitung:

  1. Nodejs installieren - enthält node (zur Ausführung von JS-Programmen) und npm (Paket-Manager). Siehe https://nodejs.org/en/, nimm dort die LTS-Version.
  2. Wenn der Rotz installiert ist, öffnest Du eine Command Shell. Darin sollte das Kommando "npm" ausführbar sein. Falls nicht, stimmt etwas mit den Systempfaden nicht.
  3. Paket installieren npm install node-fronius-solar
  4. Jetzt hast Du im aktuellen Verzeichnis ein Verzeichnis "node-fronius-solar". Darin liegt dann die Datei "example.js". Diese Datei musst Du noch editieren um die IP-Adresse anzupassen
  5. cd node-fronius-solar, dann examples.js ausführen node example.js

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

node hatte ich schon installiert, aber sonst habe ich noch nicht wirklich viel damit gemacht.
bei der ausführung kommt der fehler:

root@smart-home:/home/pi/pimatic-app/node_modules/pimatic-fronius-solar/node_modules/node-fronius-solar# node example.js

/home/pi/pimatic-app/node_modules/pimatic-fronius-solar/node_modules/node-fronius-solar/example.js:2
..    util = require('util'),
^
SyntaxError: Unexpected token .
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

ich hatte vorher schon das node-fronius-solar installiert.
sollte ich das vorher löschen oder kann man es darüber installieren?

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

habe das paket jetz ganz neu installiert.
bei node example.js kommt:

root@smart-home:/home/pi/pimatic-app/node_modules/node-fronius-solar# node example.js
{ [Error: connect ECONNREFUSED]
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect' }
{ [Error: connect ECONNREFUSED]
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect' }

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Sorry, Du musst auch den Port ändern. Vermutlich auf 80!

https://github.com/mwittig/node-fronius-solar/blob/master/example.js#L4-L5

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

die abfrage per node klappt soweit.

root@smart-home:/home/pi/pimatic-app/node_modules/node-fronius-solar# node example.js
{ Head:
   { RequestArguments:
      { DataCollection: 'CommonInverterData',
        DeviceClass: 'Inverter',
        DeviceId: '1',
        Scope: 'Device' },
     Status:
      { Code: 0,
        Reason: '',
        UserMessage: '' },
     Timestamp: '2016-03-21T12:30:27+01:00' },
  Body:
   { Data:
      { DAY_ENERGY: { Value: 7489, Unit: 'Wh' },
        FAC: { Value: 49.95, Unit: 'Hz' },
        IAC: { Value: 7.12, Unit: 'A' },
        IDC: { Value: 5.88, Unit: 'A' },
        PAC: { Value: 1686, Unit: 'W' },
        TOTAL_ENERGY: { Value: 525892, Unit: 'Wh' },
        UAC: { Value: 233.3, Unit: 'V' },
        UDC: { Value: 293.9, Unit: 'V' },
        YEAR_ENERGY: { Value: 478714, Unit: 'Wh' },
        DeviceStatus:
         { StatusCode: 7,
           MgmtTimerRemainingTime: -1,
           ErrorCode: 0,
           LEDColor: 2,
           LEDState: 0,
           StateToReset: false } } } }
1133 'milliseconds elapsed'
{ Head:
   { RequestArguments: { resource: '5/0/', print: 'names' },
     Status:
      { Code: 0,
        Reason: '',
        UserMessage: '',
        ErrorDetail: { Nodes: [] } },
     Timestamp: '2016-03-21T12:30:28+01:00' },
  Body:
   { Data:
      { TimeStamp: { value: 1458559826, unit: 'sec' },
        Enable: { value: 1, unit: '1' },
        Visible: { value: 1, unit: '1' },
        Power_P_Generate: { value: 1678, unit: 'W' },
        Power_P_Load: { value: -3473.91, unit: 'W' },
        Power_P_Grid: { value: 1795.91, unit: 'W' },
        Power_Akku_Sum: { value: null, unit: 'W' },
        Power_PV_Sum: { value: 1678, unit: 'W' },
        Relative_Current_SelfConsumption: { value: 100, unit: '%' },
        Relative_Current_Autonomy: { value: 48.302921, unit: '%' },
        Power_P_SelfConsumption: { value: -1678, unit: 'W' } } } }
1922 'milliseconds elapsed'

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Das sieht doch gut aus, oder? Nun ist die Frage wie Du die Daten verarbeiten willst?! Wenn es Dir hauptsächlich um die Abfrage der Daten via Web geht, solltest Du mal einen Blick auf "pimatic" werfen. Für pimatic habe ich auch einen Plugin geschrieben, allerdings müsste ich dies moch entsprechend um die neue Datenabfrage erweitern.

https://pimatic.org/
https://pimatic.org/plugins/pimatic-fronius-solar/

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

pimatic habe ich alles schon am laufen.
mir würde es darum gehen das ich die daten wie im pimatic-fronius-solar weiter verarbeiten kann.
nur eben mit der neuen abfrage.
interessant wären die statistiken und das ich auf die daten rules anwenden kann damit ich bei überschuss verbraucher per z-wave schalten kann um den eigenverbrauch zu erhöhen.
habe pimatic, fronius-solar und z-wave bereits alles installiert.
nur kann man mit den aktuellen daten im fronius-solar nicht viel bez. eigenverbrauch anfangen.
da wären die neuen daten hilfreicher!

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

ok, das klingt spannend. Ich gebe Dir Bescheid wenn ich eine neue Version von pimatic-fronius-solar fertig habe, Das wir aber ein paar Tage dauern

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

ok, bin schon neugierig ob das so funktioniert wie ich mir das vorstelle ;-)

from node-fronius-solar.

ikewestbrook avatar ikewestbrook commented on June 23, 2024

Würde mich ebenfalls interessieren!

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

Hab grade mal die URL per Browser angetestet. Bei mir greift dabei die Passwort - Abfrage (htaccess, user, pass) des Webfrontend. Die ist zwar abschaltbar, aber...
Den code habe ich noch nicht getestet.

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

Bei mir hängt der Fronius im internen netz, deshalb habe ich die Passwortabfrage abgedreht.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

@mplessing
Markus, wenn Du Dich ein wenig mit REST auskennst und einen REST-Client zur Hand hast (z.B. Postman für Chrome) könntest Du bitte mal username/pasword als authorization header mitschicken. Der Server müsste dies akzeptieren, falls die Authorisierung via HTTP-BasicAuth erfolgt.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Da fällt mir gerade ein, dass ich die Unterstützung für HTTP-BasicAuth bereits implementiert habe. Du könntest also auch mit "example.js" testen, wenn Du in den "options" noch "username" und "password" hinzufügst.

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

habe eben versucht das webfrontent mit user pw zu schützen.
klappt bei mir aber nicht, kommt keine abfrage.
kann sein das es da versionsbedingt unterschiede gibt.
ich habe die version:
Platinenversion 2.4D
Softwareversion 3.4.2-1

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

@mplessing
vielleicht kannst du es bei deinem fronius versuchen!

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

Klar, ich schau mir das heute Abend an :)

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

Hi,
war leider zu spät dran - Sonne war schon weg und WR hatte sich schlafen gelegt. Das mit der Basic-Auth teste ich also morgen. Ich habe unterwegs im ChangeLog für meinen WR aber folgendes gesehen und gleich mal aufgerufen. Solar-API Doku auf Seite 37.

Enthält fast alles bis auf Selfconsumption und Authonomie. Die habe ich nirgends gefunden.

Neue Abfrage in der solar api ab Version 3.3.9-X:
http://192.168.x.xxx/solar_api/v1/GetPowerFlowRealtimeData.fcgi

Die Abfrage läuft ohne Parameter und gibt bei mir das zurück (Ohne S0-Zähler am WR sind die Werte "null"):

{
    "Head" : {
        "RequestArguments" : {},
        "Status" : {
            "Code" : 0,
            "Reason" : "",
            "UserMessage" : ""
        },
        "Timestamp" : "2016-03-25T15:19:21+01:00"
    },
    "Body" : {
        "Data" : {
            "Site" : {
                "Mode" : "produce-only",
                "P_Grid" : null,
                "P_Load" : null,
                "P_Akku" : null,
                "P_PV" : 291,
                "E_Day" : 7653,
                "E_Year" : 841228,
                "E_Total" : 7978902
            },
            "Inverters" : {
                "1" : {
                    "DT" : 110,
                    "P" : 291
                }
            }
        }
    }
}

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

meiner sagt bei der Abfrage:

{
    "Head" : {
        "RequestArguments" : {},
        "Status" : {
            "Code" : 0,
            "Reason" : "",
            "UserMessage" : ""
        },
        "Timestamp" : "2016-03-26T08:06:19+01:00"
    },
    "Body" : {
        "Data" : {
            "Site" : {
                "Mode" : "meter",
                "P_Grid" : 647.46,
                "P_Load" : -915.46,
                "P_Akku" : null,
                "P_PV" : 268,
                "E_Day" : 399,
                "E_Year" : 533025,
                "E_Total" : 580203.0625,
                "Meter_Location" : "grid"
            },
            "Inverters" : {
                "1" : {
                    "DT" : 122,
                    "P" : 268
                }
            }
        }
    }
}

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

@mwittig Hatte keinen Erfolg heute mit BasicAuth (username, password) in den options der example.js
Was kann das noch für ein AuthTyp sein?

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

Hallo nochmal, grade mit nem Sniffer geprüft, es wird ein Digest-Auth benutzt.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Hi Markus, vielen Dank für die Rückmeldung! Ich habe mal eine experimentelle Unterstützung für Digest-Auth realisiert. Es wäre toll, wenn Du es mal ausprobieren könntest. Da ich noch kein Paket gebaut habe, muss Du es folgendermassen installieren:

# git muss installiert sein, `sudo apt-get install git-core
npm install mwittig/node-fronius-solar

Ich plane auch "GetPowerFlowRealtimeData.fcgi" zu unterstützen. Dieser Call scheint mir noch besser geeignet, da auch die akkumulierten Werte (Tag/Jahr/Total) der PV-Erzeugung zurückgegeben werden.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Ich habe einen ersten Wurf für die Unterstützung von "ComponentsData" in Pimatic realisiert. Der Code ist aber noch nicht veröffentlicht, da ich noch diverse Tests durchführen muss und ich gerne noch das Thema "DigestAuth" klären würde. "GetPowerFlowRealtimeData" werde ich auf auch unterstützen.

Screenshot

Ihr werdet selber auf einfache Weise festlegen können, welche Attribute das Device haben soll. Wenn Ihr z.B. keine Batterie habt, könnt ihr "powerAkkuSum" weglassen. Zusätzlich könnt ihr natürlich mittels "xAttributeOptions" Attribute ausblenden, die nicht angezeigt werden sollen aber dennoch z.B. für Regeln verfügbar sein sollen.

...
FroniusComponentsData: {
    title: "Fronius GetComponentsData Device (using an undocumented API call of the PV data logger)"
    description: "Provides access to data of a Fronius Inverter supporting Solar API 1.1"
    type: "object"
    extensions: ["xLink", "xAttributeOptions"]
    properties:
      attributes:
        type: "array"
        default: ["powerGenerate", "powerLoad", "powerGrid", "powerAkkuSum", "powerPvSum", "relativeSelfConsumption", "relativeAutonomy", "powerSelfConsumption"]
        format: "table"
        items:
          type: "string"
...
    {
      "id": "fronius2",
      "class": "FroniusComponentsData",
      "name": "Fronius Inverter 2",
      "host": "localhost",
      "attributes": [
        "powerGenerate",
        "relativeSelfConsumption",
        "relativeAutonomy"
      ]
    },

Screenshot

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

@mplessing "Es geht um GetPowerFlowRealtimeData". Hast Du einen Link auf die aktuelle API-Dokumentation? In der Version, die ich auf der Web-Site gefunden habe sind E_day, E_Month und E_Total nicht dokumentiert.

from node-fronius-solar.

madison2007 avatar madison2007 commented on June 23, 2024

die auth kann ich leider nicht testen, egal was ich einstelle, bei mir kommt keine auth abfrage!

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

Hallo Marcus,

ich habe ehrlich gesagt auch kein aktuelles Dokument gefunden, das diese Parameter enthält, sie sind aber offenbar bei beiden Testern vorhanden... kein Plan :D

Mit dem neuen modul bekomme ich gar keinen output und wenn ich consoleDebug forciere, sehe ich die params und dass er beim ersten Aufruf schon aussteigt. Der Zweite für "CommonInverterData" wird gar nicht mehr gemacht.

Beim test-server geht es problemlos.
Bei Verbindung mit meinem Fronius nur, wenn ich den ersten Aufruf auskommentiere.

Der Digest-Auth scheint also zu funktionieren, aber scheinbar nicht mehr der reguläre solar_api call.

Grüße Markus

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Hi Markus, danke für die Info! Kann sein, dass die Digest-Auth nur für den undokumentierten Call notwendig ist, da der Call ein Bestandteil der WebAnwendung ist?! Die reguläre Solar-API funktionierte bei Dir doch auch vorher komplett ohne Authentisierung, oder? Die Solar-API enthält ja auch nichts zum Thema Authentisierung.

Also dann schreibe ich den Digest-Client so um, dass der Client den Service Call ohne Authensierung auufruft, falls der Server fpr den ersten HTTP-Request kein "Nonce" schickt. So müsste es mit beiden Services funktionieren.

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

Genau, solar_api ist ohne auth, das andere ist irgendein anderer interner json-call. Ich denke auch, dass es in der vorgeschlagenen Weise gehen wird.

Grüße Markus

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Ok, ich habe die library mal entsprechend aktualisiert. Es wäre toll, wenn Du das noch mal bei Gelegenheit testen könntest. Du musst einfach noch mal "npm install mwittig/node-fronius-solar" ausführen um den aktuellen Stand zu bekommen.

from node-fronius-solar.

mplessing avatar mplessing commented on June 23, 2024

Grade getestet, sieht gut aus. Beide Aufrufe liefern Daten :)

Nur der Vollständigkeit halber:
Platinenversion 2.2B
Softwareversion 3.4.2-1

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Super! Danke fürs Ausprobieren! Ich werde dann noch "GetPowerFlowRealtimeData" integrieren und in paar Tagen eine neue Version des Plugin fertigstellen.

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

Ich habe den aktuellen Stand released und auch das PimaticPlugin entsprechend erweitert. Details hierzu findet ihr im README. Vielen Dank für Eure Anregungen und die Unterstützung beim Testen. Ich wünsche Euch viel Spass beim Ausprobieren!

Für Probleme mit dem Pimatic Plugin benutzt bitte auch den Issue Tracker auf der Plugin-Projektseite. Wenn Euch das Plugin gefällt, würde ich mich natürlich auch über Eure "Sterne" auf der Plugin-Projektseite oder "Upvotes" im Forum freuen :)

from node-fronius-solar.

mwittig avatar mwittig commented on June 23, 2024

@madison2007 Hallo. Ich wollte mal hören, ob Du das Pimatic Plugin einsetzt und Regeln zur Eigenverbrauchsoptimierung nutzt. Wir haben hierzu eine Anfrage im Forum. https://forum.pimatic.org/topic/1760/fronius-inverter-connectivity

from node-fronius-solar.

Related Issues (5)

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.