Package: fancontrolbridge
The MQTT Fan Controller BridgeDescriptionThe bridge acts as a middleman between a MQTT broker and the Arduino-based
PID fan controller (connected via a serial port [USB] to the bridge). The bridge subscribes
to a command topic described in the config, and forwards the commands received in
that topic to the Controller via a serial port. The responses from the
Controller will be forwarded to the topics also described in the config.InstallationThere is currently no easy way to install the package since it's still
in early development phase (well, pip might offer something, but YMMV).ConfigurationThe config fileThe Bridge expects to find a config file in$XDG_CONFIG_HOME/fancontrolbridge/config.yaml.
This may be overridden by specifying a config file when starting the Bridge with
the flag-c(example:fancontrolbridge -c ./config.yaml).Example of a full config file:modules:-type:mqttmessengerconfig:publish_events:channel_1_status:fancontrolbridge/test/ch1/statuschannel_2_status:fancontrolbridge/test/ch2/statuschannel_1_settings:fancontrolbridge/test/ch1/settingschannel_2_settings:fancontrolbridge/test/ch2/settingscontroller_command_results:fancontrolbridge/command-resultssubscribe_topics:-fancontrolbridge/commandshost:<mqtt_bridge_host>-type:fancontrollercommunicatorconfig:port:/dev/ttyACM0bauds:9600command_topic:fancontrolbridge/commandsThe MQTTMessenger configpublish_eventsandsubscribe_topicsThe configuration file allows setting command topic which the Bridge
will then listen to for the commands, and the topics to which the responses
from the Controller should be forwarded to.Command topic config example:subscribe_topics:-fancontrolbridge/commandsResponse publish topics config example:publish_events:channel_1_status:fancontrolbridge/test/ch1/statuschannel_2_status:fancontrolbridge/test/ch2/statuschannel_1_settings:fancontrolbridge/test/ch1/settingschannel_2_settings:fancontrolbridge/test/ch2/settingscontroller_command_results:fancontrolbridge/command-resultsThe commands received from the commands topics will be evaluated and sent
to the Controller if they are formed correctly. Evaluation results of all commands
and the results of sending the commands to the Controller commands will be forwarded
to thecontroller_command_resultstopic.The responses from the Controller forGETcommands will be forwarded to the topicschannel_<number>_status(for status report commands) andchannel_<number>_settings(for getting the current settings).To recap:There will be a message incontroller_command_resultsforeverycommand
received from the command topics.Listen to this to determine if any command got successfully forwarded.SendingGET_STATUScommand results in a response tochannel_<number>_statustopic containing current status (temps, rpm and output) of one channel on the Controller.SendingGET_SETTINGScommand results in a response tochannel_<number>_settingstopic containing current settings (mode and PID parameters) of one channel on the Controller.Setting the MQTT broker host, username and passwordThe location of your MQTT broker must be set inhost: <mqtt_bridge_host>.If your MQTT broker requires username and password to be provided, you may
export them as environment variables inside the container before starting
the application (in Linux):exportFANCONTROLBRIDGE_MQTTMESSENGER__USERNAME=usernameexportFANCONTROLBRIDGE_MQTTMESSENGER__PASSWORD=passwordYou may also provide these via a.envfile as is expected in thedocker-compose.yamlfile.The FanControllerCommunicator configportThe port in which the Controller is connected. Sometimes/dev/ttyACM0.baudsCommunication speed of the Controller. Usually9600.command_topicThe MQTT topic on which the commands get delivered to the Bridge.Should
matchone of thesubscribe_topicson MQTTMessenger configuration. This allows
us to develop additional MQTT-listening functionality which are necessarily
not Controller Command topics.In the example config:command_topic: fancontrolbridge/commands.RunningTBACommandsThe Bridge expects commands to be sent as JSON objects.Forsettinga parameter of the Controller, the command object should
containcommand,channelandvalue:{"command": <command_name_string>, "channel": <channel_id>, "value": <value_to_set>}And for getting status and settings reports from the Controller, leave the
value out of the command JSON:{"command": <command_name_string>, "channel": <channel_id>}The command names are fixed, and the channel may currently be 1 or 2.SET_TARGETThe CommandSET_TARGETsets a new target temperature for a channel.
The target temperature will becutto one decimal (Example: 23.56 -> 23.5).
Use a period as decimal separator.Example of setting target temperature to 42.5 C on channel 1:{"command":"SET_TARGET","channel":1,"value":42.5}SET_KPThe commandSET_KPsets the P control term of the PID
controller for a channel. The value will becutto two decimals.Example of setting P to 10.42 on channel 1:{"command":"SET_KP","channel":1,"value":10.42}SET_KIThe commandSET_KIsets the I control term of the PID
controller for a channel. The value will becutto two decimals.Example of setting I to 5.2 on channel 1:{"command":"SET_KI","channel":1,"value":5.2}SET_KDThe commandSET_KDsets the D control term of the PID
controller for a channel. The value will becutto two decimals.Example of setting D to 0.37 on channel 1:{"command":"SET_KD","channel":1,"value":0.37}SET_MODEThe commandSET_MODEsets the output drive mode of a channel.
There are two possible modes to set (note: three possible modes on the
Controller itself):0: Manual drive by setting the output withSET_OUTPUT.1: Automatic PID-controlled drive.Example of setting the drive mode tomanualon channel 2:{"command":"SET_MODE","channel":2,"value":0}Note:The output speed should be explicitly set, with another command,
after setting the drive mode to manual. See the command below for setting speed
manually.SET_OUTPUTThe commandSET_OUTPUTsets the output speed for a channel.
The speed should be between 0-255, where 0 means the lowest possible
speed a fan can go, and 255 the fastest speed. Only integers should be sent.Example of setting the speed to 128 (50 %) on channel 2:{"command":"SET_OUTPUT","channel":2,"value":128}Note:The output speed will not be set unless the drive mode is set
to manual.GET_STATUSThe commandGET_STATUSrequests the Controller for current status (channel,
current temperature, target temperature, fan speed and raw output).Example of getting the status of channel 2:{"command":"GET_STATUS","channel":2}The status will be sent to thechannel_<number>_statustopic described in the
config file. It looks like this:{"temp":0,"target":30,"speed":0,"output":255}GET_SETTINGSThe commandGET_SETTINGSrequests the Controller for current settings (channel,
mode, P, I and D tuning terms).Example of getting the settings of channel 2:{"command":"GET_SETTINGS","channel":2}The settings will be sent to thechannel_<number>_settingstopic described in the
config file. It looks like this:{"mode":0,"kp":4,"ki":0.4,"kd":2}Note:There are three possible modes for the Controller to be in:0: Manual drive1: Automatic drive2: Forced FULL SPEED (usually caused by error reading temperature sensor)DevelopmentThere is a development Docker container provided for ensuring identical
development environments for each developer. This is also to lessen the
need for developers to install dependencies on their system (even though
venvs exist).The port where the Arduino board resides must be provided as an environment
variable (this is to pass the port to the Docker container).
For example:export ARDUINO_PORT=/dev/ttyACM0.Build the container with:docker-compose build [--no-cache]and run withdocker-compose run dev.Docker and Docker Compose should obviously be installed, but those are
basically the only requirements for developer machines.All development tasks should be run inside the container, unless otherwise
stated.Installing MQTTFanController in editable modeAll development tasks require installing MQTTFanController, since this
also installs all dependencies from PyPI.During development it's quite useful to be able to run the app in
editable mode. This allows you to modify the code without reinstalling
the package every time there is a change to the source code. This can be
achieved by runningpip install -e ..Running MQTTFanController inside the containerBefore starting the bridge a configuration file must be provided. An example
config is provided above. If your MQTT broker requires username
and password to be provided, you may export them as environment variables
inside the container before starting the application:exportFANCONTROLBRIDGE_MQTTMESSENGER__USERNAME=usernameexportFANCONTROLBRIDGE_MQTTMESSENGER__PASSWORD=passwordThe app may be started simply by runningfancontrolbridge -c ./config.yamlafter providing necessary configurations.Running unit testsUnit tests can be run by runningpython -m unittest.Viewing logs during developmentIf you would like to view the logs outside the Docker container while
developing, there's an easy way to achieve it:Note: These should be run outside the containerFirst get the running container id with:docker psFollow the logs withdocker logs <container-id> -f