The hub consists of a WebServer in NodeJS running the Aedes MQTT broker. Aedes uses Redis as its backing store.
It uses a PostgreSQL for data storage.
It does not have any authentication at the moment; authentication will be built on top of Passport.
Idea is for the Hub
to be the main controller unit that is 'auto-discoverable' by the clients
or nodes
.
Each node
on boot up tries to connect to hubofthings.local
and on connection publishes its capabilities in terms of Control Units it is managing. With the advent of ESP83xx based Tasmota devices there will be some sort auto-discovery for these devices built in as well.
Control units are typically an ESP82xx or ESP32 (or any compute module like Pi Zero W) running an instance of the MQTT client
. Since an ESP82xx can control multiple items via GPIO ports, a control unit must declare what it can do, when connecting to the MQTT broker, in this case the Hub.
A control unit needs to support MQTT, https and the TCP/IP stack to be a part of the Hub's network.
A control unit could be running other open source firmwares like Tasmota. So our capabilities should be able to use Tasmota's capabilities definition if possible.
Control units could be Zigbee based devices too via Zigbee to MQTT bridge based on CC2531 Zigbee repeaters. We like to be able to discover such devices and bring them under control.
Control unit Capability (CC) is the description of a single capability of the CU. A CU can have multiple capabilities at the same time, e.g. Drive Relays and provide Temperature or Light sensor reading etc. The maximum number of CCs is typically guided by maximum number of addressable GPIO pins or I2C functions.
TBD.- Forms authentication using Passport for user authentication.
- Idea is to run a token server on Hub and authorized clients get issued security token.
A RaspberryPi can power 5v relays from its 5v pins and drive it through any of its GPIO ports.
Warning
What goes on the other side of the Relay is beyond the scope of this framework. If you are dealing with high voltage (110v/230v), high current, relays please be careful and take all safety measures that are standard while dealing with high voltage.
I am assuming you are using Relays to trip 3.3v-5v circuits ;-)
- Initialize : The CU can be initialized (this is almost directly related to the gpiozero
ìnitialize
command. CUs are coded in python and uses the gpiozero library under the hood) - On : The CU has a ON state
- Off : The CU has an OFF state
- Close: The CU is in an unresponsive state and cannot respond to anything other than Initialize.
- Update: All CUs should be able to update themselves on this command. The details of updating an air-gapped network is to be worked out later.
This is represented as the following JSON payload
{
"ccType": "Relay",
"ccTypeId": 1001,
"ccGpioPin": 17,
"ccActions": [
{
"name": "Initialize",
"deps": []
},
{
"name": "On",
"deps" : ["Initialize"]
},
{
"name": "Off",
"deps": ["Initialize", "On"]
},
{
"name": "Close",
"deps": ["Initialize"]
}
]
}
When a Hub starts communicating with a CU it stores a 'session' state of the CU to provide appropriate views on the UI.
The state is persisted on actions and also on a timer.
Since CUs communicate with the Hub over WiFi (at the moment), it is important only recognized CUs are allowed to talk to the Hub. Towards this, each CU needs to be registered manually once they establish a connection.
If a CU is not registered it is blacklisted after a while.
When a CU is blacklisted it is informed of the decision and all future requests are ignored (how? Block IP?)
hubofthings.local
is online- CU comes online and tries to connect to
hubofthings.local
- If connected, CU sends out a Registration message to the
/Register
channel and registers to listen to the/Register/[mac-address]
channel. - The registration information is stored into the DB and the system waits for it to be acted upon.
- When the user whitelists the CU (from the
hubofthings.local
site), the mqtt server sends out a message on the/Register/[mac-address]
channel to the tell the CU that it is now whitelisted and it can communicate with the Hub. This payload also contains a security token that the CU must use for future requests. - Once the the CU receives registration confirmation it registers to listen to
/cu/[mac-address]
channel. - When a CU fails to reach
hubofthings.local
it retries connection with an increasing time gap. A CU continues for 24 hours and then shuts itself down if it cannot reachhubofthings.local
to register itself.
- Before we roll out automated registrations on custom hardware we will need to implement manual registrations for Tasmota devices on our own network. This is because we need other features such as graphs and data storage sorted and get the software in a usable alpha state.
Recent developments like Zigbee and Zigbee2Mqtt implies we might have hardware that is easier to communicate without custom firmware so the hub should take advantage of these devices as well. - Manual registration involves following features
- Register CUs to Hub via MQTT Channels
- Have CU page to turn it on and off and other features
- Define CU Capabilities and actions per CU
- Save CU Capability values like Power consumption
Initially commands are initiated from the Hub via the web interface only. There will be provision of CU to CU command exchange in the future so that devices like capacitive switch pHATs and other fancy input methods can be used to send commands to other CUs.
- Hub presents all capabilities of a particular CU as 'appropriate components' on screen. For example the "Initialize" capability can be represented as a "Button".
- Whenever the state is changed, Hub saves the snapshot in the DB. Refer to cuState section in Data Layer.
- Pressing a
Button
sends acommand
message to the/cu/[mac-address]/command
channel.
- Once the CC receives a
command
it tries to complete the action. - Once action is complete the CC sends back a
response
payload to the/cu/[mac-address]/response
and report back the status.
The database for the web server
Accounts collection used by Passport (reserved for future use)
Session data as used by Passport and express-session
Control units collection that stores the list of CUs that connected to the hub
id: Unique identifier
deviceId: MAC address provided while Registering
{
_id: number; //PK
deviceId: string; //Unique
description: string;
}
Describes CCs of a Control unit.
Each control unit can have multiple capabilities and there is a one to many relationship.
cuId
is the foreign key pointing back to the control-unit.
{
id: number; //PK
cuId: number; //FK
type: string;
typeId: number;
gpioPin: number;
}
{
id: number; //PK
ccId : number: //FK
name: string;
dependencies: json;
}
Describes the state of a Control Unit's capability.
{
id: number; //PK
ccaId: number; //FK
cuId: ObjectId;
capabilityId: ObjectId;
type: string;
gpioPin: number;
state: any;
}