Hacker News new | ask | show | jobs
by sprior 1516 days ago
Not a lot of code but a somewhat different use of Prolog than you're likely to see elsewhere. I used my fork of a MQTT library for Prolog (https://github.com/sprior/swi-mqtt-pack) to implement the central controller for my home automation system. The system responds to MQTT events and then coordinates the appropriate action by sending MQTT messages to other home services. Recent versions of SWI-Prolog also support redis and I've started using that to store device configuration and state between services. The MQTT version is actually a reimplementation of my previous version which used CORBA for inter-service communication.

I don't distribute the home automation code however it's pretty specific to my house. The MQTT library provides some building block examples.

You can also see some other comments I've made on HN which describe some other details.

1 comments

That is cool! How compact is code that sets groups of behavior? Can you paste any examples? This seems like one of the really powerful aspects of Prolog. That we can work on the microscopic level, and the computer can prove correctness or find solutions to competing constraints.
Here's part of a sample sequence: 1) Smarthome gets a notification of a vehicle detected in the driveway 2) sends a request to get an image from the driveway camera 3) gets the image, sends it off for storage and analysis 4) sends it to an image recognition service which returns a description(make/model/color + other info) as JSON 5) receives analysis, matches it to known vehicles and announces the results

The send_display_vehicle_id(Id) in the end actually does a lot, it queries redis for previously announced display type devices, then looks up the capabilities (bit depth, resolution) of each device and formats accordingly then sends the display request for each. Also send_android_notification sends the request to some Java code that initiates a push message to my phone and watch.

None of this is rocket science in terms of Prolog message(MQTTPathAsList, MessageBody) is my general predicate for handling an incoming MQTT message once I've subscribed to it and it's convenient to deal with a MQTT topic path as a list.

message(['Smarthome','Notify', 'vehicle','motion'],_):- log('brain saw vehicle motion'), get_short_timestamp(S), atomic_list_concat([S, ' Vehicle Motion'], NotificationMessage), send_android_notification('Smarthome', NotificationMessage), request_image('alibi4').

request_image(Camera) :- publish(['Smarthome', 'Video', Camera, 'brain', 'request']).

message(['Smarthome','Video', _ ,'brain','response'],Image):- store_image(Image, 'brain'), analyze_image(Image, 'brain').

analyze_image(Image, Id) :- publish(['Smarthome', 'Sighthound', 'analyze', Id], Image).

message(['Smarthome','Vehicle', 'Sighthound'],VehicleJson):- vehicle_id(VehicleJson, Id), get_short_timestamp(S), atomic_list_concat([S, ' brain saw vehicle: ', Id], NotificationMessage), send_android_notification('vehicle', NotificationMessage), send_display_vehicle_id(Id), atom_concat(Id, VehicleJson, Description), atom_concat('brain saw vehicle: ', Description, Message), log(Message).