{"id":17383137,"url":"https://github.com/womoak75/opendew","last_synced_at":"2025-07-05T19:36:04.524Z","repository":{"id":233026879,"uuid":"785795800","full_name":"womoak75/OpenDew","owner":"womoak75","description":"temperature / humidity / dew point controlled ventilation system running on OpenWrt","archived":false,"fork":false,"pushed_at":"2024-04-13T06:03:51.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-14T16:14:34.903Z","etag":null,"topics":["dewpoint","humidity-sensor","openwrt","shellscript","temperature-sensor","ventilation"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/womoak75.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-12T16:34:41.000Z","updated_at":"2024-04-25T18:36:33.479Z","dependencies_parsed_at":"2024-04-25T18:36:31.866Z","dependency_job_id":null,"html_url":"https://github.com/womoak75/OpenDew","commit_stats":null,"previous_names":["womoak75/opendew"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/womoak75%2FOpenDew","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/womoak75%2FOpenDew/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/womoak75%2FOpenDew/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/womoak75%2FOpenDew/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/womoak75","download_url":"https://codeload.github.com/womoak75/OpenDew/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245924493,"owners_count":20694728,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dewpoint","humidity-sensor","openwrt","shellscript","temperature-sensor","ventilation"],"created_at":"2024-10-16T07:40:44.337Z","updated_at":"2025-03-27T20:49:32.207Z","avatar_url":"https://github.com/womoak75.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg src=\"docs/logo.svg\" width=\"50\" /\u003e OpenDew \n\n![overview](docs/overview.svg)\n\n## what is it\n\na collection of simple shellscripts to \n* collect data from external wireless temperature/humidity sensors\n* calculate dewpoint temperature\n* turn on/off a fan (through a smartplug)\n\n## why\n\nwhen last did you ventilate the cellar?\n\n## why openwrt / rtl_433 / shellscript ?\n\nthe choise of the components was defined by availability in my stuff box. :)\n\n## todo\n\nadd support for wired sensors (i2c/onewire)?\n\n## hardware\n\n- an OpenWRT compatible router (e.g. some from TP-Link) with USB port\n- a Realtek RTL2832 based DVB dongle (https://osmocom.org/projects/rtl-sdr/wiki)\n- some temperature/humidity sensors (433/868Mhz)\n\n## software\n\n- (os) http://openwrt.org\n- (sdr) https://github.com/merbanan/rtl_433 / \n- (broker) https://mosquitto.org\n\n![flow](docs/dataflow.svg)\n\n### mqttreader\n\nreads rtl_433 sensor data from 'rtl_433/{hostname}/events' (rtl_433 default topic)\n\n```json\n{\n  \"time\": \"2024-04-07 16:27:27.095538\",\n  \"model\": \"Nexus-TH\",\n  \"id\": 231,\n  \"channel\": 1,\n  \"battery_ok\": 1,\n  \"temperature_C\": 27.4,\n  \"humidity\": 35\n}\n```\n\n```json\n{\n  \"time\": \"2024-04-07 16:27:27.095538\",\n  \"model\": \"Bresser-3CH\",\n  \"id\": 116,\n  \"channel\": 3,\n  \"battery_ok\": 1,\n  \"temperature_C\": 15.5,\n  \"humidity\": 63,\n  \"mic\": \"CHECKSUM\"\n}\n```\n\nand publishes to 'app/dewpoint/sensors/in'\n\n```json\n{ \"name\": \"id1-231\", \"temperature_C\": 27.4, \"humidity\": 35 }\n```\n\n```json\n{ \"name\": \"id3-116\", \"temperature_C\": 15.5, \"humidity\": 63 }\n```\n\n### sensormaster\n\nreads sensor data from 'app/dewpoint/sensor/in'\n\n```json\n{ \"name\": \"id1-231\", \"temperature_C\": 27.4, \"humidity\": 35 }\n```\n\n```json\n{ \"name\": \"id3-116\", \"temperature_C\": 15.5, \"humidity\": 63 }\n```\n\nuses a configuration to map from external sensor ids to internal names\n\n```json\n[\n    {\n        \"name\":\"id3-116\",\n        \"id\":\"keller1\"\n    },  \n    {\n        \"name\":\"id1-231\",\n        \"id\":\"aussen1stock\"\n    }\n]\n```\n\ncalculate dewpoint according to temperature / humidity and publishes to 'app/dewpoint/in'\n\n```json\n{\n    \"ts\":\"2024-04-07_16:27:29+CEST\", \n    \"name\":\"aussen1stock\",  \n    \"temperature_C\":27.4, \n    \"humidity\":35,\n    \"dew\":10.5808\n}\n```\n```json\n{\n    \"ts\":\"2024-04-07_16:27:30+CEST\",\n    \"name\":\"keller1\",\n    \"temperature_C\":15.5,\n    \"humidity\":63,\n    \"dew\":8.48191\n}\n```\n\n### dewcalculator\n\nread from 'app/dewpoint/in'\n\n\n```json\n{\n    \"ts\":\"2024-04-07_16:27:29+CEST\", \n    \"name\":\"aussen1stock\",  \n    \"temperature_C\":27.4, \n    \"humidity\":35,\n    \"dew\":10.5808\n}\n```\n```json\n{\n    \"ts\":\"2024-04-07_16:27:30+CEST\",\n    \"name\":\"keller1\",\n    \"temperature_C\":15.5,\n    \"humidity\":63,\n    \"dew\":8.48191\n}\n```\n\nhas a mapping where multiple indoor/outdoor sensors can be configured.\n\n```json\n{\n    \"insensors\": [\n        \"keller1\"\n    ],\n    \"outsensors\": [\n        \"aussen1stock\"\n    ]\n}\n```\n\nwhen data from every sensor is available   \naverage outdoor/indoor temperature, humidity and dewpoint are calculated.\n\npublishes to 'app/dewpoint/out'\n\n```json\n{\n  \"ts\": \"2024-04-07_16:27:32+CEST\",\n  \"dew_avg\": {\n    \"delta\": -2.09889,\n    \"indoor\": 8.48191,\n    \"outdoor\": 10.5808\n  },\n  \"temperature_avg\": {\n    \"indoor\": 15.5,\n    \"outdoor\": 27.4\n  },\n  \"humidity_avg\": {\n    \"indoor\": 63,\n    \"outdoor\": 35\n  },\n  \"sensors\": {\n    \"indoor\": [\n      {\n        \"ts\": \"2024-04-07_16:26:10+CEST\",\n        \"name\": \"keller1\",\n        \"temperature_C\": 15.5,\n        \"humidity\": 63,\n        \"dew\": 8.48191\n      }\n    ],\n    \"outdoor\": [\n      {\n        \"ts\": \"2024-04-07_16:27:29+CEST\",\n        \"name\": \"aussen1stock\",\n        \"temperature_C\": 27.4,\n        \"humidity\": 35,\n        \"dew\": 10.5808\n      }\n    ]\n  },\n  \"app\": {\n    \"dew_diff_min\": 1.0,\n    \"dew_diff_max\": 2.3,\n    \"room_temperature_min\": 10.0\n  }\n}\n\n```\n\n### dewapp\n\nreads from 'app/dewpoint/out'\n\n```json\n{\n  \"ts\": \"2024-04-07_16:27:32+CEST\",\n  \"dew_avg\": {\n    \"delta\": -2.09889,\n    \"indoor\": 8.48191,\n    \"outdoor\": 10.5808\n  },\n  \"temperature_avg\": {\n    \"indoor\": 15.5,\n    \"outdoor\": 27.4\n  },\n  \"humidity_avg\": {\n    \"indoor\": 63,\n    \"outdoor\": 35\n  },\n  \"sensors\": {\n    \"indoor\": [\n      {\n        \"ts\": \"2024-04-07_16:26:10+CEST\",\n        \"name\": \"keller1\",\n        \"temperature_C\": 15.5,\n        \"humidity\": 63,\n        \"dew\": 8.48191\n      }\n    ],\n    \"outdoor\": [\n      {\n        \"ts\": \"2024-04-07_16:27:29+CEST\",\n        \"name\": \"aussen1stock\",\n        \"temperature_C\": 27.4,\n        \"humidity\": 35,\n        \"dew\": 10.5808\n      }\n    ]\n  },\n  \"app\": {\n    \"dew_diff_min\": 1.0,\n    \"dew_diff_max\": 2.3,\n    \"room_temperature_min\": 10.0\n  }\n}\n```\n\ncalculates if fan should be turned on/off according temperature / dewpoint data.\n\npublishes to 'app/dewpoint/control'\n\n```json\n{\n    \"ts\":\"2024-04-07_16:27:37+CEST\",\n    \"type\":\"control\",\n    \"fan\":0\n}\n```\n\n### dewcontrol\n\nreads from 'app/dewpoint/control'\n\n```json\n{\n    \"ts\":\"2024-04-07_16:27:37+CEST\",\n    \"type\":\"control\",\n    \"fan\":0\n}\n```\n\nread user provided functions from '/etc/opendew/custom.sh'\n\n```sh\n\n# custom user actions can be executed here\n\ncustom_fanon() {\n\tlogger \"custom fan on :)\"\n    curl http://espplug.fritz.box/cm?cmnd=Power%20on\n}\n\ncustom_fanoff() {\n\tlogger \"custom fan off :)\"\n    curl http://espplug.fritz.box/cm?cmnd=Power%20off\n}\n\ncustom_status_on() {\n    logger \"custom status changed to on\"\n}\n\ncustom_status_off() {\n    logger \"custom status changed to off\"\n}\n```\n\nexecutes custom_fanoff() or custom_fanon()  functions (if defined).\n\n## configuration\n\nconfigfile '/etc/opendew/opendew.cfg'\n\n```\n\nMQTTHOST=\"localhost\"\nMQTTPORT=\"1883\"\nMQTTUSER=\"\"\nMQTTPASS=\"\"\n\nMQTTTOPICBASE=\"app/dewpoint\"\n\nMQTTREADER_INTOPIC=\"rtl_433/+/events\"\n\nDEW_DIFF_MAX=2.3\nDEW_DIFF_MIN=1.0 \nROOM_TEMP_MIN=10.0\n\nSENSORMASTERCONFIG='[{\"name\":\"id3-116\",\"id\":\"keller1\"},{\"name\":\"id1-231\",\"id\":\"aussen1stock\"}]'\n\nSENSORCONFIG='{\"insensors\":[\"keller1\"],\"outsensors\":[\"aussen1stock\"]}'\n\n```\n### sensor mapping (rtl_433 to internal)\n\n```\nSENSORMASTERCONFIG='[{\"name\":\"id3-116\",\"id\":\"keller1\"},{\"name\":\"id1-231\",\"id\":\"aussen1stock\"}]'\n```\nIn a first step, the sensor data must be converted from the rtl_433 proprietary format into the application's own data format.\n\n```json\n// rtl_433 specific\n{\n  \"time\": \"2024-04-07 16:27:27.095538\",\n  \"model\": \"Bresser-3CH\",\n  \"id\": 116,\n  \"channel\": 3,\n  \"battery_ok\": 1,\n  \"temperature_C\": 15.5,\n  \"humidity\": 63,\n  \"mic\": \"CHECKSUM\"\n}\n```\nto\n```json\n// dew app specific\n{ \n  \"name\": \"id3-116\", \n  \"temperature_C\": 15.5, \n  \"humidity\": 63 \n}\n```\nDuring this process, a unique ID is also assigned to each sensor, which is then used internally. In the event of a sensor replacement (e.g., due to a defect), only the mapping to the internal name/ID needs to be changed.\n\nThe ID generation follows the following pattern:\n```\nid{rtl_433.channel}-{rtl_433.id}\n```\ne.g. \n```\nid:116, channel=3 -\u003e 'id3-116'\n```\n### sensor mapping (internal to in/outsensor)\n\n```\nSENSORCONFIG='{\"insensors\":[\"keller1\",\"keller2\",\"keller3\"],\"outsensors\":[\"aussen1stock\",\"aussenterrasse\"]}'\n```\n\nIndoor and outdoor sensors can be defined as 1 to n sensors each. The respective value (temperature, humidity, and dew point) is determined as the average across all configured sensors for indoor/outdoor use.\n\n## faq\n\n### will it also run on a 'real' linux system?\n\nProbably.  \nThe shellscripts should run on any linux system, but startup scripts for initd / systemd are necessary.\n\n### is there a UI available?\n\nNo.\n\n### how to display data?\n\nUse your favorite home automation system.  \nFor example: [FHEM](https://fhem.de/)\n\n![flow](docs/temp_humidity_diagram.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwomoak75%2Fopendew","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwomoak75%2Fopendew","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwomoak75%2Fopendew/lists"}