User friendly timer app using node.js to control Tasmota powered smartplugs
The provided codebase consists of two primary files: index.js
(running on the server side) and index.html
(interpreted on the client side). Additionaly there are two configuration files:
config.json
: authentication details for the end user and log settings.settings.json
: authentication details for the Tasmota devices.Together, these files create a web-based interface for using Tasmota-powered devices as a timer. The following description outlines the functionality and interactions between these files.
The index.html
file is a web page designed to control the timerfunction on a Tasmota devices via a simple user interface. It contains several HTML elements, JavaScript functions, and CSS references to facilitate control and status monitoring of the Tasmota timer. This part is rendered and executed at the client side, to create a GUI and define actions for its control elements. The static file index.html together with the ascociated stylesheet (index.css
) are served by a call to index.js.
Head Section:
index.css
).
Body Section:
div
with the ID controls
including a dropdown menu for selecting a device, a switch to toggle device power, Inputs for setting timer duration in hours and minutes and Buttons to set and clear timers.
div
with the ID log
displays the current timer status, last user action, and error messages when aplicable.
Embedded within the HTML file, the JavaScript handles the interaction using the following logic:
Initialization and WebSocket Setup:
Device Control Functions:
togglePower()
: Toggles the power state of the selected device and updates the status display.
setTimerWithDelta()
: Sets a timer based on user input for hours and minutes and enables timers on the device.
clearTimer()
: Clears any active timers on the device and updates the status display.
updateDeviceStatus()
: Fetches and displays the current power and timer status of the selected device.
deviceChanged()
: Updates the status display when a different device is selected.
Utility Functions:
getLocalTimeString()
: Returns the current local time as a formatted string.
getSelectedDevice()
: Retrieves the currently selected device from the dropdown menu.
sendCommand()
: Sends commands to the server to interact with the device, handling responses and errors appropriately.
Event Listeners:
The index.js
file implements the server-side logic using Node.js, handling HTTP requests to interact with Tasmota devices. It reads configuration settings, manages user authentication, and serves static files and API endpoints. This part is executed at the server side. The following functionality is provided:
Dependencies and Initialization:*
http
, fs
, path
, crypto
, and url
.
Configuration File Loading:
Reads and parses config.json
and settings.json
to load user credentials and device accounts.
Server Creation:
Creates an HTTP server to listen for incoming requests.
Request Handling:
Handles different routes based on the request URL:
<ul><li><code>POST /login</code>: Authenticates users using credentials from the request body.
</li><li>Serves static files (<code>index.html</code>, <code>styles.css</code>, <code>favicon.ico</code>, and <code>header.png</code>).
</li><li><code>GET /devices</code>: Returns a list of available Tasmota devices defined in <code>settings.json</code>.
</li><li>The following device-specific routes are defined (<code>/setPower</code>, <code>/getTime</code>, <code>/setTimer</code>, <code>/clearTimer</code>, <code>/getTimerStatus</code>, <code>/getPowerStatus</code>, <code>/enableTimers</code>, <code>/disableTimers</code>).
</li></ul>
Command Execution:
Defines functions to handle device commands:
<ul><li><code>handleSetPower()</code>: Sets the power state of a device.
</li><li><code>handleSetTimer()</code>: Sets a timer on a device.
</li><li><code>handleClearTimer()</code>: Clears a timer on a device.
</li><li><code>handleGetTimerStatus()</code>, <code>handleGetPowerStatus()</code> <code>handleGetTime()</code>: Fetches current status information from the device for timer, switchstatus and time.
</li><li><code>handleEnableTimers()</code>, <code>handleDisableTimers()</code> Enables or disables timers on a device.
</li></ul>
Utility Functions:
isAuthorized()
: Checks if a request contains valid authentication credentials.
serveStaticFile()
: Serves static files from the server's public directory.
logMessage()
: Logs messages to a file if debug mode is enabled.
getRequestOptions()
: Prepares HTTP request options for sending commands to Tasmota devices.
makeRequest()
: Makes HTTP requests to Tasmota devices and processes responses.
getCurrentDeviceTime()
: Get the current time from the Tasmota device.
sanitizeInput()
: Sanitize input to prevent XSS attacks.
The server logs client actions and errors to a log file if debug mode is enabled (by setting ‘debug’ to ‘true’ in config.json
, providing traceability and aiding in debugging issues. Please be aware that there is no mechanism implemented to manage the logfiles. Logging is only to be switched on to allow for investigation or for development purposes (in order to prevent filesystem overflow).