Follow sunset/sunrise in VRM DESS Trade mode

This Node-RED flow automates setting battery discharge restrictions for a Victron Energy system based on sunrise and sunset times for a given location. Here's a breakdown of the flow:

  1. Daily Injection (426f5b74668d1a6b): This node triggers the flow daily at 22:00 (10 PM) in your local timezone. It injects a timestamp, but the payload isn't actually used later in the flow. The important part is the scheduled time.

  2. Sun Position Calculation (37c9a6df5ed98310): This suncron node calculates sunrise and sunset times based on the provided latitude (48.9147167) and longitude (24.6682185). Important: You should change these coordinates to your actual location for accurate sunrise/sunset times. The node outputs an object containing these times.

  3. Function Node - Schedule Creation (e0b6c70677569798): This is the core logic of the flow. It takes the output from the suncron node and creates a battery discharge schedule.

    • It extracts the sunrise and sunset times from the suncron output.
    • It constructs a schedule array with three entries:
      • 00:00 to sunrise: Restrict discharge (presumably to prioritize charging from solar).
      • sunrise to sunset: Allow discharge (to use stored energy when solar is unavailable).
      • sunset to 00:00: Restrict discharge again.
    • It formats this schedule into the structure required by the Victron VRM API. Specifically, it creates a JSON string representing an array containing a single object with days (0-6 for all days of the week) and the schedule as defined above.
    • Crucially, it clears the entire msg object before setting the new payload. This is essential to prevent unintended data from previous nodes from interfering with the VRM API call.
    • If the suncron data is invalid or missing, it logs a warning and sets an empty array as the payload to avoid errors.
  4. VRM API Call (1d4ac16e0acc5e6a): This node sends the generated schedule to the Victron VRM API.

    • vrm (33cf008ea8e9d911): This configuration node stores your VRM API credentials. You'll need to configure this with your actual VRM portal ID, access token, etc.
    • idSite: THIS IS THE MOST IMPORTANT PART TO CHANGE. The idSite field is set to 000000. You MUST replace 000000 with the actual ID of your VRM site. This ID identifies the specific installation you're controlling. You can find this ID in your VRM portal URL or by using the VRM API directly to list your installations.
    • The api_type is set to installations and installations to patch-dynamic-ess-settings, indicating that this call is updating the dynamic ESS settings.
    • The payload of this node comes from the function node and contains the JSON string of the battery discharge schedule.
  5. Debug Node (be370ca5931e2729): This node is used for debugging. It's currently inactive. If you activate it, it will display the messages passing through the flow, which can be useful for troubleshooting.

In summary: The flow retrieves sunrise/sunset times, creates a battery discharge schedule based on these times, and sends that schedule to the Victron VRM API to dynamically adjust the ESS behavior. The critical step is to replace the placeholder 000000 in the idSite field of the VRM API node with your actual VRM site ID. Without this change, the flow will not work correctly and will likely result in errors.

[{"id":"d7b06853644b688b","type":"group","z":"1fb7f5b976e694f6","name":"Set battery discharge restrictions based on sunrise sunset - maximize Sun generation","style":{"label":true},"nodes":["426f5b74668d1a6b","be370ca5931e2729","37c9a6df5ed98310","e0b6c70677569798","1d4ac16e0acc5e6a"],"x":34,"y":519,"w":792,"h":322},{"id":"426f5b74668d1a6b","type":"inject","z":"1fb7f5b976e694f6","g":"d7b06853644b688b","name":"Daily at 22:00 Your Timezone","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"00 22 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":560,"wires":[["37c9a6df5ed98310"]]},{"id":"be370ca5931e2729","type":"debug","z":"1fb7f5b976e694f6","g":"d7b06853644b688b","name":"All object debug","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":700,"y":740,"wires":[]},{"id":"37c9a6df5ed98310","type":"suncron","z":"1fb7f5b976e694f6","g":"d7b06853644b688b","name":"Set Your Location coordinates here","lat":"48.9147167","lon":"24.6682185","replay":false,"ejectScheduleOnUpdate":false,"sunrisePayload":"1","sunrisePayloadType":"num","sunriseTopic":"sunrise","sunriseOffsetType":1,"sunriseOffsetHours":0,"sunriseOffsetMinutes":0,"sunriseOffset":0,"sunriseEndPayload":"","sunriseEndPayloadType":"str","sunriseEndTopic":"","sunriseEndOffsetType":1,"sunriseEndOffsetHours":0,"sunriseEndOffsetMinutes":0,"sunriseEndOffset":0,"goldenHourEndPayload":"","goldenHourEndPayloadType":"str","goldenHourEndTopic":"","goldenHourEndOffsetType":1,"goldenHourEndOffsetHours":0,"goldenHourEndOffsetMinutes":0,"goldenHourEndOffset":0,"solarNoonPayload":"","solarNoonPayloadType":"str","solarNoonTopic":"","solarNoonOffsetType":1,"solarNoonOffsetHours":0,"solarNoonOffsetMinutes":0,"solarNoonOffset":0,"goldenHourPayload":"","goldenHourPayloadType":"str","goldenHourTopic":"","goldenHourOffsetType":1,"goldenHourOffsetHours":0,"goldenHourOffsetMinutes":0,"goldenHourOffset":0,"sunsetStartPayload":"","sunsetStartPayloadType":"str","sunsetStartTopic":"","sunsetStartOffsetType":1,"sunsetStartOffsetHours":0,"sunsetStartOffsetMinutes":0,"sunsetStartOffset":0,"sunsetPayload":"1","sunsetPayloadType":"num","sunsetTopic":"sunset","sunsetOffsetType":1,"sunsetOffsetHours":0,"sunsetOffsetMinutes":0,"sunsetOffset":0,"duskPayload":"","duskPayloadType":"str","duskTopic":"","duskOffsetType":1,"duskOffsetHours":0,"duskOffsetMinutes":0,"duskOffset":0,"nauticalDuskPayload":"","nauticalDuskPayloadType":"str","nauticalDuskTopic":"","nauticalDuskOffsetType":1,"nauticalDuskOffsetHours":0,"nauticalDuskOffsetMinutes":0,"nauticalDuskOffset":0,"nightPayload":"","nightPayloadType":"str","nightTopic":"","nightOffsetType":1,"nightOffsetHours":0,"nightOffsetMinutes":0,"nightOffset":0,"nadirPayload":"","nadirPayloadType":"str","nadirTopic":"","nadirOffsetType":1,"nadirOffsetHours":0,"nadirOffsetMinutes":0,"nadirOffset":0,"nightEndPayload":"","nightEndPayloadType":"str","nightEndTopic":"","nightEndOffsetType":1,"nightEndOffsetHours":0,"nightEndOffsetMinutes":0,"nightEndOffset":0,"nauticalDawnPayload":"","nauticalDawnPayloadType":"str","nauticalDawnTopic":"","nauticalDawnOffsetType":1,"nauticalDawnOffsetHours":0,"nauticalDawnOffsetMinutes":0,"nauticalDawnOffset":0,"dawnPayload":"","dawnPayloadType":"str","dawnTopic":"","dawnOffsetType":1,"dawnOffsetHours":0,"dawnOffsetMinutes":0,"dawnOffset":0,"x":260,"y":800,"wires":[["e0b6c70677569798"]]},{"id":"e0b6c70677569798","type":"function","z":"1fb7f5b976e694f6","g":"d7b06853644b688b","name":"Set battery discharge restrictions based on sunrise sunset","func":"const suncronData = msg;\n\nif (suncronData && suncronData.schedule && suncronData.schedule.sunrise && suncronData.schedule.sunset) {\n  const sunriseTime = new Date(suncronData.schedule.sunrise.sunEventTime);\n  const sunsetTime = new Date(suncronData.schedule.sunset.sunEventTime);\n\n  const schedule = [ // Creating the inner schedule array directly\n    {\n      from: \"00:00\",\n      to: sunriseTime.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' }),\n      restrict: true\n    },\n    {\n      from: sunriseTime.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' }),\n      to: sunsetTime.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' }),\n      restrict: false\n    },\n    {\n      from: sunsetTime.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' }),\n      to: \"00:00\", // or \"00:00\" for the next day\n      restrict: true\n    }\n  ];\n\n  const batteryDischargeRestrictionSchedule = {\n    days: [0, 1, 2, 3, 4, 5, 6],\n    schedule: schedule // Assign the schedule array\n  };\n\n  msg = {'payload': {}};  // Important: Clear the entire msg object\n\n  msg.payload = {'batteryDischargeRestrictionSchedule': JSON.stringify([ // Creating the array with the object inside\n    {\n      days: batteryDischargeRestrictionSchedule.days,\n      schedule: batteryDischargeRestrictionSchedule.schedule\n    }\n  ])};\n\n\n} else {\n  node.warn(\"Invalid or missing suncron data. Check if 'schedule', 'sunrise', and 'sunset' properties exist.\");\n  msg.payload = []; // or a default schedule if you have one.  Returning an empty array to match expected format.\n}\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":640,"wires":[["be370ca5931e2729","1d4ac16e0acc5e6a"]]},{"id":"1d4ac16e0acc5e6a","type":"vrm-api","z":"1fb7f5b976e694f6","g":"d7b06853644b688b","vrm":"33cf008ea8e9d911","name":"Update Dynamic ESS configuration","api_type":"installations","idUser":"","users":"","idSite":"000000","installations":"patch-dynamic-ess-settings","attribute":"","stats_interval":"","show_instance":false,"stats_start":"","stats_end":"","use_utc":false,"gps_start":"","gps_end":"","widgets":"","instance":"","vrm_id":"","country":"","b_max":"","tb_max":"","fb_max":"","tg_max":"","fg_max":"","b_cycle_cost":"","buy_price_formula":"","sell_price_formula":"","green_mode_on":"","feed_in_possible":"","feed_in_control_on":"","b_goal_hour":"","b_goal_SOC":"","store_in_global_context":false,"verbose":true,"x":640,"y":800,"wires":[["be370ca5931e2729"]]},{"id":"33cf008ea8e9d911","type":"config-vrm-api","name":"VRM"}]

Flow Info

Created 1 month, 3 weeks ago
Rating: not yet rated

Owner

Actions

Rate:

Node Types

Core
  • debug (x1)
  • function (x1)
  • inject (x1)
Other

Tags

  • suncron
  • victron
  • DESS
  • ess
  • ua
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option