{"id":23924658,"url":"https://github.com/smartenough-org/smartenough","last_synced_at":"2026-04-13T20:31:49.855Z","repository":{"id":136844518,"uuid":"290339560","full_name":"smartenough-org/smartenough","owner":"smartenough-org","description":"SmartEnough is a DIY smarthome project","archived":false,"fork":false,"pushed_at":"2026-02-09T00:43:21.000Z","size":1331,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-09T06:39:28.914Z","etag":null,"topics":["embedded","esp32","homeassistant","rust-lang","smarthome","stm32"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smartenough-org.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"publiccode":null,"codemeta":null}},"created_at":"2020-08-25T22:44:38.000Z","updated_at":"2026-02-09T00:43:25.000Z","dependencies_parsed_at":"2024-12-28T00:21:59.841Z","dependency_job_id":"59663c93-b1d8-441f-a629-7b1df8933893","html_url":"https://github.com/smartenough-org/smartenough","commit_stats":null,"previous_names":["smartenough-org/smartenough"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/smartenough-org/smartenough","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartenough-org%2Fsmartenough","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartenough-org%2Fsmartenough/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartenough-org%2Fsmartenough/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartenough-org%2Fsmartenough/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smartenough-org","download_url":"https://codeload.github.com/smartenough-org/smartenough/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartenough-org%2Fsmartenough/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31770718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T20:17:16.280Z","status":"ssl_error","status_checked_at":"2026-04-13T20:17:08.216Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["embedded","esp32","homeassistant","rust-lang","smarthome","stm32"],"created_at":"2025-01-05T19:17:28.052Z","updated_at":"2026-04-13T20:31:49.843Z","avatar_url":"https://github.com/smartenough-org.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"* SmartEnough\nSmartEnough is an open source smart home solution that combines affordable\noff-the-shelf hardware with a robust software architecture. Built for people\nthat don't want to pay premium for each IO they add to the system, who want to\ntrust the system's reliability and who are not afraid of some tinkering.\n\n** SmartEnough design goals\n- Extra cheap hardware: doable by hand (soldering iron or breadboard) and\n  upgradable to something more sturdy with ordered PCBs. 48+ IO per single board\n  possible and way cheaper $/IO than in any available commercial solutions.\n- Robust, resiliant, secure: communication and power over twisted pair cables -\n  no batteries, no radio, no cloud.\n- Supports house wiring in \"constellation of star topologies\". We don't have a\n  device in each light switch or socket, but neither are we limited to a single\n  central control point. Cables from lights/shutters and switches should meet\n  somewhere in one or more electrical boxes that are connected together with a\n  twisted pair cable to form a CAN bus. Bus can span multiple devices in single\n  electrical box, or connect multiple points in a bus or semi-bus configuration.\n- Instant response to input.\n- Event on one board can cause an action on another (eg. stair switches) via a\n  bus without requiring a computer and HomeAssistant - eg. stair lighting.\n- Can gather door/window/movement sensor data and be used as an alarm system.\n- Open \u0026 customizable: I'm building it to suit my needs, trying to keep it open\n  for any additional sensible functions.\n- Integrates with HomeAssistant, but can do a lot without it.\n\n** Resources\nThe core system software is in two repositories:\n- [[https://github.com/smartenough-org/io-ctrl][io-ctrl]]:\n  Firmware for IO controller board that handles IO - reads switches and\n  sensors, changes outputs. Contains also firmware for hardware part (left side)\n  of =CAN\u003c-\u003eUSB\u003c-\u003eMQTT= bridge to talk to HomeAssistant.\n- [[https://github.com/smartenough-org/io-gate][io-gate]]:\n  computer part of =CAN\u003c-\u003eUSB\u003c-\u003eMQT= bridge (right part) to convert CAN\n  messages to MQTT events that can be understood by HomeAssistant.\n- Firmware is in Rust, written with Embassy framework for STM32G431 device.\n  Should migrate easy enough to other chips assuming enough peripherals are\n  available (CAN and USB working together, 128kB+ Flash, 32kB+ RAM).\n\nRest of the resources include:\n- KiCAD (schematic + board) designs for IO controller board (can be used for\n  gate as well).\n- KiCAD for organized power injection with protection.\n- KiCAD for additional ESPHOME boards for less critical components (like\n  temperature sensors).\n- 3D printing (FreeCad) designs for DIN rail (mount in electrical boxes) and\n  other project boxes for boards (OpenSCAD).\n- This repository in addition can contain anything smarthome related I might\n  publish (eg. some micropython watering experiments)\n\n** Example deployment\n[[media/deployment-diagram.png]]\n\nThat's my currently working deployment. NOTE: CAN should not be a star, it\nshould be a bus. Hence in one case I send CAN signal back over another cable\npair in the same cable to \"flatten\" it out. Bus gets longer (it's around 50m\ntotal), but stubs are shorter.\n\n*** Connecting cables\nI use two pairs for power, one for CAN and one for optional CAN return and a bit\nweird RJ45 wiring to indicate the cable is a \"SMART\" cable not Ethernet. I also\nmark those in a visible way. Anything will work as long as CAN and FORWARD is in\nthe same twisted pair (my mapping will work with normal T568B too).\n\n| T568B | CAN  |   |                       |\n|-------+------+---+-----------------------|\n| w-o   | w-o  | 1 | CAN_L                 |\n| o     | o    | 2 | CAN_H                 |\n| w-g   | w-g  | 3 | IN POWER, 24V         |\n| bl    | g    | 4 | IN POWER, GND (swap!) |\n| w-bl  | w-bl | 5 | IN POWER, 24V         |\n| g     | bl   | 6 | IN POWER, GND (swap!) |\n| w-br  | w-br | 7 | CAN_L FORWARD         |\n| br    | br   | 8 | CAN_H FORWARD         |\n\n*** CAN configuration\nI use CAN because it's a multi-master bus, no \"leader\" device on the BUS needs\nto poll for data from \"following\" devices. When input event occurs or output\nchanges state a board broadcasts a message on the bus. Another board can see\nthis message and react by changing it's outputs.\n\nGate is a special device that serves as a bidirectional =CAN\u003c-\u003eUSB\u003c-\u003eMQTT=\nbridge. It receives CAN messages, converts them and publishes them on MQTT. It\nalso subscribes to MQTT topics and if something is published there it sends a\nCAN request to for example toggle an Output.\n\nI use 250kbps CAN speed and 11-bit addressing. I opted for a simple CAN protocol\n(as opposed to more versatile CANopen). Address relates to a \"message\" more than\na \"sender/receiver\" and is used in determining the priority on the bus. Given\nthat:\n- Messages must be properly unique,\n- lower values have higher priorities,\n- we want at least 64 devices on the bus,\nI picked 6 bit for device address and 5 for message type (32 different message\ntypes). Format: =TTTTTAAAAAA (T)ype + (A)ddress=.\n\nReporting errors, propagating output/input changes, setting output has higher\npriority than requesting status, reporting status, time announcements or some\ndebug ping/pong messages.\n\nMessage body consists of up to 8 bytes of data, system typically uses 2-3.\nExample: Request output change has 2 bytes: Index of output to change and byte\nrepresenting state (Off, On, Toggle). Message address points at the device that\nshould change output (\"destination\").\n\nMessage \"Output changed\" has similarly output index and state (Off, On), but\naddress points to a message source instead. I don't use RTR (remote frames).\n\nConscise list of used commands (but see message.rs for details):\n- ERROR 0x02 - Error happened.\n- OUTPUT_CHANGED 0x04 - My output changed\n- INPUT_CHANGED 0x05 -  My input was changed\n- SET_OUTPUT 0x08 - Set output X to Y (or invert state)\n- CALL_PROC 0x0A - Call a predefined procedure in VM\n- CALL_SHUTTER 0x0B - Pass command to Shutter code\n- STATUS_IO 0x0E - My current IO status, not necessarily changed.\n- INFO 0x12 - Similar to ERROR, but low priority (eg. Device started)\n- PONG 0x1D\n- PING 0x1E\n\nCall Shutter is longest command as it includes a shutter index and a command\nbyte that can contain a height and a tilt of the shutter.\n\n** IO Controller MainBoard\nFor details on components and software see\n[[https://github.com/smartenough-org/io-ctrl][io-ctrl]].\n\nThis board controls IOs when paired with some relay/SSR module. It sits in an\nelectrical box where it can read signals from light switches and control power\nto lighting. It's talks with the world via classical twisted pair cable: CAT5e\nUTP. Cable carries power (24V+) and a CAN bus.\n\n[[hardware/board_v1.png]]\n[[hardware/schematic_v1.png]]\n\n** Power distribution board\nPower board distributes power with some protection (capacitors, resettable\nindividual fuses, main fuses, zener diodes to limit voltage, diodes to prevent\ninvalid polarization). It also connects CAN BUS together in configured various\nways (directly, or using FORWARD pair). In general it allows me to connect the\ncables from boards in the main central hub easily.\n\n[[hardware/powerboard_v1.png]]\n\n** ESPHome \"Uniboard\"\nIt's not strictly part of my main smarthome. A universal PCB board for ESP32 S2\nMini modules I have. It has power stabilization, 1-wire pull-up, some analog\ninputs, RS485 interface, four MOSFETs for RGBW or anything else (garage door\ncontrol).\n\nI use it with Esphome (over Wifi) where I can't reach with my CAN bus, or where\nI don't need the resiliency or just temporarily. For example to gather\ntemperature readings around heat pump.\n\n[[hardware/uniboard.png]]\n\n** Greenfinger\n\nAutomatic plant watering using ESP8266 (or ESP32) using Micropython.\nIntegrates with HomeAssistant over MQTT:\n- Reports status (humidity, operations).\n- Can be controlled over MQTT (more water NOW).\n\nIt was 100% stable during a period of about a year. Plants died for unrelated\nreasons. ;)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartenough-org%2Fsmartenough","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmartenough-org%2Fsmartenough","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartenough-org%2Fsmartenough/lists"}