Energy Savings with Open Dental using n8n/Home Assistant

For requests or help with our API
Post Reply
joergzastrau
Posts: 23
Joined: Sun Feb 27, 2022 2:53 am

Energy Savings with Open Dental using n8n/Home Assistant

Post by joergzastrau » Sat Nov 05, 2022 12:58 pm

Dear all,

the following automation n8n code (https://n8n.io/) in connection with home assistant (Smart Home) https://www.home-assistant.io/ reduces the office temperature to 17 degree celsius until two hours before the first appointment and after the last patient has left. 20 degrees celsius during office hours. This will result in energy savings (your milage will vary - people say abt. 5% to 25%).

Requirements:

.) OD version 21.1 or later with RO API access
.) n8n (tested with version 0.195.5, port 5678)
.) home assistant with temperature control and some controllable heating device (tested with version 2022.8.7, port 8123, and Homematic IP Cloud integration, search for "HmIP-WLAN-HAP", "hmip etrv-b" and "demo")

We use Docker images for n8n and homematic and google integration. Setup see http://opendentalsoft.com/forum/viewtop ... f=9&t=7749

Code (to be copy&pasted into n8n GUI, adoption of credentials and Server IP necessary):

Code: Select all

{
  "meta": {
    "instanceId": "c5bbe0e4dd0c2a71ee01ba0477f0fe876e4ef1ddb06022d07739fda528d4f9f1"
  },
  "nodes": [
    {
      "parameters": {},
      "id": "304efeaa-df7f-4f43-9d7f-baa4755c0f77",
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        1320,
        620
      ]
    },
    {
      "parameters": {
        "functionCode": "// only retrieve future appointments with updated last acces DateTStamp\n// this is to avoid a full update after open dental software upgrade that involves touching all mysql tables\nlet baseurl = 'http://192.168.1.60:30223/api/v1/appointments?date='+$json[\"DateToday\"]\n\n//Alternate URL for testing\n//let baseurl = 'http://192.168.1.60:30223/api/v1/appointments?date=2022-11-08'\n\nreturn [\n    {\n      json: {\n        url : baseurl\n      }\n    }\n]"
      },
      "name": "Create URL",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1740,
        800
      ],
      "id": "8264c165-e201-4b7e-90ec-bcc53b183979"
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "={{$node[\"Functionx\"].json[\"url\"]}}{{$json[\"url\"]}}",
        "options": {
          "splitIntoItems": true
        }
      },
      "name": "OD API Get multiple",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        1960,
        800
      ],
      "alwaysOutputData": true,
      "notesInFlow": true,
      "id": "d527eb10-e36c-46ef-831c-fa00781fd11a",
      "credentials": {
        "httpHeaderAuth": {
          "id": "5",
          "name": "Header Auth KL Office"
        }
      },
      "notes": "For production use Date_Stop and DateTStamp in query."
    },
    {
      "parameters": {
        "value": "={{ new Date(new Date().getTime()) }}",
        "dataPropertyName": "DateToday",
        "toFormat": "YYYY-MM-DD",
        "options": {}
      },
      "name": "Today",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        1520,
        800
      ],
      "id": "901ea2d4-d884-415e-aa38-4ff0aeb4da8f"
    },
    {
      "parameters": {
        "operation": "sort",
        "sortFieldsUi": {
          "sortField": [
            {
              "fieldName": "AptDateTime"
            }
          ]
        },
        "options": {}
      },
      "name": "Sort by AptDateTime",
      "type": "n8n-nodes-base.itemLists",
      "typeVersion": 1,
      "position": [
        1320,
        1040
      ],
      "id": "e160af70-56a1-4601-97cd-0c7ceaa2db47",
      "continueOnFail": true
    },
    {
      "parameters": {
        "operation": "sort",
        "sortFieldsUi": {
          "sortField": [
            {
              "fieldName": "AptDateTimeEnd",
              "order": "descending"
            }
          ]
        },
        "options": {}
      },
      "name": "Sort by AptDateTime1",
      "type": "n8n-nodes-base.itemLists",
      "typeVersion": 1,
      "position": [
        1320,
        1220
      ],
      "id": "a9b8bc0f-b394-4e44-a960-45e39ab8d471",
      "continueOnFail": true
    },
    {
      "parameters": {
        "value": "={{$json[\"AptDateTime\"]}}",
        "dataPropertyName": "AptDateTime",
        "custom": true,
        "options": {
          "toTimezone": "UTC"
        }
      },
      "id": "b878802a-239b-43f9-892c-1f7bc639c71e",
      "name": "AptDateTime to UTC",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        2180,
        800
      ]
    },
    {
      "parameters": {
        "action": "calculate",
        "value": "={{$json[\"AptDateTime\"]}}",
        "duration": "={{$json[\"Pattern\"].length*5*60}}",
        "timeUnit": "seconds",
        "dataPropertyName": "AptDateTimeEnd",
        "options": {
          "fromFormat": ""
        }
      },
      "id": "c8796177-1a4d-4d05-8910-552a1eb577f2",
      "name": "Calculate AptDateTimeEnd",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        2400,
        800
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "AptDateTimeEnd",
              "value": "={{$json[\"AptDateTime\"]}}"
            }
          ]
        },
        "options": {}
      },
      "id": "c6914620-999d-41aa-a9ad-04b6bd7973c2",
      "name": "End of Day UTC",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1520,
        1220
      ],
      "executeOnce": true
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "AptDateTime",
              "value": "={{$json[\"AptDateTime\"]}}"
            }
          ]
        },
        "options": {}
      },
      "id": "786e3807-eb97-4c89-844c-ee33c1ee1542",
      "name": "Start of Day UTC",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1520,
        1040
      ],
      "executeOnce": true
    },
    {
      "parameters": {
        "resource": "service",
        "operation": "call",
        "domain": "climate",
        "service": "=set_temperature",
        "serviceAttributes": {
          "attributes": [
            {
              "name": "entity_id",
              "value": "all"
            },
            {
              "name": "temperature",
              "value": "20"
            }
          ]
        }
      },
      "id": "0589cef2-ea16-42d8-b24a-f5b7db2c813a",
      "name": "Home Assistant Temp High",
      "type": "n8n-nodes-base.homeAssistant",
      "typeVersion": 1,
      "position": [
        2640,
        1020
      ],
      "credentials": {
        "homeAssistantApi": {
          "id": "10",
          "name": "Home Assistant account"
        }
      }
    },
    {
      "parameters": {
        "value": "={{ new Date(new Date().getTime()) }}",
        "dataPropertyName": "DateTimeUTC",
        "custom": true,
        "options": {
          "fromFormat": "="
        }
      },
      "id": "486e2fda-bc94-4976-9857-a23d7b2216fd",
      "name": "Date Time UTC",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        1960,
        1220
      ],
      "notes": "Configure X hrs. Here"
    },
    {
      "parameters": {
        "action": "calculate",
        "value": "={{$json[\"AptDateTime\"]}}",
        "operation": "subtract",
        "duration": 2,
        "timeUnit": "hours",
        "dataPropertyName": "DateTime HAVC High",
        "options": {}
      },
      "id": "d7c3547f-3f1e-4be6-9901-1d022a0a1dfb",
      "name": "Date & Time Temp High",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        1740,
        1040
      ]
    },
    {
      "parameters": {
        "action": "calculate",
        "value": "={{$json[\"AptDateTimeEnd\"]}}",
        "duration": 1,
        "timeUnit": "hours",
        "dataPropertyName": "DateTime HAVC Low",
        "options": {}
      },
      "name": "Date Time Temp Low",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 1,
      "position": [
        1740,
        1220
      ],
      "id": "4df241c6-f3ad-4efb-92d7-0d14a662b8f2"
    },
    {
      "parameters": {
        "resource": "service",
        "operation": "call",
        "domain": "climate",
        "service": "=set_temperature",
        "serviceAttributes": {
          "attributes": [
            {
              "name": "entity_id",
              "value": "all"
            },
            {
              "name": "temperature",
              "value": "17"
            }
          ]
        }
      },
      "id": "0da6f997-a836-4f90-83c7-668423adca95",
      "name": "Home Assistant Temp Low",
      "type": "n8n-nodes-base.homeAssistant",
      "typeVersion": 1,
      "position": [
        2640,
        1200
      ],
      "credentials": {
        "homeAssistantApi": {
          "id": "10",
          "name": "Home Assistant account"
        }
      }
    },
    {
      "parameters": {
        "mode": "mergeByIndex"
      },
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 1,
      "position": [
        2180,
        1120
      ],
      "id": "118e94fe-cd01-4247-a66f-96fbf9733fdb"
    },
    {
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "mode": "everyX",
              "value": 15,
              "unit": "minutes"
            }
          ]
        }
      },
      "id": "48186e77-d21d-413b-a357-da071aa25de8",
      "name": "Cron",
      "type": "n8n-nodes-base.cron",
      "typeVersion": 1,
      "position": [
        1320,
        800
      ]
    },
    {
      "parameters": {
        "conditions": {
          "dateTime": [
            {
              "value1": "={{$json[\"DateTimeUTC\"]}}",
              "value2": "={{$json[\"DateTime HAVC High\"]}}"
            },
            {
              "value1": "={{$json[\"DateTimeUTC\"]}}",
              "operation": "before",
              "value2": "={{$json[\"DateTime HAVC Low\"]}}"
            }
          ]
        }
      },
      "id": "fe21bc58-975c-460c-b353-7733995c8a85",
      "name": "Conditions Temp High",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        2400,
        1040
      ]
    },
    {
      "parameters": {
        "conditions": {
          "dateTime": [
            {
              "value1": "={{$json[\"DateTimeUTC\"]}}",
              "value2": "={{$json[\"DateTime HAVC Low\"]}}"
            }
          ]
        }
      },
      "id": "87d9799c-6995-4a02-9ff6-1df3adc65227",
      "name": "Conditions Temp Low",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        2400,
        1220
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Today",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create URL": {
      "main": [
        [
          {
            "node": "OD API Get multiple",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OD API Get multiple": {
      "main": [
        [
          {
            "node": "AptDateTime to UTC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Today": {
      "main": [
        [
          {
            "node": "Create URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort by AptDateTime": {
      "main": [
        [
          {
            "node": "Start of Day UTC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort by AptDateTime1": {
      "main": [
        [
          {
            "node": "End of Day UTC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AptDateTime to UTC": {
      "main": [
        [
          {
            "node": "Calculate AptDateTimeEnd",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate AptDateTimeEnd": {
      "main": [
        [
          {
            "node": "Sort by AptDateTime",
            "type": "main",
            "index": 0
          },
          {
            "node": "Sort by AptDateTime1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "End of Day UTC": {
      "main": [
        [
          {
            "node": "Date Time Temp Low",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start of Day UTC": {
      "main": [
        [
          {
            "node": "Date & Time Temp High",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Date Time UTC": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Date & Time Temp High": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Date Time Temp Low": {
      "main": [
        [
          {
            "node": "Date Time UTC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Conditions Temp Low",
            "type": "main",
            "index": 0
          },
          {
            "node": "Conditions Temp High",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cron": {
      "main": [
        [
          {
            "node": "Today",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Conditions Temp High": {
      "main": [
        [
          {
            "node": "Home Assistant Temp High",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Conditions Temp Low": {
      "main": [
        [
          {
            "node": "Home Assistant Temp Low",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Please ask.

Joerg

Post Reply