UW6CVVLAGPKK7R6YMWJXCLHZ2CIZ5D5PM4SYUYMEWM4IZ2LNAHZAC 7MCTB5G2W6IB7JQXGO2HCMRHBUYIOKXI4MBODKLAJIK66EMLC5ZQC DWRIJC3G3GO36DMH65IRX4ZQQWMV34ALGAJCY36EWG6XDQDCFKLAC YG7GE7B4XADVZW6KH3YSLWTT2SWZG6TMANKXZGD7PFD7LZZKNIXAC LGZNYFFGJK4SH7YLVPOYQXMMCBRVJL7WVB4IUPFG2DIYDIRFDY3AC TTGQE67TYYDNM3Y7JV3CCS4UC4JKXRQQW7APQWF3WUEETENLA4FAC CR2255NATVJXRQTX4WYZAVA25EFXMPPJNOBEEGW3ABPJF72KOHQAC STDY5XXCKSH6GAHQLYZDNU7BUONGLAPHNQZR2HSFZE7F4IWE3AUQC 6P7BMIJ3DK5H2DWBJNOF2PNVHL3GO7HA4GVS6DHSJ7VQNEJW4A7QC O4JWKS2JQCFJWX5UHTPR7XTWGELR7ZEFISK62ZNMGUJ6DZQ5HZ7QC N44CYCGQAWWGNV4D53SEJFM4UTSEZDT2YO33XGFXI2W37HQHKWDQC import { browser } from '$app/environment'import { onMount, tick } from 'svelte'import type { Writable } from 'svelte/store'import { get } from 'svelte/store'import { getContext } from 'svelte'import type * as P from 'plotly.js-dist-min'import * as Grain from '../../../../../grain-types'import {chooseScale,relayout,modeBarButtonsToRemove,} from '../../../../../plot'import type { Sample } from '../../../../../plot'import type { Derived, PVGIS, PVGISInputs } from '../calcul'import * as calcul from '../calcul'import PlusCircle from '../../../../PlusCircle.svelte'import XCircle from '../../../../XCircle.svelte'import Question from '../../../../Question.svelte'
import { browser } from '$app/environment'import { onMount, tick } from 'svelte'import type { Writable } from 'svelte/store'import { get } from 'svelte/store'import { getContext } from 'svelte'import type * as P from 'plotly.js-dist-min'import * as Grain from '../../../../../grain-types'import {chooseScale,relayout,modeBarButtonsToRemove,} from '../../../../../plot'import type { Sample } from '../../../../../plot'import type { Derived, PVGIS, PVGISInputs } from '../calcul'import * as calcul from '../calcul'import PlusCircle from '../../../../PlusCircle.svelte'import XCircle from '../../../../XCircle.svelte'import Question from '../../../../Question.svelte'
let s: Derived = getContext('simulation')let prms: Writable<{prm: null | numbernom: stringprenom: stringsiret: stringpro: booleanconsentement: booleanreleve?: stringnumerorue?: stringcodeinsee?: stringserie?: string}[]> = getContext('prms')let prms_modified: Writable<boolean> = getContext('prms_modified')let profils: Writable<{ type: string; conso: number }[]> =getContext('profils')let profils_modified: Writable<boolean> = getContext('profils_modified')const soleil: Writable<Sample> = getContext('soleil')const expert: Writable<boolean> = getContext('expert')let _communaute: Writable<(Grain.Communaute & { isMoving?: boolean }) | null> = getContext('communaute')
let s: Derived = getContext('simulation')let prms: Writable<{prm: null | numbernom: stringprenom: stringsiret: stringpro: booleanconsentement: booleanreleve?: stringnumerorue?: stringcodeinsee?: stringserie?: string}[]> = getContext('prms')let prms_modified: Writable<boolean> = getContext('prms_modified')let profils: Writable<{ type: string; conso: number }[]> =getContext('profils')let profils_modified: Writable<boolean> = getContext('profils_modified')const soleil: Writable<Sample> = getContext('soleil')const expert: Writable<boolean> = getContext('expert')let _communaute: Writable<(Grain.Communaute & { isMoving?: boolean }) | null> = getContext('communaute')
const annee = $derived.by(() => {console.log('derived by')let annee = data.anneeif (!annee) {annee = {}}for (let i = 0; i < $prms.length; i++) {const p = $prms[i]if (p.releve) {annee[p.prm || i] = []for (const j of p.releve.split('\n')) {const l = j.split(/;|,| /)if (l.length >= 2) {const d = new Date(l[0])const v = parseInt(l[1])if (d && !isNaN(v)) {annee[p.prm || i].push(v)}}}console.log(annee[p.prm || i])}}return annee})
const annee = $derived.by(() => {console.log('derived by')let annee = data.anneeif (!annee) {annee = {}}for (let i = 0; i < $prms.length; i++) {const p = $prms[i]if (p.releve) {annee[p.prm || i] = []for (const j of p.releve.split('\n')) {const l = j.split(/;|,| /)if (l.length >= 2) {const d = new Date(l[0])const v = parseInt(l[1])if (d && !isNaN(v)) {annee[p.prm || i].push(v)}}}console.log(annee[p.prm || i])}}return annee})
function addPrm() {console.log('ajouter un compteur')prms.update((prms) => {prms.push({prm: null,nom: '',prenom: '',siret: '',pro: true,consentement: false,})return prms})prms_modified.set(true)}
function addPrm() {console.log('ajouter un compteur')prms.update((prms) => {prms.push({prm: null,nom: '',prenom: '',siret: '',pro: true,consentement: false,})return prms})prms_modified.set(true)}
onMount(async () => {Plotly = await import('plotly.js-dist-min')s.p.puissance.subscribe((value) => {puissance = valueif (initialised) {updatePlot(puissance, communaute)}})_communaute.subscribe((value) => {communaute = valueif (initialised) {updatePlot(puissance, communaute)}})pvgis.subscribe((pvgis) => {console.log('pvgis updated')if (initialised && pvgis.pvgis?.inputs != pvgis_) {pvgis_ = pvgis.pvgis?.inputs || nullupdatePlot(puissance, communaute)}})if ($prms.length) {for (let p of $prms) {p.consentement = false}}initialised = trueupdatePlot(puissance, communaute)})
onMount(async () => {Plotly = await import('plotly.js-dist-min')s.p.puissance.subscribe((value) => {puissance = valueif (initialised) {updatePlot(puissance, communaute)}})_communaute.subscribe((value) => {communaute = valueif (initialised) {updatePlot(puissance, communaute)}})pvgis.subscribe((pvgis) => {console.log('pvgis updated')if (initialised && pvgis.pvgis?.inputs != pvgis_) {pvgis_ = pvgis.pvgis?.inputs || nullupdatePlot(puissance, communaute)}})if ($prms.length) {for (let p of $prms) {p.consentement = false}}initialised = trueupdatePlot(puissance, communaute)})
let darkMode = falseif (browser) {darkMode =window.matchMedia &&window.matchMedia('(prefers-color-scheme: dark)').matcheswindow.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {darkMode = !!event.matchesredraw()})}
let darkMode = falseif (browser) {darkMode =window.matchMedia &&window.matchMedia('(prefers-color-scheme: dark)').matcheswindow.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {darkMode = !!event.matchesredraw()})}
function addProfil() {profils.update((p) => {const prt = Object.keys(profils_)p.push({ type: prt[0], conso: 0 })return p})profils_modified.set(true)updatePlot(puissance, communaute)}
function addProfil() {profils.update((p) => {const prt = Object.keys(profils_)p.push({ type: prt[0], conso: 0 })return p})profils_modified.set(true)updatePlot(puissance, communaute)}
function delProfil(i: number) {profils.update((p) => {p.splice(i, 1)return p})profils_modified.set(true)updatePlot(puissance, communaute)}
function delProfil(i: number) {profils.update((p) => {p.splice(i, 1)return p})profils_modified.set(true)updatePlot(puissance, communaute)}
async function refresh(event: SubmitEvent) {event.preventDefault()prms_modified.set(true)if ($prms) {prm_loading = trueawait tick()for (let i = 0; i < $prms.length; i++) {var file = document.getElementById(`releve-${i}`) as HTMLInputElement | nullconsole.log('FILE', file?.files)if (file?.files?.length) {var reader = new FileReader()reader.readAsText(file.files[0], 'UTF-8')let r: string | undefined = await new Promise((resolve) => {reader.onload = function (evt) {console.log(typeof evt.target?.result)let result = evt.target?.result?.toString()if (result) {resolve(result)} else {resolve(undefined)}}})console.log('r', r)$prms[i].releve = r}let siret = document.getElementById(`siret-${i}`) as HTMLInputElement | nullif (siret?.value) {let now = performance.now()// Rate-limiting: pas plus de 7 requêtes par seconde.if (now - lastRequest < 150) {await sleep(150 - (now - lastRequest))}lastRequest = nowconst resp = await fetch(`https://recherche-entreprises.api.gouv.fr/search?q=${siret.value}`)if (resp.status == 200) {type Ent = {results: {dirigeants: {nom: stringprenoms: string}[]matching_etablissements: {libelle_voie: stringcommune: string}[]}[]}let ent: Ent = await resp.json()console.log(ent.results[0].matching_etablissements[0].commune)if (ent.results.length) {$prms[i].nom = ent.results[0].dirigeants[0].nom$prms[i].prenom =ent.results[0].dirigeants[0].prenoms$prms[i].codeinsee =ent.results[0].matching_etablissements[0].communeconsole.log($prms[i])}}}}console.log($prms)const resp = await fetch(`${Grain.server}/api/grain/projet/${data_.id || 'nouveau'}/prms`,{method: 'POST',body: JSON.stringify($prms),})if (resp.ok) {data.annee = await resp.json()}prm_loading = falseawait tick()} else {erreur = 'La liste des PRMs est vide'}await updatePlot(puissance, communaute)}
async function refresh(event: SubmitEvent) {event.preventDefault()prms_modified.set(true)if ($prms) {prm_loading = trueawait tick()for (let i = 0; i < $prms.length; i++) {var file = document.getElementById(`releve-${i}`) as HTMLInputElement | nullconsole.log('FILE', file?.files)if (file?.files?.length) {var reader = new FileReader()reader.readAsText(file.files[0], 'UTF-8')let r: string | undefined = await new Promise((resolve) => {reader.onload = function (evt) {console.log(typeof evt.target?.result)let result = evt.target?.result?.toString()if (result) {resolve(result)} else {resolve(undefined)}}})console.log('r', r)$prms[i].releve = r}let siret = document.getElementById(`siret-${i}`) as HTMLInputElement | nullif (siret?.value) {let now = performance.now()// Rate-limiting: pas plus de 7 requêtes par seconde.if (now - lastRequest < 150) {await sleep(150 - (now - lastRequest))}lastRequest = nowconst resp = await fetch(`https://recherche-entreprises.api.gouv.fr/search?q=${siret.value}`)if (resp.status == 200) {type Ent = {results: {dirigeants: {nom: stringprenoms: string}[]matching_etablissements: {libelle_voie: stringcommune: string}[]}[]}let ent: Ent = await resp.json()console.log(ent.results[0].matching_etablissements[0].commune)if (ent.results.length) {$prms[i].nom = ent.results[0].dirigeants[0].nom$prms[i].prenom =ent.results[0].dirigeants[0].prenoms$prms[i].codeinsee =ent.results[0].matching_etablissements[0].communeconsole.log($prms[i])}}}}console.log($prms)const resp = await fetch(`${Grain.server}/api/grain/projet/${data_.id || 'nouveau'}/prms`,{method: 'POST',body: JSON.stringify($prms),})if (resp.ok) {data.annee = await resp.json()}prm_loading = falseawait tick()} else {erreur = 'La liste des PRMs est vide'}await updatePlot(puissance, communaute)}
let somme: Sample = {hourly: {x: [],y: [],},daily: {x: [],y: [],},weekly: {x: [],y: [],},x: [],y: [],type: 'bar',line: {color: '#b81111',width: 1,},marker: {color: '#b81111',width: 1,},name: 'Consommation totale',bucket: 1,}
let somme: Sample = {hourly: {x: [],y: [],},daily: {x: [],y: [],},weekly: {x: [],y: [],},x: [],y: [],type: 'bar',line: {color: '#b81111',width: 1,},marker: {color: '#b81111',width: 1,},name: 'Consommation totale',bucket: 1,}
async function updatePv(puissance: number,communaute: (Grain.Communaute & { isMoving?: boolean }) | null) {if (communaute?.isMoving) {return pvgis}pvgis_loading = trueawait calcul.updatePv(puissance, communaute, pvgis, soleil)pvgis_loading = falseawait tick()}
async function updatePv(puissance: number,communaute: (Grain.Communaute & { isMoving?: boolean }) | null) {if (communaute?.isMoving) {return pvgis}pvgis_loading = trueawait calcul.updatePv(puissance, communaute, pvgis, soleil)pvgis_loading = falseawait tick()}
async function updatePlot(puissance: number,communaute: (Grain.Communaute & { isMoving?: boolean }) | null) {console.log('isMoving', communaute?.isMoving)if (communaute?.isMoving) {return}if (!browser) {return}
async function updatePlot(puissance: number,communaute: (Grain.Communaute & { isMoving?: boolean }) | null) {console.log('isMoving', communaute?.isMoving)if (communaute?.isMoving) {return}if (!browser) {return}
await updatePv(puissance, communaute)console.log('updated')prm_loading = truelet auto_ = await calcul.updatePlot(annee || {},$profils,profils_,somme,soleil)prm_loading = falseauto = auto_.autototalProd = auto_.totalProdtotalConso = auto_.totalConsoconsole.log('updated auto', auto, totalProd, totalConso)if (!Plotly) {Plotly = await import('plotly.js-dist-min')}redraw()}
await updatePv(puissance, communaute)console.log('updated')prm_loading = truelet auto_ = await calcul.updatePlot(annee || {},$profils,profils_,somme,soleil)prm_loading = falseauto = auto_.autototalProd = auto_.totalProdtotalConso = auto_.totalConsoconsole.log('updated auto', auto, totalProd, totalConso)if (!Plotly) {Plotly = await import('plotly.js-dist-min')}redraw()}
function relayout_(event: Plotly.PlotRelayoutEvent) {console.log('relayout_')const plot = document.getElementById('plot')!relayout(event, plot, Plotly, layout, has_plot, {prod: get(soleil),conso: somme,})}
function relayout_(event: Plotly.PlotRelayoutEvent) {console.log('relayout_')const plot = document.getElementById('plot')!relayout(event, plot, Plotly, layout, has_plot, {prod: get(soleil),conso: somme,})}
function redraw() {console.log('redraw')const plot = document.getElementById('plot')if (!plot) returnlet soleil_ = get(soleil)chooseScale(soleil_)chooseScale(somme)let unite: stringif (soleil_.bucket == 24) {unite = 'kWh/jour'} else if (soleil_.bucket == 24 * 7) {unite = 'kWh/semaine'} else {unite = 'kWh'}layout = {title: 'Autoconsommation',autosize: true,automargin: true,plot_bgcolor: '#fff0',paper_bgcolor: '#fff0',font: {color: darkMode ? '#fff' : '#000',},xaxis: {gridcolor: darkMode ? '#444' : '#bbb',ticklabeloverflow: 'allow',ticklabelstep: 4,tickangle: 45,tickformat: soleil_.bucket < 24 ? '%x %X' : '%x',type: 'datetime',},yaxis: {title: { text: unite },gridcolor: darkMode ? '#444' : '#bbb',color: darkMode ? '#fff' : '#000',},showlegend: true,legend: {xanchor: 'center',x: 0.5,y: -0.4,orientation: 'h',},}
function redraw() {console.log('redraw')const plot = document.getElementById('plot')if (!plot) returnlet soleil_ = get(soleil)chooseScale(soleil_)chooseScale(somme)let unite: stringif (soleil_.bucket == 24) {unite = 'kWh/jour'} else if (soleil_.bucket == 24 * 7) {unite = 'kWh/semaine'} else {unite = 'kWh'}layout = {title: 'Autoconsommation',autosize: true,automargin: true,plot_bgcolor: '#fff0',paper_bgcolor: '#fff0',font: {color: darkMode ? '#fff' : '#000',},xaxis: {gridcolor: darkMode ? '#444' : '#bbb',ticklabeloverflow: 'allow',ticklabelstep: 4,tickangle: 45,tickformat: soleil_.bucket < 24 ? '%x %X' : '%x',type: 'datetime',},yaxis: {title: { text: unite },gridcolor: darkMode ? '#444' : '#bbb',color: darkMode ? '#fff' : '#000',},showlegend: true,legend: {xanchor: 'center',x: 0.5,y: -0.4,orientation: 'h',},}
if (has_plot.has_plot) {console.log('has plot')//@ts-expect-error Plotly+typescript = mehPlotly!.update(plot, [soleil, somme], layout)} else {console.log("doesn't have plot")//@ts-expect-error Plotly+typescript = mehPlotly!.newPlot(plot, [soleil_, somme], layout, {responsive: true,modeBarButtonsToRemove: modeBarButtonsToRemove,})//@ts-expect-error Plotly+typescript = mehplot.on('plotly_relayout', relayout_)has_plot.has_plot = true}
if (has_plot.has_plot) {console.log('has plot')//@ts-expect-error Plotly+typescript = mehPlotly!.update(plot, [soleil, somme], layout)} else {console.log("doesn't have plot")//@ts-expect-error Plotly+typescript = mehPlotly!.newPlot(plot, [soleil_, somme], layout, {responsive: true,modeBarButtonsToRemove: modeBarButtonsToRemove,})//@ts-expect-error Plotly+typescript = mehplot.on('plotly_relayout', relayout_)has_plot.has_plot = true}
var dataProd = [{values: [Math.round(auto), Math.round(totalProd - auto)],labels: ['Autoconsommé', 'Surplus'],marker: { colors: ['#ffbf00dd', '#b81111dd'] },type: 'pie',sort: false,hole: 0.5,},]
var dataProd = [{values: [Math.round(auto), Math.round(totalProd - auto)],labels: ['Autoconsommé', 'Surplus'],marker: { colors: ['#ffbf00dd', '#b81111dd'] },type: 'pie',sort: false,hole: 0.5,},]
var dataConso = [{values: [Math.round(auto), Math.round(totalConso - auto)],labels: ['Autoproduit', 'Fournisseur'],marker: { colors: ['#ffbf00dd', '#b81111dd'] },type: 'pie',sort: false,hole: 0.5,},]
var dataConso = [{values: [Math.round(auto), Math.round(totalConso - auto)],labels: ['Autoproduit', 'Fournisseur'],marker: { colors: ['#ffbf00dd', '#b81111dd'] },type: 'pie',sort: false,hole: 0.5,},]
if (totalProd && totalConso) {plotStyle = 'min-height:450px'Plotly.react('autoProd',//@ts-expect-error Plotly+typescript = mehdataProd,{title: "Autoconsommation sur l'année",font: {color: darkMode ? '#fff' : '#000',},plot_bgcolor: '#fff0',paper_bgcolor: '#fff0',autosize: true,automargin: true,legend: {orientation: 'h',},},{ responsive: true })Plotly.react('autoConso',//@ts-expect-error Plotly+typescript = mehdataConso,{title: "Autoproduction sur l'année",font: {color: darkMode ? '#fff' : '#000',},plot_bgcolor: '#fff0',paper_bgcolor: '#fff0',autosize: true,automargin: true,legend: {orientation: 'h',},},{ responsive: true })} else {plotStyle = ''}}
if (totalProd && totalConso) {plotStyle = 'min-height:450px'Plotly.react('autoProd',//@ts-expect-error Plotly+typescript = mehdataProd,{title: "Autoconsommation sur l'année",font: {color: darkMode ? '#fff' : '#000',},plot_bgcolor: '#fff0',paper_bgcolor: '#fff0',autosize: true,automargin: true,legend: {orientation: 'h',},},{ responsive: true })Plotly.react('autoConso',//@ts-expect-error Plotly+typescript = mehdataConso,{title: "Autoproduction sur l'année",font: {color: darkMode ? '#fff' : '#000',},plot_bgcolor: '#fff0',paper_bgcolor: '#fff0',autosize: true,automargin: true,legend: {orientation: 'h',},},{ responsive: true })} else {plotStyle = ''}}
--color-base-200: oklch(88% 0.0117 37.42);--color-base-300: oklch(85% 0.0117 37.42);--color-base-content: oklch(12% 0.042 264.695);--color-primary: #b81413;--color-primary-content: oklch(98% 0.003 247.858);--color-secondary: #de5e1c;--color-secondary-content: oklch(94% 0.028 342.258);--color-accent: #b81413;--color-accent-content: oklch(98% 0.003 247.858);--color-neutral: oklch(14% 0.005 285.823);--color-neutral-content: oklch(98% 0.003 247.858);--color-info: oklch(0.8403 0.1724 84.08);--color-info-content: oklch(12% 0.042 264.695);--color-success: oklch(76% 0.177 163.223);--color-success-content: oklch(37% 0.077 168.94);--color-warning: oklch(82% 0.189 84.429);--color-warning-content: oklch(41% 0.112 45.904);--color-error: oklch(0.5915 0.202 21.24);--color-error-content: oklch(27% 0.105 12.094);
--color-base-200: oklch(88% 0.0117 37.42);--color-base-300: oklch(85% 0.0117 37.42);--color-base-content: oklch(12% 0.042 264.695);--color-primary: #b81413;--color-primary-content: oklch(98% 0.003 247.858);--color-secondary: #de5e1c;--color-secondary-content: oklch(94% 0.028 342.258);--color-accent: #b81413;--color-accent-content: oklch(98% 0.003 247.858);--color-neutral: oklch(14% 0.005 285.823);--color-neutral-content: oklch(98% 0.003 247.858);--color-info: oklch(0.8403 0.1724 84.08);--color-info-content: oklch(12% 0.042 264.695);--color-success: oklch(76% 0.177 163.223);--color-success-content: oklch(37% 0.077 168.94);--color-warning: oklch(82% 0.189 84.429);--color-warning-content: oklch(41% 0.112 45.904);--color-error: oklch(0.5915 0.202 21.24);--color-error-content: oklch(27% 0.105 12.094);
--color-primary: #b81413;--color-primary-content: white;--color-secondary: #de5e1c;--color-secondary-content: black;--color-accent: #b81413;--color-accent-content: white;--color-info: oklch(0.8403 0.1724 84.08);--color-info-content: black;--color-success: oklch(76% 0.177 163.223);--color-success-content: oklch(37% 0.077 168.94);--color-warning: oklch(82% 0.189 84.429);--color-warning-content: oklch(41% 0.112 45.904);--color-error: oklch(0.5915 0.202 21.24);--color-error-content: oklch(27% 0.105 12.094);--tab-border-color: white;
--color-primary: #b81413;--color-primary-content: white;--color-secondary: #de5e1c;--color-secondary-content: black;--color-accent: #b81413;--color-accent-content: white;--color-info: oklch(0.8403 0.1724 84.08);--color-info-content: black;--color-success: oklch(76% 0.177 163.223);--color-success-content: oklch(37% 0.077 168.94);--color-warning: oklch(82% 0.189 84.429);--color-warning-content: oklch(41% 0.112 45.904);--color-error: oklch(0.5915 0.202 21.24);--color-error-content: oklch(27% 0.105 12.094);--tab-border-color: white;