Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload file js #163

Merged
merged 2 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldMetadata, useForm } from '@conform-to/react'

Check warning on line 1 in heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

'FieldMetadata' is defined but never used

Check warning on line 1 in heat-stack/app/components/ui/heat/CaseSummaryComponents/EnergyUseHistory.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

'useForm' is defined but never used
import { Form } from '@remix-run/react'
import { ErrorList } from "./ErrorList.tsx"
import { Input } from '#/app/components/ui/input.tsx'
Expand All @@ -7,6 +7,7 @@

import { AnalysisHeader } from './AnalysisHeader.tsx'
import { EnergyUseHistoryChart } from './EnergyUseHistoryChart.tsx'
import { Upload } from 'lucide-react'


// type EnergyUseProps = {fields: any};
Expand All @@ -20,10 +21,44 @@
<div>
<h2 className={`${titleClass}`}>Energy Use History</h2>
<div>
<Button type="submit">Upload</Button>
<input
id="energy_use_upload"
aria-label="Upload your energy billing company's bill."
onChange={event => {
const file = event.target.files?.[0]
if (file) {
// const reader = new FileReader()
// reader.onloadend = async (event) => {
// console.log('reader.result', reader.result)
// }
// reader.readAsText(file)
} else {
// setPreviewImage(null)
}
console.log('Boom!')
}}
name="energy_use_upload"
type="file"
accept="text/csv"
/>
<Button type="submit"> <Upload className="h-4 w-4 mr-2" /> Upload</Button>
</div>
<AnalysisHeader />
<EnergyUseHistoryChart />
</div>
)
}



// const file = event.target.files?.[0]

// if (file) {
// const reader = new FileReader()
// reader.onloadend = () => {
// setPreviewImage(reader.result as string)
// }
// reader.readAsDataURL(file)
// } else {
// setPreviewImage(null)
// }
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ export function HomeInformation(props: HomeInformationProps) {

<div className="mt-4 flex space-x-2">
<div>
<Input name={props.fields.livingSpace.name} id="livingArea" type="number" />
<Input name={props.fields.livingArea.name} id="livingArea" type="number" />
<div className="min-h-[32px] px-4 pb-3 pt-1">
<ErrorList
id={props.fields.livingSpace.errorId}
errors={props.fields.livingSpace.errors}
id={props.fields.livingArea.errorId}
errors={props.fields.livingArea.errors}
/>
</div>
<p className={`${descriptiveClass}`}>
Expand Down
4 changes: 2 additions & 2 deletions heat-stack/app/routes/_heat+/Inputs1.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const addressMaxLength = 100
const HomeInformationSchema = z.object({
name: z.string().min(1).max(nameMaxLength),
address: z.string().min(1).max(addressMaxLength),
livingSpace: z.number().min(1),
livingArea: z.number().min(1),
})

export async function action({ request, params }: ActionFunctionArgs) {
Expand Down Expand Up @@ -56,7 +56,7 @@ export async function action({ request, params }: ActionFunctionArgs) {
// - [ ] Build form #2 and #3
// - [ ] Form errors (if we think of a use case - 2 fields conflicting...)

const { name, address, livingSpace } = submission.value
const { name, address, livingArea } = submission.value

// await updateNote({ id: params.noteId, title, content })

Expand Down
99 changes: 98 additions & 1 deletion heat-stack/app/routes/_heat+/single.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { invariantResponse } from '@epic-web/invariant'
import { json, ActionFunctionArgs } from '@remix-run/node'
import { Form, redirect, useActionData } from '@remix-run/react'
import { z } from 'zod'
import GeocodeUtil from "#app/utils/GeocodeUtil.js";
import WeatherUtil from "#app/utils/WeatherUtil.js";
import PyodideUtil from "#app/utils/pyodide.util.js";

// TODO NEXT WEEK
// - [x] Server side error checking/handling
Expand All @@ -32,6 +35,7 @@ import { HomeInformation } from '../../components/ui/heat/CaseSummaryComponents/
import HeatLoadAnalysis from './heatloadanalysis.tsx'
import { Button } from '#/app/components/ui/button.tsx'


const nameMaxLength = 50
const addressMaxLength = 100

Expand Down Expand Up @@ -69,12 +73,15 @@ export async function action({ request, params }: ActionFunctionArgs) {
// Checks if url has a homeId parameter, throws 400 if not there
// invariantResponse(params.homeId, 'homeId param is required')

console.log("action started")

const formData = await request.formData()
const submission = parseWithZod(formData, {
schema: Schema,
})

if (submission.status !== 'success') {
console.error("submission failed",submission)
return submission.reply()
// submission.reply({
// // You can also pass additional error to the `reply` method
Expand All @@ -97,10 +104,99 @@ export async function action({ request, params }: ActionFunctionArgs) {
designTemperatureOverride } = submission.value

// await updateNote({ id: params.noteId, title, content })
//code snippet from - https://github.com/epicweb-dev/web-forms/blob/2c10993e4acffe3dd9ad7b9cb0cdf89ce8d46ecf/exercises/04.file-upload/01.solution.multi-part/app/routes/users%2B/%24username_%2B/notes.%24noteId_.edit.tsx#L180

// const formData = await parseMultipartFormData(
// request,
// createMemoryUploadHandler({ maxPartSize: MAX_UPLOAD_SIZE }),
// )

console.log("loading PU/PM/GU/WU");

// CONSOLE: loading PU/PM/GU/WU
// Error: No known package with name 'pydantic_core'
// Error: No known package with name 'pydantic_core'
// at addPackageToLoad (/workspaces/home-energy-analysis-tool/heat-stack/public/pyodide-env/pyodide.asm.js:9:109097)
// at recursiveDependencies (/workspaces/home-energy-analysis-tool/heat-stack/public/pyodide-env/pyodide.asm.js:9:109370)
// at loadPackage (/workspaces/home-energy-analysis-tool/heat-stack/public/pyodide-env/pyodide.asm.js:9:111435)
// at initializePackageIndex (/workspaces/home-energy-analysis-tool/heat-stack/public/pyodide-env/pyodide.asm.js:9:108508)

// const PU = PyodideUtil.getInstance();
// const PM = await PU.getPyodideModule();
const GU = new GeocodeUtil();
const WU = new WeatherUtil();
// console.log("loaded PU/PM/GU/WU");

/**
*
* @param longitude
* @param latitude
* @param start_date
* @param end_date
* @returns {SI,TIWD,BI} Summary input: hardcoded data.TIWD: TemperatureInput: WeatherData from calling open meto API
* Billing input: hardcoded data
*
* Function just to generate test data. inputs come from the values entered in from HomeInformation component
*/
async function genny(longitude: number, latitude: number, start_date: string, end_date: string) {
// SI = new SummaryInput(6666,"GAS",80,67,null,null,60);
// was living_area: number, fuel_type: FuelType, heating_system_efficiency: number, thermostat_set_point: number, setback_temperature: number | null, setback_hours_per_day: number | null, design_temperature: number

type SchemaZodFromFormType = z.infer<typeof Schema>;



const oldSummaryInput = {
living_area: 6666,
fuel_type: "GAS",
heating_system_efficiency: 80,
thermostat_set_point: 67,
setback_temperature: null,
setback_hours_per_day: null,
design_temperature: 60,
};

const SI: SchemaZodFromFormType = Schema.parse({
livingArea: oldSummaryInput.living_area,
address: '123 Main St', // Provide a valid address
name: 'My Home', // Provide a valid name
fuelType: oldSummaryInput.fuel_type === 'GAS' ? 'Natural Gas' : oldSummaryInput.fuel_type,
heatingSystemEfficiency: oldSummaryInput.heating_system_efficiency,
thermostatSetPoint: oldSummaryInput.thermostat_set_point,
setbackTemperature: oldSummaryInput.setback_temperature,
setbackHoursPerDay: oldSummaryInput.setback_hours_per_day,
designTemperatureOverride: oldSummaryInput.design_temperature,
});

console.log("SI", SI)


// const TIWD: TemperatureInput = await WU.getThatWeathaData(longitude, latitude, start_date, end_date);
const TIWD = await WU.getThatWeathaData(longitude, latitude, start_date, end_date);
const BI = [{
period_start_date: new Date("2023-12-30"),//new Date("2023-12-30"),
period_end_date: new Date("2024-01-06"),
usage:100,
inclusion_override: null
}];
return {SI, TIWD, BI};
}


let { x, y } = await GU.getLL(address);
console.log("geocoded", x,y)

return redirect(`/inputs1`)
let { SI, TIWD, BI } = await genny(x,y,"2024-01-01","2024-01-03")

// PU.runit(SI,null,TIWD,JSON.stringify(BI));
// CSV entrypoint parse_gas_bill(data: str, company: NaturalGasCompany)
// Main form entrypoint

return redirect(`/single`)
}



export default function Inputs() {
const lastResult = useActionData<typeof action>()
const [form, fields] = useForm({
Expand All @@ -119,6 +215,7 @@ export default function Inputs() {
method="post"
onSubmit={form.onSubmit}
action="/single"
encType="multipart/form-data"
>
<HomeInformation fields={fields} />
<CurrentHeatingSystem fields={fields} />
Expand Down
29 changes: 29 additions & 0 deletions heat-stack/app/utils/GeocodeUtil.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const BASE_URL = "https://geocoding.geo.census.gov";
const ADDRESS_ENDPOINT = "/geocoder/locations/address";
const params = new URLSearchParams();

class GeocodeUtil {

/**
*
* @param {*} street
* @param {*} city
* @param {*} state
* @returns x,y {x,y} lon/lat. If the given address was valid. I've implemented 0 handling here.
* This is the happiest of paths, with hardcoded values also...
*/
async getLL(address) {
params.append("onelineaddress",address);
params.append("format","json");
params.append("benchmark",2020);

let url = new URL(BASE_URL+ADDRESS_ENDPOINT+"?"+params.toString());
let rezzy = await fetch(url);
let jrez = await rezzy.json();
let coordz = jrez.result.addressMatches[0].coordinates;
console.log(coordz);
return coordz;
}
}

export default GeocodeUtil;
31 changes: 31 additions & 0 deletions heat-stack/app/utils/WeatherUtil.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { time } from "console";

const BASE_URL = "https://archive-api.open-meteo.com";
const WHATEVER_PATH = "/v1/archive";
const params = new URLSearchParams();

class WeatherUtil {

async getThatWeathaData(longitude,latitude,startDate, endDate) {
params.append("latitude",latitude);
params.append("longitude",longitude);
params.append("daily","temperature_2m_max");
params.append("timezone","America/New_York");
params.append("start_date",startDate);
params.append("end_date",endDate);
params.append("temperature_unit","fahrenheit");

let url = new URL(BASE_URL+WHATEVER_PATH+"?"+params.toString());
let rezzy = await fetch(url);
let jrez = await rezzy.json();
let dates = [];
jrez.daily.time.forEach(timeStr => {
dates.push(new Date(timeStr));
});
let temperatures = jrez.daily.temperature_2m_max
// console.log({dates,temperatures});
return {dates,temperatures};
}
}

export default WeatherUtil;
Loading
Loading