-
-
Save yholkamp/8e6af834be1f277536e76dd355d523dd to your computer and use it in GitHub Desktop.
Post daily frank energie trading results to onbalansmarkt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class FrankEnergie { | |
| constructor(authToken = null, refreshToken = null) { | |
| this.DATA_URL = "https://frank-graphql-prod.graphcdn.app/"; | |
| this.auth = authToken || refreshToken ? { authToken, refreshToken } : null; | |
| } | |
| async query(queryData) { | |
| const headers = { | |
| 'Content-Type': 'application/json', | |
| ...(this.auth && { 'Authorization': `Bearer ${this.auth.authToken}` }) | |
| }; | |
| try { | |
| const response = await fetch(this.DATA_URL, { | |
| method: 'POST', | |
| headers, | |
| body: JSON.stringify(queryData) | |
| }); | |
| const data = await response.json(); | |
| if (data.errors) { | |
| for (const error of data.errors) { | |
| if (error.message === "user-error:auth-not-authorised") { | |
| throw new Error("Authentication required"); | |
| } | |
| } | |
| } | |
| return data; | |
| } catch (error) { | |
| throw new Error(`Request failed: ${error.message}`); | |
| } | |
| } | |
| async login(username, password) { | |
| const query = { | |
| query: ` | |
| mutation Login($email: String!, $password: String!) { | |
| login(email: $email, password: $password) { | |
| authToken | |
| refreshToken | |
| } | |
| } | |
| `, | |
| operationName: "Login", | |
| variables: { email: username, password } | |
| }; | |
| const response = await this.query(query); | |
| this.auth = response.data.login; | |
| return this.auth; | |
| } | |
| async getPrices(startDate, endDate) { | |
| const query = { | |
| query: ` | |
| query MarketPrices($startDate: Date!, $endDate: Date!) { | |
| marketPricesElectricity(startDate: $startDate, endDate: $endDate) { | |
| from | |
| till | |
| marketPrice | |
| marketPriceTax | |
| sourcingMarkupPrice | |
| energyTaxPrice | |
| } | |
| marketPricesGas(startDate: $startDate, endDate: $endDate) { | |
| from | |
| till | |
| marketPrice | |
| marketPriceTax | |
| sourcingMarkupPrice | |
| energyTaxPrice | |
| } | |
| } | |
| `, | |
| variables: { | |
| startDate: startDate.toISOString().split('T')[0], | |
| endDate: endDate.toISOString().split('T')[0] | |
| }, | |
| operationName: "MarketPrices" | |
| }; | |
| return await this.query(query); | |
| } | |
| async getSmartBatteries() { | |
| if (!this.auth) { | |
| throw new Error("Authentication required"); | |
| } | |
| const query = { | |
| query: ` | |
| query SmartBatteries { | |
| smartBatteries { | |
| brand | |
| capacity | |
| createdAt | |
| externalReference | |
| id | |
| maxChargePower | |
| maxDischargePower | |
| provider | |
| updatedAt | |
| } | |
| } | |
| `, | |
| operationName: "SmartBatteries" | |
| }; | |
| return await this.query(query); | |
| } | |
| async getSmartBatterySessions(deviceId, startDate, endDate) { | |
| if (!this.auth) { | |
| throw new Error("Authentication required"); | |
| } | |
| const query = { | |
| query: ` | |
| query SmartBatterySessions($startDate: String!, $endDate: String!, $deviceId: String!) { | |
| smartBatterySessions( | |
| startDate: $startDate | |
| endDate: $endDate | |
| deviceId: $deviceId | |
| ) { | |
| deviceId | |
| periodEndDate | |
| periodStartDate | |
| periodTradingResult | |
| sessions { | |
| cumulativeTradingResult | |
| date | |
| tradingResult | |
| } | |
| totalTradingResult | |
| } | |
| } | |
| `, | |
| operationName: "SmartBatterySessions", | |
| variables: { | |
| deviceId, | |
| startDate: startDate.toISOString().split('T')[0], | |
| endDate: endDate.toISOString().split('T')[0] | |
| } | |
| }; | |
| return await this.query(query); | |
| } | |
| isAuthenticated() { | |
| return this.auth !== null; | |
| } | |
| } | |
| class OnbalansMarkt { | |
| constructor(apiKey) { | |
| this.apiUrl = 'https://onbalansmarkt.com/nexus/api/live'; | |
| this.apiKey = apiKey; | |
| } | |
| async sendMeasurement({ | |
| timestamp, | |
| batteryResult, | |
| batteryResultTotal = null, | |
| batteryCharge = null, | |
| batteryPower = null, | |
| deliveryToday = null, | |
| productionToday = null, | |
| loadBalancingActive = null, | |
| solarResult = null, | |
| chargerResult = null | |
| }) { | |
| // Validate required fields | |
| if (!timestamp || !batteryResult) { | |
| throw new Error('timestamp and batteryResult are required fields'); | |
| } | |
| // Prepare the payload | |
| const payload = { | |
| timestamp, | |
| batteryResult: batteryResult.toString(), | |
| ...(batteryResultTotal !== null && { batteryResultTotal: batteryResultTotal.toString() }), | |
| ...(batteryCharge !== null && { batteryCharge: batteryCharge.toString() }), | |
| ...(batteryPower !== null && { batteryPower: batteryPower.toString() }), | |
| ...(deliveryToday !== null && { deliveryToday: deliveryToday.toString() }), | |
| ...(productionToday !== null && { productionToday: productionToday.toString() }), | |
| ...(loadBalancingActive !== null && { loadBalancingActive: loadBalancingActive.toString() }), | |
| ...(solarResult !== null && { solarResult: solarResult.toString() }), | |
| ...(chargerResult !== null && { chargerResult: chargerResult.toString() }) | |
| }; | |
| try { | |
| const response = await fetch(this.apiUrl, { | |
| method: 'POST', | |
| headers: { | |
| 'Accept': 'application/json', | |
| 'Authorization': `Bearer ${this.apiKey}`, | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify(payload) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| return await response.json(); | |
| } catch (error) { | |
| console.error('Error sending measurement:', error); | |
| throw error; | |
| } | |
| } | |
| } | |
| const frank = new FrankEnergie(); | |
| await frank.login("[email protected]", "mijnfrankpassword"); | |
| const onbalansmarkt = new OnbalansMarkt("API-KEY-ONBALANSMARKT.COM"); | |
| // Get all smart batteries | |
| const batteries = await frank.getSmartBatteries(); | |
| console.log(batteries); | |
| let yesterday = new Date(); | |
| yesterday.setHours(0,0,0,0); | |
| yesterday.setDate(yesterday.getDate() - 1); | |
| // Get sessions for a specific battery | |
| if (batteries.data.smartBatteries.length > 0) { | |
| const batteryId = batteries.data.smartBatteries[0].id; | |
| const sessions = await frank.getSmartBatterySessions( | |
| batteryId, | |
| yesterday, | |
| yesterday | |
| ); | |
| console.log(sessions); | |
| onbalansmarkt.sendMeasurement({ | |
| timestamp: yesterday.toISOString(), | |
| batteryResult: sessions.data.smartBatterySessions.periodTradingResult, | |
| loadBalancingActive: "off" | |
| }); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment