[PRES] [presentations] master: Confoo IOT talk

From: Date: Mon, 23 Feb 2026 17:04:34 +0000
Subject: [PRES] [presentations] master: Confoo IOT talk
Groups: php.pres 
Request: Send a blank email to pres+get-2508@lists.php.net to get a copy of this message
Author: Derick Rethans (derickr) Date: 2026-02-23T16:59:40Z Commit: https://github.com/php/presentations/commit/fc118f9042621ad99a6b432ade2e2e1b982bda95 Raw diff: https://github.com/php/presentations/commit/fc118f9042621ad99a6b432ade2e2e1b982bda95.diff Confoo IOT talk Changed paths: A iot-confoo26.xml A slides/iot/.ha-php-mqtt-next-animations.xml.swp A slides/iot/MQTT-all.png A slides/iot/chapter-and-then-there-was-light.xml A slides/iot/chapter-desk-control.xml A slides/iot/chapter-plans-and-trees.xml A slides/iot/chapter-smart-heating.xml A slides/iot/esp32-code.png A slides/iot/esp32-lego-box.png A slides/iot/esp32-schematic.png A slides/iot/esp32-vga-palette.png A slides/iot/go-streamdeck-code.xml A slides/iot/go-streamdeck-configuration.xml A slides/iot/go-streamdeck-publish-mqtt.xml A slides/iot/ha-action-turn-lights-off-bright.png A slides/iot/ha-action-turn-lights-off.png A slides/iot/ha-action-turn-lights-on-dark.png A slides/iot/ha-action-turn-lights-on-enter.png A slides/iot/ha-actions-turn-lights-on.png A slides/iot/ha-add-mqtt-integration.xml A slides/iot/ha-create-forecast-mqtt-trigger.xml A slides/iot/ha-create-mqtt-trigger.xml A slides/iot/ha-dim-lights-action.png A slides/iot/ha-forecast.png A slides/iot/ha-forecast.xml A slides/iot/ha-luminance-both.png A slides/iot/ha-luminance-non-smooth.png A slides/iot/ha-nest-data-1.xml A slides/iot/ha-nest-data-2.xml A slides/iot/ha-nest-data-mqtt-result.xml A slides/iot/ha-nest-data-mqtt-step0.xml A slides/iot/ha-nest-data-mqtt-step2.xml A slides/iot/ha-nest-data-mqtt-step3.xml A slides/iot/ha-nest-data-mqtt-step4.xml A slides/iot/ha-nest-data-mqtt.xml A slides/iot/ha-nest-data.xml A slides/iot/ha-nest-heat-slope1.png A slides/iot/ha-nest-heat-slope2.png A slides/iot/ha-nest-schedule-alone.png A slides/iot/ha-nest-schedule.png A slides/iot/ha-nest-schedule.xml A slides/iot/ha-nest-slope-0.jpeg A slides/iot/ha-nest-slope-1.jpeg A slides/iot/ha-nest-slope-2.jpeg A slides/iot/ha-nest-slope.xcf A slides/iot/ha-nest-slope1.png A slides/iot/ha-nest-slope2.png A slides/iot/ha-nest-temperature.png A slides/iot/ha-php-mqtt-code-rgb.xml A slides/iot/ha-php-mqtt-code.xml A slides/iot/ha-php-mqtt-lego-box-design.xml A slides/iot/ha-php-mqtt-lego-box-prototype.xml A slides/iot/ha-php-mqtt-next-animations.xml A slides/iot/ha-php-mqtt-result-rainy.xml A slides/iot/ha-php-mqtt-result-sunny.xml A slides/iot/ha-php-mqtt-result-unknown.xml A slides/iot/ha-php-mqtt-result.xml A slides/iot/ha-php-mqtt.xml A slides/iot/ha-program-esp32-board.xml A slides/iot/ha-sensor-current-temp1.png A slides/iot/ha-sensor-current-temp2.png A slides/iot/ha-smooth-brightness.png A slides/iot/ha-tree-lights.png A slides/iot/ha-zigbee-network.png A slides/iot/heating-rate.png A slides/iot/heating-schedule.png A slides/iot/home-assistant-1.xml A slides/iot/icons.png A slides/iot/iot-elephpant-shelf.jpeg A slides/iot/iot-esp32-matrix.jpeg A slides/iot/iot-homeassistant-zigbee.jpeg A slides/iot/iot-homeassistant.jpeg A slides/iot/iot-human-detector.jpeg A slides/iot/iot-lamp-dim.gif A slides/iot/iot-lego-lights.jpeg A slides/iot/iot-matrix-sun-paper.jpeg A slides/iot/iot-monty.jpeg A slides/iot/iot-motion-detector.jpeg A slides/iot/iot-smartlife-plug.jpeg A slides/iot/iot-streamdeck-home.jpeg A slides/iot/iot-streamdeck-obs.jpeg A slides/iot/iot-weather-lego-prototype.jpeg A slides/iot/iot-weather-lego-prototype..jpeg.jpeg A slides/iot/iot-weather-rainy.jpeg A slides/iot/iot-weather-sunny.jpeg A slides/iot/iot-weather-unknown.jpeg A slides/iot/iot-wedding-tree-switch.jpeg A slides/iot/iot-wedding-tree.jpeg A slides/iot/lights-options.png A slides/iot/livingroom-ok.xml A slides/iot/livingroom-party.xml A slides/iot/monty.xml A slides/iot/mqtt-integration.png A slides/iot/mqtt-logo.svg A slides/iot/mqtt-project-goal.xml A slides/iot/mqtt-whats-next-elephpants.xml A slides/iot/mqtt-whats-next-esp32-board.xml A slides/iot/mqtt-whats-next-lego.xml A slides/iot/mqtt-whats-next-weather-matrix.xml A slides/iot/mqtt-whats-next.xml A slides/iot/mqtt.xml A slides/iot/office-lights-dim.xml A slides/iot/office-lights-goals.xml A slides/iot/office-lights-turn-off-bright-enough.xml A slides/iot/office-lights-turn-off-leave.xml A slides/iot/office-lights-turn-on.xml A slides/iot/party-lights.gif A slides/iot/smart-plug-1.xml A slides/iot/streamdeck.xml A slides/iot/the_internet_from_the_it_crowd.jpeg A slides/iot/varying-light-smoothed.xml A slides/iot/varying-light.xml A slides/iot/wishing-tree.xml A slides/iot/zigbee-network..xml A templates/default/sub.ezt Diff: diff --git a/iot-confoo26.xml b/iot-confoo26.xml new file mode 100644 index 00000000..d02180bf --- /dev/null +++ b/iot-confoo26.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8"?> +<presentation css="derick.css"> +<topic>IOT</topic> +<title>Automating My House with PHP &amp; Go</title> +<event>ConFoo 2026</event> +<location>Montréal, Canada</location> +<date>Feb 26th, 2026</date> +<speaker>Derick Rethans</speaker> +<email>derick@derickrethans.nl</email> +<mastodon>@derickr@phpc.social</mastodon> +<twitter>derickr</twitter> +<url>https://derickrethans.nl/talks/iot-confoo26</url> +<joindin>https://derickrethans.nl</joindin> +<slide>slides/xdebug/title.xml</slide> +<slide>slides/mongodb/me.xml</slide> + +Chapter 1: Plants and Trees +================================= + +<slide>slides/iot/chapter-plans-and-trees.xml</slide> + +<slide>slides/iot/monty.xml</slide> +<slide>slides/iot/smart-plug-1.xml</slide> +<slide>slides/iot/home-assistant-1.xml</slide> +<slide>slides/iot/zigbee-network.xml</slide> +<slide>slides/iot/wishing-tree.xml</slide> + +Chapter 2: And Then There Was Light +=================================== + +<slide>slides/iot/chapter-and-then-there-was-light.xml</slide> + +<slide>slides/iot/varying-light.xml</slide> +<slide>slides/iot/office-lights-goals..xml</slide> +<slide>slides/iot/office-lights-turn-off-leave.xml</slide> +<slide>slides/iot/office-lights-turn-off-bright-enough.xml</slide> +<slide>slides/iot/varying-light-smoothed.xml</slide> +<slide>slides/iot/office-lights-turn-on.xml</slide> +<slide>slides/iot/office-lights-dim.xml</slide> + +<slide>slides/iot/livingroom-party.xml</slide> +<slide>slides/iot/livingroom-ok.xml</slide> + +Chapter 3: Desk Control +======================= + +<slide>slides/iot/chapter-desk-control.xml</slide> +<slide>slides/iot/streamdeck.xml</slide> +<slide>slides/iot/mqtt-project-goal.xml</slide> +<slide>slides/iot/mqtt.xml</slide> +<slide>slides/iot/ha-add-mqtt-integration.xml</slide> +<slide>slides/iot/ha-create-mqtt-trigger.xml</slide> +<slide>slides/iot/go-streamdeck-configuration.xml</slide> +<slide>slides/iot/go-streamdeck-code.xml</slide> +<slide>slides/iot/go-streamdeck-publish-mqtt.xml</slide> + +Chapter 4: Blinking Lights +=========================== + +<slide>slides/iot/ha-forecast.xml</slide> + +<slide>slides/iot/ha-create-forecast-mqtt-trigger.xml</slide> +<slide>slides/iot/ha-program-esp32-board.xml</slide> +<slide>slides/iot/mqtt-whats-next-esp32-board.xml</slide> +<slide>slides/iot/ha-php-mqtt.xml</slide> +<slide>slides/iot/ha-php-mqtt-code.xml</slide> +<slide>slides/iot/ha-php-mqtt-result-unknown.xml</slide> +<slide>slides/iot/ha-php-mqtt-result-rainy.xml</slide> +<slide>slides/iot/ha-php-mqtt-code-rgb.xml</slide> +<slide>slides/iot/ha-php-mqtt-result-sunny.xml</slide> +<slide>slides/iot/ha-php-mqtt-lego-box-prototype.xml</slide> +<slide>slides/iot/ha-php-mqtt-lego-box-design.xml</slide> +<slide>slides/iot/ha-php-mqtt-next-animations.xml</slide> + +Chapter 5: Smart Heating? +========================= + +<slide>slides/iot/chapter-smart-heating.xml</slide> +<slide>slides/iot/ha-nest-schedule.xml</slide> +<slide>slides/iot/ha-nest-data.xml</slide> +<slide>slides/iot/ha-nest-data-1.xml</slide> +<slide>slides/iot/ha-nest-data-2.xml</slide> +<slide>slides/iot/ha-nest-data-mqtt.xml</slide> +<slide>slides/iot/ha-nest-data-mqtt-step0.xml</slide> +<slide>slides/iot/ha-nest-data-mqtt-step2.xml</slide> +<slide>slides/iot/ha-nest-data-mqtt-step3.xml</slide> +<slide>slides/iot/ha-nest-data-mqtt-result.xml</slide> + + +Conclusion +========== + +<slide>slides/iot/mqtt-whats-next-elephpants.xml</slide> +<slide>slides/iot/mqtt-whats-next-lego.xml</slide> + +<slide>slides/mongodb/questions.xml</slide> +<slide>slides/xdebug/resources.xml</slide> + +</presentation> diff --git a/slides/iot/.ha-php-mqtt-next-animations.xml.swp b/slides/iot/.ha-php-mqtt-next-animations.xml.swp new file mode 100644 index 00000000..6165d690 Binary files /dev/null and b/slides/iot/..ha-php-mqtt-next-animations.xml.swp differ diff --git a/slides/iot/MQTT-all.png b/slides/iot/MQTT-all.png new file mode 100644 index 00000000..994fa424 Binary files /dev/null and b/slides/iot/MQTT-all.png differ diff --git a/slides/iot/chapter-and-then-there-was-light.xml b/slides/iot/chapter-and-then-there-was-light.xml new file mode 100644 index 00000000..96f9c994 --- /dev/null +++ b/slides/iot/chapter-and-then-there-was-light.xml @@ -0,0 +1,3 @@ +<slide style="title"> +<title>Chapter 2: And Then There Was Light</title> +</slide> diff --git a/slides/iot/chapter-desk-control.xml b/slides/iot/chapter-desk-control.xml new file mode 100644 index 00000000..590432aa --- /dev/null +++ b/slides/iot/chapter-desk-control.xml @@ -0,0 +1,3 @@ +<slide style="title" background="iot-streamdeck-home.jpeg"> +<title>Chapter 3: Desk Control</title> +</slide> diff --git a/slides/iot/chapter-plans-and-trees.xml b/slides/iot/chapter-plans-and-trees.xml new file mode 100644 index 00000000..f1530826 --- /dev/null +++ b/slides/iot/chapter-plans-and-trees.xml @@ -0,0 +1,4 @@ +<slide style="title"> +<title>Chapter 1: Plants and Trees</title> +</slide> + diff --git a/slides/iot/chapter-smart-heating.xml b/slides/iot/chapter-smart-heating.xml new file mode 100644 index 00000000..1db50815 --- /dev/null +++ b/slides/iot/chapter-smart-heating.xml @@ -0,0 +1,4 @@ +<slide style="title" background="lights-options.png"> +<title><br/><br/>Chapter 5: Smart Heating |777777|?|<br/><br/><br/>&#160;</title> +<image filename="ha-nest-schedule-alone.png"/> +</slide> diff --git a/slides/iot/esp32-code.png b/slides/iot/esp32-code.png new file mode 100644 index 00000000..f7e52697 Binary files /dev/null and b/slides/iot/esp32-code.png differ diff --git a/slides/iot/esp32-lego-box.png b/slides/iot/esp32-lego-box.png new file mode 100644 index 00000000...caef7f08 Binary files /dev/null and b/slides/iot/esp32-lego-box.png differ diff --git a/slides/iot/esp32-schematic.png b/slides/iot/esp32-schematic.png new file mode 100644 index 00000000..8b0874f1 Binary files /dev/null and b/slides/iot/esp32-schematic.png differ diff --git a/slides/iot/esp32-vga-palette.png b/slides/iot/esp32-vga-palette.png new file mode 100644 index 00000000..e4923fb9 Binary files /dev/null and b/slides/iot/esp32-vga-palette.png differ diff --git a/slides/iot/go-streamdeck-code..xml b/slides/iot/go-streamdeck-code.xml new file mode 100644 index 00000000..e421a6fd --- /dev/null +++ b/slides/iot/go-streamdeck-code.xml @@ -0,0 +1,67 @@ +<slide style="title"> +<blurb class="large">Step 4: Make Stream Deck Listen for Incoming MQTT Messages</blurb> +<break/> +<example inline="2"> +import ( + mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/spf13/viper" +) + +type MqttThing struct { + SD *streamdeck.StreamDeck + Brightness *Brightness + mqtt_client mqtt.Client + actions []MqttAction +} + +type MqttSubscription struct { + Topic string mapstructure:"topic" +} + +type MqttAction struct { + Topic string mapstructure:"topic" + Value string mapstructure:"value" + Type string mapstructure:"type" + BrightnessLevel *int mapstructure:"brightnessLevel" +} + +func (p *MqttThing) onMqttMessageReceived(client mqtt.Client, message mqtt.Message) { + payload := string(message.Payload()[:]) + + for _, topic := range p.actions { + if topic.Topic == message.Topic() &amp;&amp; topic.Value == payload { + if topic.Type == "brightness" &amp;&amp; topic.BrightnessLevel != nil { + p.Brightness.SetBrightnessLevel(*topic.BrightnessLevel) + } + } + } +} + +func (p *MqttThing) Init() { + opts := mqtt.NewClientOptions(). + AddBroker(viper.GetString("mqtt.broker")). + SetClientID(viper.GetString("mqtt.clientid")). + SetUsername(viper.GetString("mqtt.username")). + SetPassword(viper.GetString("mqtt.password")) + + viper.UnmarshalKey("mqtt.actions", &amp;p.actions) + + opts.OnConnect = func(c mqtt.Client) { + var subscriptions []MqttSubscription + viper.UnmarshalKey("mqtt.subscriptions", &amp;subscriptions) + + for _, topic := range subscriptions { + if token := p.mqtt_client.Subscribe(topic.Topic, byte(0), p.onMqttMessageReceived); + token.Wait() &amp;&amp; token.Error() != nil { + panic(token.Error()) + } + } + } + + p.mqtt_client = mqtt.NewClient(opts) + if conn_token := p.mqtt_client.Connect(); conn_token.Wait() &amp;&amp; conn_token.Error() != nil { + log.Warn()..Err(conn_token.Error()).Msg("Cannot connect to MQTT") + } +} +</example> +</slide> diff --git a/slides/iot/go-streamdeck-configuration.xml b/slides/iot/go-streamdeck-configuration.xml new file mode 100644 index 00000000..1c8a319b --- /dev/null +++ b/slides/iot/go-streamdeck-configuration.xml @@ -0,0 +1,25 @@ +<slide style="title"> +<blurb class="large">Step 3: Set Up the MQTT Integration for Stream Deck</blurb> +<break/> +<example inline="2"> + # MQTT Integration + mqtt: + broker: "tcp://192.168.42.213:1883" + clientid: "go-streamdeck" + username: "mqtt" + password: "homeassistant-mqtt-XXXXXXX" + subscriptions: + - topic: *"entities/+/state_change"* + actions: + - topic: *"entities/human_detector/state_change"* + value: *on|off* + *type: brightness* + brightnessLevel: 0 + - topic: "entities/human_detector/state_change" + type: brightness + value: off|on + brightnessLevel: 1 +</example> + +<blurb class="center">Subscriptions vs Actions</blurb> +</slide> diff --git a/slides/iot/go-streamdeck-publish-mqtt.xml b/slides/iot/go-streamdeck-publish-mqtt.xml new file mode 100644 index 00000000..9b770e71 --- /dev/null +++ b/slides/iot/go-streamdeck-publish-mqtt.xml @@ -0,0 +1,28 @@ +<slide style="title"> +<blurb class="large">Step 5: Publish to MQTT</blurb> +<break/> +<blurb>Configuration:</blurb> +<example inline="2"> +HousePage: + - Index: 0 + Type: mqtt-color + Arguments: + - StateId: office-lights + - Name: "LIGHT" + - PublishTopic: "homeautomation/office" + - ActivePublishPayload: "light" + - InactivePublishPayload: "dark" + - ActiveStateColor: "#00ff00" + - InactiveStateColor: "#ff0000" +</example> +<break/> + +<blurb>To publish to MQTT:</blurb> +<example inline="2"> +mq.mqtt.mqtt_client.Publish(mq.PublishTopic, 0, false, mq..NextPublishPayload) +</example> + +<break/> +<blurb>Hooking it into the Streamdeck-Goui code was trickier…</blurb> + +</slide> diff --git a/slides/iot/ha-action-turn-lights-off-bright.png b/slides/iot/ha-action-turn-lights-off-bright.png new file mode 100644 index 00000000...3a0bdbb4 Binary files /dev/null and b/slides/iot/ha-action-turn-lights-off-bright.png differ diff --git a/slides/iot/ha-action-turn-lights-off.png b/slides/iot/ha-action-turn-lights-off.png new file mode 100644 index 00000000..ef5acc69 Binary files /dev/null and b/slides/iot/ha-action-turn-lights-off.png differ diff --git a/slides/iot/ha-action-turn-lights-on-dark.png b/slides/iot/ha-action-turn-lights-on-dark.png new file mode 100644 index 00000000..083c389e Binary files /dev/null and b/slides/iot/ha-action-turn-lights-on-dark.png differ diff --git a/slides/iot/ha-action-turn-lights-on-enter.png b/slides/iot/ha-action-turn-lights-on-enter.png new file mode 100644 index 00000000..29a02d48 Binary files /dev/null and b/slides/iot/ha-action-turn-lights-on-enter.png differ diff --git a/slides/iot/ha-actions-turn-lights-on.png b/slides/iot/ha-actions-turn-lights-on.png new file mode 100644 index 00000000..d40583fa Binary files /dev/null and b/slides/iot/ha-actions-turn-lights-on.png differ diff --git a/slides/iot/ha-add-mqtt-integration.xml b/slides/iot/ha-add-mqtt-integration.xml new file mode 100644 index 00000000..36424977 --- /dev/null +++ b/slides/iot/ha-add-mqtt-integration.xml @@ -0,0 +1,6 @@ +<slide style="title"> +<blurb class="large">Step 1: Add MQTT Integration to Home Assistant</blurb> +<break/> +<image filename="mqtt-integration.png"/> +<blurb class="center">%https://www.home-assistant.io/integrations/mqtt%</blurb> +</slide> diff --git a/slides/iot/ha-create-forecast-mqtt-trigger.xml b/slides/iot/ha-create-forecast-mqtt-trigger.xml new file mode 100644 index 00000000..a6def605 --- /dev/null +++ b/slides/iot/ha-create-forecast-mqtt-trigger.xml @@ -0,0 +1,23 @@ +<slide style="title"> +<blurb class="large">Step 1: Create MQTT Trigger in Home Assistant</blurb> +<break/> +<example> +alias: Forecast Changes +description: "" +triggers: + - trigger: state + entity_id: + - weather.forecast_home +conditions: [] +actions: + - action: mqtt.publish + metadata: {} + data: + qos: 0 + topic: homeautomation/forecast + payload: "{{trigger.to_state.state}}" +mode: single +</example> + +<blurb class="center">The payload contains the new (current) state.</blurb> +</slide> diff --git a/slides/iot/ha-create-mqtt-trigger.xml b/slides/iot/ha-create-mqtt-trigger.xml new file mode 100644 index 00000000..871a2172 --- /dev/null +++ b/slides/iot/ha-create-mqtt-trigger.xml @@ -0,0 +1,25 @@ +<slide style="title"> +<blurb class="large">Step 2: Create MQTT Trigger in Home Assistant</blurb> +<break/> +<example> +alias: MQTT Trigger for Presence Sensor +description: "" +triggers: + - trigger: state + entity_id: + - binary_sensor.human_detector +conditions: [] +actions: + - action: mqtt.publish + metadata: {} + data: + evaluate_payload: false + qos: 0 + retain: false + topic: entities/{{trigger.to_state.object_id}}/state_change + payload: "{{trigger.from_state.state}}|{{trigger.to_state.state}}" +mode: single +</example> + +<blurb class="center">The payload contains the old and new state.</blurb> +</slide> diff --git a/slides/iot/ha-dim-lights-action.png b/slides/iot/ha-dim-lights-action.png new file mode 100644 index 00000000..189ca1a7 Binary files /dev/null and b/slides/iot/ha-dim-lights-action.png differ diff --git a/slides/iot/ha-forecast.png b/slides/iot/ha-forecast.png new file mode 100644 index 00000000..ebfe0026 Binary files /dev/null and b/slides/iot/ha-forecast.png differ diff --git a/slides/iot/ha-forecast.xml b/slides/iot/ha-forecast.xml new file mode 100644 index 00000000..af9d7e7a --- /dev/null +++ b/slides/iot/ha-forecast.xml @@ -0,0 +1,3 @@ +<slide style="title" background="iot-matrix-sun-paper.jpeg"> +<title>Chapter 4: Displaying The Weather</title> +</slide> diff --git a/slides/iot/ha-luminance-both.png b/slides/iot/ha-luminance-both.png new file mode 100644 index 00000000..6b3c104a Binary files /dev/null and b/slides/iot/ha-luminance-both.png differ diff --git a/slides/iot/ha-luminance-non-smooth.png b/slides/iot/ha-luminance-non-smooth.png new file mode 100644 index 00000000..915266f1 Binary files /dev/null and b/slides/iot/ha-luminance-non-smooth.png differ diff --git a/slides/iot/ha-nest-data-1.xml b/slides/iot/ha-nest-data-1.xml new file mode 100644 index 00000000..e435fe4b --- /dev/null +++ b/slides/iot/ha-nest-data-1.xml @@ -0,0 +1 @@ +<slide background="ha-nest-slope-1.jpeg"/> diff --git a/slides/iot/ha-nest-data-2.xml b/slides/iot/ha-nest-data-2.xml new file mode 100644 index 00000000..810b7e0e --- /dev/null +++ b/slides/iot/ha-nest-data-2.xml @@ -0,0 +1,19 @@ +<slide background="ha-nest-slope-2.jpeg"> + +<div class="left-side"> +<break lines="4"/> +<div class="light-bg"> +<blurb>Collect:</blurb> +<div effect="fade-in"> +<list><bullet>When Nest Turns On and Off</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Current Livingroom Temperature</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Current Outside Temperature</bullet></list> +</div> +</div> +</div> + +</slide> diff --git a/slides/iot/ha-nest-data-mqtt-result.xml b/slides/iot/ha-nest-data-mqtt-result.xml new file mode 100644 index 00000000..6163a90a --- /dev/null +++ b/slides/iot/ha-nest-data-mqtt-result.xml @@ -0,0 +1,9 @@ +<slide> +<title>Result‽</title> + +<image filename="heating-rate.png"/> + +<div effect="fade-in"> +<blurb class="big-centre">INCONCLUSIVE</blurb> +</div> +</slide> diff --git a/slides/iot/ha-nest-data-mqtt-step0.xml b/slides/iot/ha-nest-data-mqtt-step0.xml new file mode 100644 index 00000000..59ae94c9 --- /dev/null +++ b/slides/iot/ha-nest-data-mqtt-step0.xml @@ -0,0 +1,13 @@ +<slide> +<title>Step 0: Create Current Temperature Sensor</title> + +<break lines="2"/> + +<div effect="fade-out"> +<image filename="ha-sensor-current-temp1.png"/> +</div> + +<div effect="fade-in"> +<image filename="ha-sensor-current-temp2.png"/> +</div> +</slide> diff --git a/slides/iot/ha-nest-data-mqtt-step2.xml b/slides/iot/ha-nest-data-mqtt-step2.xml new file mode 100644 index 00000000..de00fd94 --- /dev/null +++ b/slides/iot/ha-nest-data-mqtt-step2.xml @@ -0,0 +1,27 @@ +<slide style="title"> +<blurb class="large">Step 2: Create PHP Script to Import Into Database</blurb> +<example><![CDATA[<?php +$mqtt->subscribe('tempwise/+/state_change', function($topic, $msg, $ret, $matchWild) use ($c) { + if ( ! preg_match( '@^tempwise/(.*)/state_change$@', $topic, $matchedTopic)) { + return; + } + $topic = $matchedTopic[1]; + + $valueParts = explode( '|', $msg); + $value = array_last($valueParts); + + $value = match($value) { + 'on' => true, + 'off' => false, + default => (double) $value, + }; + + $doc = [ + 'ts' => new MongoDB\BSON\UTCDateTime(), + 't' => $topic, + 'v' => $value, + ]; + + $result = $c->insertOne($doc); +}, 0);]]></example> +</slide> diff --git a/slides/iot/ha-nest-data-mqtt-step3.xml b/slides/iot/ha-nest-data-mqtt-step3.xml new file mode 100644 index 00000000..6a7ae651 --- /dev/null +++ b/slides/iot/ha-nest-data-mqtt-step3.xml @@ -0,0 +1,40 @@ +<slide background="ha-nest-slope-2.jpeg"> +<title>Step 3: Calculate Heating Rate</title> +<div class="left-side"> +<div class="light-bg"> + +<div effect="fade-in"> +<list><bullet>Loop over all elements for %nest% events</bullet></list> +</div> + +<div effect="fade-in"> +<list><bullet>Find closest livingroom temperature before and after</bullet></list> +</div> + +<div effect="fade-in"> +<list><bullet>Temperature(s) at Nest on/off points:<br/> +~ΔT~ = ΔT<sub>1</sub> - ΔT<sub>0</sub><br/> +~Δt~ = Δt<sub>1</sub> - Δt<sub>0</sub><br/> +~x~ = t<sub>nest</sub> - t<sub>0</sub><br/> +~T~<sub>nest</sub> = ((x / Δt) * ΔT) + ΔT<sub>0</sub> *°C* +</bullet></list> +</div> + +<div effect="fade-in"> +<list><bullet>Rate between Nest on/off points:<br/> +~ΔT~ = T<sub>off</sub> - T<sub>on</sub><br/> +~Δt~ = t<sub>off</sub> - t<sub>on</sub><br/> + +~rate~ = ΔT / Δt *°C / second*<br/> +</bullet></list> +</div> + +<div effect="fade-in"> +<list><bullet>Average Outside Temperature:<br/> +ΔT<sub>outside</sub> = (T<sub>outside,0</sub> + T<sub>outside,1</sub>) / 2 *°C* +</bullet></list> +</div> + +</div> +</div> +</slide> diff --git a/slides/iot/ha-nest-data-mqtt-step4.xml b/slides/iot/ha-nest-data-mqtt-step4.xml new file mode 100644 index 00000000..6c6f5b43 --- /dev/null +++ b/slides/iot/ha-nest-data-mqtt-step4.xml @@ -0,0 +1,19 @@ +<slide> + +<div class="left-side"> +<break lines="4"/> +<div class="light-bg"> +<blurb>Collect:</blurb> +<div effect="fade-in"> +<list><bullet>When Nest Turns On and Off</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Current Livingroom Temperature</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Current Outside Temperature</bullet></list> +</div> +</div> +</div> + +</slide> diff --git a/slides/iot/ha-nest-data-mqtt.xml b/slides/iot/ha-nest-data-mqtt.xml new file mode 100644 index 00000000..c03377ee --- /dev/null +++ b/slides/iot/ha-nest-data-mqtt.xml @@ -0,0 +1,25 @@ +<slide style="title"> +<blurb class="large">Step 1: Create MQTT Trigger in Home Assistant</blurb> +<break/> +<example inline="2"> +alias: Temperature MQTT Trigger +description: "" +triggers: + - trigger: state + entity_id: + - sensor.living_room_temperature + *- sensor.current_temperature* + - binary_sensor.nest_on +conditions: [] +actions: + - action: mqtt.publish + metadata: {} + data: + evaluate_payload: false + qos: 0 + retain: false + topic: tempwise/{{trigger.to_state.object_id}}/state_change + payload: "{{trigger.from_state.state}}|{{trigger.to_state.state}}" +mode: single +</example> +</slide> diff --git a/slides/iot/ha-nest-data.xml b/slides/iot/ha-nest-data.xml new file mode 100644 index 00000000..da8d10d6 --- /dev/null +++ b/slides/iot/ha-nest-data.xml @@ -0,0 +1 @@ +<slide background="ha-nest-slope-0.jpeg"/> diff --git a/slides/iot/ha-nest-heat-slope1.png b/slides/iot/ha-nest-heat-slope1.png new file mode 100644 index 00000000..27cc3d1f Binary files /dev/null and b/slides/iot/ha-nest-heat-slope1.png differ diff --git a/slides/iot/ha-nest-heat-slope2.png b/slides/iot/ha-nest-heat-slope2.png new file mode 100644 index 00000000..383939c0 Binary files /dev/null and b/slides/iot/ha-nest-heat-slope2.png differ diff --git a/slides/iot/ha-nest-schedule-alone.png b/slides/iot/ha-nest-schedule-alone.png new file mode 100644 index 00000000..0063f8ae Binary files /dev/null and b/slides/iot/ha-nest-schedule-alone.png differ diff --git a/slides/iot/ha-nest-schedule.png b/slides/iot/ha-nest-schedule.png new file mode 100644 index 00000000..388d7a06 Binary files /dev/null and b/slides/iot/ha-nest-schedule.png differ diff --git a/slides/iot/ha-nest-schedule.xml b/slides/iot/ha-nest-schedule.xml new file mode 100644 index 00000000..91f7afce --- /dev/null +++ b/slides/iot/ha-nest-schedule.xml @@ -0,0 +1,23 @@ +<slide background="ha-nest-schedule.png"> + +<div class="left-side"> +<break lines="14"/> +<div class="light-bg"> +<div effect="fade-in"> +<list><bullet>Schedules *Target* Temperature</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Estimate Heating Efficiency</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Is Inside/Outside Temperature Differencial Important?</bullet></list> +</div> +<div effect="fade-in"> +<break lines="3"/> +<blurb>Future:</blurb> +<list><bullet>Estimate Temperature Loss</bullet></list> +</div> +</div> +</div> + +</slide> diff --git a/slides/iot/ha-nest-slope-0.jpeg b/slides/iot/ha-nest-slope-0.jpeg new file mode 100644 index 00000000..0cf95f58 Binary files /dev/null and b/slides/iot/ha-nest-slope-0.jpeg differ diff --git a/slides/iot/ha-nest-slope-1.jpeg b/slides/iot/ha-nest-slope-1.jpeg new file mode 100644 index 00000000..3749c7dd Binary files /dev/null and b/slides/iot/ha-nest-slope-1.jpeg differ diff --git a/slides/iot/ha-nest-slope-2.jpeg b/slides/iot/ha-nest-slope-2.jpeg new file mode 100644 index 00000000..2c9b4f6e Binary files /dev/null and b/slides/iot/ha-nest-slope-2.jpeg differ diff --git a/slides/iot/ha-nest-slope.xcf b/slides/iot/ha-nest-slope.xcf new file mode 100644 index 00000000..6904554e Binary files /dev/null and b/slides/iot/ha-nest-slope.xcf differ diff --git a/slides/iot/ha-nest-slope1.png b/slides/iot/ha-nest-slope1.png new file mode 100644 index 00000000..f1524b81 Binary files /dev/null and b/slides/iot/ha-nest-slope1.png differ diff --git a/slides/iot/ha-nest-slope2.png b/slides/iot/ha-nest-slope2.png new file mode 100644 index 00000000..aee5c677 Binary files /dev/null and b/slides/iot/ha-nest-slope2.png differ diff --git a/slides/iot/ha-nest-temperature.png b/slides/iot/ha-nest-temperature.png new file mode 100644 index 00000000..deb9ddfa Binary files /dev/null and b/slides/iot/ha-nest-temperature.png differ diff --git a/slides/iot/ha-php-mqtt-code-rgb.xml b/slides/iot/ha-php-mqtt-code-rgb.xml new file mode 100644 index 00000000..018460f8 --- /dev/null +++ b/slides/iot/ha-php-mqtt-code-rgb.xml @@ -0,0 +1,58 @@ +<slide> +<title>Image Upgrade</title> + +<div effect="fade-out"> +<blurb>Image Definition as RGB:</blurb> +<example><![CDATA[ +$spritesRGB = [ + 'sunny' => [ + 0, 0, 0, 5, 3, 1, 117, 97, 42, 140, 115, 47, 140, 115, 47, 117, 98, 42, 0, 0, + 0, 0, 0, 0, 5, 3, 1, 81, 81, 0, 245, 201, 77, 237, 193, 66, 237, 193, 66, + 245, 201, 77, 81, 81, 0, 5, 4, 1, 116, 97, 41, 246, 202, 77, 251, 193, 58, + 253, 173, 30, 250, 169, 26, 249, 190, 55, 245, 201, 77, 115, 96, 41, 140, + 116, 47, 237, 193, 66, 252, 172, 30, 250, 168, 23, 248, 164, 17, 246, 162, + 15, 237, 192, 66, 140, 116, 47, 139, 115, 47, 237, 193, 66, 250, 168, 24, + 247, 164, 16, 245, 160, 11, 243, 158, 10, 237, 193, 66, 141, 116, 48, 116, + 97, 42, 245, 201, 77, 248, 189, 54, 245, 161, 14, 242, 158, 9, 246, 186, + 53, 244, 200, 77, 117, 98, 42, 5, 3, 1, 81, 81, 0, 246, 202, 77, 237, 193, + 66, 236, 192, 66, 245, 201, 77, 81, 81, 0, 0, 0, 0, 0, 0, 0, 5, 4, 1, 117, + 97, 42, 140, 116, 47, 140, 115, 47, 115, 95, 41, 5, 4, 1, 0, 0, 0, + ], +];]]></example> + +<blurb>Update MQTT Client Buffer Size:</blurb> +<example> +- MQTTClient mqtt = MQTTClient(); ++ MQTTClient mqtt = MQTTClient(1024); +</example> +</div> + +<div effect="fade-in"> +<example> + if (strcmp("setlsrgb", command) == 0) { + long start = doc["s"], current = start, counter = 0; + unsigned char r = 0, g = 0, b = 0; + + JsonArray data = doc["d"]; + + for (JsonVariant item : data) { + unsigned char value = item; + + if (counter % 3 == 0) { + r = value; + } else if (counter % 3 == 1) { + g = value; + } else { + b = value; + devices[dev].setPixelColor(current % devices[dev].numPixels(), r, g, b); + current++; + } + + counter++; + } + devices[dev].show(); + } +</example> +</div> + +</slide> diff --git a/slides/iot/ha-php-mqtt-code.xml b/slides/iot/ha-php-mqtt-code.xml new file mode 100644 index 00000000..c95d9e87 --- /dev/null +++ b/slides/iot/ha-php-mqtt-code.xml @@ -0,0 +1,82 @@ +<slide> +<title>The PHP Code</title> + +<div effect="fade-out"> +<blurb>Connect to MQTT Broker:</blurb> +<example><![CDATA[ +<?php +require 'vendor/autoload.php'; + +$server = '192.168.42.213'; +$port = 1883; +$clientId = 'mqttfun-esp32-react-on-weather'; + +$connectionSettings = (new \PhpMqtt\Client\ConnectionSettings) + ->setUsername("mqtt") + ->setPassword("homeassistant-XXXXXXXXXXXX"); + +$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId); +$mqtt->connect($connectionSettings); +]]></example> +</div> +<div effect="fade-in-out"> +<blurb>Publish Simple Message:</blurb> +<example><![CDATA[ +$docBrightness = [ + 'c' => 'setbrightness', + 'b' => 20, +]; +$mqtt->publish('esp32_lights/1', json_encode($docBrightness), 0); +]]></example> +</div> +<div effect="fade-in-out"> +<blurb>Subscribe Handler:</blurb> +<example><![CDATA[ +$mqtt->subscribe('homeautomation/forecast', + function ($topic, $message, $retained, $matchedWildcards) use ($sprites, $mqtt) { + $imageData = match ($message) { + 'rainy' => $sprites['rainy'], + 'sunny' => $sprites['sunny'], + default => $sprites['unknown'], + }; + + $mqttMessage = [ + 'c' => 'setls', + 's' => 0, + 'd' => $imageData, + ]; + $mqtt->publish('esp32_lights/1', json_encode($mqttMessage), 0); + }, + 0 +); +]]></example> +</div> +<div effect="fade-in-out"> +<blurb>Loop:</blurb> +<example><![CDATA[ +$mqtt->loop(true); +$mqtt->disconnect(); +]]></example> +</div> + +<div effect="fade-in"> +<blurb>Image Definition(s):</blurb> +<example><![CDATA[ +$sprites = [ + …, + 'rainy' => [ + 0, 17, 0, 23, 20, 0, 0, 0, + 0, 18, 24, 25, 25, 25, 8, 18, + 19, 25, 25, 25, 25, 24, 25, 23, + 24, 25, 25, 25, 24, 24, 24, 24, + 8, 24, 24, 24, 24, 24, 24, 22, + 0, 55, 0, 18, 9, 55, 0, 0, + 0, 0, 55, 176, 0, 104, 55, 0, + 0, 0, 127, 55, 0, 0, 0, 55 + ], + … +];]]></example> +<image filename="icons.png"/> +</div> + +</slide> diff --git a/slides/iot/ha-php-mqtt-lego-box-design.xml b/slides/iot/ha-php-mqtt-lego-box-design.xml new file mode 100644 index 00000000..c9992c61 --- /dev/null +++ b/slides/iot/ha-php-mqtt-lego-box-design.xml @@ -0,0 +1,3 @@ +<slide style="title" background="esp32-lego-box.png"> +<title>LEGO™ to the Rescue!</title> +</slide> diff --git a/slides/iot/ha-php-mqtt-lego-box-prototype.xml b/slides/iot/ha-php-mqtt-lego-box-prototype.xml new file mode 100644 index 00000000..3c1f4231 --- /dev/null +++ b/slides/iot/ha-php-mqtt-lego-box-prototype.xml @@ -0,0 +1,3 @@ +<slide style="title" background="iot-weather-lego-prototype.jpeg"> +<title>It's Still A Prototype…</title> +</slide> diff --git a/slides/iot/ha-php-mqtt-next-animations.xml b/slides/iot/ha-php-mqtt-next-animations.xml new file mode 100644 index 00000000..5a2e7133 --- /dev/null +++ b/slides/iot/ha-php-mqtt-next-animations.xml @@ -0,0 +1,3 @@ +<slide style="title" background="iot-weather-sunny.jpeg"> +<title>Future Plan: Animations</title> +</slide> diff --git a/slides/iot/ha-php-mqtt-result-rainy.xml b/slides/iot/ha-php-mqtt-result-rainy.xml new file mode 100644 index 00000000..41a2c2e0 --- /dev/null +++ b/slides/iot/ha-php-mqtt-result-rainy.xml @@ -0,0 +1 @@ +<slide background="iot-weather-rainy.jpeg"/> diff --git a/slides/iot/ha-php-mqtt-result-sunny.xml b/slides/iot/ha-php-mqtt-result-sunny.xml new file mode 100644 index 00000000..62544ac6 --- /dev/null +++ b/slides/iot/ha-php-mqtt-result-sunny.xml @@ -0,0 +1 @@ +<slide background="iot-weather-sunny.jpeg"/> diff --git a/slides/iot/ha-php-mqtt-result-unknown.xml b/slides/iot/ha-php-mqtt-result-unknown.xml new file mode 100644 index 00000000..9fd7d8b8 --- /dev/null +++ b/slides/iot/ha-php-mqtt-result-unknown.xml @@ -0,0 +1 @@ +<slide background="iot-weather-unknown.jpeg"/> diff --git a/slides/iot/ha-php-mqtt-result.xml b/slides/iot/ha-php-mqtt-result.xml new file mode 100644 index 00000000..41a2c2e0 --- /dev/null +++ b/slides/iot/ha-php-mqtt-result.xml @@ -0,0 +1 @@ +<slide background="iot-weather-rainy.jpeg"/> diff --git a/slides/iot/ha-php-mqtt.xml b/slides/iot/ha-php-mqtt.xml new file mode 100644 index 00000000..a09a23d8 --- /dev/null +++ b/slides/iot/ha-php-mqtt.xml @@ -0,0 +1,28 @@ +<slide> +<title>Step 4: Glue Between HA Forecast and ESP32</title> + +<div class="light-bg"> +<div effect="fade-in"> +<list><bullet>Subscribe to MQTT Topic %homeautomation/forecast%</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Figure Out Which Image to Use</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Publish Complex Message to %esp32_lights/1%</bullet></list> +</div> +<div effect="fade-in"> +<break lines="2"/> +<list><bullet>PHP is a great language for this</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>MQTT Client on Packagist: %php-mqtt/client%</bullet></list> +</div> +</div> + +<div effect="fade-in"> +<break lines="3"/> +<image filename="icons.png"/> +</div> + +</slide> diff --git a/slides/iot/ha-program-esp32-board.xml b/slides/iot/ha-program-esp32-board.xml new file mode 100644 index 00000000..eade86bf --- /dev/null +++ b/slides/iot/ha-program-esp32-board.xml @@ -0,0 +1,36 @@ +<slide background="esp32-code.png"> +<title>Step 2: Program a Micro Controller to Drive the LED Matrix</title> + +<div class="left-side"> +<div class="light-bg"> +<div effect="fade-in"> +<list><bullet>Arduino IDE → CLI</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>C / C++</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Connecting to WiFi</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Connecting to MQTT and Handling Messages</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Use Messages to Write Images</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Re-learn About Palettes</bullet></list> +</div> +</div> +</div> + +<div class="right-side"> +<break lines="12"/> +<div class="light-bg"> +<div effect="fade-in"> +<image filename="esp32-vga-palette.png"/> +</div> +</div> +</div> + +</slide> diff --git a/slides/iot/ha-sensor-current-temp1.png b/slides/iot/ha-sensor-current-temp1.png new file mode 100644 index 00000000..b1b14e24 Binary files /dev/null and b/slides/iot/ha-sensor-current-temp1.png differ diff --git a/slides/iot/ha-sensor-current-temp2.png b/slides/iot/ha-sensor-current-temp2.png new file mode 100644 index 00000000..3e8d5ed0 Binary files /dev/null and b/slides/iot/ha-sensor-current-temp2.png differ diff --git a/slides/iot/ha-smooth-brightness.png b/slides/iot/ha-smooth-brightness.png new file mode 100644 index 00000000..351a0673 Binary files /dev/null and b/slides/iot/ha-smooth-brightness.png differ diff --git a/slides/iot/ha-tree-lights.png b/slides/iot/ha-tree-lights.png new file mode 100644 index 00000000..16572c30 Binary files /dev/null and b/slides/iot/ha-tree-lights.png differ diff --git a/slides/iot/ha-zigbee-network.png b/slides/iot/ha-zigbee-network.png new file mode 100644 index 00000000..52e9d7bf Binary files /dev/null and b/slides/iot/ha-zigbee-network.png differ diff --git a/slides/iot/heating-rate.png b/slides/iot/heating-rate.png new file mode 100644 index 00000000..5c9dc77f Binary files /dev/null and b/slides/iot/heating-rate..png differ diff --git a/slides/iot/heating-schedule.png b/slides/iot/heating-schedule.png new file mode 100644 index 00000000..5c29702d Binary files /dev/null and b/slides/iot/heating-schedule.png differ diff --git a/slides/iot/home-assistant-1.xml b/slides/iot/home-assistant-1.xml new file mode 100644 index 00000000..a259816b --- /dev/null +++ b/slides/iot/home-assistant-1.xml @@ -0,0 +1,19 @@ +<slide background="iot-homeassistant.jpeg"> +<title>Home Assistant</title> + +<div effect="fade-in"> +<break lines="1"/> +<div class="light-bg right-side"> +<image filename="iot-homeassistant-zigbee.jpeg"/> +<blurb align="center">Home Assistant Zigbee Dongle</blurb> +</div> +</div> + +<div effect="fade-in"> +<break lines="15"/> +<div class="light-bg left-side"> +<image filename="the_internet_from_the_it_crowd.jpeg"/> +<blurb align="center">"The Internet"</blurb> +</div> +</div> +</slide> diff --git a/slides/iot/icons.png b/slides/iot/icons.png new file mode 100644 index 00000000..0badaaf5 Binary files /dev/null and b/slides/iot/icons.png differ diff --git a/slides/iot/iot-elephpant-shelf.jpeg b/slides/iot/iot-elephpant-shelf.jpeg new file mode 100644 index 00000000..19920712 Binary files /dev/null and b/slides/iot/iot-elephpant-shelf.jpeg differ diff --git a/slides/iot/iot-esp32-matrix.jpeg b/slides/iot/iot-esp32-matrix.jpeg new file mode 100644 index 00000000..7e8a3453 Binary files /dev/null and b/slides/iot/iot-esp32-matrix.jpeg differ diff --git a/slides/iot/iot-homeassistant-zigbee.jpeg b/slides/iot/iot-homeassistant-zigbee.jpeg new file mode 100644 index 00000000..8ddf127e Binary files /dev/null and b/slides/iot/iot-homeassistant-zigbee.jpeg differ diff --git a/slides/iot/iot-homeassistant.jpeg b/slides/iot/iot-homeassistant.jpeg new file mode 100644 index 00000000..e92ea76e Binary files /dev/null and b/slides/iot/iot-homeassistant.jpeg differ diff --git a/slides/iot/iot-human-detector.jpeg b/slides/iot/iot-human-detector.jpeg new file mode 100644 index 00000000..866e14c5 Binary files /dev/null and b/slides/iot/iot-human-detector.jpeg differ diff --git a/slides/iot/iot-lamp-dim.gif b/slides/iot/iot-lamp-dim.gif new file mode 100644 index 00000000..c89ed8b6 Binary files /dev/null and b/slides/iot/iot-lamp-dim.gif differ diff --git a/slides/iot/iot-lego-lights.jpeg b/slides/iot/iot-lego-lights.jpeg new file mode 100644 index 00000000..c657ae98 Binary files /dev/null and b/slides/iot/iot-lego-lights.jpeg differ diff --git a/slides/iot/iot-matrix-sun-paper.jpeg b/slides/iot/iot-matrix-sun-paper.jpeg new file mode 100644 index 00000000..fbecb9d3 Binary files /dev/null and b/slides/iot/iot-matrix-sun-paper.jpeg differ diff --git a/slides/iot/iot-monty.jpeg b/slides/iot/iot-monty.jpeg new file mode 100644 index 00000000..85004402 Binary files /dev/null and b/slides/iot/iot-monty.jpeg differ diff --git a/slides/iot/iot-motion-detector.jpeg b/slides/iot/iot-motion-detector..jpeg new file mode 100644 index 00000000..ac02dd69 Binary files /dev/null and b/slides/iot/iot-motion-detector.jpeg differ diff --git a/slides/iot/iot-smartlife-plug.jpeg b/slides/iot/iot-smartlife-plug.jpeg new file mode 100644 index 00000000..7528a595 Binary files /dev/null and b/slides/iot/iot-smartlife-plug.jpeg differ diff --git a/slides/iot/iot-streamdeck-home.jpeg b/slides/iot/iot-streamdeck-home.jpeg new file mode 100644 index 00000000..06b9d440 Binary files /dev/null and b/slides/iot/iot-streamdeck-home.jpeg differ diff --git a/slides/iot/iot-streamdeck-obs.jpeg b/slides/iot/iot-streamdeck-obs.jpeg new file mode 100644 index 00000000..9fb6d260 Binary files /dev/null and b/slides/iot/iot-streamdeck-obs..jpeg differ diff --git a/slides/iot/iot-weather-lego-prototype.jpeg b/slides/iot/iot-weather-lego-prototype.jpeg new file mode 100644 index 00000000..140ff761 Binary files /dev/null and b/slides/iot/iot-weather-lego-prototype.jpeg differ diff --git a/slides/iot/iot-weather-lego-prototype.jpeg.jpeg b/slides/iot/iot-weather-lego-prototype.jpeg.jpeg new file mode 100644 index 00000000..140ff761 Binary files /dev/null and b/slides/iot/iot-weather-lego-prototype.jpeg.jpeg differ diff --git a/slides/iot/iot-weather-rainy.jpeg b/slides/iot/iot-weather-rainy.jpeg new file mode 100644 index 00000000..39564050 Binary files /dev/null and b/slides/iot/iot-weather-rainy.jpeg differ diff --git a/slides/iot/iot-weather-sunny.jpeg b/slides/iot/iot-weather-sunny.jpeg new file mode 100644 index 00000000..4995591d Binary files /dev/null and b/slides/iot/iot-weather-sunny.jpeg differ diff --git a/slides/iot/iot-weather-unknown.jpeg b/slides/iot/iot-weather-unknown.jpeg new file mode 100644 index 00000000..25fa1589 Binary files /dev/null and b/slides/iot/iot-weather-unknown.jpeg differ diff --git a/slides/iot/iot-wedding-tree-switch.jpeg b/slides/iot/iot-wedding-tree-switch.jpeg new file mode 100644 index 00000000..a03759b2 Binary files /dev/null and b/slides/iot/iot-wedding-tree-switch.jpeg differ diff --git a/slides/iot/iot-wedding-tree.jpeg b/slides/iot/iot-wedding-tree.jpeg new file mode 100644 index 00000000..e2d6e22b Binary files /dev/null and b/slides/iot/iot-wedding-tree.jpeg differ diff --git a/slides/iot/lights-options.png b/slides/iot/lights-options.png new file mode 100644 index 00000000..3077dca8 Binary files /dev/null and b/slides/iot/lights-options.png differ diff --git a/slides/iot/livingroom-ok.xml b/slides/iot/livingroom-ok.xml new file mode 100644 index 00000000..5291b7a0 --- /dev/null +++ b/slides/iot/livingroom-ok.xml @@ -0,0 +1,19 @@ +<slide> +<title>What Are We Using It For?</title> + +<image filename="lights-options.png"/> + + +<div class="light-bg right-side"> +<break/> +<image filename="heating-schedule.png"/> +<blurb class="small center">Heating Schedule</blurb> +</div> + +<break lines="2"/> +<blurb>Things to do:</blurb> +<list> + <bullet>Automation for turning the heating to Eco mode</bullet> + <bullet>Cleverder Heating</bullet> +</list> +</slide> diff --git a/slides/iot/livingroom-party.xml b/slides/iot/livingroom-party.xml new file mode 100644 index 00000000..b56ccdb8 --- /dev/null +++ b/slides/iot/livingroom-party.xml @@ -0,0 +1,6 @@ +<slide style="title" background="party-lights.gif"> +<title>Party Lights</title> + +<div effect="fade-in"><break lines="26"/><blurb class="big-centre">*NOT ALLOWED*</blurb></div> + +</slide> diff --git a/slides/iot/monty.xml b/slides/iot/monty.xml new file mode 100644 index 00000000..827d9bec --- /dev/null +++ b/slides/iot/monty.xml @@ -0,0 +1,4 @@ +<slide style="title" background="iot-monty.jpeg"> +<title>Monty</title> +</slide> + diff --git a/slides/iot/mqtt-integration.png b/slides/iot/mqtt-integration.png new file mode 100644 index 00000000..bd890427 Binary files /dev/null and b/slides/iot/mqtt-integration.png differ diff --git a/slides/iot/mqtt-logo.svg b/slides/iot/mqtt-logo.svg new file mode 100644 index 00000000..b0df6127 --- /dev/null +++ b/slides/iot/mqtt-logo.svg @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1100 320" overflow="visible" xml:space="preserve"> +<g id="black_bg" display="none"> +</g> +<g id="logos"> + <g> + <g> + <path fill="#660066" d="M399.6,165.3c1.7,3.7,3.3,7.5,4.8,11.4c1.5-4,3.1-7.8,4.9-11.6c1.7-3.7,3.5-7.4,5.3-10.9L465,54.8 c0.9-1.7,1.8-3,2.8-4c0.9-0.9,2-1.6,3.2-2.1c1.2-0.5,2.5-0.7,4-0.7c1.5,0,3.2,0,5.2,0H515v196.6h-40.2V131.4 c0-5.5,0.3-11.4,0.8-17.8l-52.1,101.1c-1.6,3.2-3.8,5.5-6.5,7.2c-2.7,1.6-5..9,2.4-9.4,2.4h-6.2c-3.5,0-6.6-0.8-9.4-2.4 c-2.7-1.6-4.9-4-6.5-7.2L333,113.5c0.4,3.2,0.6,6.3,0.8,9.4c0.2,3.1,0.3,6,0.3,8.6v113.1h-40.2V48h34.8c2,0,3.7,0,5.2,0 s2.8,0.2,4,0.7c1.2,0.5,2.2,1.1,3.2,2.1c0.9,0.9,1.9,2.3,2.8,4l50.6,99.9C396.2,158.1,398,161.6,399.6,165.3z"/> + <path fill="#660066" d="M730.7,146.2c0,8.5-0.9,16.6-2.6,24.4c-1.8,7.8-4.3,15.1-7.6,21.9c-3.3,6.8-7.3,13.2-12.2,19 c-4.8,5.9-10.3,11-16.4,15.5l49.8,54.4h-37.5c-5.4,0-10.3-0.7-14.7-2c-4.4-1.3-8.3-3.9-11.7-7.9l-24.4-27.4 c-4,0..8-8,1.4-12.1,1.9c-4.1,0.4-8.3,0.7-12.6,0.7c-15.3,0-29.3-2.6-41.9-7.7c-12.6-5.1-23.4-12.2-32.3-21.3 c-9-9-15.9-19.7-20.8-31.9c-4.9-12.2-7.4-25.5-7..4-39.7c0-14.2,2.5-27.4,7.4-39.7c4.9-12.2,11.8-22.9,20.8-31.9 c9-9,19.7-16.1,32.3-21.2c12.6-5.1,26.5-7.7,41.9-7.7c15.3,0,29.2,2.6,41.8,7.8c12.6,5.2,23.3,12.3,32.2,21.3 c8.9,9,15.8,19.6,20.7,31.9C728.3,118.8,730.7,132,730.7,146.2z M684,146.2c0-9.7-1.3-18.5-3.8-26.3c-2.5-7.8-6.1-14.4-10.9-19.8 c-4.7-5.4-10.5-9.5-17.3-12.4c-6.8-2.9-14.6-4.3-23.4-4.3c-8.8,0-16.7,1.4-23.6,4.3c-6.9,2.9-12.7,7-17.4,12.4 c-4.7,5.4-8.3,12-10.9,19.8c-2.5,7.8-3.8,16.5-3.8,26.3c0,9.8,1.3,18.6,3.8,26.4c2.5,7.8,6.1,14.4,10.9,19.8 c4.7,5.4,10.5,9.5,17.4,12.4c6.9,2.8,14.7,4.3,23.6,4.3c8.7,0,16.5-1.4,23.4-4..3c6.8-2.8,12.6-7,17.3-12.4 c4.7-5.4,8.3-12,10.9-19.8C682.8,164.8,684,156,684,146.2z"/> + <path fill="#660066" d="M877.2,47.9v36.2h-53.3v160.5h-45.6V84.1h-53.3V47.9H877.2z"/> + <path fill="#660066" d="M1051.8,47.9v36.2h-55.3v160.5h-45.6V84.1h-53.3V47.9H1051.8z"/> + </g> + </g> + <path fill="#FFFFFF" d="M46,64.2v31c0.2,0,0..4,0,0.6,0c84.4,0,153.2,68,153.9,151.8h30.1C229.8,146.3,147.4,64.5,46,64.2z"/> + <path fill="#FFFFFF" d="M46,128.2v31c0.2,0,0.4,0,0.6,0c48.9,0,88.8,39.3,89.5,87.8h30.1C165.5,181.6,111.9,128.5,46,128.2z"/> + <path fill="#FFFFFF" d="M248.8,166.8v-62.5c-7.7-10.5-17.2-22.5-26.7-31.8c-10.6-10.5-23-20-35-28.3h-66.4 C178.9,65.1,225.6,110,248.8,166.8z"/> + <path fill="#660066" d="M46.5,159.2c-0.2,0-0.4,0-0.6,0v77.6c0,5.6,4.6,10.2,10.2,10.2H136C135.3,198.5,95.5,159.2,46.5,159.2z"/> + <path fill="#660066" d="M46.5,95.2c-0.2,0-0.4,0-0.6,0v33c65.9,0.3,119.5,53.3,120.2,118..8h34.2C199.7,163.2,131,95.2,46.5,95.2z"/> + <path fill="#660066" d="M248.8,236.9v-70.1c-23.2-56.8-69.9-101.7-128-122.6H56.1c-5.6,0-10.2,4.6-10.2,10.2v9.9 c101.4,0.3,183.9,82,184.5,182.8h8.2C244.3,247,248.8,242.5,248.8,236.9z"/> + <path fill="#660066" d="M222.1,72.5c9.4,9.4,19,21..3,26.7,31.8v-50c0-5.6-4.5-10.1-10.1-10.1h-51.5C199.2,52.5,211.6,62,222.1,72.5 z"/> +</g> +</svg> \ No newline at end of file diff --git a/slides/iot/mqtt-project-goal.xml b/slides/iot/mqtt-project-goal.xml new file mode 100644 index 00000000..69329fc2 --- /dev/null +++ b/slides/iot/mqtt-project-goal.xml @@ -0,0 +1,19 @@ +<slide background="iot-streamdeck-obs.jpeg"> +<title>Goal: Dim the Stream Deck When I Leave The Room</title> + +<div effect="fade-in"> +<break lines="1"/> +<div class="light-bg left-side"> +<image filename="iot-human-detector.jpeg" width="800"/> +<blurb align="center">Human Detector</blurb> +</div> +</div> + +<div effect="fade-in"> +<break lines="8"/> +<div class="light-bg right-side"> +<image filename="iot-homeassistant.jpeg" width="800"/> +<blurb align="center">Home Assistant</blurb> +</div> +</div> +</slide> diff --git a/slides/iot/mqtt-whats-next-elephpants.xml b/slides/iot/mqtt-whats-next-elephpants.xml new file mode 100644 index 00000000..c0326ad1 --- /dev/null +++ b/slides/iot/mqtt-whats-next-elephpants.xml @@ -0,0 +1,3 @@ +<slide style="title" background="iot-elephpant-shelf.jpeg"> +<title>Future Plan: Light Up The Elephpants</title> +</slide> diff --git a/slides/iot/mqtt-whats-next-esp32-board.xml b/slides/iot/mqtt-whats-next-esp32-board.xml new file mode 100644 index 00000000..184184aa --- /dev/null +++ b/slides/iot/mqtt-whats-next-esp32-board.xml @@ -0,0 +1,8 @@ +<slide background="iot-esp32-matrix.jpeg"> +<title>Step 3: Learn How To Solder…</title> + +<break lines="12"/> +<div class="light-bg right-side"> +<image filename="esp32-schematic.png"/> +</div> +</slide> diff --git a/slides/iot/mqtt-whats-next-lego.xml b/slides/iot/mqtt-whats-next-lego.xml new file mode 100644 index 00000000..028db644 --- /dev/null +++ b/slides/iot/mqtt-whats-next-lego.xml @@ -0,0 +1,3 @@ +<slide style="title" background="iot-lego-lights.jpeg"> +<title>Future Plan: Be Clever With the Lego Space Model Lights</title> +</slide> diff --git a/slides/iot/mqtt-whats-next-weather-matrix.xml b/slides/iot/mqtt-whats-next-weather-matrix.xml new file mode 100644 index 00000000..c8417240 --- /dev/null +++ b/slides/iot/mqtt-whats-next-weather-matrix.xml @@ -0,0 +1,3 @@ +<slide style="title" background="iot-matrix-sun-paper.jpeg"> +<title>Future Plan: Push Weather Forecast to LED Matrix</title> +</slide> diff --git a/slides/iot/mqtt-whats-next.xml b/slides/iot/mqtt-whats-next.xml new file mode 100644 index 00000000..9b770e71 --- /dev/null +++ b/slides/iot/mqtt-whats-next.xml @@ -0,0 +1,28 @@ +<slide style="title"> +<blurb class="large">Step 5: Publish to MQTT</blurb> +<break/> +<blurb>Configuration:</blurb> +<example inline="2"> +HousePage: + - Index: 0 + Type: mqtt-color + Arguments: + - StateId: office-lights + - Name: "LIGHT" + - PublishTopic: "homeautomation/office" + - ActivePublishPayload: "light" + - InactivePublishPayload: "dark" + - ActiveStateColor: "#00ff00" + - InactiveStateColor: "#ff0000" +</example> +<break/> + +<blurb>To publish to MQTT:</blurb> +<example inline="2"> +mq.mqtt.mqtt_client.Publish(mq.PublishTopic, 0, false, mq.NextPublishPayload) +</example> + +<break/> +<blurb>Hooking it into the Streamdeck-Goui code was trickier…</blurb> + +</slide> diff --git a/slides/iot/mqtt.xml b/slides/iot/mqtt.xml new file mode 100644 index 00000000..7a82515f --- /dev/null +++ b/slides/iot/mqtt.xml @@ -0,0 +1,14 @@ +<slide> + +<break lines="4"/> +<image filename="mqtt-logo.svg"/> + +<break lines="2"/> +<blurb class="center"> +MQTT is a lightweight, publish–subscribe, machine-to-machine network protocol +for message queue/message queuing service. It is designed for connections with +remote locations that have devices with resource constraints or limited network +bandwidth, such as in the Internet of things (IoT). +</blurb> + +</slide> diff --git a/slides/iot/office-lights-dim.xml b/slides/iot/office-lights-dim.xml new file mode 100644 index 00000000..0d9460c1 --- /dev/null +++ b/slides/iot/office-lights-dim.xml @@ -0,0 +1,19 @@ +<slide> +<title>Dimming Lights</title> + +<div class="light-bg right-side"> +<image filename="ha-dim-lights-action.png"/> +</div> + +<blurb>*Ceiling Office Light*</blurb> +<list> +<bullet>Brighten when you enter the room</bullet> +<bullet>Dim when you leave the room</bullet> +</list> + +<break/> +<div class="light-bg left-side"> +<image filename="iot-lamp-dim.gif"/> +</div> + +</slide> diff --git a/slides/iot/office-lights-goals.xml b/slides/iot/office-lights-goals.xml new file mode 100644 index 00000000..6d37eaaa --- /dev/null +++ b/slides/iot/office-lights-goals.xml @@ -0,0 +1,24 @@ +<slide> +<title>Office Lights: Goals</title> + +<blurb>*Standing Office Light*</blurb> +<list> +<bullet>Turn off if you leave for 5 minutes</bullet> +<bullet>Turn off when it gets *bright enough*</bullet> +<bullet>Turn on when a human enters the room and it's *darkish*</bullet> +<bullet>Turn on when it turns *darkish* and there is a human there</bullet> +</list> + +<div effect="fade-in"> +<break/> +<blurb>*Ceiling Office Light*</blurb> +<list> +<bullet>Brighten when you enter the room</bullet> +<bullet>Dim when you leave the room</bullet> +<bullet>Turn off if nobody is in the room for more than 5 minutes</bullet> +<bullet>Turn off when it's *bright enough*</bullet> +<bullet>Turn on when its *darkish*</bullet> +<bullet>Turn on when you enter the room and it is *darkish*</bullet> +</list> +</div> +</slide> diff --git a/slides/iot/office-lights-turn-off-bright-enough.xml b/slides/iot/office-lights-turn-off-bright-enough.xml new file mode 100644 index 00000000..a25601d4 --- /dev/null +++ b/slides/iot/office-lights-turn-off-bright-enough.xml @@ -0,0 +1,21 @@ +<slide> +<title>Turn Off When It's Bright</title> + +<div class="light-bg right-side"> +<image filename="iot-motion-detector.jpeg"/> +<blurb align="center" class="small">Motion Detector</blurb> +</div> + +<blurb>Standing Office Light</blurb> +<list> +<bullet>Turn off when it gets *bright enough*</bullet> +</list> + +<blurb>Ceiling Office Light</blurb> +<list> +<bullet>Turn off when it's *bright enough*</bullet> +</list> + +<image filename="ha-action-turn-lights-off-bright.png"/> + +</slide> diff --git a/slides/iot/office-lights-turn-off-leave.xml b/slides/iot/office-lights-turn-off-leave.xml new file mode 100644 index 00000000..872ebe63 --- /dev/null +++ b/slides/iot/office-lights-turn-off-leave.xml @@ -0,0 +1,21 @@ +<slide> +<title>Turn Off When Leaving</title> + +<div class="light-bg right-side"> +<image filename="iot-human-detector.jpeg"/> +<blurb align="center" class="small">Human Presense Sensor</blurb> +</div> + +<blurb>Standing Office Light</blurb> +<list> +<bullet>Turn off if you leave for 5 minutes</bullet> +</list> + +<blurb>Ceiling Office Light</blurb> +<list> +<bullet>Turn off if nobody is in the room for more than 5 minutes</bullet> +</list> + +<image filename="ha-action-turn-lights-off.png"/> + +</slide> diff --git a/slides/iot/office-lights-turn-on.xml b/slides/iot/office-lights-turn-on.xml new file mode 100644 index 00000000..0ff156c1 --- /dev/null +++ b/slides/iot/office-lights-turn-on.xml @@ -0,0 +1,29 @@ +<slide> +<title>Turn On When It's Dark</title> + +<div class="light-bg right-side"> +<image filename="ha-actions-turn-lights-on.png"/> +</div> + +<div class="left-side"> +<blurb>Standing Office Light</blurb> +<list> +<bullet>Turn on when a human enters the room and it's *darkish*</bullet> +<bullet>Turn on when it turns *darkish* and there is a human there</bullet> +</list> + +<blurb>Ceiling Office Light</blurb> +<list> +<bullet>Turn on when its *darkish*</bullet> +<bullet>Turn on when you enter the room and it is *darkish*</bullet> +</list> +<break/> +<blurb>Needs a filter helper to provide smoothed value</blurb> +</div> + +<div class="light-bg right-side"> +<image filename="ha-smooth-brightness.png"/> +</div> + +</slide> + diff --git a/slides/iot/party-lights.gif b/slides/iot/party-lights.gif new file mode 100644 index 00000000..9a10b6e7 Binary files /dev/null and b/slides/iot/party-lights.gif differ diff --git a/slides/iot/smart-plug-1.xml b/slides/iot/smart-plug-1.xml new file mode 100644 index 00000000..991faf76 --- /dev/null +++ b/slides/iot/smart-plug-1.xml @@ -0,0 +1,15 @@ +<slide background="iot-smartlife-plug.jpeg"> +<title>SmartLife Plug</title> + +<div effect="fade-in"> +<break lines="21"/> +<div class="light-bg left-side"> +<break lines="1"/> +<list> + <bullet>Requires an app</bullet> + <bullet>Requires the internet</bullet> +</list> +<break lines="1"/> +</div> +</div> +</slide> diff --git a/slides/iot/streamdeck.xml b/slides/iot/streamdeck.xml new file mode 100644 index 00000000..99420b1a --- /dev/null +++ b/slides/iot/streamdeck.xml @@ -0,0 +1,60 @@ +<slide background="iot-streamdeck-home.jpeg"> + +<div class="left-side"> +<break lines="8"/> +<div class="light-bg"> +<div effect="fade-in"> +<list><bullet>Run a Shell Command</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>A Clock</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Control My Streaming Light</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>The Brightness of the Stream Deck</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Time Tracking</bullet></list> +</div> +<div effect="fade-in"> +<list><bullet>Opening Other Pages</bullet></list> +</div> +</div> +</div> + +<div effect="fade-in"> +<div class="light-bg right-side"> +<example> +Home: + - Index: 0 + Type: pages + - Index: 5 + Type: clock + Arguments: + - Hue: 90 + - ClockName: "Xdebug" + - Index: 10 + Type: brightness + Arguments: + - LevelLow: 10 + - ImageLow: "bright-000.png" + - LevelNormal: 50 + - ImageNormal: "bright-050.png" + - LevelHigh: 90 + - ImageHigh: "bright-100.png" + - Index: 11 + Type: litra + Arguments: + - 0: "4000,25" + - 3: "6500,80" + - Index: 13 + Type: command + Image: "lock.png" + Arguments: + - Command: "/home/derick/bin/obs/lock.sh" +</example> +</div> +</div> +</slide> diff --git a/slides/iot/the_internet_from_the_it_crowd.jpeg b/slides/iot/the_internet_from_the_it_crowd.jpeg new file mode 100644 index 00000000..18be884c Binary files /dev/null and b/slides/iot/the_internet_from_the_it_crowd.jpeg differ diff --git a/slides/iot/varying-light-smoothed.xml b/slides/iot/varying-light-smoothed.xml new file mode 100644 index 00000000..70e0f967 --- /dev/null +++ b/slides/iot/varying-light-smoothed.xml @@ -0,0 +1,6 @@ +<slide> +<title>Varying Light Smoothed</title> + +<image filename="ha-luminance-both.png"/> + +</slide> diff --git a/slides/iot/varying-light.xml b/slides/iot/varying-light.xml new file mode 100644 index 00000000..5918ef53 --- /dev/null +++ b/slides/iot/varying-light.xml @@ -0,0 +1,6 @@ +<slide> +<title>Varying Light</title> + +<image filename="ha-luminance-non-smooth.png"/> + +</slide> diff --git a/slides/iot/wishing-tree.xml b/slides/iot/wishing-tree.xml new file mode 100644 index 00000000..54bd8244 --- /dev/null +++ b/slides/iot/wishing-tree.xml @@ -0,0 +1,23 @@ +<slide> +<title>Christmas Tree</title> + +<div class="light-bg left-side"> +<image filename="iot-wedding-tree.jpeg"/> +</div> + +<div effect="fade-in"> +<div class="light-bg right-side"> +<image filename="iot-wedding-tree-switch.jpeg"/> +<blurb align="center">The "Easy to Reach" Switch</blurb> +</div> +</div> + +<div effect="fade-in"> +<div class="light-bg right-side"> +<break lines="2"/> +<blurb align="center">Now Automated</blurb> +<image filename="ha-tree-lights.png"/> +</div> +</div> + +</slide> diff --git a/slides/iot/zigbee-network.xml b/slides/iot/zigbee-network.xml new file mode 100644 index 00000000..957d5f10 --- /dev/null +++ b/slides/iot/zigbee-network.xml @@ -0,0 +1,15 @@ +<slide background="ha-zigbee-network.png"> +<title>Zigbee</title> + +<break lines="21"/> +<div class="light-bg"> +<break lines="1"/> +<list> + <bullet>Coordinator: Controls the network</bullet> + <bullet>Routers: Mains Powered Tech, with forwarding</bullet> + <bullet>End Devices: Battery Operated Sensors</bullet> +</list> +<break lines="1"/> +</div> + +</slide> diff --git a/templates/default/sub.ezt b/templates/default/sub.ezt new file mode 100644 index 00000000..da47e236 --- /dev/null +++ b/templates/default/sub.ezt @@ -0,0 +1,2 @@ +{use $node} +<sub>{$node->nodeValue}</sub>

« previous php.pres (#2508) next »